1 //===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the clang::ParseAST method. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Parse/ParseAST.h" 15 #include "clang/Sema/Sema.h" 16 #include "clang/Sema/CodeCompleteConsumer.h" 17 #include "clang/Sema/SemaConsumer.h" 18 #include "clang/Sema/ExternalSemaSource.h" 19 #include "clang/AST/ASTConsumer.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/ExternalASTSource.h" 22 #include "clang/AST/Stmt.h" 23 #include "clang/Parse/Parser.h" 24 #include "llvm/ADT/OwningPtr.h" 25 #include "llvm/Support/CrashRecoveryContext.h" 26 #include <cstdio> 27 28 using namespace clang; 29 30 //===----------------------------------------------------------------------===// 31 // Public interface to the file 32 //===----------------------------------------------------------------------===// 33 34 /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as 35 /// the file is parsed. This inserts the parsed decls into the translation unit 36 /// held by Ctx. 37 /// 38 void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, 39 ASTContext &Ctx, bool PrintStats, 40 TranslationUnitKind TUKind, 41 CodeCompleteConsumer *CompletionConsumer) { 42 43 llvm::OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer, 44 TUKind, 45 CompletionConsumer)); 46 47 // Recover resources if we crash before exiting this method. 48 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleaupSema(S.get()); 49 50 ParseAST(*S.get(), PrintStats); 51 } 52 53 void clang::ParseAST(Sema &S, bool PrintStats) { 54 // Collect global stats on Decls/Stmts (until we have a module streamer). 55 if (PrintStats) { 56 Decl::CollectingStats(true); 57 Stmt::CollectingStats(true); 58 } 59 60 // Also turn on collection of stats inside of the Sema object. 61 bool OldCollectStats = PrintStats; 62 std::swap(OldCollectStats, S.CollectStats); 63 64 ASTConsumer *Consumer = &S.getASTConsumer(); 65 66 llvm::OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S)); 67 Parser &P = *ParseOP.get(); 68 69 PrettyStackTraceParserEntry CrashInfo(P); 70 71 // Recover resources if we crash before exiting this method. 72 llvm::CrashRecoveryContextCleanupRegistrar<Parser> 73 CleaupParser(ParseOP.get()); 74 75 S.getPreprocessor().EnterMainSourceFile(); 76 P.Initialize(); 77 S.Initialize(); 78 79 if (ExternalASTSource *External = S.getASTContext().getExternalSource()) 80 External->StartTranslationUnit(Consumer); 81 82 Parser::DeclGroupPtrTy ADecl; 83 84 while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file. 85 // If we got a null return and something *was* parsed, ignore it. This 86 // is due to a top-level semicolon, an action override, or a parse error 87 // skipping something. 88 if (ADecl) 89 Consumer->HandleTopLevelDecl(ADecl.get()); 90 }; 91 // Check for any pending objective-c implementation decl. 92 while ((ADecl = P.FinishPendingObjCActions())) 93 Consumer->HandleTopLevelDecl(ADecl.get()); 94 95 // Process any TopLevelDecls generated by #pragma weak. 96 for (SmallVector<Decl*,2>::iterator 97 I = S.WeakTopLevelDecls().begin(), 98 E = S.WeakTopLevelDecls().end(); I != E; ++I) 99 Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); 100 101 Consumer->HandleTranslationUnit(S.getASTContext()); 102 103 std::swap(OldCollectStats, S.CollectStats); 104 if (PrintStats) { 105 llvm::errs() << "\nSTATISTICS:\n"; 106 P.getActions().PrintStats(); 107 S.getASTContext().PrintStats(); 108 Decl::PrintStats(); 109 Stmt::PrintStats(); 110 Consumer->PrintStats(); 111 } 112 } 113