Skip to content

Commit 14bb4b6

Browse files
committed
[Debug Info] Emit -gdwarf-types debug info for Builtin.FixedArray<>
This commit also changes how specialized types are being emitted. Previously we would not emitthe detailed member information in the specialized type itself, and instead rely on the fact that it was present in the unspecialized type, however, this wold prevent us from emitting any bound generic members, so we're now emitting the members in both variants of the type. rdar://144315592
1 parent 31250c6 commit 14bb4b6

File tree

7 files changed

+77
-51
lines changed

7 files changed

+77
-51
lines changed

lib/IRGen/DebugTypeInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ LLVM_DUMP_METHOD void DebugTypeInfo::dump() const {
191191
std::optional<CompletedDebugTypeInfo>
192192
CompletedDebugTypeInfo::getFromTypeInfo(swift::Type Ty, const TypeInfo &Info,
193193
IRGenModule &IGM) {
194+
if (!Ty || Ty->hasTypeParameter())
195+
return {};
194196
auto *StorageType = IGM.getStorageTypeForUnlowered(Ty);
195197
std::optional<uint64_t> SizeInBits;
196198
if (StorageType->isSized())

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,24 +1119,22 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11191119
return FwdDecl;
11201120
}
11211121

1122-
llvm::DICompositeType *
1123-
createStructType(DebugTypeInfo DbgTy, NominalTypeDecl *Decl,
1124-
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
1125-
unsigned SizeInBits, unsigned AlignInBits,
1126-
llvm::DINode::DIFlags Flags, llvm::DIType *DerivedFrom,
1127-
unsigned RuntimeLang, StringRef UniqueID) {
1122+
llvm::DICompositeType *createStructType(
1123+
NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
1124+
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
1125+
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1126+
StringRef MangledName, llvm::DIType *SpecificationOf = nullptr) {
11281127
StringRef Name = Decl->getName().str();
11291128
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1130-
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1131-
UniqueID, Name);
1129+
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1130+
Name);
11321131
// Collect the members.
11331132
SmallVector<llvm::Metadata *, 16> Elements;
11341133
unsigned OffsetInBits = 0;
11351134
for (VarDecl *VD : Decl->getStoredProperties()) {
1136-
auto memberTy = DbgTy.getType()->getTypeOfMember(VD);
1137-
1135+
auto memberTy = Type->getTypeOfMember(VD);
11381136
if (auto DbgTy = CompletedDebugTypeInfo::getFromTypeInfo(
1139-
VD->getInterfaceType(),
1137+
memberTy,
11401138
IGM.getTypeInfoForUnlowered(
11411139
IGM.getSILTypes().getAbstractionPattern(VD), memberTy),
11421140
IGM))
@@ -1145,13 +1143,14 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11451143
else
11461144
// Without complete type info we can only create a forward decl.
11471145
return DBuilder.createForwardDecl(
1148-
llvm::dwarf::DW_TAG_structure_type, UniqueID, Scope, File, Line,
1146+
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
11491147
llvm::dwarf::DW_LANG_Swift, SizeInBits, 0);
11501148
}
11511149

1152-
auto DITy = DBuilder.createStructType(
1153-
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
1154-
DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
1150+
llvm::DINodeArray BoundParams = collectGenericParams(Type);
1151+
auto DITy = createStruct(
1152+
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1153+
DBuilder.getOrCreateArray(Elements), BoundParams, SpecificationOf);
11551154
DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
11561155
return DITy;
11571156
}
@@ -1267,6 +1266,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12671266
auto *Decl = Type->getNominalOrBoundGenericNominal();
12681267
if (!Decl)
12691268
return nullptr;
1269+
1270+
// This temporary forward decl seems to be redundant. Can it be removed?
12701271
StringRef Name = Decl->getName().str();
12711272
auto FwdDecl = createTemporaryReplaceableForwardDecl(
12721273
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
@@ -1298,11 +1299,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12981299
}
12991300
}
13001301

1302+
// Create the substituted type.
13011303
auto *OpaqueType =
1302-
createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : "", File, Line,
1303-
SizeInBits, AlignInBits, Flags, MangledName,
1304-
collectGenericParams(Type), UnsubstitutedDITy);
1305-
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
1304+
createStructType(Type, Decl, Scope, File, Line, SizeInBits, AlignInBits,
1305+
Flags, MangledName, UnsubstitutedDITy);
13061306
return OpaqueType;
13071307
}
13081308

@@ -1712,23 +1712,32 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17121712
}
17131713

