diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a6d58aeef11bdd..f832a067237eb5 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -445,6 +445,7 @@ void CodeGenModule::checkAliases() { void CodeGenModule::clear() { DeferredDeclsToEmit.clear(); + EmittedDeferredDecls.clear(); if (OpenMPRuntime) OpenMPRuntime->clear(); } @@ -510,6 +511,9 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, void CodeGenModule::Release() { EmitDeferred(); + DeferredDecls.insert(EmittedDeferredDecls.begin(), + EmittedDeferredDecls.end()); + EmittedDeferredDecls.clear(); EmitVTablesOpportunistically(); applyGlobalValReplacements(); applyReplacements(); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index da43b9616c88e2..10b49da27dab70 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -344,6 +344,20 @@ class CodeGenModule : public CodeGenTypeCache { std::vector DeferredDeclsToEmit; void addDeferredDeclToEmit(GlobalDecl GD) { DeferredDeclsToEmit.emplace_back(GD); + addEmittedDeferredDecl(GD); + } + + /// Decls that were DeferredDecls and have now been emitted. + llvm::DenseMap EmittedDeferredDecls; + + void addEmittedDeferredDecl(GlobalDecl GD) { + if (!llvm::isa(GD.getDecl())) + return; + llvm::GlobalVariable::LinkageTypes L = getFunctionLinkage(GD); + if (llvm::GlobalValue::isLinkOnceLinkage(L) || + llvm::GlobalValue::isWeakLinkage(L)) { + EmittedDeferredDecls[getMangledName(GD)] = GD; + } } /// List of alias we have emitted. Used to make sure that what they point to @@ -1516,6 +1530,11 @@ class CodeGenModule : public CodeGenTypeCache { NewBuilder->WeakRefReferences = std::move(WeakRefReferences); NewBuilder->TBAA = std::move(TBAA); + + assert(NewBuilder->EmittedDeferredDecls.empty() && + "Still have (unmerged) EmittedDeferredDecls deferred decls"); + + NewBuilder->EmittedDeferredDecls = std::move(EmittedDeferredDecls); } private: diff --git a/clang/test/Interpreter/code-undo.cpp b/clang/test/Interpreter/code-undo.cpp index d825460f3b4a42..9a908d6b7e4556 100644 --- a/clang/test/Interpreter/code-undo.cpp +++ b/clang/test/Interpreter/code-undo.cpp @@ -20,4 +20,9 @@ int foo() { return 2; } auto r3 = printf("foo() = %d\n", foo()); // CHECK-NEXT: foo() = 2 +inline int bar() { return 42;} +auto r4 = bar(); +%undo +auto r5 = bar(); + %quit