clang API Documentation
00001 //===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the clang::ParseAST method. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Parse/ParseAST.h" 00015 #include "clang/AST/ASTConsumer.h" 00016 #include "clang/AST/ASTContext.h" 00017 #include "clang/AST/DeclCXX.h" 00018 #include "clang/AST/ExternalASTSource.h" 00019 #include "clang/AST/Stmt.h" 00020 #include "clang/Parse/ParseDiagnostic.h" 00021 #include "clang/Parse/Parser.h" 00022 #include "clang/Sema/CodeCompleteConsumer.h" 00023 #include "clang/Sema/ExternalSemaSource.h" 00024 #include "clang/Sema/Sema.h" 00025 #include "clang/Sema/SemaConsumer.h" 00026 #include "llvm/Support/CrashRecoveryContext.h" 00027 #include <cstdio> 00028 #include <memory> 00029 00030 using namespace clang; 00031 00032 namespace { 00033 00034 /// If a crash happens while the parser is active, an entry is printed for it. 00035 class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry { 00036 const Parser &P; 00037 public: 00038 PrettyStackTraceParserEntry(const Parser &p) : P(p) {} 00039 void print(raw_ostream &OS) const override; 00040 }; 00041 00042 /// If a crash happens while the parser is active, print out a line indicating 00043 /// what the current token is. 00044 void PrettyStackTraceParserEntry::print(raw_ostream &OS) const { 00045 const Token &Tok = P.getCurToken(); 00046 if (Tok.is(tok::eof)) { 00047 OS << "<eof> parser at end of file\n"; 00048 return; 00049 } 00050 00051 if (Tok.getLocation().isInvalid()) { 00052 OS << "<unknown> parser at unknown location\n"; 00053 return; 00054 } 00055 00056 const Preprocessor &PP = P.getPreprocessor(); 00057 Tok.getLocation().print(OS, PP.getSourceManager()); 00058 if (Tok.isAnnotation()) { 00059 OS << ": at annotation token\n"; 00060 } else { 00061 // Do the equivalent of PP.getSpelling(Tok) except for the parts that would 00062 // allocate memory. 00063 bool Invalid = false; 00064 const SourceManager &SM = P.getPreprocessor().getSourceManager(); 00065 unsigned Length = Tok.getLength(); 00066 const char *Spelling = SM.getCharacterData(Tok.getLocation(), &Invalid); 00067 if (Invalid) { 00068 OS << ": unknown current parser token\n"; 00069 return; 00070 } 00071 OS << ": current parser token '" << StringRef(Spelling, Length) << "'\n"; 00072 } 00073 } 00074 00075 } // namespace 00076 00077 //===----------------------------------------------------------------------===// 00078 // Public interface to the file 00079 //===----------------------------------------------------------------------===// 00080 00081 /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as 00082 /// the file is parsed. This inserts the parsed decls into the translation unit 00083 /// held by Ctx. 00084 /// 00085 void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, 00086 ASTContext &Ctx, bool PrintStats, 00087 TranslationUnitKind TUKind, 00088 CodeCompleteConsumer *CompletionConsumer, 00089 bool SkipFunctionBodies) { 00090 00091 std::unique_ptr<Sema> S( 00092 new Sema(PP, Ctx, *Consumer, TUKind, CompletionConsumer)); 00093 00094 // Recover resources if we crash before exiting this method. 00095 llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get()); 00096 00097 ParseAST(*S.get(), PrintStats, SkipFunctionBodies); 00098 } 00099 00100 void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) { 00101 // Collect global stats on Decls/Stmts (until we have a module streamer). 00102 if (PrintStats) { 00103 Decl::EnableStatistics(); 00104 Stmt::EnableStatistics(); 00105 } 00106 00107 // Also turn on collection of stats inside of the Sema object. 00108 bool OldCollectStats = PrintStats; 00109 std::swap(OldCollectStats, S.CollectStats); 00110 00111 ASTConsumer *Consumer = &S.getASTConsumer(); 00112 00113 std::unique_ptr<Parser> ParseOP( 00114 new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); 00115 Parser &P = *ParseOP.get(); 00116 00117 PrettyStackTraceParserEntry CrashInfo(P); 00118 00119 // Recover resources if we crash before exiting this method. 00120 llvm::CrashRecoveryContextCleanupRegistrar<Parser> 00121 CleanupParser(ParseOP.get()); 00122 00123 S.getPreprocessor().EnterMainSourceFile(); 00124 P.Initialize(); 00125 00126 // C11 6.9p1 says translation units must have at least one top-level 00127 // declaration. C++ doesn't have this restriction. We also don't want to 00128 // complain if we have a precompiled header, although technically if the PCH 00129 // is empty we should still emit the (pedantic) diagnostic. 00130 Parser::DeclGroupPtrTy ADecl; 00131 ExternalASTSource *External = S.getASTContext().getExternalSource(); 00132 if (External) 00133 External->StartTranslationUnit(Consumer); 00134 00135 if (P.ParseTopLevelDecl(ADecl)) { 00136 if (!External && !S.getLangOpts().CPlusPlus) 00137 P.Diag(diag::ext_empty_translation_unit); 00138 } else { 00139 do { 00140 // If we got a null return and something *was* parsed, ignore it. This 00141 // is due to a top-level semicolon, an action override, or a parse error 00142 // skipping something. 00143 if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) 00144 return; 00145 } while (!P.ParseTopLevelDecl(ADecl)); 00146 } 00147 00148 // Process any TopLevelDecls generated by #pragma weak. 00149 for (SmallVectorImpl<Decl *>::iterator 00150 I = S.WeakTopLevelDecls().begin(), 00151 E = S.WeakTopLevelDecls().end(); I != E; ++I) 00152 Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); 00153 00154 Consumer->HandleTranslationUnit(S.getASTContext()); 00155 00156 std::swap(OldCollectStats, S.CollectStats); 00157 if (PrintStats) { 00158 llvm::errs() << "\nSTATISTICS:\n"; 00159 P.getActions().PrintStats(); 00160 S.getASTContext().PrintStats(); 00161 Decl::PrintStats(); 00162 Stmt::PrintStats(); 00163 Consumer->PrintStats(); 00164 } 00165 }