17141714
llvm::DICompositeType *
1715-
createOpaqueStruct(llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File,
1716-
unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
1717-
llvm::DINode::DIFlags Flags, StringRef MangledName,
1718-
llvm::DINodeArray BoundParams = {},
1719-
llvm::DIType *SpecificationOf = nullptr) {
1715+
createStruct(llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File,
1716+
unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
1717+
llvm::DINode::DIFlags Flags, StringRef MangledName,
1718+
llvm::DINodeArray Elements, llvm::DINodeArray BoundParams,
1719+
llvm::DIType *SpecificationOf) {
17201720

17211721
auto StructType = DBuilder.createStructType(
17221722
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1723-
/* DerivedFrom */ nullptr,
1724-
DBuilder.getOrCreateArray(ArrayRef<llvm::Metadata *>()),
1725-
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName, SpecificationOf);
1723+
/* DerivedFrom */ nullptr, Elements, llvm::dwarf::DW_LANG_Swift,
1724+
nullptr, MangledName, SpecificationOf);
17261725

17271726
if (BoundParams)
17281727
DBuilder.replaceArrays(StructType, nullptr, BoundParams);
17291728
return StructType;
17301729
}
17311730

1731+
llvm::DICompositeType *
1732+
createOpaqueStruct(llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File,
1733+
unsigned Line, unsigned SizeInBits, unsigned AlignInBits,
1734+
llvm::DINode::DIFlags Flags, StringRef MangledName,
1735+
llvm::DINodeArray BoundParams = {},
1736+
llvm::DIType *SpecificationOf = nullptr) {
1737+
return createStruct(Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
1738+
MangledName, {}, BoundParams, SpecificationOf);
1739+
}
1740+
17321741
bool shouldCacheDIType(llvm::DIType *DITy, DebugTypeInfo &DbgTy) {
17331742
// Don't cache a type alias to a forward declaration either.
17341743
if (DbgTy.isFixedBuffer() || DITy->isForwardDecl())
@@ -1794,7 +1803,20 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17941803
llvm_unreachable("not a real type");
17951804

17961805
case TypeKind::BuiltinFixedArray: {
1797-
// TODO: provide proper array debug info
1806+
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1807+
auto *FixedArray = llvm::cast<swift::BuiltinFixedArrayType>(BaseTy);
1808+
llvm::DIType *ElementTy = getOrCreateType(FixedArray->getElementType());
1809+
llvm::SmallVector<llvm::Metadata *, 2> Subscripts;
1810+
if (auto NumElts = FixedArray->getFixedInhabitedSize()) {
1811+
auto *NumEltsNode = llvm::ConstantAsMetadata::get(
1812+
llvm::ConstantInt::get(IGM.Int64Ty, *NumElts));
1813+
Subscripts.push_back(DBuilder.getOrCreateSubrange(
1814+
NumEltsNode /*count*/, nullptr /*lowerBound*/,
1815+
nullptr /*upperBound*/, nullptr /*stride*/));
1816+
}
1817+
return DBuilder.createArrayType(SizeInBits, AlignInBits, ElementTy,
1818+
DBuilder.getOrCreateArray(Subscripts));
1819+
}
17981820
unsigned FwdDeclLine = 0;
17991821
return createOpaqueStruct(Scope, "Builtin.FixedArray", MainFile,
18001822
FwdDeclLine, SizeInBits, AlignInBits, Flags,
@@ -1876,9 +1898,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18761898
return createSpecializedStructOrClassType(
18771899
StructTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
18781900
Flags, MangledName);
1879-
return createStructType(DbgTy, Decl, Scope, L.File, L.Line,
1880-
SizeInBits, AlignInBits, Flags, nullptr,
1881-
llvm::dwarf::DW_LANG_Swift, MangledName);
1901+
return createStructType(StructTy, Decl, Scope, L.File, L.Line,
1902+
SizeInBits, AlignInBits, Flags, MangledName);
18821903
}
18831904
StringRef Name = Decl->getName().str();
18841905
if (!SizeInBitsOrNull)
@@ -1910,9 +1931,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
19101931
ClassTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
19111932
Flags, MangledName);
19121933

1913-
auto *DIType = createStructType(
1914-
DbgTy, Decl, Scope, File, L.Line, SizeInBits, AlignInBits,
1915-
Flags, nullptr, llvm::dwarf::DW_LANG_Swift, MangledName);
1934+
auto *DIType =
1935+
createStructType(ClassTy, Decl, Scope, File, L.Line, SizeInBits,
1936+
AlignInBits, Flags, MangledName);
19161937
assert(DIType && "Unexpected null DIType!");
19171938
assert(DIType && "createStructType should never return null!");
19181939
auto SuperClassTy = ClassTy->getSuperclass();

test/DebugInfo/BoundGenericStruct.swift

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,11 @@ public let s = S<Int>(t: 0)
1212
// CHECK: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
1313
// CHECK: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$sSiD"
1414

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

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

