ParseAST.cpp revision 478851c3ed6bd784e7377dffd8e57b200c1b9ba9
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/Parse/ParseDiagnostic.h" 16#include "clang/Sema/Sema.h" 17#include "clang/Sema/CodeCompleteConsumer.h" 18#include "clang/Sema/SemaConsumer.h" 19#include "clang/Sema/ExternalSemaSource.h" 20#include "clang/AST/ASTConsumer.h" 21#include "clang/AST/ASTContext.h" 22#include "clang/AST/DeclCXX.h" 23#include "clang/AST/ExternalASTSource.h" 24#include "clang/AST/Stmt.h" 25#include "clang/Parse/Parser.h" 26#include "llvm/ADT/OwningPtr.h" 27#include "llvm/Support/CrashRecoveryContext.h" 28#include <cstdio> 29 30using namespace clang; 31 32//===----------------------------------------------------------------------===// 33// Public interface to the file 34//===----------------------------------------------------------------------===// 35 36/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as 37/// the file is parsed. This inserts the parsed decls into the translation unit 38/// held by Ctx. 39/// 40void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, 41 ASTContext &Ctx, bool PrintStats, 42 TranslationUnitKind TUKind, 43 CodeCompleteConsumer *CompletionConsumer, 44 bool SkipFunctionBodies) { 45 46 OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer, 47 TUKind, 48 CompletionConsumer)); 49 50 // Recover resources if we crash before exiting this method. 51 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get()); 52 53 ParseAST(*S.get(), PrintStats, SkipFunctionBodies); 54} 55 56void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) { 57 // Collect global stats on Decls/Stmts (until we have a module streamer). 58 if (PrintStats) { 59 Decl::EnableStatistics(); 60 Stmt::EnableStatistics(); 61 } 62 63 // Also turn on collection of stats inside of the Sema object. 64 bool OldCollectStats = PrintStats; 65 std::swap(OldCollectStats, S.CollectStats); 66 67 ASTConsumer *Consumer = &S.getASTConsumer(); 68 69 OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S, 70 SkipFunctionBodies)); 71 Parser &P = *ParseOP.get(); 72 73 PrettyStackTraceParserEntry CrashInfo(P); 74 75 // Recover resources if we crash before exiting this method. 76 llvm::CrashRecoveryContextCleanupRegistrar<Parser> 77 CleanupParser(ParseOP.get()); 78 79 S.getPreprocessor().EnterMainSourceFile(); 80 P.Initialize(); 81 S.Initialize(); 82 83 // C11 6.9p1 says translation units must have at least one top-level 84 // declaration. C++ doesn't have this restriction. We also don't want to 85 // complain if we have a precompiled header, although technically if the PCH 86 // is empty we should still emit the (pedantic) diagnostic. 87 Parser::DeclGroupPtrTy ADecl; 88 ExternalASTSource *External = S.getASTContext().getExternalSource(); 89 if (External) 90 External->StartTranslationUnit(Consumer); 91 92 if (P.ParseTopLevelDecl(ADecl)) { 93 if (!External && !S.getLangOpts().CPlusPlus) 94 P.Diag(diag::ext_empty_translation_unit); 95 } else { 96 do { 97 // If we got a null return and something *was* parsed, ignore it. This 98 // is due to a top-level semicolon, an action override, or a parse error 99 // skipping something. 100 if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) 101 return; 102 } while (!P.ParseTopLevelDecl(ADecl)); 103 } 104 105 // Process any TopLevelDecls generated by #pragma weak. 106 for (SmallVector<Decl*,2>::iterator 107 I = S.WeakTopLevelDecls().begin(), 108 E = S.WeakTopLevelDecls().end(); I != E; ++I) 109 Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); 110 111 Consumer->HandleTranslationUnit(S.getASTContext()); 112 113 std::swap(OldCollectStats, S.CollectStats); 114 if (PrintStats) { 115 llvm::errs() << "\nSTATISTICS:\n"; 116 P.getActions().PrintStats(); 117 S.getASTContext().PrintStats(); 118 Decl::PrintStats(); 119 Stmt::PrintStats(); 120 Consumer->PrintStats(); 121 } 122} 123