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" 145f757f3fSDimitry 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 } 82*0fca6ea1SDimitry Andric void CompleteExternalDeclaration(DeclaratorDecl *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 } 1615f757f3fSDimitry 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); 2123a079333SDimitry Andric 2133a079333SDimitry Andric if (getCodeGen()) 2143a079333SDimitry Andric CachedInCodeGenModule = GenModule(); 2153a079333SDimitry Andric 21606c3fb27SDimitry Andric std::unique_ptr<ASTConsumer> IncrConsumer = 21706c3fb27SDimitry Andric std::make_unique<IncrementalASTConsumer>(Interp, CI->takeASTConsumer()); 21806c3fb27SDimitry 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(); 22306c3fb27SDimitry Andric 22406c3fb27SDimitry Andric // An initial PTU is needed as CUDA includes some headers automatically 22506c3fb27SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 22606c3fb27SDimitry Andric if (auto E = PTU.takeError()) { 22706c3fb27SDimitry Andric consumeError(std::move(E)); // FIXME 22806c3fb27SDimitry Andric return; // PTU.takeError(); 22906c3fb27SDimitry Andric } 23006c3fb27SDimitry Andric 2313a079333SDimitry Andric if (getCodeGen()) { 2323a079333SDimitry Andric PTU->TheModule = GenModule(); 23306c3fb27SDimitry Andric assert(PTU->TheModule && "Failed to create initial PTU"); 23406c3fb27SDimitry Andric } 235fe6060f1SDimitry Andric } 236fe6060f1SDimitry Andric 23781ad6265SDimitry Andric IncrementalParser::~IncrementalParser() { 23881ad6265SDimitry Andric P.reset(); 23981ad6265SDimitry Andric Act->FinalizeAction(); 24081ad6265SDimitry Andric } 241fe6060f1SDimitry Andric 242fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 243fe6060f1SDimitry Andric IncrementalParser::ParseOrWrapTopLevelDecl() { 244fe6060f1SDimitry Andric // Recover resources if we crash before exiting this method. 245fe6060f1SDimitry Andric Sema &S = CI->getSema(); 246fe6060f1SDimitry Andric llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(&S); 247fe6060f1SDimitry Andric Sema::GlobalEagerInstantiationScope GlobalInstantiations(S, /*Enabled=*/true); 248fe6060f1SDimitry Andric Sema::LocalEagerInstantiationScope LocalInstantiations(S); 249fe6060f1SDimitry Andric 250fe6060f1SDimitry Andric PTUs.emplace_back(PartialTranslationUnit()); 251fe6060f1SDimitry Andric PartialTranslationUnit &LastPTU = PTUs.back(); 252fe6060f1SDimitry Andric // Add a new PTU. 253fe6060f1SDimitry Andric ASTContext &C = S.getASTContext(); 254fe6060f1SDimitry Andric C.addTranslationUnitDecl(); 255fe6060f1SDimitry Andric LastPTU.TUPart = C.getTranslationUnitDecl(); 256fe6060f1SDimitry Andric 257fe6060f1SDimitry Andric // Skip previous eof due to last incremental input. 25806c3fb27SDimitry Andric if (P->getCurToken().is(tok::annot_repl_input_end)) { 25906c3fb27SDimitry Andric P->ConsumeAnyToken(); 260fe6060f1SDimitry Andric // FIXME: Clang does not call ExitScope on finalizing the regular TU, we 261fe6060f1SDimitry Andric // might want to do that around HandleEndOfTranslationUnit. 262fe6060f1SDimitry Andric P->ExitScope(); 263fe6060f1SDimitry Andric S.CurContext = nullptr; 264fe6060f1SDimitry Andric // Start a new PTU. 265fe6060f1SDimitry Andric P->EnterScope(Scope::DeclScope); 266fe6060f1SDimitry Andric S.ActOnTranslationUnitScope(P->getCurScope()); 267fe6060f1SDimitry Andric } 268fe6060f1SDimitry Andric 269fe6060f1SDimitry Andric Parser::DeclGroupPtrTy ADecl; 27081ad6265SDimitry Andric Sema::ModuleImportState ImportState; 27181ad6265SDimitry Andric for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF; 27281ad6265SDimitry Andric AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) { 273fe6060f1SDimitry Andric if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get())) 274fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 275fe6060f1SDimitry Andric "The consumer rejected a decl", 276fe6060f1SDimitry Andric std::error_code()); 277fe6060f1SDimitry Andric } 278fe6060f1SDimitry Andric 279fe6060f1SDimitry Andric DiagnosticsEngine &Diags = getCI()->getDiagnostics(); 280fe6060f1SDimitry Andric if (Diags.hasErrorOccurred()) { 28181ad6265SDimitry Andric PartialTranslationUnit MostRecentPTU = {C.getTranslationUnitDecl(), 28281ad6265SDimitry Andric nullptr}; 28381ad6265SDimitry Andric CleanUpPTU(MostRecentPTU); 284fe6060f1SDimitry Andric 28581ad6265SDimitry Andric Diags.Reset(/*soft=*/true); 28681ad6265SDimitry Andric Diags.getClient()->clear(); 287fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed.", 288fe6060f1SDimitry Andric std::error_code()); 289fe6060f1SDimitry Andric } 290fe6060f1SDimitry Andric 291fe6060f1SDimitry Andric // Process any TopLevelDecls generated by #pragma weak. 292fe6060f1SDimitry Andric for (Decl *D : S.WeakTopLevelDecls()) { 293fe6060f1SDimitry Andric DeclGroupRef DGR(D); 294fe6060f1SDimitry Andric Consumer->HandleTopLevelDecl(DGR); 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric 297fe6060f1SDimitry Andric LocalInstantiations.perform(); 298fe6060f1SDimitry Andric GlobalInstantiations.perform(); 299fe6060f1SDimitry Andric 300fe6060f1SDimitry Andric Consumer->HandleTranslationUnit(C); 301fe6060f1SDimitry Andric 302fe6060f1SDimitry Andric return LastPTU; 303fe6060f1SDimitry Andric } 304fe6060f1SDimitry Andric 305fe6060f1SDimitry Andric llvm::Expected<PartialTranslationUnit &> 306fe6060f1SDimitry Andric IncrementalParser::Parse(llvm::StringRef input) { 307fe6060f1SDimitry Andric Preprocessor &PP = CI->getPreprocessor(); 308fe6060f1SDimitry Andric assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode!?"); 309fe6060f1SDimitry Andric 310fe6060f1SDimitry Andric std::ostringstream SourceName; 311fe6060f1SDimitry Andric SourceName << "input_line_" << InputCount++; 312fe6060f1SDimitry Andric 313fe6060f1SDimitry Andric // Create an uninitialized memory buffer, copy code in and append "\n" 314fe6060f1SDimitry Andric size_t InputSize = input.size(); // don't include trailing 0 315fe6060f1SDimitry Andric // MemBuffer size should *not* include terminating zero 316fe6060f1SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> MB( 317fe6060f1SDimitry Andric llvm::WritableMemoryBuffer::getNewUninitMemBuffer(InputSize + 1, 318fe6060f1SDimitry Andric SourceName.str())); 319fe6060f1SDimitry Andric char *MBStart = const_cast<char *>(MB->getBufferStart()); 320fe6060f1SDimitry Andric memcpy(MBStart, input.data(), InputSize); 321fe6060f1SDimitry Andric MBStart[InputSize] = '\n'; 322fe6060f1SDimitry Andric 323fe6060f1SDimitry Andric SourceManager &SM = CI->getSourceManager(); 324fe6060f1SDimitry Andric 325fe6060f1SDimitry Andric // FIXME: Create SourceLocation, which will allow clang to order the overload 326fe6060f1SDimitry Andric // candidates for example 327fe6060f1SDimitry Andric SourceLocation NewLoc = SM.getLocForStartOfFile(SM.getMainFileID()); 328fe6060f1SDimitry Andric 329fe6060f1SDimitry Andric // Create FileID for the current buffer. 330fe6060f1SDimitry Andric FileID FID = SM.createFileID(std::move(MB), SrcMgr::C_User, /*LoadedID=*/0, 331fe6060f1SDimitry Andric /*LoadedOffset=*/0, NewLoc); 332fe6060f1SDimitry Andric 333fe6060f1SDimitry Andric // NewLoc only used for diags. 33404eeddc0SDimitry Andric if (PP.EnterSourceFile(FID, /*DirLookup=*/nullptr, NewLoc)) 335fe6060f1SDimitry Andric return llvm::make_error<llvm::StringError>("Parsing failed. " 336fe6060f1SDimitry Andric "Cannot enter source file.", 337fe6060f1SDimitry Andric std::error_code()); 338fe6060f1SDimitry Andric 339fe6060f1SDimitry Andric auto PTU = ParseOrWrapTopLevelDecl(); 340fe6060f1SDimitry Andric if (!PTU) 341fe6060f1SDimitry Andric return PTU.takeError(); 342fe6060f1SDimitry Andric 343fe6060f1SDimitry Andric if (PP.getLangOpts().DelayedTemplateParsing) { 344fe6060f1SDimitry Andric // Microsoft-specific: 345fe6060f1SDimitry Andric // Late parsed templates can leave unswallowed "macro"-like tokens. 346fe6060f1SDimitry Andric // They will seriously confuse the Parser when entering the next 347fe6060f1SDimitry Andric // source file. So lex until we are EOF. 348fe6060f1SDimitry Andric Token Tok; 349fe6060f1SDimitry Andric do { 350fe6060f1SDimitry Andric PP.Lex(Tok); 35106c3fb27SDimitry Andric } while (Tok.isNot(tok::annot_repl_input_end)); 35206c3fb27SDimitry Andric } else { 353fe6060f1SDimitry Andric Token AssertTok; 354fe6060f1SDimitry Andric PP.Lex(AssertTok); 35506c3fb27SDimitry Andric assert(AssertTok.is(tok::annot_repl_input_end) && 356fe6060f1SDimitry Andric "Lexer must be EOF when starting incremental parse!"); 357fe6060f1SDimitry Andric } 358fe6060f1SDimitry Andric 35906c3fb27SDimitry Andric if (std::unique_ptr<llvm::Module> M = GenModule()) 36006c3fb27SDimitry Andric PTU->TheModule = std::move(M); 36106c3fb27SDimitry Andric 362fe6060f1SDimitry Andric return PTU; 363fe6060f1SDimitry Andric } 364349cc55cSDimitry Andric 36506c3fb27SDimitry Andric std::unique_ptr<llvm::Module> IncrementalParser::GenModule() { 36606c3fb27SDimitry Andric static unsigned ID = 0; 36706c3fb27SDimitry Andric if (CodeGenerator *CG = getCodeGen()) { 3683a079333SDimitry Andric // Clang's CodeGen is designed to work with a single llvm::Module. In many 3693a079333SDimitry Andric // cases for convenience various CodeGen parts have a reference to the 3703a079333SDimitry Andric // llvm::Module (TheModule or Module) which does not change when a new 3713a079333SDimitry Andric // module is pushed. However, the execution engine wants to take ownership 3723a079333SDimitry Andric // of the module which does not map well to CodeGen's design. To work this 3733a079333SDimitry Andric // around we created an empty module to make CodeGen happy. We should make 3743a079333SDimitry Andric // sure it always stays empty. 3753a079333SDimitry Andric assert((!CachedInCodeGenModule || 3763a079333SDimitry Andric (CachedInCodeGenModule->empty() && 3773a079333SDimitry Andric CachedInCodeGenModule->global_empty() && 3783a079333SDimitry Andric CachedInCodeGenModule->alias_empty() && 3793a079333SDimitry Andric CachedInCodeGenModule->ifunc_empty())) && 3803a079333SDimitry Andric "CodeGen wrote to a readonly module"); 38106c3fb27SDimitry Andric std::unique_ptr<llvm::Module> M(CG->ReleaseModule()); 38206c3fb27SDimitry Andric CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext()); 38306c3fb27SDimitry Andric return M; 38406c3fb27SDimitry Andric } 38506c3fb27SDimitry Andric return nullptr; 38606c3fb27SDimitry Andric } 38706c3fb27SDimitry Andric 38881ad6265SDimitry Andric void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) { 38981ad6265SDimitry Andric TranslationUnitDecl *MostRecentTU = PTU.TUPart; 390*0fca6ea1SDimitry Andric if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { 391*0fca6ea1SDimitry Andric for (auto &&[Key, List] : *Map) { 39281ad6265SDimitry Andric DeclContextLookupResult R = List.getLookupResult(); 393*0fca6ea1SDimitry Andric std::vector<NamedDecl *> NamedDeclsToRemove; 394*0fca6ea1SDimitry Andric bool RemoveAll = true; 39581ad6265SDimitry Andric for (NamedDecl *D : R) { 396*0fca6ea1SDimitry Andric if (D->getTranslationUnitDecl() == MostRecentTU) 397*0fca6ea1SDimitry Andric NamedDeclsToRemove.push_back(D); 398*0fca6ea1SDimitry Andric else 399*0fca6ea1SDimitry Andric RemoveAll = false; 400*0fca6ea1SDimitry Andric } 401*0fca6ea1SDimitry Andric if (LLVM_LIKELY(RemoveAll)) { 402*0fca6ea1SDimitry Andric Map->erase(Key); 403*0fca6ea1SDimitry Andric } else { 404*0fca6ea1SDimitry Andric for (NamedDecl *D : NamedDeclsToRemove) 40581ad6265SDimitry Andric List.remove(D); 40681ad6265SDimitry Andric } 40781ad6265SDimitry Andric } 40881ad6265SDimitry Andric } 409*0fca6ea1SDimitry Andric 410*0fca6ea1SDimitry Andric // FIXME: We should de-allocate MostRecentTU 411*0fca6ea1SDimitry Andric for (Decl *D : MostRecentTU->decls()) { 412*0fca6ea1SDimitry Andric auto *ND = dyn_cast<NamedDecl>(D); 413*0fca6ea1SDimitry Andric if (!ND) 414*0fca6ea1SDimitry Andric continue; 415*0fca6ea1SDimitry Andric // Check if we need to clean up the IdResolver chain. 416*0fca6ea1SDimitry Andric if (ND->getDeclName().getFETokenInfo() && !D->getLangOpts().ObjC && 417*0fca6ea1SDimitry Andric !D->getLangOpts().CPlusPlus) 418*0fca6ea1SDimitry Andric getCI()->getSema().IdResolver.RemoveDecl(ND); 41981ad6265SDimitry Andric } 42081ad6265SDimitry Andric } 42181ad6265SDimitry Andric 422349cc55cSDimitry Andric llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { 42306c3fb27SDimitry Andric CodeGenerator *CG = getCodeGen(); 424349cc55cSDimitry Andric assert(CG); 425349cc55cSDimitry Andric return CG->GetMangledName(GD); 426349cc55cSDimitry Andric } 427fe6060f1SDimitry Andric } // end namespace clang 428