// LLVM clang/lib/Frontend/CompilerInstance.cpp Line 1028 // clang::CompilerInstance::ExecuteAction for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { // Reset the ID tables if we are reusing the SourceManager and parsing // regular files. if (hasSourceManager() && !Act.isModelParsingAction()) getSourceManager().clearIDTables();
if (Act.BeginSourceFile(*this, FIF)) { if (llvm::Error Err = Act.Execute()) { consumeError(std::move(Err)); // FIXME this drops errors on the floor. } Act.EndSourceFile(); } }
// LLVM clang/lib/Frontend/FrontendAction.cpp Line 1125 voidASTFrontendAction::ExecuteAction(){ CompilerInstance &CI = getCompilerInstance(); if (!CI.hasPreprocessor()) return;
// FIXME: Move the truncation aspect of this into Sema, we delayed this till // here so the source manager would be initialized. if (hasCodeCompletionSupport() && !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) CI.createCodeCompletionConsumer();
// Use a code completion consumer? CodeCompleteConsumer *CompletionConsumer = nullptr; if (CI.hasCodeCompletionConsumer()) CompletionConsumer = &CI.getCodeCompletionConsumer();
if (!CI.hasSema()) CI.createSema(getTranslationUnitKind(), CompletionConsumer);
// LLVM clang/lib/Parse/ParseAST.cpp Line 114 voidclang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies){ // Collect global stats on Decls/Stmts (until we have a module streamer). if (PrintStats) { Decl::EnableStatistics(); Stmt::EnableStatistics(); }
// Also turn on collection of stats inside of the Sema object. bool OldCollectStats = PrintStats; std::swap(OldCollectStats, S.CollectStats);
// Initialize the template instantiation observer chain. // FIXME: See note on "finalize" below. initialize(S.TemplateInstCallbacks, S);
ASTConsumer *Consumer = &S.getASTConsumer();
std::unique_ptr<Parser> ParseOP( new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get();
// Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<Parser> CleanupParser(ParseOP.get());
S.getPreprocessor().EnterMainSourceFile(); ExternalASTSource *External = S.getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(Consumer);
// If a PCH through header is specified that does not have an include in // the source, or a PCH is being created with #pragma hdrstop with nothing // after the pragma, there won't be any tokens or a Lexer. bool HaveLexer = S.getPreprocessor().getCurrentLexer();
for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF; AtEOF = P.ParseTopLevelDecl(ADecl, ImportState)) { // 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. if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) return; } }
// Process any TopLevelDecls generated by #pragma weak. for (Decl *D : S.WeakTopLevelDecls()) Consumer->HandleTopLevelDecl(DeclGroupRef(D));
// For C++20 modules, the codegen for module initializers needs to be altered // and to be able to use a name based on the module name.
// At this point, we should know if we are building a non-header C++20 module. if (S.getLangOpts().CPlusPlusModules && !S.getLangOpts().IsHeaderFile && !S.getLangOpts().CurrentModule.empty()) { // If we are building the module from source, then the top level module // will be here. Module *CodegenModule = S.getCurrentModule(); bool Interface = true; if (CodegenModule) // We only use module initializers for interfaces (including partition // implementation units). Interface = S.currentModuleIsInterface(); else // If we are building the module from a PCM file, then the module can be // found here. CodegenModule = S.getPreprocessor().getCurrentModule(); // If neither. then .... assert(CodegenModule && "codegen for a module, but don't know which?"); if (Interface) S.getASTContext().setModuleForCodeGen(CodegenModule); } Consumer->HandleTranslationUnit(S.getASTContext());
// Finalize the template instantiation observer chain. // FIXME: This (and init.) should be done in the Sema class, but because // Sema does not have a reliable "Finalize" function (it has a // destructor, but it is not guaranteed to be called ("-disable-free")). // So, do the initialization above and do the finalization here: finalize(S.TemplateInstCallbacks, S);
std::swap(OldCollectStats, S.CollectStats); if (PrintStats) { llvm::errs() << "\nSTATISTICS:\n"; if (HaveLexer) P.getActions().PrintStats(); S.getASTContext().PrintStats(); Decl::PrintStats(); Stmt::PrintStats(); Consumer->PrintStats(); } }