Skip to content

[Debug Info] Emit -gdwarf-types debug info for Builtin.FixedArray<> #79181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/IRGen/DebugTypeInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ LLVM_DUMP_METHOD void DebugTypeInfo::dump() const {
std::optional<CompletedDebugTypeInfo>
CompletedDebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &Info,
IRGenModule &IGM) {
if (!Ty || Ty->hasTypeParameter())
return {};
auto *StorageType = IGM.getStorageTypeForUnlowered(Ty);
std::optional<uint64_t> SizeInBits;
if (StorageType->isSized())
Expand Down
267 changes: 176 additions & 91 deletions lib/IRGen/IRGenDebugInfo.cpp

Large diffs are not rendered by default.

35 changes: 14 additions & 21 deletions test/DebugInfo/BoundGenericStruct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,14 @@ public let s = S<Int>(t: 0)
// CHECK: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
// CHECK: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$sSiD"

// DWARF: !DICompositeType(tag: DW_TAG_structure_type,
// DWARF-SAME: templateParams: ![[PARAMS:[0-9]+]]
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVySiGD"
// DWARF-SAME: specification:
// DWARF-DAG: !DICompositeType(tag: DW_TAG_structure_type, {{.*}}templateParams: ![[PARAMS:[0-9]+]]{{.*}}identifier: "$s18BoundGenericStruct1SVySiGD"{{.*}}specification:

// DWARF: ![[PARAMS]] = !{![[INTPARAM:[0-9]+]]}
// DWARF: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
// DWARF: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Int", {{.*}}identifier: "$sSiD"
// DWARF-DAG: ![[PARAMS]] = !{![[INTPARAM:[0-9]+]]}
// DWARF-DAG: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
// DWARF-DAG: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Int", {{.*}}identifier: "$sSiD"

// DWARF: !DICompositeType(tag: DW_TAG_structure_type, name: "S",
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVyxGD")
// DWARF: !DIDerivedType(tag: DW_TAG_member, name: "t"
// DWARF: ![[GENERIC_PARAM_TYPE:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$sxD"
// DWARF-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "S", {{.*}}identifier: "$s18BoundGenericStruct1SVyxGD")
// DWARF-DAG: !DIDerivedType(tag: DW_TAG_member, name: "t"


public struct S2<T> {
Expand All @@ -39,17 +34,15 @@ public let inner = S2<Double>.Inner(t:4.2)
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
// CHECK-SAME: flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift)

// DWARF: !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", scope: ![[SCOPE1:[0-9]+]],{{.*}} size: 64, {{.*}}, templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD",{{.*}} specification: ![[SPECIFICATION:[0-9]+]]
// DWARF: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
// DWARF-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", scope: ![[SCOPE1:[0-9]+]],{{.*}} size: 64, elements: ![[ELEMENTS1:[0-9]+]], {{.*}}templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD", specification: ![[SPECIFICATION:[0-9]+]])
// DWARF-DAG: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",

// DWARF: ![[PARAMS2]] = !{![[PARAMS3:[0-9]+]]}
// DWARF: ![[PARAMS3]] = !DITemplateTypeParameter(type: ![[PARAMS4:[0-9]+]])
// DWARF: ![[PARAMS4]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Double",
// DWARF-SAME: size: 64, {{.*}}runtimeLang: DW_LANG_Swift, identifier: "$sSdD")
// DWARF-DAG: ![[PARAMS2]] = !{![[PARAMS3:[0-9]+]]}
// DWARF-DAG: ![[PARAMS3]] = !DITemplateTypeParameter(type: ![[PARAMS4:[0-9]+]])
// DWARF-DAG: ![[PARAMS4]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Double"{{.*}} size: 64, {{.*}}runtimeLang: DW_LANG_Swift,{{.*}} identifier: "$sSdD")

// DWARF: [[SPECIFICATION]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Inner",
// DWARF-SAME: elements: ![[ELEMENTS1:[0-9]+]], runtimeLang: DW_LANG_Swift, identifier: "$s18BoundGenericStruct2S2V5InnerVyx_GD")
// DWARF-DAG: [[SPECIFICATION]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", {{.*}}runtimeLang: DW_LANG_Swift, identifier: "$s18BoundGenericStruct2S2V5InnerVyx_GD")

// DWARF: ![[ELEMENTS1]] = !{![[ELEMENTS2:[0-9]+]]}
// DWARF-DAG: ![[ELEMENTS1]] = !{![[ELEMENTS2:[0-9]+]]}

// DWARF: ![[ELEMENTS2]] = !DIDerivedType(tag: DW_TAG_member, name: "t", {{.*}}, baseType: ![[GENERIC_PARAM_TYPE]])
// DWARF-DAG: ![[ELEMENTS2]] = !DIDerivedType(tag: DW_TAG_member, name: "t"
2 changes: 1 addition & 1 deletion test/DebugInfo/classes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class SomeClass {

// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "SomeClass",
// CHECK-SAME: size: {{64|32}}, elements:
// CHECK-SAME: runtimeLang: DW_LANG_Swift, identifier: "$s7classes9SomeClassCD")
// CHECK-SAME: runtimeLang: DW_LANG_Swift,{{.*}} identifier: "$s7classes9SomeClassCD")

// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "first",
// CHECK-SAME: size: {{64|32}})
Expand Down
5 changes: 2 additions & 3 deletions test/DebugInfo/enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ enum Either {
// DWARF: DIDerivedType(tag: DW_TAG_member, name: "Neither",
// DWARF-SAME: baseType: null)
}
// CHECK: ![[EMPTY:.*]] = !{}
let E : Either = .Neither;

// CHECK: !DICompositeType({{.*}}name: "Color",
// CHECK-SAME: size: 8,
// CHECK-SAME: identifier: "$s4enum5ColorOD"

enum Color : UInt64 {
// This is effectively a 2-bit bitfield:
// DWARF: DICompositeType(tag: DW_TAG_enumeration_type, name: "Color",
Expand Down Expand Up @@ -72,8 +72,7 @@ let movie : Maybe<Color> = .none

public enum Nothing { }
public func foo(_ empty : Nothing) { }
// CHECK: !DICompositeType({{.*}}name: "Nothing", {{.*}}elements: ![[EMPTY]]

// CHECK: !DICompositeType({{.*}}name: "Nothing"
// CHECK: !DICompositeType({{.*}}name: "$s4enum4RoseOyxG{{z?}}D"
enum Rose<A> {
case MkRose(() -> A, () -> [Rose<A>])
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/parent-scope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public struct Generic<T : P> {
// But only one concrete type is expected.
// CHECK: !DISubprogram({{.*}}linkageName: "$s4main8ConcreteV3getSiSgyF",
// CHECK-SAME: scope: ![[CONC:[0-9]+]],
// CHECK: ![[CONC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Concrete", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, elements: !{{[0-9]+}}, runtimeLang: DW_LANG_Swift, identifier: "$s4main8ConcreteVD")
// CHECK: ![[CONC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Concrete", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, runtimeLang: DW_LANG_Swift, identifier: "$s4main8ConcreteVD")
public struct Concrete {
public func get() -> Int? {
return nil
Expand Down
55 changes: 55 additions & 0 deletions test/DebugInfo/typealias-recursive.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -gdwarf-types -o - | %FileCheck %s

protocol TraitsProtocol {
associatedtype IntType: FixedWidthInteger
}

final class MyClass<SomeTraits: TraitsProtocol> {
typealias Traits = SomeTraits
private var blame: MyClass<Traits>?
}

struct Traits32: TraitsProtocol {
typealias IntType = UInt32
}

let v : MyClass<Traits32>? = nil


// This typedef is not necessary from a semantic point of view, but the result
// of a trade-off done to preserve type sugar (= not generally canonicalizing types).
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "$s4main7MyClassCyAC6TraitsayAA8Traits32V_GGSgD", {{.*}}baseType: ![[CANONICAL:[0-9]+]])
// CHECK-DAG: ![[CANONICAL]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$s4main7MyClassCyAA8Traits32VGSgD", specification: ![[OPTIONAL:[0-9]+]])

// CHECK-DAG: ![[OPTIONAL]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Optional"

// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", {{.*}}templateParams: ![[PARAMS:[0-9]+]], identifier: "$s4main7MyClassCyAA8Traits32VGD", specification: ![[SPEC:[0-9]+]])
// CHECK-DAG: ![[PARAMS]] = !{![[PARAM:[0-9]+]]}
// CHECK-DAG: ![[PARAM]] = !DITemplateTypeParameter(type: ![[TRAITS32:[0-9]+]])
// CHECK-DAG: ![[TRAITS32]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Traits32"
// CHECK-DAG: ![[SPEC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", {{.*}}identifier: "$s4main7MyClassCyxGD")


// have a second cache from (DIScope???, CanonicalMangledName) -> DIType
// if is non-canonical type emit a typealias to DIType.

struct C {}
struct A {
typealias B = C
let b: B
}

struct D {
typealias B = C
let b: B
}

let a : A? = nil
let b : D? = nil

// Check that the mechanism creating the canoicalization typedefs, doesn't merge
// more than it should:
// CHECK-DAG: ![[B1:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s4main1AV1BaD"
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "b", {{.*}} baseType: ![[B1]])
// CHECK-DAG: ![[B2:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s4main1DV1BaD"
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "b", {{.*}}, baseType: ![[B2]])
12 changes: 12 additions & 0 deletions test/DebugInfo/typealias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,15 @@ extension Up where A.A == Int {
var gg: DependentAlias<Self> = 123
}
}

typealias UsedAsGenericParameter = Float
struct S<T> {}
public func bar() {
let s = S<UsedAsGenericParameter>()
// CHECK-DAG: !DILocalVariable(name: "s",{{.*}} type: ![[LET_S_WITH_ALIAS:[0-9]+]]
// CHECK-DAG: ![[LET_S_WITH_ALIAS]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[S_WITH_ALIAS:[0-9]+]]
// CHECK-DAG: ![[S_WITH_ALIAS]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}elements: ![[ELTS:[0-9]+]]
// CHECK-DAG: ![[ELTS]] = !{![[MEMBER:[0-9]+]]}
// CHECK-DAG: ![[MEMBER]] = !DIDerivedType(tag: DW_TAG_member, {{.*}}baseType: ![[USED_AS_GENERIC:[0-9]+]])
// CHECK-DAG: ![[USED_AS_GENERIC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s9typealias1SVyAA22UsedAsGenericParameteraGD"
}
12 changes: 10 additions & 2 deletions test/DebugInfo/typealias_indirect.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
// RUN: %target-swift-frontend %s -emit-ir -parse-as-library -module-name a -g -o - | %FileCheck %s
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10LocalAliasaD", {{.*}}baseType: ![[BASETY:[0-9]+]]
// CHECK: ![[BASETY]]{{.*}}$sSbD

// FIXME: While we can preserve that ClassAlias = MyClass<LocalAlias, Bool>
// and we can preserve that MyClass<LocalAlias, Bool> = MyClass<Bool, Bool>
// we cannot preserve that LocalAlias = Bool.

// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a7MyClassCyAA10LocalAliasaSbGD",{{.*}}baseType: ![[BOOLBOOLTY:[0-9]+]]
// CHECK: ![[BOOLBOOLTY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", {{.*}}identifier: "$s1a7MyClassCyS2bGD"

// FIXME: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10LocalAliasaD", {{.*}}baseType: ![[BASETY:[0-9]+]]
// FIXME: ![[BASETY]]{{.*}}$sSbD
public class MyClass<A, B> {}
public typealias LocalAlias = Bool
public typealias ClassAlias = MyClass<LocalAlias, Bool>
Expand Down
9 changes: 8 additions & 1 deletion test/DebugInfo/value-generics-embedded.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@
// REQUIRES: swift_feature_Embedded
// REQUIRES: swift_feature_ValueGenerics

// CHECK-DAG: !DICompositeType({{.*}}templateParams: ![[SLAB_PARAMS:.*]], {{.*}}identifier: "$es11InlineArrayVy$0_4main8MySpriteVGD"
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "InlineArray",{{.*}}size: 64{{.*}}elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, templateParams: ![[SLAB_PARAMS:[0-9]+]], identifier: "$es11InlineArrayVy$0_4main8MySpriteVGD", specification:
// CHECK-DAG: ![[SLAB_PARAMS]] = !{![[COUNT_PARAM:.*]], ![[ELEMENT_PARAM:.*]]}
// CHECK-DAG: ![[COUNT_PARAM]] = !DITemplateTypeParameter(type: ![[COUNT_TYPE:.*]])
// CHECK-DAG: ![[COUNT_TYPE]] = !DICompositeType({{.*}}name: "$e$0_D"
// CHECK-DAG: ![[ELEMENT_PARAM]] = !DITemplateTypeParameter(type: ![[ELEMENT_TYPE:.*]])
// CHECK-DAG: ![[ELEMENT_TYPE]] = !DICompositeType({{.*}}name: "MySprite", {{.*}}identifier: "$e4main8MySpriteVD"

// CHECK-DAG: ![[ELTS]] = !{![[STORAGE_MEMBER:.*]]}
// CHECK-DAG: ![[STORAGE_MEMBER]] = !DIDerivedType(tag: DW_TAG_member, name: "_storage",{{.*}}baseType: ![[ARRAY:[0-9]+]], size: 64
// CHECK-DAG: ![[ARRAY]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELEMENT_TYPE]], size: 64, elements: ![[SUBRANGES:[0-9]+]])
// CHECK-DAG: ![[SUBRANGES]] = !{![[DIM:[0-9]+]]}
// CHECK-DAG: ![[DIM]] = !DISubrange(count: 1)

struct MySprites {
var bricks: InlineArray<1, MySprite>
}
Expand Down