2008-02-06 08:23:21 +08:00
|
|
|
//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-02-06 08:23:21 +08:00
|
|
|
// This file implements the clang::ParseAST method.
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-02-06 08:23:21 +08:00
|
|
|
#include "clang/Sema/ParseAST.h"
|
2007-03-01 03:32:13 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2007-09-16 06:56:56 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
2008-05-20 08:43:19 +08:00
|
|
|
#include "clang/AST/TranslationUnit.h"
|
2006-11-10 12:58:55 +08:00
|
|
|
#include "Sema.h"
|
2006-08-17 14:28:25 +08:00
|
|
|
#include "clang/Parse/Action.h"
|
|
|
|
#include "clang/Parse/Parser.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Public interface to the file
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-09-16 06:56:56 +08:00
|
|
|
/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
|
2007-11-03 14:24:16 +08:00
|
|
|
/// the file is parsed. This takes ownership of the ASTConsumer and
|
|
|
|
/// ultimately deletes it.
|
2007-12-20 06:51:13 +08:00
|
|
|
void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, bool PrintStats) {
|
2007-09-16 06:56:56 +08:00
|
|
|
// Collect global stats on Decls/Stmts (until we have a module streamer).
|
|
|
|
if (PrintStats) {
|
|
|
|
Decl::CollectingStats(true);
|
|
|
|
Stmt::CollectingStats(true);
|
|
|
|
}
|
|
|
|
|
2008-06-04 23:55:15 +08:00
|
|
|
ASTContext Context(PP.getLangOptions(), PP.getSourceManager(),
|
|
|
|
PP.getTargetInfo(),
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
PP.getIdentifierTable(), PP.getSelectorTable());
|
2007-09-16 06:56:56 +08:00
|
|
|
|
2008-06-04 23:55:15 +08:00
|
|
|
TranslationUnit TU(Context);
|
2008-06-17 02:00:42 +08:00
|
|
|
TU.SetOwnsDecls(false);
|
|
|
|
|
2008-05-27 12:23:47 +08:00
|
|
|
|
|
|
|
Sema S(PP, Context, *Consumer);
|
|
|
|
Parser P(PP, S);
|
2008-02-06 08:15:02 +08:00
|
|
|
PP.EnterMainSourceFile();
|
|
|
|
|
|
|
|
// Initialize the parser.
|
|
|
|
P.Initialize();
|
2007-09-16 06:56:56 +08:00
|
|
|
|
2008-06-01 04:11:04 +08:00
|
|
|
Consumer->InitializeTU(TU);
|
2007-09-16 06:56:56 +08:00
|
|
|
|
2008-02-06 08:15:02 +08:00
|
|
|
Parser::DeclTy *ADecl;
|
2008-05-20 08:43:19 +08:00
|
|
|
|
2008-02-06 08:15:02 +08:00
|
|
|
while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
|
|
|
|
// If we got a null return and something *was* parsed, ignore it. This
|
|
|
|
// is due to a top-level semicolon, an action override, or a parse error
|
|
|
|
// skipping something.
|
2008-05-20 08:43:19 +08:00
|
|
|
if (ADecl) {
|
|
|
|
Decl* D = static_cast<Decl*>(ADecl);
|
|
|
|
TU.AddTopLevelDecl(D); // TranslationUnit now owns the Decl.
|
|
|
|
Consumer->HandleTopLevelDecl(D);
|
|
|
|
}
|
2008-02-06 08:15:02 +08:00
|
|
|
};
|
2007-10-27 03:46:17 +08:00
|
|
|
|
2007-09-16 06:56:56 +08:00
|
|
|
if (PrintStats) {
|
|
|
|
fprintf(stderr, "\nSTATISTICS:\n");
|
2008-02-06 08:15:02 +08:00
|
|
|
P.getActions().PrintStats();
|
2007-09-16 06:56:56 +08:00
|
|
|
Context.PrintStats();
|
|
|
|
Decl::PrintStats();
|
|
|
|
Stmt::PrintStats();
|
2007-11-03 14:24:16 +08:00
|
|
|
Consumer->PrintStats();
|
2007-09-16 06:56:56 +08:00
|
|
|
|
|
|
|
Decl::CollectingStats(false);
|
|
|
|
Stmt::CollectingStats(false);
|
|
|
|
}
|
2007-11-03 14:24:16 +08:00
|
|
|
|
|
|
|
delete Consumer;
|
2007-09-16 06:56:56 +08:00
|
|
|
}
|