diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index f5ae83a2faca97..79e9a462a3d727 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1486,6 +1486,33 @@ class CodeGenModule : public CodeGenTypeCache { void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, const Decl *D) const; + /// Move some lazily-emitted states to the NewBuilder. This is especially + /// essential for the incremental parsing environment like Clang Interpreter, + /// because we'll lose all important information after each repl. + void moveLazyEmissionStates(CodeGenModule *NewBuilder) { + assert(DeferredDeclsToEmit.empty() && + "Should have emitted all decls deferred to emit."); + assert(NewBuilder->DeferredDecls.empty() && + "Newly created module should not have deferred decls"); + NewBuilder->DeferredDecls = std::move(DeferredDecls); + + assert(NewBuilder->DeferredVTables.empty() && + "Newly created module should not have deferred vtables"); + NewBuilder->DeferredVTables = std::move(DeferredVTables); + + assert(NewBuilder->MangledDeclNames.empty() && + "Newly created module should not have mangled decl names"); + assert(NewBuilder->Manglings.empty() && + "Newly created module should not have manglings"); + NewBuilder->Manglings = std::move(Manglings); + + assert(WeakRefReferences.empty() && + "Not all WeakRefRefs have been applied"); + NewBuilder->WeakRefReferences = std::move(WeakRefReferences); + + NewBuilder->TBAA = std::move(TBAA); + } + private: llvm::Constant *GetOrCreateLLVMFunction( StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 50b7fd8eb993c6..8e97a298ce7fa3 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -134,7 +134,14 @@ namespace { llvm::LLVMContext &C) { assert(!M && "Replacing existing Module?"); M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + + std::unique_ptr OldBuilder = std::move(Builder); + Initialize(*Ctx); + + if (OldBuilder) + OldBuilder->moveLazyEmissionStates(Builder.get()); + return M.get(); } diff --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp index 298046c068c37f..61e68990acf961 100644 --- a/clang/test/Interpreter/execute.cpp +++ b/clang/test/Interpreter/execute.cpp @@ -13,4 +13,8 @@ struct S { float f = 1.0; S *m = nullptr;} s; auto r2 = printf("S[f=%f, m=0x%llx]\n", s.f, reinterpret_cast(s.m)); // CHECK-NEXT: S[f=1.000000, m=0x0] + +inline int foo() { return 42; } +int r3 = foo(); + quit