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