1fe6060f1SDimitry Andric //===--------- IncrementalParser.cpp - Incremental Compilation -----------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric // 9fe6060f1SDimitry Andric // This file implements the class which performs incremental code compilation. 10fe6060f1SDimitry Andric // 11fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include "IncrementalParser.h" 14fe6060f1SDimitry Andric #include "clang/AST/DeclContextInternals.h" 15fe6060f1SDimitry Andric #include "clang/CodeGen/BackendUtil.h" 16fe6060f1SDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 17fe6060f1SDimitry Andric #include "clang/CodeGen/ModuleBuilder.h" 18fe6060f1SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 19fe6060f1SDimitry Andric #include "clang/Frontend/FrontendAction.h" 20fe6060f1SDimitry Andric #include "clang/FrontendTool/Utils.h" 21*06c3fb27SDimitry Andric #include "clang/Interpreter/Interpreter.h" 22fe6060f1SDimitry Andric #include "clang/Parse/Parser.h" 23fe6060f1SDimitry Andric #include "clang/Sema/Sema.h" 24fe6060f1SDimitry Andric #include "llvm/Option/ArgList.h" 25fe6060f1SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h" 26fe6060f1SDimitry Andric #include "llvm/Support/Error.h" 27fe6060f1SDimitry Andric #include "llvm/Support/Timer.h" 28fe6060f1SDimitry Andric 29fe6060f1SDimitry Andric #include <sstream> 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric namespace clang { 32fe6060f1SDimitry Andric 33*06c3fb27SDimitry Andric class IncrementalASTConsumer final : public ASTConsumer { 34*06c3fb27SDimitry Andric Interpreter &Interp; 35*06c3fb27SDimitry Andric std::unique_ptr<ASTConsumer> Consumer; 36*06c3fb27SDimitry Andric 37*06c3fb27SDimitry Andric public: 38*06c3fb27SDimitry Andric IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr<ASTConsumer> C) 39*06c3fb27SDimitry Andric : Interp(InterpRef), Consumer(std::move(C)) {} 40*06c3fb27SDimitry Andric 41*06c3fb27SDimitry Andric bool HandleTopLevelDecl(DeclGroupRef DGR) override final { 42*06c3fb27SDimitry Andric if (DGR.isNull()) 43*06c3fb27SDimitry Andric return true; 44*06c3fb27SDimitry Andric if (!Consumer) 45*06c3fb27SDimitry Andric return true; 46*06c3fb27SDimitry Andric 47*06c3fb27SDimitry Andric for (Decl *D : DGR) 48*06c3fb27SDimitry Andric if (auto *TSD = llvm::dyn_cast<TopLevelStmtDecl>(D); 49*06c3fb27SDimitry Andric TSD && TSD->isSemiMissing()) 50*06c3fb27SDimitry Andric TSD->setStmt(Interp.SynthesizeExpr(cast<Expr>(TSD->getStmt()))); 51*06c3fb27SDimitry Andric 52*06c3fb27SDimitry Andric return Consumer->HandleTopLevelDecl(DGR); 53*06c3fb27SDimitry Andric } 54*06c3fb27SDimitry Andric void HandleTranslationUnit(ASTContext &Ctx) override final { 55*06c3fb27SDimitry Andric Consumer->HandleTranslationUnit(Ctx); 56*06c3fb27SDimitry Andric } 57*06c3fb27SDimitry Andric void HandleInlineFunctionDefinition(FunctionDecl *D) override final { 58*06c3fb27SDimitry Andric Consumer->HandleInlineFunctionDefinition(D); 59*06c3fb27SDimitry Andric } 60*06c3fb27SDimitry Andric void HandleInterestingDecl(DeclGroupRef D) override final { 61*06c3fb27SDimitry Andric Consumer->HandleInterestingDecl(D); 62*06c3fb27SDimitry Andric } 63*06c3fb27SDimitry Andric void HandleTagDeclDefinition(TagDecl *D) override final { 64*06c3fb27SDimitry Andric Consumer->HandleTagDeclDefinition(D); 65*06c3fb27SDimitry Andric } 66*06c3fb27SDimitry Andric void HandleTagDeclRequiredDefinition(const TagDecl *D) override final { 67*06c3fb27SDimitry Andric Consumer->HandleTagDeclRequiredDefinition(D); 68*06c3fb27SDimitry Andric } 69*06c3fb27SDimitry Andric void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final { 70*06c3fb27SDimitry Andric Consumer->HandleCXXImplicitFunctionInstantiation(D); 71*06c3fb27SDimitry Andric } 72*06c3fb27SDimitry Andric void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final { 73*06c3fb27SDimitry Andric Consumer->HandleTopLevelDeclInObjCContainer(D); 74*06c3fb27SDimitry Andric } 75*06c3fb27SDimitry Andric void HandleImplicitImportDecl(ImportDecl *D) override final { 76*06c3fb27SDimitry Andric Consumer->HandleImplicitImportDecl(D); 77*06c3fb27SDimitry Andric } 78*06c3fb27SDimitry Andric void CompleteTentativeDefinition(VarDecl *D) override final { 79*06c3fb27SDimitry Andric Consumer->CompleteTentativeDefinition(D); 80*06c3fb27SDimitry Andric } 81*06c3fb27SDimitry Andric void CompleteExternalDeclaration(VarDecl *D) override final { 82*06c3fb27SDimitry Andric Consumer->CompleteExternalDeclaration(D); 83*06c3fb27SDimitry Andric } 84*06c3fb27SDimitry Andric void AssignInheritanceModel(CXXRecordDecl *RD) override final { 85*06c3fb27SDimitry Andric Consumer->AssignInheritanceModel(RD); 86*06c3fb27SDimitry Andric } 87*06c3fb27SDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final { 88*06c3fb27SDimitry Andric Consumer->HandleCXXStaticMemberVarInstantiation(D); 89*06c3fb27SDimitry Andric } 90*06c3fb27SDimitry Andric void HandleVTable(CXXRecordDecl *RD) override final { 91*06c3fb27SDimitry Andric Consumer->HandleVTable(RD); 92*06c3fb27SDimitry Andric } 93*06c3fb27SDimitry Andric ASTMutationListener *GetASTMutationListener() override final { 94*06c3fb27SDimitry Andric return Consumer->GetASTMutationListener(); 95*06c3fb27SDimitry Andric } 96*06c3fb27SDimitry Andric ASTDeserializationListener *GetASTDeserializationListener() override final { 97*06c3fb27SDimitry Andric return Consumer->GetASTDeserializationListener(); 98*06c3fb27SDimitry Andric } 99*06c3fb27SDimitry Andric void PrintStats() override final { Consumer->PrintStats(); } 100*06c3fb27SDimitry Andric bool shouldSkipFunctionBody(Decl *D) override final { 101*06c3fb27SDimitry Andric return Consumer->shouldSkipFunctionBody(D); 102*06c3fb27SDimitry Andric } 103*06c3fb27SDimitry Andric static bool classof(const clang::ASTConsumer *) { return true; } 104*06c3fb27SDimitry Andric }; 105*06c3fb27SDimitry Andric 106fe6060f1SDimitry Andric /// A custom action enabling the incremental processing functionality. 107fe6060f1SDimitry Andric /// 108fe6060f1SDimitry Andric /// The usual \p FrontendAction expects one call to ExecuteAction and once it 109fe6060f1SDimitry Andric /// sees a call to \p EndSourceFile it deletes some of the important objects 110fe6060f1SDimitry Andric /// such as \p Preprocessor and \p Sema assuming no further input will come. 111fe6060f1SDimitry Andric /// 112fe6060f1SDimitry Andric /// \p IncrementalAction ensures it keep its underlying action's objects alive 113fe6060f1SDimitry Andric /// as long as the \p IncrementalParser needs them. 114fe6060f1SDimitry Andric /// 115fe6060f1SDimitry Andric class IncrementalAction : public WrapperFrontendAction { 116fe6060f1SDimitry Andric private: 117fe6060f1SDimitry Andric bool IsTerminating = false; 118fe6060f1SDimitry Andric 119fe6060f1SDimitry Andric public: 120fe6060f1SDimitry Andric IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, 121fe6060f1SDimitry Andric llvm::Error &Err) 122fe6060f1SDimitry Andric : WrapperFrontendAction([&]() { 123fe6060f1SDimitry Andric llvm::ErrorAsOutParameter EAO(&Err); 124fe6060f1SDimitry Andric std::unique_ptr<FrontendAction> Act; 125fe6060f1SDimitry Andric switch (CI.getFrontendOpts().ProgramAction) { 126fe6060f1SDimitry Andric default: 127fe6060f1SDimitry Andric Err = llvm::createStringError( 128fe6060f1SDimitry Andric std::errc::state_not_recoverable, 129fe6060f1SDimitry Andric "Driver initialization failed. " 130fe6060f1SDimitry Andric "Incremental mode for action %d is not supported", 131fe6060f1SDimitry Andric CI.getFrontendOpts().ProgramAction); 132fe6060f1SDimitry Andric return Act; 133fe6060f1SDimitry Andric case frontend::ASTDump: 134bdd1243dSDimitry Andric [[fallthrough]]; 135fe6060f1SDimitry Andric case frontend::ASTPrint: 136bdd1243dSDimitry Andric [[fallthrough]]; 137fe6060f1SDimitry Andric case frontend::ParseSyntaxOnly: 138fe6060f1SDimitry Andric Act = CreateFrontendAction(CI); 139fe6060f1SDimitry Andric break; 140349cc55cSDimitry Andric case frontend::PluginAction: 141bdd1243dSDimitry Andric [[fallthrough]]; 142fe6060f1SDimitry Andric case frontend::EmitAssembly: 143bdd1243dSDimitry Andric [[fallthrough]]; 144bdd1243dSDimitry Andric case frontend::EmitBC: 145bdd1243dSDimitry Andric [[fallthrough]]; 146fe6060f1SDimitry Andric case frontend::EmitObj: 147bdd1243dSDimitry Andric [[fallthrough]]; 148bdd1243dSDimitry Andric case frontend::PrintPreprocessedInput: 149bdd1243dSDimitry Andric [[fallthrough]]; 150fe6060f1SDimitry Andric case frontend::EmitLLVMOnly: 151fe6060f1SDimitry Andric Act.reset(new EmitLLVMOnlyAction(&LLVMCtx)); 152fe6060f1SDimitry Andric break; 153fe6060f1SDimitry Andric } 154fe6060f1SDimitry Andric return Act; 155fe6060f1SDimitry Andric }()) {} 156fe6060f1SDimitry Andric FrontendAction *getWrapped() const { return WrappedAction.get(); } 157fe6060f1SDimitry Andric TranslationUnitKind getTranslationUnitKind() override { 158fe6060f1SDimitry Andric return TU_Incremental; 159fe6060f1SDimitry Andric } 160fe6060f1SDimitry Andric void ExecuteAction() override { 161fe6060f1SDimitry Andric CompilerInstance &CI = getCompilerInstance(); 162fe6060f1SDimitry Andric assert(CI.hasPreprocessor() && "No PP!"); 163fe6060f1SDimitry Andric 164fe6060f1SDimitry Andric // FIXME: Move the truncation aspect of this into Sema, we delayed this till 165fe6060f1SDimitry Andric // here so the source manager would be initialized. 166fe6060f1SDimitry Andric if (hasCodeCompletionSupport() && 167fe6060f1SDimitry Andric !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) 168fe6060f1SDimitry Andric CI.createCodeCompletionConsumer(); 169fe6060f1SDimitry Andric 170fe6060f1SDimitry Andric // Use a code completion consumer? 171fe6060f1SDimitry Andric CodeCompleteConsumer *CompletionConsumer = nullptr; 172fe6060f1SDimitry Andric if (CI.hasCodeCompletionConsumer()) 173fe6060f1SDimitry Andric CompletionConsumer = &CI.getCodeCompletionConsumer(); 174fe6060f1SDimitry Andric 175fe6060f1SDimitry Andric Preprocessor &PP = CI.getPreprocessor(); 176fe6060f1SDimitry Andric PP.EnterMainSourceFile(); 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric if (!CI.hasSema()) 179fe6060f1SDimitry Andric CI.createSema(getTranslationUnitKind(), CompletionConsumer); 180fe6060f1SDimitry Andric } 181fe6060f1SDimitry Andric 182fe6060f1SDimitry Andric // Do not terminate after processing the input. This allows us to keep various 183fe6060f1SDimitry Andric // clang objects alive and to incrementally grow the current TU. 184fe6060f1SDimitry Andric void EndSourceFile() override { 185fe6060f1SDimitry Andric // The WrappedAction can be nullptr if we issued an error in the ctor. 186fe6060f1SDimitry Andric if (IsTerminating && getWrapped()) 187fe6060f1SDimitry Andric WrapperFrontendAction::EndSourceFile(); 188fe6060f1SDimitry Andric } 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric void FinalizeAction() { 191fe6060f1SDimitry Andric assert(!IsTerminating && "Already finalized!"); 192fe6060f1SDimitry Andric IsTerminating = true; 193fe6060f1SDimitry Andric EndSourceFile(); 194fe6060f1SDimitry Andric } 195fe6060f1SDimitry Andric }; 196fe6060f1SDimitry Andric 197*06c3fb27SDimitry Andric CodeGenerator *IncrementalParser::getCodeGen() const { 198*06c3fb27SDimitry Andric FrontendAction *WrappedAct = Act->getWrapped(); 199*06c3fb27SDimitry Andric if (!WrappedAct->hasIRSupport()) 200*06c3fb27SDimitry Andric return nullptr; 201*06c3fb27SDimitry Andric return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator(); 202*06c3fb27SDimitry Andric } 203*06c3fb27SDimitry Andric 204*06c3fb27SDimitry Andric IncrementalParser::IncrementalParser() {} 205*06c3fb27SDimitry Andric 206*06c3fb27SDimitry Andric IncrementalParser::IncrementalParser(Interpreter &Interp, 207*06c3fb27SDimitry Andric std::unique_ptr<CompilerInstance> Instance, 208fe6060f1SDimitry Andric llvm::LLVMContext &LLVMCtx, 209fe6060f1SDimitry Andric llvm::Error &Err) 210fe6060f1SDimitry Andric : CI(std::move(Instance)) { 211fe6060f1SDimitry Andric llvm::ErrorAsOutParameter EAO(&Err); 212fe6060f1SDimitry Andric Act = std::make_unique<IncrementalAction>(*CI, LLVMCtx, Err); 213fe6060f1SDimitry Andric if (Err) 214fe6060f1SDimitry Andric return; 215fe6060f1SDimitry Andric CI->ExecuteAction(*Act); 216*06c3fb27SDimitry Andric std::unique_ptr<ASTConsumer> IncrConsumer = 217*06c3fb27SDimitry Andric std::make_unique<IncrementalASTConsumer>(Interp, CI->takeASTConsumer()); 218*06c3fb27SDimitry Andric CI->setASTConsumer(std::move(IncrConsumer)); 219fe6060f1SDimitry Andric Consumer = &CI->getASTConsumer(); 220fe6060f1SDimitry Andric P.reset( 221fe6060f1SDimitry Andric new Parser(CI->getPreprocessor(), CI->getSema(), /*SkipBodies=*/false)); 222fe6060f1SDimitry Andric P->Initialize(); 223*06c3fb27SDimitry Andric 224*06c3fb27SDimitry Andric // An initial PTU is needed as CUDA includes some headers automatically 225*06c3fb27SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 226*06c3fb27SDimitry Andric if (auto E = PTU.takeError()) { 227*06c3fb27SDimitry Andric consumeError(std::move(E)); // FIXME 228*06c3fb27SDimitry Andric return; // PTU.takeError(); 229*06c3fb27SDimitry Andric } 230*06c3fb27SDimitry Andric 231*06c3fb27SDimitry Andric if (CodeGenerator *CG = getCodeGen()) { 232*06c3fb27SDimitry Andric std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); 233*06c3fb27SDimitry Andric CG->StartModule("incr_module_" + std::to_string(PTUs.size()), 234*06c3fb27SDimitry Andric M->getContext()); 235*06c3fb27SDimitry Andric PTU->TheModule = std::move(M); 236*06c3fb27SDimitry Andric assert(PTU->TheModule && "Failed to create initial PTU"); 237*06c3fb27SDimitry Andric } 238fe6060f1SDimitry Andric } 239fe6060f1SDimitry Andric 24081ad6265SDimitry Andric IncrementalParser::~IncrementalParser() { 24181ad6265SDimitry Andric P.reset(); 24281ad6265SDimitry Andric Act->FinalizeAction(); 24381ad6265SDimitry Andric } 244fe6060f1SDimitry Andric 245fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 246fe6060f1SDimitry Andric IncrementalParser::ParseOrWrapTopLevelDecl() { 247fe6060f1SDimitry Andric // Recover resources if we crash before exiting this method. 248fe6060f1SDimitry Andric Sema &S = CI->getSema(); 249fe6060f1SDimitry Andric llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S); 250fe6060f1SDimitry Andric Sema::GlobalEagerInstantiationScope GlobalInstantiations(S, /*Enabled=*/true); 251fe6060f1SDimitry Andric Sema::LocalEagerInstantiationScope LocalInstantiations(S); 252fe6060f1SDimitry Andric 253fe6060f1SDimitry Andric PTUs.emplace_back(PartialTranslationUnit()); 254fe6060f1SDimitry Andric PartialTranslationUnit &LastPTU = PTUs.back(); 255fe6060f1SDimitry Andric // Add a new PTU. 256fe6060f1SDimitry Andric ASTContext &C = S.getASTContext(); 257fe6060f1SDimitry Andric C.addTranslationUnitDecl(); 258fe6060f1SDimitry Andric LastPTU.TUPart = C.getTranslationUnitDecl(); 259fe6060f1SDimitry Andric 260fe6060f1SDimitry Andric // Skip previous eof due to last incremental input. 261*06c3fb27SDimitry Andric if (P->getCurToken().is(tok::annot_repl_input_end)) { 262*06c3fb27SDimitry Andric P->ConsumeAnyToken(); 263fe6060f1SDimitry Andric // FIXME: Clang does not call ExitScope on finalizing the regular TU, we 264fe6060f1SDimitry Andric // might want to do that around HandleEndOfTranslationUnit. 265fe6060f1SDimitry Andric P->ExitScope(); 266fe6060f1SDimitry Andric S.CurContext = nullptr; 267fe6060f1SDimitry Andric // Start a new PTU. 268fe6060f1SDimitry Andric P->EnterScope(Scope::DeclScope); 269fe6060f1SDimitry Andric S.ActOnTranslationUnitScope(P->getCurScope()); 270fe6060f1SDimitry Andric } 271fe6060f1SDimitry Andric 272fe6060f1SDimitry Andric Parser::DeclGroupPtrTy ADecl; 27381ad6265SDimitry Andric Sema::ModuleImportState ImportState; 27481ad6265SDimitry Andric for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF; 27581ad6265SDimitry Andric AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) { 276fe6060f1SDimitry Andric if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) 277fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 278fe6060f1SDimitry Andric "The consumer rejected a decl", 279fe6060f1SDimitry Andric std::error_code()); 280fe6060f1SDimitry Andric } 281fe6060f1SDimitry Andric 282fe6060f1SDimitry Andric DiagnosticsEngine &Diags = getCI()->getDiagnostics(); 283fe6060f1SDimitry Andric if (Diags.hasErrorOccurred()) { 28481ad6265SDimitry Andric PartialTranslationUnit MostRecentPTU = {C.getTranslationUnitDecl(), 28581ad6265SDimitry Andric nullptr}; 28681ad6265SDimitry Andric CleanUpPTU(MostRecentPTU); 287fe6060f1SDimitry Andric 28881ad6265SDimitry Andric Diags.Reset(/*soft=*/true); 28981ad6265SDimitry Andric Diags.getClient()->clear(); 290fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed.", 291fe6060f1SDimitry Andric std::error_code()); 292fe6060f1SDimitry Andric } 293fe6060f1SDimitry Andric 294fe6060f1SDimitry Andric // Process any TopLevelDecls generated by #pragma weak. 295fe6060f1SDimitry Andric for (Decl *D : S.WeakTopLevelDecls()) { 296fe6060f1SDimitry Andric DeclGroupRef DGR(D); 297fe6060f1SDimitry Andric Consumer->HandleTopLevelDecl(DGR); 298fe6060f1SDimitry Andric } 299fe6060f1SDimitry Andric 300fe6060f1SDimitry Andric LocalInstantiations.perform(); 301fe6060f1SDimitry Andric GlobalInstantiations.perform(); 302fe6060f1SDimitry Andric 303fe6060f1SDimitry Andric Consumer->HandleTranslationUnit(C); 304fe6060f1SDimitry Andric 305fe6060f1SDimitry Andric return LastPTU; 306fe6060f1SDimitry Andric } 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 309fe6060f1SDimitry Andric IncrementalParser::Parse(llvm::StringRef input) { 310fe6060f1SDimitry Andric Preprocessor &PP = CI->getPreprocessor(); 311fe6060f1SDimitry Andric assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?"); 312fe6060f1SDimitry Andric 313fe6060f1SDimitry Andric std::ostringstream SourceName; 314fe6060f1SDimitry Andric SourceName << "input_line_" << InputCount++; 315fe6060f1SDimitry Andric 316fe6060f1SDimitry Andric // Create an uninitialized memory buffer, copy code in and append "\n" 317fe6060f1SDimitry Andric size_t InputSize = input.size(); // don't include trailing 0 318fe6060f1SDimitry Andric // MemBuffer size should *not* include terminating zero 319fe6060f1SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> MB( 320fe6060f1SDimitry Andric llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1, 321fe6060f1SDimitry Andric SourceName.str())); 322fe6060f1SDimitry Andric char *MBStart = const_cast<char *>(MB->getBufferStart()); 323fe6060f1SDimitry Andric memcpy(MBStart, input.data(), InputSize); 324fe6060f1SDimitry Andric MBStart[InputSize] = '\n'; 325fe6060f1SDimitry Andric 326fe6060f1SDimitry Andric SourceManager &SM = CI->getSourceManager(); 327fe6060f1SDimitry Andric 328fe6060f1SDimitry Andric // FIXME: Create SourceLocation, which will allow clang to order the overload 329fe6060f1SDimitry Andric // candidates for example 330fe6060f1SDimitry Andric SourceLocation NewLoc = SM.getLocForStartOfFile(SM.getMainFileID()); 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric // Create FileID for the current buffer. 333fe6060f1SDimitry Andric FileID FID = SM.createFileID(std::move(MB), SrcMgr::C_User, /*LoadedID=*/0, 334fe6060f1SDimitry Andric /*LoadedOffset=*/0, NewLoc); 335fe6060f1SDimitry Andric 336fe6060f1SDimitry Andric // NewLoc only used for diags. 33704eeddc0SDimitry Andric if (PP.EnterSourceFile(FID, /*DirLookup=*/nullptr, NewLoc)) 338fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 339fe6060f1SDimitry Andric "Cannot enter source file.", 340fe6060f1SDimitry Andric std::error_code()); 341fe6060f1SDimitry Andric 342fe6060f1SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 343fe6060f1SDimitry Andric if (!PTU) 344fe6060f1SDimitry Andric return PTU.takeError(); 345fe6060f1SDimitry Andric 346fe6060f1SDimitry Andric if (PP.getLangOpts().DelayedTemplateParsing) { 347fe6060f1SDimitry Andric // Microsoft-specific: 348fe6060f1SDimitry Andric // Late parsed templates can leave unswallowed "macro"-like tokens. 349fe6060f1SDimitry Andric // They will seriously confuse the Parser when entering the next 350fe6060f1SDimitry Andric // source file. So lex until we are EOF. 351fe6060f1SDimitry Andric Token Tok; 352fe6060f1SDimitry Andric do { 353fe6060f1SDimitry Andric PP.Lex(Tok); 354*06c3fb27SDimitry Andric } while (Tok.isNot(tok::annot_repl_input_end)); 355*06c3fb27SDimitry Andric } else { 356fe6060f1SDimitry Andric Token AssertTok; 357fe6060f1SDimitry Andric PP.Lex(AssertTok); 358*06c3fb27SDimitry Andric assert(AssertTok.is(tok::annot_repl_input_end) && 359fe6060f1SDimitry Andric "Lexer must be EOF when starting incremental parse!"); 360fe6060f1SDimitry Andric } 361fe6060f1SDimitry Andric 362*06c3fb27SDimitry Andric if (std::unique_ptr<llvm::Module> M = GenModule()) 363*06c3fb27SDimitry Andric PTU->TheModule = std::move(M); 364*06c3fb27SDimitry Andric 365fe6060f1SDimitry Andric return PTU; 366fe6060f1SDimitry Andric } 367349cc55cSDimitry Andric 368*06c3fb27SDimitry Andric std::unique_ptr<llvm::Module> IncrementalParser::GenModule() { 369*06c3fb27SDimitry Andric static unsigned ID = 0; 370*06c3fb27SDimitry Andric if (CodeGenerator *CG = getCodeGen()) { 371*06c3fb27SDimitry Andric std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); 372*06c3fb27SDimitry Andric CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext()); 373*06c3fb27SDimitry Andric return M; 374*06c3fb27SDimitry Andric } 375*06c3fb27SDimitry Andric return nullptr; 376*06c3fb27SDimitry Andric } 377*06c3fb27SDimitry Andric 37881ad6265SDimitry Andric void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { 37981ad6265SDimitry Andric TranslationUnitDecl *MostRecentTU = PTU.TUPart; 38081ad6265SDimitry Andric TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); 38181ad6265SDimitry Andric if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { 38281ad6265SDimitry Andric for (auto I = Map->begin(); I != Map->end(); ++I) { 38381ad6265SDimitry Andric StoredDeclsList &List = I->second; 38481ad6265SDimitry Andric DeclContextLookupResult R = List.getLookupResult(); 38581ad6265SDimitry Andric for (NamedDecl *D : R) { 38681ad6265SDimitry Andric if (D->getTranslationUnitDecl() == MostRecentTU) { 38781ad6265SDimitry Andric List.remove(D); 38881ad6265SDimitry Andric } 38981ad6265SDimitry Andric } 39081ad6265SDimitry Andric if (List.isNull()) 39181ad6265SDimitry Andric Map->erase(I); 39281ad6265SDimitry Andric } 39381ad6265SDimitry Andric } 39481ad6265SDimitry Andric } 39581ad6265SDimitry Andric 396349cc55cSDimitry Andric llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { 397*06c3fb27SDimitry Andric CodeGenerator *CG = getCodeGen(); 398349cc55cSDimitry Andric assert(CG); 399349cc55cSDimitry Andric return CG->GetMangledName(GD); 400349cc55cSDimitry Andric } 401349cc55cSDimitry Andric 402fe6060f1SDimitry Andric } // end namespace clang 403