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" 14*5f757f3fSDimitry Andric 15fe6060f1SDimitry Andric #include "clang/AST/DeclContextInternals.h" 16fe6060f1SDimitry Andric #include "clang/CodeGen/BackendUtil.h" 17fe6060f1SDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 18fe6060f1SDimitry Andric #include "clang/CodeGen/ModuleBuilder.h" 19fe6060f1SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 20fe6060f1SDimitry Andric #include "clang/Frontend/FrontendAction.h" 21fe6060f1SDimitry Andric #include "clang/FrontendTool/Utils.h" 2206c3fb27SDimitry Andric #include "clang/Interpreter/Interpreter.h" 23fe6060f1SDimitry Andric #include "clang/Parse/Parser.h" 24fe6060f1SDimitry Andric #include "clang/Sema/Sema.h" 25fe6060f1SDimitry Andric #include "llvm/Option/ArgList.h" 26fe6060f1SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h" 27fe6060f1SDimitry Andric #include "llvm/Support/Error.h" 28fe6060f1SDimitry Andric #include "llvm/Support/Timer.h" 29fe6060f1SDimitry Andric 30fe6060f1SDimitry Andric #include <sstream> 31fe6060f1SDimitry Andric 32fe6060f1SDimitry Andric namespace clang { 33fe6060f1SDimitry Andric 3406c3fb27SDimitry Andric class IncrementalASTConsumer final : public ASTConsumer { 3506c3fb27SDimitry Andric Interpreter &Interp; 3606c3fb27SDimitry Andric std::unique_ptr<ASTConsumer> Consumer; 3706c3fb27SDimitry Andric 3806c3fb27SDimitry Andric public: 3906c3fb27SDimitry Andric IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr<ASTConsumer> C) 4006c3fb27SDimitry Andric : Interp(InterpRef), Consumer(std::move(C)) {} 4106c3fb27SDimitry Andric 4206c3fb27SDimitry Andric bool HandleTopLevelDecl(DeclGroupRef DGR) override final { 4306c3fb27SDimitry Andric if (DGR.isNull()) 4406c3fb27SDimitry Andric return true; 4506c3fb27SDimitry Andric if (!Consumer) 4606c3fb27SDimitry Andric return true; 4706c3fb27SDimitry Andric 4806c3fb27SDimitry Andric for (Decl *D : DGR) 4906c3fb27SDimitry Andric if (auto *TSD = llvm::dyn_cast<TopLevelStmtDecl>(D); 5006c3fb27SDimitry Andric TSD && TSD->isSemiMissing()) 5106c3fb27SDimitry Andric TSD->setStmt(Interp.SynthesizeExpr(cast<Expr>(TSD->getStmt()))); 5206c3fb27SDimitry Andric 5306c3fb27SDimitry Andric return Consumer->HandleTopLevelDecl(DGR); 5406c3fb27SDimitry Andric } 5506c3fb27SDimitry Andric void HandleTranslationUnit(ASTContext &Ctx) override final { 5606c3fb27SDimitry Andric Consumer->HandleTranslationUnit(Ctx); 5706c3fb27SDimitry Andric } 5806c3fb27SDimitry Andric void HandleInlineFunctionDefinition(FunctionDecl *D) override final { 5906c3fb27SDimitry Andric Consumer->HandleInlineFunctionDefinition(D); 6006c3fb27SDimitry Andric } 6106c3fb27SDimitry Andric void HandleInterestingDecl(DeclGroupRef D) override final { 6206c3fb27SDimitry Andric Consumer->HandleInterestingDecl(D); 6306c3fb27SDimitry Andric } 6406c3fb27SDimitry Andric void HandleTagDeclDefinition(TagDecl *D) override final { 6506c3fb27SDimitry Andric Consumer->HandleTagDeclDefinition(D); 6606c3fb27SDimitry Andric } 6706c3fb27SDimitry Andric void HandleTagDeclRequiredDefinition(const TagDecl *D) override final { 6806c3fb27SDimitry Andric Consumer->HandleTagDeclRequiredDefinition(D); 6906c3fb27SDimitry Andric } 7006c3fb27SDimitry Andric void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final { 7106c3fb27SDimitry Andric Consumer->HandleCXXImplicitFunctionInstantiation(D); 7206c3fb27SDimitry Andric } 7306c3fb27SDimitry Andric void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final { 7406c3fb27SDimitry Andric Consumer->HandleTopLevelDeclInObjCContainer(D); 7506c3fb27SDimitry Andric } 7606c3fb27SDimitry Andric void HandleImplicitImportDecl(ImportDecl *D) override final { 7706c3fb27SDimitry Andric Consumer->HandleImplicitImportDecl(D); 7806c3fb27SDimitry Andric } 7906c3fb27SDimitry Andric void CompleteTentativeDefinition(VarDecl *D) override final { 8006c3fb27SDimitry Andric Consumer->CompleteTentativeDefinition(D); 8106c3fb27SDimitry Andric } 8206c3fb27SDimitry Andric void CompleteExternalDeclaration(VarDecl *D) override final { 8306c3fb27SDimitry Andric Consumer->CompleteExternalDeclaration(D); 8406c3fb27SDimitry Andric } 8506c3fb27SDimitry Andric void AssignInheritanceModel(CXXRecordDecl *RD) override final { 8606c3fb27SDimitry Andric Consumer->AssignInheritanceModel(RD); 8706c3fb27SDimitry Andric } 8806c3fb27SDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final { 8906c3fb27SDimitry Andric Consumer->HandleCXXStaticMemberVarInstantiation(D); 9006c3fb27SDimitry Andric } 9106c3fb27SDimitry Andric void HandleVTable(CXXRecordDecl *RD) override final { 9206c3fb27SDimitry Andric Consumer->HandleVTable(RD); 9306c3fb27SDimitry Andric } 9406c3fb27SDimitry Andric ASTMutationListener *GetASTMutationListener() override final { 9506c3fb27SDimitry Andric return Consumer->GetASTMutationListener(); 9606c3fb27SDimitry Andric } 9706c3fb27SDimitry Andric ASTDeserializationListener *GetASTDeserializationListener() override final { 9806c3fb27SDimitry Andric return Consumer->GetASTDeserializationListener(); 9906c3fb27SDimitry Andric } 10006c3fb27SDimitry Andric void PrintStats() override final { Consumer->PrintStats(); } 10106c3fb27SDimitry Andric bool shouldSkipFunctionBody(Decl *D) override final { 10206c3fb27SDimitry Andric return Consumer->shouldSkipFunctionBody(D); 10306c3fb27SDimitry Andric } 10406c3fb27SDimitry Andric static bool classof(const clang::ASTConsumer *) { return true; } 10506c3fb27SDimitry Andric }; 10606c3fb27SDimitry Andric 107fe6060f1SDimitry Andric /// A custom action enabling the incremental processing functionality. 108fe6060f1SDimitry Andric /// 109fe6060f1SDimitry Andric /// The usual \p FrontendAction expects one call to ExecuteAction and once it 110fe6060f1SDimitry Andric /// sees a call to \p EndSourceFile it deletes some of the important objects 111fe6060f1SDimitry Andric /// such as \p Preprocessor and \p Sema assuming no further input will come. 112fe6060f1SDimitry Andric /// 113fe6060f1SDimitry Andric /// \p IncrementalAction ensures it keep its underlying action's objects alive 114fe6060f1SDimitry Andric /// as long as the \p IncrementalParser needs them. 115fe6060f1SDimitry Andric /// 116fe6060f1SDimitry Andric class IncrementalAction : public WrapperFrontendAction { 117fe6060f1SDimitry Andric private: 118fe6060f1SDimitry Andric bool IsTerminating = false; 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric public: 121fe6060f1SDimitry Andric IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, 122fe6060f1SDimitry Andric llvm::Error &Err) 123fe6060f1SDimitry Andric : WrapperFrontendAction([&]() { 124fe6060f1SDimitry Andric llvm::ErrorAsOutParameter EAO(&Err); 125fe6060f1SDimitry Andric std::unique_ptr<FrontendAction> Act; 126fe6060f1SDimitry Andric switch (CI.getFrontendOpts().ProgramAction) { 127fe6060f1SDimitry Andric default: 128fe6060f1SDimitry Andric Err = llvm::createStringError( 129fe6060f1SDimitry Andric std::errc::state_not_recoverable, 130fe6060f1SDimitry Andric "Driver initialization failed. " 131fe6060f1SDimitry Andric "Incremental mode for action %d is not supported", 132fe6060f1SDimitry Andric CI.getFrontendOpts().ProgramAction); 133fe6060f1SDimitry Andric return Act; 134fe6060f1SDimitry Andric case frontend::ASTDump: 135bdd1243dSDimitry Andric [[fallthrough]]; 136fe6060f1SDimitry Andric case frontend::ASTPrint: 137bdd1243dSDimitry Andric [[fallthrough]]; 138fe6060f1SDimitry Andric case frontend::ParseSyntaxOnly: 139fe6060f1SDimitry Andric Act = CreateFrontendAction(CI); 140fe6060f1SDimitry Andric break; 141349cc55cSDimitry Andric case frontend::PluginAction: 142bdd1243dSDimitry Andric [[fallthrough]]; 143fe6060f1SDimitry Andric case frontend::EmitAssembly: 144bdd1243dSDimitry Andric [[fallthrough]]; 145bdd1243dSDimitry Andric case frontend::EmitBC: 146bdd1243dSDimitry Andric [[fallthrough]]; 147fe6060f1SDimitry Andric case frontend::EmitObj: 148bdd1243dSDimitry Andric [[fallthrough]]; 149bdd1243dSDimitry Andric case frontend::PrintPreprocessedInput: 150bdd1243dSDimitry Andric [[fallthrough]]; 151fe6060f1SDimitry Andric case frontend::EmitLLVMOnly: 152fe6060f1SDimitry Andric Act.reset(new EmitLLVMOnlyAction(&LLVMCtx)); 153fe6060f1SDimitry Andric break; 154fe6060f1SDimitry Andric } 155fe6060f1SDimitry Andric return Act; 156fe6060f1SDimitry Andric }()) {} 157fe6060f1SDimitry Andric FrontendAction *getWrapped() const { return WrappedAction.get(); } 158fe6060f1SDimitry Andric TranslationUnitKind getTranslationUnitKind() override { 159fe6060f1SDimitry Andric return TU_Incremental; 160fe6060f1SDimitry Andric } 161*5f757f3fSDimitry Andric 162fe6060f1SDimitry Andric void ExecuteAction() override { 163fe6060f1SDimitry Andric CompilerInstance &CI = getCompilerInstance(); 164fe6060f1SDimitry Andric assert(CI.hasPreprocessor() && "No PP!"); 165fe6060f1SDimitry Andric 166fe6060f1SDimitry Andric // Use a code completion consumer? 167fe6060f1SDimitry Andric CodeCompleteConsumer *CompletionConsumer = nullptr; 168fe6060f1SDimitry Andric if (CI.hasCodeCompletionConsumer()) 169fe6060f1SDimitry Andric CompletionConsumer = &CI.getCodeCompletionConsumer(); 170fe6060f1SDimitry Andric 171fe6060f1SDimitry Andric Preprocessor &PP = CI.getPreprocessor(); 172fe6060f1SDimitry Andric PP.EnterMainSourceFile(); 173fe6060f1SDimitry Andric 174fe6060f1SDimitry Andric if (!CI.hasSema()) 175fe6060f1SDimitry Andric CI.createSema(getTranslationUnitKind(), CompletionConsumer); 176fe6060f1SDimitry Andric } 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric // Do not terminate after processing the input. This allows us to keep various 179fe6060f1SDimitry Andric // clang objects alive and to incrementally grow the current TU. 180fe6060f1SDimitry Andric void EndSourceFile() override { 181fe6060f1SDimitry Andric // The WrappedAction can be nullptr if we issued an error in the ctor. 182fe6060f1SDimitry Andric if (IsTerminating && getWrapped()) 183fe6060f1SDimitry Andric WrapperFrontendAction::EndSourceFile(); 184fe6060f1SDimitry Andric } 185fe6060f1SDimitry Andric 186fe6060f1SDimitry Andric void FinalizeAction() { 187fe6060f1SDimitry Andric assert(!IsTerminating && "Already finalized!"); 188fe6060f1SDimitry Andric IsTerminating = true; 189fe6060f1SDimitry Andric EndSourceFile(); 190fe6060f1SDimitry Andric } 191fe6060f1SDimitry Andric }; 192fe6060f1SDimitry Andric 19306c3fb27SDimitry Andric CodeGenerator *IncrementalParser::getCodeGen() const { 19406c3fb27SDimitry Andric FrontendAction *WrappedAct = Act->getWrapped(); 19506c3fb27SDimitry Andric if (!WrappedAct->hasIRSupport()) 19606c3fb27SDimitry Andric return nullptr; 19706c3fb27SDimitry Andric return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator(); 19806c3fb27SDimitry Andric } 19906c3fb27SDimitry Andric 20006c3fb27SDimitry Andric IncrementalParser::IncrementalParser() {} 20106c3fb27SDimitry Andric 20206c3fb27SDimitry Andric IncrementalParser::IncrementalParser(Interpreter &Interp, 20306c3fb27SDimitry Andric std::unique_ptr<CompilerInstance> Instance, 204fe6060f1SDimitry Andric llvm::LLVMContext &LLVMCtx, 205fe6060f1SDimitry Andric llvm::Error &Err) 206fe6060f1SDimitry Andric : CI(std::move(Instance)) { 207fe6060f1SDimitry Andric llvm::ErrorAsOutParameter EAO(&Err); 208fe6060f1SDimitry Andric Act = std::make_unique<IncrementalAction>(*CI, LLVMCtx, Err); 209fe6060f1SDimitry Andric if (Err) 210fe6060f1SDimitry Andric return; 211fe6060f1SDimitry Andric CI->ExecuteAction(*Act); 21206c3fb27SDimitry Andric std::unique_ptr<ASTConsumer> IncrConsumer = 21306c3fb27SDimitry Andric std::make_unique<IncrementalASTConsumer>(Interp, CI->takeASTConsumer()); 21406c3fb27SDimitry Andric CI->setASTConsumer(std::move(IncrConsumer)); 215fe6060f1SDimitry Andric Consumer = &CI->getASTConsumer(); 216fe6060f1SDimitry Andric P.reset( 217fe6060f1SDimitry Andric new Parser(CI->getPreprocessor(), CI->getSema(), /*SkipBodies=*/false)); 218fe6060f1SDimitry Andric P->Initialize(); 21906c3fb27SDimitry Andric 22006c3fb27SDimitry Andric // An initial PTU is needed as CUDA includes some headers automatically 22106c3fb27SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 22206c3fb27SDimitry Andric if (auto E = PTU.takeError()) { 22306c3fb27SDimitry Andric consumeError(std::move(E)); // FIXME 22406c3fb27SDimitry Andric return; // PTU.takeError(); 22506c3fb27SDimitry Andric } 22606c3fb27SDimitry Andric 22706c3fb27SDimitry Andric if (CodeGenerator *CG = getCodeGen()) { 22806c3fb27SDimitry Andric std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); 22906c3fb27SDimitry Andric CG->StartModule("incr_module_" + std::to_string(PTUs.size()), 23006c3fb27SDimitry Andric M->getContext()); 23106c3fb27SDimitry Andric PTU->TheModule = std::move(M); 23206c3fb27SDimitry Andric assert(PTU->TheModule && "Failed to create initial PTU"); 23306c3fb27SDimitry Andric } 234fe6060f1SDimitry Andric } 235fe6060f1SDimitry Andric 23681ad6265SDimitry Andric IncrementalParser::~IncrementalParser() { 23781ad6265SDimitry Andric P.reset(); 23881ad6265SDimitry Andric Act->FinalizeAction(); 23981ad6265SDimitry Andric } 240fe6060f1SDimitry Andric 241fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 242fe6060f1SDimitry Andric IncrementalParser::ParseOrWrapTopLevelDecl() { 243fe6060f1SDimitry Andric // Recover resources if we crash before exiting this method. 244fe6060f1SDimitry Andric Sema &S = CI->getSema(); 245fe6060f1SDimitry Andric llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S); 246fe6060f1SDimitry Andric Sema::GlobalEagerInstantiationScope GlobalInstantiations(S, /*Enabled=*/true); 247fe6060f1SDimitry Andric Sema::LocalEagerInstantiationScope LocalInstantiations(S); 248fe6060f1SDimitry Andric 249fe6060f1SDimitry Andric PTUs.emplace_back(PartialTranslationUnit()); 250fe6060f1SDimitry Andric PartialTranslationUnit &LastPTU = PTUs.back(); 251fe6060f1SDimitry Andric // Add a new PTU. 252fe6060f1SDimitry Andric ASTContext &C = S.getASTContext(); 253fe6060f1SDimitry Andric C.addTranslationUnitDecl(); 254fe6060f1SDimitry Andric LastPTU.TUPart = C.getTranslationUnitDecl(); 255fe6060f1SDimitry Andric 256fe6060f1SDimitry Andric // Skip previous eof due to last incremental input. 25706c3fb27SDimitry Andric if (P->getCurToken().is(tok::annot_repl_input_end)) { 25806c3fb27SDimitry Andric P->ConsumeAnyToken(); 259fe6060f1SDimitry Andric // FIXME: Clang does not call ExitScope on finalizing the regular TU, we 260fe6060f1SDimitry Andric // might want to do that around HandleEndOfTranslationUnit. 261fe6060f1SDimitry Andric P->ExitScope(); 262fe6060f1SDimitry Andric S.CurContext = nullptr; 263fe6060f1SDimitry Andric // Start a new PTU. 264fe6060f1SDimitry Andric P->EnterScope(Scope::DeclScope); 265fe6060f1SDimitry Andric S.ActOnTranslationUnitScope(P->getCurScope()); 266fe6060f1SDimitry Andric } 267fe6060f1SDimitry Andric 268fe6060f1SDimitry Andric Parser::DeclGroupPtrTy ADecl; 26981ad6265SDimitry Andric Sema::ModuleImportState ImportState; 27081ad6265SDimitry Andric for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF; 27181ad6265SDimitry Andric AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) { 272fe6060f1SDimitry Andric if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) 273fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 274fe6060f1SDimitry Andric "The consumer rejected a decl", 275fe6060f1SDimitry Andric std::error_code()); 276fe6060f1SDimitry Andric } 277fe6060f1SDimitry Andric 278fe6060f1SDimitry Andric DiagnosticsEngine &Diags = getCI()->getDiagnostics(); 279fe6060f1SDimitry Andric if (Diags.hasErrorOccurred()) { 28081ad6265SDimitry Andric PartialTranslationUnit MostRecentPTU = {C.getTranslationUnitDecl(), 28181ad6265SDimitry Andric nullptr}; 28281ad6265SDimitry Andric CleanUpPTU(MostRecentPTU); 283fe6060f1SDimitry Andric 28481ad6265SDimitry Andric Diags.Reset(/*soft=*/true); 28581ad6265SDimitry Andric Diags.getClient()->clear(); 286fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed.", 287fe6060f1SDimitry Andric std::error_code()); 288fe6060f1SDimitry Andric } 289fe6060f1SDimitry Andric 290fe6060f1SDimitry Andric // Process any TopLevelDecls generated by #pragma weak. 291fe6060f1SDimitry Andric for (Decl *D : S.WeakTopLevelDecls()) { 292fe6060f1SDimitry Andric DeclGroupRef DGR(D); 293fe6060f1SDimitry Andric Consumer->HandleTopLevelDecl(DGR); 294fe6060f1SDimitry Andric } 295fe6060f1SDimitry Andric 296fe6060f1SDimitry Andric LocalInstantiations.perform(); 297fe6060f1SDimitry Andric GlobalInstantiations.perform(); 298fe6060f1SDimitry Andric 299fe6060f1SDimitry Andric Consumer->HandleTranslationUnit(C); 300fe6060f1SDimitry Andric 301fe6060f1SDimitry Andric return LastPTU; 302fe6060f1SDimitry Andric } 303fe6060f1SDimitry Andric 304fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 305fe6060f1SDimitry Andric IncrementalParser::Parse(llvm::StringRef input) { 306fe6060f1SDimitry Andric Preprocessor &PP = CI->getPreprocessor(); 307fe6060f1SDimitry Andric assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?"); 308fe6060f1SDimitry Andric 309fe6060f1SDimitry Andric std::ostringstream SourceName; 310fe6060f1SDimitry Andric SourceName << "input_line_" << InputCount++; 311fe6060f1SDimitry Andric 312fe6060f1SDimitry Andric // Create an uninitialized memory buffer, copy code in and append "\n" 313fe6060f1SDimitry Andric size_t InputSize = input.size(); // don't include trailing 0 314fe6060f1SDimitry Andric // MemBuffer size should *not* include terminating zero 315fe6060f1SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> MB( 316fe6060f1SDimitry Andric llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1, 317fe6060f1SDimitry Andric SourceName.str())); 318fe6060f1SDimitry Andric char *MBStart = const_cast<char *>(MB->getBufferStart()); 319fe6060f1SDimitry Andric memcpy(MBStart, input.data(), InputSize); 320fe6060f1SDimitry Andric MBStart[InputSize] = '\n'; 321fe6060f1SDimitry Andric 322fe6060f1SDimitry Andric SourceManager &SM = CI->getSourceManager(); 323fe6060f1SDimitry Andric 324fe6060f1SDimitry Andric // FIXME: Create SourceLocation, which will allow clang to order the overload 325fe6060f1SDimitry Andric // candidates for example 326fe6060f1SDimitry Andric SourceLocation NewLoc = SM.getLocForStartOfFile(SM.getMainFileID()); 327fe6060f1SDimitry Andric 328fe6060f1SDimitry Andric // Create FileID for the current buffer. 329fe6060f1SDimitry Andric FileID FID = SM.createFileID(std::move(MB), SrcMgr::C_User, /*LoadedID=*/0, 330fe6060f1SDimitry Andric /*LoadedOffset=*/0, NewLoc); 331fe6060f1SDimitry Andric 332fe6060f1SDimitry Andric // NewLoc only used for diags. 33304eeddc0SDimitry Andric if (PP.EnterSourceFile(FID, /*DirLookup=*/nullptr, NewLoc)) 334fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 335fe6060f1SDimitry Andric "Cannot enter source file.", 336fe6060f1SDimitry Andric std::error_code()); 337fe6060f1SDimitry Andric 338fe6060f1SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 339fe6060f1SDimitry Andric if (!PTU) 340fe6060f1SDimitry Andric return PTU.takeError(); 341fe6060f1SDimitry Andric 342fe6060f1SDimitry Andric if (PP.getLangOpts().DelayedTemplateParsing) { 343fe6060f1SDimitry Andric // Microsoft-specific: 344fe6060f1SDimitry Andric // Late parsed templates can leave unswallowed "macro"-like tokens. 345fe6060f1SDimitry Andric // They will seriously confuse the Parser when entering the next 346fe6060f1SDimitry Andric // source file. So lex until we are EOF. 347fe6060f1SDimitry Andric Token Tok; 348fe6060f1SDimitry Andric do { 349fe6060f1SDimitry Andric PP.Lex(Tok); 35006c3fb27SDimitry Andric } while (Tok.isNot(tok::annot_repl_input_end)); 35106c3fb27SDimitry Andric } else { 352fe6060f1SDimitry Andric Token AssertTok; 353fe6060f1SDimitry Andric PP.Lex(AssertTok); 35406c3fb27SDimitry Andric assert(AssertTok.is(tok::annot_repl_input_end) && 355fe6060f1SDimitry Andric "Lexer must be EOF when starting incremental parse!"); 356fe6060f1SDimitry Andric } 357fe6060f1SDimitry Andric 35806c3fb27SDimitry Andric if (std::unique_ptr<llvm::Module> M = GenModule()) 35906c3fb27SDimitry Andric PTU->TheModule = std::move(M); 36006c3fb27SDimitry Andric 361fe6060f1SDimitry Andric return PTU; 362fe6060f1SDimitry Andric } 363349cc55cSDimitry Andric 36406c3fb27SDimitry Andric std::unique_ptr<llvm::Module> IncrementalParser::GenModule() { 36506c3fb27SDimitry Andric static unsigned ID = 0; 36606c3fb27SDimitry Andric if (CodeGenerator *CG = getCodeGen()) { 36706c3fb27SDimitry Andric std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); 36806c3fb27SDimitry Andric CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext()); 36906c3fb27SDimitry Andric return M; 37006c3fb27SDimitry Andric } 37106c3fb27SDimitry Andric return nullptr; 37206c3fb27SDimitry Andric } 37306c3fb27SDimitry Andric 37481ad6265SDimitry Andric void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { 37581ad6265SDimitry Andric TranslationUnitDecl *MostRecentTU = PTU.TUPart; 37681ad6265SDimitry Andric TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); 37781ad6265SDimitry Andric if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { 37881ad6265SDimitry Andric for (auto I = Map->begin(); I != Map->end(); ++I) { 37981ad6265SDimitry Andric StoredDeclsList &List = I->second; 38081ad6265SDimitry Andric DeclContextLookupResult R = List.getLookupResult(); 38181ad6265SDimitry Andric for (NamedDecl *D : R) { 38281ad6265SDimitry Andric if (D->getTranslationUnitDecl() == MostRecentTU) { 38381ad6265SDimitry Andric List.remove(D); 38481ad6265SDimitry Andric } 38581ad6265SDimitry Andric } 38681ad6265SDimitry Andric if (List.isNull()) 38781ad6265SDimitry Andric Map->erase(I); 38881ad6265SDimitry Andric } 38981ad6265SDimitry Andric } 39081ad6265SDimitry Andric } 39181ad6265SDimitry Andric 392349cc55cSDimitry Andric llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { 39306c3fb27SDimitry Andric CodeGenerator *CG = getCodeGen(); 394349cc55cSDimitry Andric assert(CG); 395349cc55cSDimitry Andric return CG->GetMangledName(GD); 396349cc55cSDimitry Andric } 397fe6060f1SDimitry Andric } // end namespace clang 398