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 bool SkipFunctionBodies) { 43 44 OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer, 45 TUKind, 46 CompletionConsumer)); 47 48 // Recover resources if we crash before exiting this method. 49 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get()); 50 51 ParseAST(*S.get(), PrintStats, SkipFunctionBodies); 52 } 53 54 void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) { 55 // Collect global stats on Decls/Stmts (until we have a module streamer). 56 if (PrintStats) { 57 Decl::EnableStatistics(); 58 Stmt::EnableStatistics(); 59 } 60 61 // Also turn on collection of stats inside of the Sema object. 62 bool OldCollectStats = PrintStats; 63 std::swap(OldCollectStats, S.CollectStats); 64 65 ASTConsumer *Consumer = &S.getASTConsumer(); 66 67 OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S, 68 SkipFunctionBodies)); 69 Parser &P = *ParseOP.get(); 70 71 PrettyStackTraceParserEntry CrashInfo(P); 72 73 // Recover resources if we crash before exiting this method. 74 llvm::CrashRecoveryContextCleanupRegistrar<Parser> 75 CleanupParser(ParseOP.get()); 76 77 S.getPreprocessor().EnterMainSourceFile(); 78 P.Initialize(); 79 S.Initialize(); 80 81 if (ExternalASTSource *External = S.getASTContext().getExternalSource()) 82 External->StartTranslationUnit(Consumer); 83 84 bool Abort = false; 85 Parser::DeclGroupPtrTy ADecl; 86 87 while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file. 88 // If we got a null return and something *was* parsed, ignore it. This 89 // is due to a top-level semicolon, an action override, or a parse error 90 // skipping something. 91 if (ADecl) { 92 if (!Consumer->HandleTopLevelDecl(ADecl.get())) { 93 Abort = true; 94 break; 95 } 96 } 97 }; 98 99 if (Abort) 100 return; 101 102 // Process any TopLevelDecls generated by #pragma weak. 103 for (SmallVector<Decl*,2>::iterator 104 I = S.WeakTopLevelDecls().begin(), 105 E = S.WeakTopLevelDecls().end(); I != E; ++I) 106 Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); 107 108 Consumer->HandleTranslationUnit(S.getASTContext()); 109 110 std::swap(OldCollectStats, S.CollectStats); 111 if (PrintStats) { 112 llvm::errs() << "\nSTATISTICS:\n"; 113 P.getActions().PrintStats(); 114 S.getASTContext().PrintStats(); 115 Decl::PrintStats(); 116 Stmt::PrintStats(); 117 Consumer->PrintStats(); 118 } 119 } 120