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