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(); } }
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); // 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(); llvm::CrashRecoveryContextCleanupRegistrar<const void, ResetStackCleanup> CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<Parser> CleanupParser(ParseOP.get()); S.getPreprocessor().EnterMainSourceFile(); P.Initialize(); Parser::DeclGroupPtrTy ADecl; ExternalASTSource *External = S.getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(Consumer); for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF; AtEOF = P.ParseTopLevelDecl(ADecl)) { // 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)); 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"; P.getActions().PrintStats(); S.getASTContext().PrintStats(); Decl::PrintStats(); Stmt::PrintStats(); Consumer->PrintStats(); } }
bool IncrementalParser::Initialize(llvm::SmallVectorImpl<ParseResultTransaction>& result, bool isChildInterpreter) { m_TransactionPool.reset(new TransactionPool); if (hasCodeGenerator()) getCodeGenerator()->Initialize(getCI()->getASTContext()); CompilationOptions CO = m_Interpreter->makeDefaultCompilationOpts(); Transaction* CurT = beginTransaction(CO); Preprocessor& PP = m_CI->getPreprocessor(); DiagnosticsEngine& Diags = m_CI->getSema().getDiagnostics(); // Pull in PCH. const std::string& PCHFileName = m_CI->getInvocation().getPreprocessorOpts().ImplicitPCHInclude; if (!PCHFileName.empty()) { Transaction* PchT = beginTransaction(CO); DiagnosticErrorTrap Trap(Diags); m_CI->createPCHExternalASTSource(PCHFileName, true /*DisablePCHValidation*/, true /*AllowPCHWithCompilerErrors*/, 0 /*DeserializationListener*/, true /*OwnsDeserializationListener*/); result.push_back(endTransaction(PchT)); if (Trap.hasErrorOccurred()) { result.push_back(endTransaction(CurT)); return false; } } addClingPragmas(*m_Interpreter); // Must happen after attaching the PCH, else PCH elements will end up // being lexed. PP.EnterMainSourceFile(); Sema* TheSema = &m_CI->getSema(); m_Parser.reset(new Parser(PP, *TheSema, false /*skipFuncBodies*/)); // Initialize the parser after PP has entered the main source file. m_Parser->Initialize(); ExternalASTSource *External = TheSema->getASTContext().getExternalSource(); if (External) External->StartTranslationUnit(m_Consumer); // Start parsing the "main file" to warm up lexing (enter caching lex mode // for ParseInternal()'s call EnterSourceFile() to make sense. while (!m_Parser->ParseTopLevelDecl()) {} // If I belong to the parent Interpreter, am using C++, and -noruntime // wasn't given on command line, then #include <new> and check ABI if (!isChildInterpreter && m_CI->getLangOpts().CPlusPlus && !m_Interpreter->getOptions().NoRuntime) { // <new> is needed by the ValuePrinter so it's a good thing to include it. // We need to include it to determine the version number of the standard // library implementation. ParseInternal("#include <new>"); // That's really C++ ABI compatibility. C has other problems ;-) CheckABICompatibility(*m_Interpreter); } // DO NOT commit the transactions here: static initialization in these // transactions requires gCling through local_cxa_atexit(), but that has not // been defined yet! ParseResultTransaction PRT = endTransaction(CurT); result.push_back(PRT); return true; }