diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1477,6 +1477,68 @@ void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, const Decl *D) const; + llvm::DenseMap &getDeferredDecls() { + return DeferredDecls; + } + + std::vector &getDeferredDeclsToEmit() { + return DeferredDeclsToEmit; + } + + std::vector &getDeferredVTables() { + return DeferredVTables; + } + + llvm::MapVector &getMangledDeclNames() { + return MangledDeclNames; + } + + llvm::StringMap &getManglings() { + return Manglings; + } + + llvm::SmallPtrSetImpl &getWeakRefReferences() { + return WeakRefReferences; + } + + std::unique_ptr &getTBAA() { return TBAA; } + + struct KeepLazyEmiitedSymRAII { + std::unique_ptr OldBuilder; + std::unique_ptr &Self; + + explicit KeepLazyEmiitedSymRAII(std::unique_ptr &Builder) + : Self(Builder) { + OldBuilder.swap(Self); + } + + ~KeepLazyEmiitedSymRAII() { + assert(OldBuilder->getDeferredDeclsToEmit().empty() && + "Should have emitted all decls deferred to emit."); + assert(Self->getDeferredDecls().empty() && + "Newly created module should not have deferred decls"); + + std::swap(Self->getDeferredDecls(), OldBuilder->getDeferredDecls()); + + assert(Self->getDeferredVTables().empty() && + "Newly created module should not have deferred vtables"); + + std::swap(Self->getDeferredVTables(), OldBuilder->getDeferredVTables()); + + assert(Self->getMangledDeclNames().empty() && + "Newly created module should not have mangled decl names"); + assert(Self->getManglings().empty() && + "Newly created module should not have manglings"); + + Self->getManglings() = std::move(OldBuilder->getManglings()); + + assert(OldBuilder->getWeakRefReferences().empty() && + "Not all WeakRefRefs have been applied"); + + std::swap(Self->getTBAA(), OldBuilder->getTBAA()); + } + }; + 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 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -133,8 +133,13 @@ llvm::Module *StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C) { assert(!M && "Replacing existing Module?"); - M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); - Initialize(*Ctx); + + { + CodeGenModule::KeepLazyEmiitedSymRAII RAIIKeeper(Builder); + M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + Initialize(*Ctx); + } + return M.get(); } diff --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp --- a/clang/test/Interpreter/execute.cpp +++ b/clang/test/Interpreter/execute.cpp @@ -13,4 +13,8 @@ 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