xref: /freebsd-src/contrib/llvm-project/clang/lib/Interpreter/IncrementalParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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