2421
// DWARF: !DICompositeType(tag: DW_TAG_structure_type, name: "S",
2522
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVyxGD")
@@ -42,10 +39,9 @@ public let inner = S2<Double>.Inner(t:4.2)
4239
// 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]+]]
4340
// DWARF: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
4441

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

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

test/DebugInfo/classes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class SomeClass {
77

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

1212
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "first",
1313
// CHECK-SAME: size: {{64|32}})

test/DebugInfo/enum.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ enum Either {
2525
// DWARF: DIDerivedType(tag: DW_TAG_member, name: "Neither",
2626
// DWARF-SAME: baseType: null)
2727
}
28-
// CHECK: ![[EMPTY:.*]] = !{}
2928
let E : Either = .Neither;
3029

3130
// CHECK: !DICompositeType({{.*}}name: "Color",
3231
// CHECK-SAME: size: 8,
3332
// CHECK-SAME: identifier: "$s4enum5ColorOD"
33+
3434
enum Color : UInt64 {
3535
// This is effectively a 2-bit bitfield:
3636
// DWARF: DICompositeType(tag: DW_TAG_enumeration_type, name: "Color",
@@ -72,8 +72,7 @@ let movie : Maybe<Color> = .none
7272

7373
public enum Nothing { }
7474
public func foo(_ empty : Nothing) { }
75-
// CHECK: !DICompositeType({{.*}}name: "Nothing", {{.*}}elements: ![[EMPTY]]
76-
75+
// CHECK: !DICompositeType({{.*}}name: "Nothing"
7776
// CHECK: !DICompositeType({{.*}}name: "$s4enum4RoseOyxG{{z?}}D"
7877
enum Rose<A> {
7978
case MkRose(() -> A, () -> [Rose<A>])

test/DebugInfo/parent-scope.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public struct Generic<T : P> {
1919
// But only one concrete type is expected.
2020
// CHECK: !DISubprogram({{.*}}linkageName: "$s4main8ConcreteV3getSiSgyF",
2121
// CHECK-SAME: scope: ![[CONC:[0-9]+]],
22-
// 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")
22+
// CHECK: ![[CONC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Concrete", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, runtimeLang: DW_LANG_Swift, identifier: "$s4main8ConcreteVD")
2323
public struct Concrete {
2424
public func get() -> Int? {
2525
return nil

test/DebugInfo/value-generics-embedded.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,20 @@
55
// REQUIRES: swift_feature_Embedded
66
// REQUIRES: swift_feature_ValueGenerics
77

8-
// CHECK-DAG: !DICompositeType({{.*}}templateParams: ![[SLAB_PARAMS:.*]], {{.*}}identifier: "$es4SlabVy$0_4main8MySpriteVGD"
8+
9+
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "Slab",{{.*}}size: 64{{.*}}elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, templateParams: ![[SLAB_PARAMS:[0-9]+]], identifier: "$es4SlabVy$0_4main8MySpriteVGD", specification:
910
// CHECK-DAG: ![[SLAB_PARAMS]] = !{![[COUNT_PARAM:.*]], ![[ELEMENT_PARAM:.*]]}
1011
// CHECK-DAG: ![[COUNT_PARAM]] = !DITemplateTypeParameter(type: ![[COUNT_TYPE:.*]])
1112
// CHECK-DAG: ![[COUNT_TYPE]] = !DICompositeType({{.*}}name: "$e$0_D"
1213
// CHECK-DAG: ![[ELEMENT_PARAM]] = !DITemplateTypeParameter(type: ![[ELEMENT_TYPE:.*]])
1314
// CHECK-DAG: ![[ELEMENT_TYPE]] = !DICompositeType({{.*}}name: "MySprite", {{.*}}identifier: "$e4main8MySpriteVD"
15+
16+
// CHECK-DAG: ![[ELTS]] = !{![[STORAGE_MEMBER:.*]]}
17+
// CHECK-DAG: ![[STORAGE_MEMBER]] = !DIDerivedType(tag: DW_TAG_member, name: "_storage",{{.*}}baseType: ![[ARRAY:[0-9]+]], size: 64
18+
// CHECK-DAG: ![[ARRAY]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[ELEMENT_TYPE]], size: 64, elements: ![[SUBRANGES:[0-9]+]])
19+
// CHECK-DAG: ![[SUBRANGES]] = !{![[DIM:[0-9]+]]}
20+
// CHECK-DAG: ![[DIM]] = !DISubrange(count: 1)
21+
1422
struct MySprites {
1523
var bricks: Slab<1, MySprite>
1624
}

0 commit comments

Comments
 (0)