[DebugInfo] Emit witness and objc method declarations in debug info

When emitting a method definition in debug info, the compiler should
also emit the method's declaration, because LLVM LTO can't unify type
definitions when a child DIE is a full subprogram definition. This is
already the behavior for standard methods, this patch implements the
same behavior for witness and objc methods as well.

rdar://123334375
This commit is contained in:
Augusto Noronha
2024-02-28 18:40:54 -08:00
parent ab9e07d34c
commit 53d1844396
3 changed files with 36 additions and 1 deletions

View File

@@ -2834,7 +2834,9 @@ IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn,
// Because there's no good way to cross the CU boundary to insert a nested
// DISubprogram definition in one CU into a type defined in another CU when
// doing LTO builds.
if (Rep == SILFunctionTypeRepresentation::Method) {
if (Rep == SILFunctionTypeRepresentation::Method ||
Rep == SILFunctionTypeRepresentation::ObjCMethod ||
Rep == SILFunctionTypeRepresentation::WitnessMethod) {
llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::toSPFlags(
/*IsLocalToUnit=*/Fn ? Fn->hasInternalLinkage() : true,
/*IsDefinition=*/false, /*IsOptimized=*/Opts.shouldOptimize());

View File

@@ -0,0 +1,16 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s
// Verify that we added a declaration for a witness method.
// CHECK: define{{.*}}@"$s4main14PutCharPrinterCAA09CharacterD0A2aDPxycfCTW"{{.*}} !dbg ![[INIT_DEF_DBG:[0-9]+]]
// CHECK: ![[INIT_DEF_DBG]] = distinct !DISubprogram(name: "init", linkageName: "$s4main14PutCharPrinterCAA09CharacterD0A2aDPxycfCTW"
// CHECK-SAME: DISPFlagDefinition{{.*}} declaration: ![[FUNC_DEF_DBG:[0-9]+]]
// CHECK: ![[FUNC_DEF_DBG]] = !DISubprogram(name: "init", linkageName: "$s4main14PutCharPrinterCAA09CharacterD0A2aDPxycfCTW"
protocol CharacterPrinter {
init()
}
class PutCharPrinter: CharacterPrinter {
public required init() {}
}

View File

@@ -0,0 +1,17 @@
// REQUIRES: objc_interop
// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s
// Verify that we added a declaration for a witness method.
// CHECK: define {{.*}}"$s4main9SomeClassC3fooyyFTo"{{.*}} !dbg ![[INIT_DEF_DBG:[0-9]+]]
// CHECK: ![[INIT_DEF_DBG]] = distinct !DISubprogram(name: "foo", linkageName: "$s4main9SomeClassC3fooyyFTo"
// CHECK-SAME: DISPFlagDefinition{{.*}} declaration: ![[FUNC_DEF_DBG:[0-9]+]]
// CHECK: ![[FUNC_DEF_DBG]] = !DISubprogram(name: "foo", linkageName: "$s4main9SomeClassC3fooyyFTo"
import Foundation
class SomeClass {
public required init() {}
@objc func foo() {}
}