void IncrementalParser::Initialize() { if (hasCodeGenerator()) getCodeGenerator()->Initialize(getCI()->getASTContext()); CompilationOptions CO; CO.DeclarationExtraction = 0; CO.ValuePrinting = CompilationOptions::VPDisabled; CO.CodeGeneration = hasCodeGenerator(); // pull in PCHs const std::string& PCHFileName = m_CI->getInvocation ().getPreprocessorOpts().ImplicitPCHInclude; if (!PCHFileName.empty()) { Transaction* CurT = beginTransaction(CO); m_CI->createPCHExternalASTSource(PCHFileName, true /*DisablePCHValidation*/, true /*AllowPCHWithCompilerErrors*/, 0 /*DeserializationListener*/); Transaction* EndedT = endTransaction(CurT); commitTransaction(EndedT); } Transaction* CurT = beginTransaction(CO); Sema* TheSema = &m_CI->getSema(); m_Parser.reset(new Parser(m_CI->getPreprocessor(), *TheSema, false /*skipFuncBodies*/)); m_CI->getPreprocessor().EnterMainSourceFile(); // Initialize the parser after we have entered the main source file. m_Parser->Initialize(); // Perform initialization that occurs after the parser has been initialized // but before it parses anything. Initializes the consumers too. TheSema->Initialize(); ExternalASTSource *External = TheSema->getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(m_Consumer); Transaction* EndedT = endTransaction(CurT); commitTransaction(EndedT); }
void clang::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); ASTConsumer *Consumer = &S.getASTConsumer(); OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); PrettyStackTraceParserEntry CrashInfo(P); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<Parser> CleanupParser(ParseOP.get()); S.getPreprocessor().EnterMainSourceFile(); P.Initialize(); S.Initialize(); // C11 6.9p1 says translation units must have at least one top-level // declaration. C++ doesn't have this restriction. We also don't want to // complain if we have a precompiled header, although technically if the PCH // is empty we should still emit the (pedantic) diagnostic. Parser::DeclGroupPtrTy ADecl; ExternalASTSource *External = S.getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(Consumer); if (P.ParseTopLevelDecl(ADecl)) { if (!External && !S.getLangOpts().CPlusPlus) P.Diag(diag::ext_empty_translation_unit); } else { do { // 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; } while (!P.ParseTopLevelDecl(ADecl)); } // Process any TopLevelDecls generated by #pragma weak. for (SmallVector<Decl*,2>::iterator I = S.WeakTopLevelDecls().begin(), E = S.WeakTopLevelDecls().end(); I != E; ++I) Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); Consumer->HandleTranslationUnit(S.getASTContext()); std::swap(OldCollectStats, S.CollectStats); if (PrintStats) { llvm::errs() << "\nSTATISTICS:\n"; P.getActions().PrintStats(); S.getASTContext().PrintStats(); Decl::PrintStats(); Stmt::PrintStats(); Consumer->PrintStats(); } }