diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index c86ff6e140f5d..a2d644923ba1b 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -2468,6 +2468,18 @@ IRGenDebugInfoImpl::emitFunction(const SILDebugScope *DS, llvm::Function *Fn, /*IsLocalToUnit=*/Fn ? Fn->hasInternalLinkage() : true, /*IsDefinition=*/true, /*IsOptimized=*/Opts.shouldOptimize()); + // When the function is a method, we only want a DW_AT_declaration there, + // because LLVM LTO can't unify type definitions when a child DIE is a full + // subprogram definition. + if (Rep == SILFunctionTypeRepresentation::Method) { + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::toSPFlags( + /*IsLocalToUnit=*/Fn ? Fn->hasInternalLinkage() : true, + /*IsDefinition=*/false, /*IsOptimized=*/Opts.shouldOptimize()); + Decl = DBuilder.createMethod(Scope, Name, LinkageName, File, Line, DIFnTy, + 0, 0, nullptr, Flags, SPFlags, + TemplateParameters, Error); + } + // Construct the DISubprogram. llvm::DISubprogram *SP = DBuilder.createFunction( Scope, Name, LinkageName, File, Line, DIFnTy, ScopeLine, Flags, SPFlags, diff --git a/test/DebugInfo/method.swift b/test/DebugInfo/method.swift new file mode 100644 index 0000000000000..3e07f77d17387 --- /dev/null +++ b/test/DebugInfo/method.swift @@ -0,0 +1,27 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s + +// Verify that we added a declaration for a method. +public struct Foo { + static func static_method() {} + func method() {} +} + +public class Bar { + static func static_method() {} + func method() {} +} + +func a_function() {} + +// CHECK: distinct !DISubprogram(name: "static_method", +// CHECK-SAME: declaration: +// CHECK: distinct !DISubprogram(name: "method", +// CHECK-SAME: declaration: +// CHECK: distinct !DISubprogram(name: "static_method", +// CHECK-SAME: declaration: +// CHECK: distinct !DISubprogram(name: "method", +// CHECK-SAME: declaration: + +// CHECK: distinct !DISubprogram(name: "a_function", +// CHECK-NOT: declaration: +// CHECK-SAME: )