diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index c7447273a42fa..2897ccdf88660 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -124,7 +124,7 @@ static void resolveTopLevelMetadata(llvm::Function *Fn, auto *DIS = Fn->getSubprogram(); if (!DIS) return; - auto *NewDIS = DIS->replaceWithDistinct(DIS->clone()); + auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone()); VMap.MD()[DIS].reset(NewDIS); // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py index ae1a0c86b45d8..f471ea728f953 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/coroutine_handle/TestCoroutineHandle.py @@ -18,8 +18,11 @@ def do_test(self, stdlib_type): self.build(dictionary={stdlib_type: "1"}) is_clang = self.expectedCompiler(["clang"]) + # Clang <= 20 used to also name the resume/destroy functions + # as `my_generator_func`. + # Never versions of clang name the clones as `.resume`/`.destroy`. test_generator_func_ptr_re = re.compile( - r"^\(a.out`my_generator_func\(\) at main.cpp:[0-9]*\)$" + r"^\(a.out`my_generator_func\(\)( \(\..*\))? at main.cpp:[0-9]*\)$" ) # Run until the initial suspension point diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp index f9a6c70fedc2d..0a493dc92fab9 100644 --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -912,29 +912,14 @@ void coro::BaseCloner::create() { assert(SP != OrigF.getSubprogram() && SP->isDistinct()); updateScopeLine(ActiveSuspend, *SP); - // Update the linkage name to reflect the modified symbol name. It - // is necessary to update the linkage name in Swift, since the - // mangling changes for resume functions. It might also be the - // right thing to do in C++, but due to a limitation in LLVM's - // AsmPrinter we can only do this if the function doesn't have an - // abstract specification, since the DWARF backend expects the - // abstract specification to contain the linkage name and asserts - // that they are identical. - if (SP->getUnit() && - SP->getUnit()->getSourceLanguage() == dwarf::DW_LANG_Swift) { - SP->replaceLinkageName(MDString::get(Context, NewF->getName())); - if (auto *Decl = SP->getDeclaration()) { - auto *NewDecl = DISubprogram::get( - Decl->getContext(), Decl->getScope(), Decl->getName(), - NewF->getName(), Decl->getFile(), Decl->getLine(), Decl->getType(), - Decl->getScopeLine(), Decl->getContainingType(), - Decl->getVirtualIndex(), Decl->getThisAdjustment(), - Decl->getFlags(), Decl->getSPFlags(), Decl->getUnit(), - Decl->getTemplateParams(), nullptr, Decl->getRetainedNodes(), - Decl->getThrownTypes(), Decl->getAnnotations(), - Decl->getTargetFuncName()); - SP->replaceDeclaration(NewDecl); - } + // Update the linkage name and the function name to reflect the modified + // name. + MDString *NewLinkageName = MDString::get(Context, NewF->getName()); + SP->replaceLinkageName(NewLinkageName); + if (DISubprogram *Decl = SP->getDeclaration()) { + TempDISubprogram NewDecl = Decl->clone(); + NewDecl->replaceLinkageName(NewLinkageName); + SP->replaceDeclaration(MDNode::replaceWithUniqued(std::move(NewDecl))); } } diff --git a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll index 4da07c91eb486..deaec7b8d7f89 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values-not_used_in_frame.ll @@ -2,18 +2,18 @@ ; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split,coro-split)' -S | FileCheck %s ; ; This file is based on coro-debug-frame-variable.ll. -; CHECK: define internal fastcc void @f.resume(ptr noundef nonnull align 16 dereferenceable(80) %begin) !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]] +; CHECK: define internal fastcc void @_Z3foov.resume(ptr noundef nonnull align 16 dereferenceable(80) %begin) !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]] ; CHECK: await.ready: ; CHECK: #dbg_value(i32 poison, ![[IVAR_RESUME:[0-9]+]], !DIExpression( ; CHECK: #dbg_value(i32 poison, ![[JVAR_RESUME:[0-9]+]], !DIExpression( ; -; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov" +; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume" ; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i" ; CHECK: ![[JVAR_RESUME]] = !DILocalVariable(name: "j" source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll" -define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 { +define void @_Z3foov(i32 %i, i32 %j) presplitcoroutine !dbg !8 { entry: %__promise = alloca i8, align 8 %x = alloca [10 x i32], align 16 diff --git a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll index 28592cc671062..5f7701c357ec3 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split,coro-split)' -S | FileCheck %s ; ; This file is based on coro-debug-frame-variable.ll. -; CHECK-LABEL: define void @f( +; CHECK-LABEL: define void @_Z3foov( ; CHECK: %[[frame:.*]] = call {{.*}} @llvm.coro.begin ; CHECK: #dbg_value(ptr %[[frame]] ; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, [[OffsetX:[0-9]*]]), @@ -20,7 +20,7 @@ ; CHECK: #dbg_value(ptr %[[frame]] ; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, [[OffsetJ:[0-9]*]], DW_OP_deref), -; CHECK-LABEL: void @f.resume( +; CHECK-LABEL: void @_Z3foov.resume( ; CHECK-SAME: ptr {{.*}} %[[frame:.*]]) ; CHECK-SAME: !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]] ; CHECK: %[[frame_alloca:.*]] = alloca ptr @@ -37,7 +37,7 @@ ; CHECK: #dbg_value(ptr %[[frame_alloca]], ![[JVAR_RESUME:[0-9]+]], ; CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetJ]], DW_OP_deref) ; -; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov" +; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume" ; CHECK: ![[FRAME_DI_NUM]] = !DILocalVariable(name: "__coro_frame" ; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i" ; CHECK: ![[XVAR_RESUME]] = !DILocalVariable(name: "x" @@ -46,7 +46,7 @@ declare void @consume(i32) -define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 { +define void @_Z3foov(i32 %i, i32 %j) presplitcoroutine !dbg !8 { entry: %__promise = alloca i8, align 8 %x = alloca [10 x i32], align 16 @@ -257,4 +257,4 @@ attributes #4 = { argmemonly nofree nosync nounwind willreturn writeonly } !21 = !DILocation(line: 43, column: 3, scope: !7) !22 = !DILocation(line: 43, column: 8, scope: !7) !23 = !DILocalVariable(name: "produced", scope: !7, file: !1, line:24, type: !10) -!30 = distinct !DIAssignID() \ No newline at end of file +!30 = distinct !DIAssignID() diff --git a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll index a3c62b2dd12e1..125ec752c8345 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll @@ -23,11 +23,11 @@ ; ; The CHECKs verify that dbg.declare intrinsics are created for the coroutine ; funclet 'f.resume', and that they reference the address of the variables on -; the coroutine frame. The debug locations for the original function 'f' are +; the coroutine frame. The debug locations for the original function 'foo' are ; static (!11 and !13), whereas the coroutine funclet will have its own new ; ones with identical line and column numbers. ; -; CHECK-LABEL: define void @f() {{.*}} { +; CHECK-LABEL: define void @_Z3foov() {{.*}} { ; CHECK: entry: ; CHECK: %j = alloca i32, align 4 ; CHECK: #dbg_declare(ptr %j, ![[JVAR:[0-9]+]], !DIExpression(), ![[JDBGLOC:[0-9]+]] @@ -36,7 +36,7 @@ ; CHECK: #dbg_declare(ptr %[[MEMORY]], ![[IVAR:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 20), ![[IDBGLOC]] ; CHECK: await.ready: ; -; CHECK-LABEL: define internal fastcc void @f.resume({{.*}}) {{.*}} { +; CHECK-LABEL: define internal fastcc void @_Z3foov.resume({{.*}}) {{.*}} { ; CHECK: entry.resume: ; CHECK-NEXT: %[[DBG_PTR:.*]] = alloca ptr ; CHECK-NEXT: #dbg_declare(ptr %[[DBG_PTR]], ![[XVAR_RESUME:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 32), @@ -58,13 +58,13 @@ ; CHECK-DAG: ![[JDBGLOC]] = !DILocation(line: 32, column: 7, scope: ![[BLK_SCOPE]]) ; CHECK-DAG: ![[XVAR_RESUME]] = !DILocalVariable(name: "x" -; CHECK-DAG: ![[RESUME_PROG_SCOPE:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov" +; CHECK-DAG: ![[RESUME_PROG_SCOPE:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume" ; CHECK-DAG: ![[IDBGLOC_RESUME]] = !DILocation(line: 24, column: 7, scope: ![[RESUME_BLK_SCOPE:[0-9]+]]) ; CHECK-DAG: ![[RESUME_BLK_SCOPE]] = distinct !DILexicalBlock(scope: ![[RESUME_PROG_SCOPE]], file: !1, line: 23, column: 12) ; CHECK-DAG: ![[IVAR_RESUME]] = !DILocalVariable(name: "i" ; CHECK-DAG: ![[JVAR_RESUME]] = !DILocalVariable(name: "j" ; CHECK-DAG: ![[JDBGLOC_RESUME]] = !DILocation(line: 32, column: 7, scope: ![[RESUME_BLK_SCOPE]]) -define void @f() presplitcoroutine !dbg !8 { +define void @_Z3foov() presplitcoroutine !dbg !8 { entry: %__promise = alloca i8, align 8 %i = alloca i32, align 4 diff --git a/llvm/test/Transforms/Coroutines/coro-debug.ll b/llvm/test/Transforms/Coroutines/coro-debug.ll index 17a0b80c5b5e5..a220073248ba3 100644 --- a/llvm/test/Transforms/Coroutines/coro-debug.ll +++ b/llvm/test/Transforms/Coroutines/coro-debug.ll @@ -6,12 +6,12 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: noinline nounwind -define ptr @f(i32 %x) #0 personality i32 0 !dbg !6 { +define ptr @flink(i32 %x) #0 personality i32 0 !dbg !6 { entry: %x.addr = alloca i32, align 4 %coro_hdl = alloca ptr, align 8 store i32 %x, ptr %x.addr, align 4 - %0 = call token @llvm.coro.id(i32 0, ptr null, ptr @f, ptr null), !dbg !16 + %0 = call token @llvm.coro.id(i32 0, ptr null, ptr @flink, ptr null), !dbg !16 %1 = call i64 @llvm.coro.size.i64(), !dbg !16 %call = call ptr @malloc(i64 %1), !dbg !16 %2 = call ptr @llvm.coro.begin(token %0, ptr %call) #7, !dbg !16 @@ -170,8 +170,8 @@ attributes #7 = { noduplicate } !31 = !DILocalVariable(name: "allocated", scope: !6, file: !7, line: 55, type: !11) !32 = !DILocalVariable(name: "inline_asm", scope: !6, file: !7, line: 55, type: !11) -; CHECK: define ptr @f(i32 %x) #0 personality i32 0 !dbg ![[ORIG:[0-9]+]] -; CHECK: define internal fastcc void @f.resume(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[RESUME:[0-9]+]] +; CHECK: define ptr @flink(i32 %x) #0 personality i32 0 !dbg ![[ORIG:[0-9]+]] +; CHECK: define internal fastcc void @flink.resume(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[RESUME:[0-9]+]] ; CHECK: entry.resume: ; CHECK: %[[DBG_PTR:.*]] = alloca ptr ; CHECK: #dbg_declare(ptr %[[DBG_PTR]], ![[RESUME_COROHDL:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, @@ -194,18 +194,18 @@ attributes #7 = { noduplicate } ; CHECK: [[DEFAULT_DEST]]: ; CHECK-NOT: {{.*}}: ; CHECK: #dbg_value(i32 %[[CALLBR_RES]] -; CHECK: define internal fastcc void @f.destroy(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[DESTROY:[0-9]+]] -; CHECK: define internal fastcc void @f.cleanup(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[CLEANUP:[0-9]+]] +; CHECK: define internal fastcc void @flink.destroy(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[DESTROY:[0-9]+]] +; CHECK: define internal fastcc void @flink.cleanup(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[CLEANUP:[0-9]+]] ; CHECK: ![[ORIG]] = distinct !DISubprogram(name: "f", linkageName: "flink" -; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "flink.resume" ; CHECK: ![[RESUME_COROHDL]] = !DILocalVariable(name: "coro_hdl", scope: ![[RESUME]] ; CHECK: ![[RESUME_X]] = !DILocalVariable(name: "x", arg: 1, scope: ![[RESUME]] ; CHECK: ![[RESUME_CONST]] = !DILocalVariable(name: "direct_const", scope: ![[RESUME]] ; CHECK: ![[RESUME_DIRECT]] = !DILocalVariable(name: "direct_mem", scope: ![[RESUME]] ; CHECK: ![[RESUME_DIRECT_VALUE]] = !DILocalVariable(name: "direct_value", scope: ![[RESUME]] -; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "flink.destroy" -; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "flink.cleanup"