Skip to content

Commit 2b70a7c

Browse files
Merge pull request #80078 from adrian-prantl/146326633
[Debug Info] Do not emit children of bound generic types
2 parents 6a3ead3 + 851470f commit 2b70a7c

File tree

5 files changed

+42
-28
lines changed

5 files changed

+42
-28
lines changed

lib/IRGen/IRGenDebugInfo.cpp

+25-17
Original file line numberDiff line numberDiff line change
@@ -1226,8 +1226,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12261226
return DITy;
12271227
}
12281228

1229-
std::pair<bool, Type>
1230-
getUnsubstituedType(Type Ty, StringRef MangledName) {
1229+
std::pair<bool, Type> getUnsubstitutedType(Type Ty, StringRef MangledName) {
12311230
if (!Ty)
12321231
return {false,{}};
12331232
// Go from Pair<Int, Double> to Pair<T, U>.
@@ -1252,7 +1251,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12521251
llvm::DIScope *Scope, llvm::DIFile *File,
12531252
unsigned Line, llvm::DINode::DIFlags Flags) {
12541253
auto [IsUnsubstituted, UnsubstitutedTy] =
1255-
getUnsubstituedType(EnumTy, MangledName);
1254+
getUnsubstitutedType(EnumTy, MangledName);
12561255
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
12571256
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
12581257
if (IsUnsubstituted)
@@ -1301,7 +1300,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13011300
Name);
13021301

13031302
auto [IsUnsubstitued, UnsubstitutedType] =
1304-
getUnsubstituedType(Type, MangledName);
1303+
getUnsubstitutedType(Type, MangledName);
13051304
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
13061305
UnsubstitutedType, IGM.getTypeInfoForUnlowered(UnsubstitutedType), IGM);
13071306
if (IsUnsubstitued)
@@ -1326,19 +1325,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13261325
}
13271326
}
13281327

1329-
// Recursive types such as `class A<B> { let a : A<A<B>> }` would produce an
1330-
// infinite chain of expansions for the type of `a`. Break these cycles by
1331-
// emitting any bound generics that still have type parameters as forward
1332-
// declarations.
1333-
if (Type->hasTypeParameter() || Type->hasPrimaryArchetype())
1334-
return createOpaqueStructWithSizedContainer(
1335-
Scope, Decl ? Decl->getNameStr() : "", File, Line, SizeInBits,
1336-
AlignInBits, Flags, MangledName, collectGenericParams(Type, true),
1337-
UnsubstitutedDITy);
1328+
// Generally, we don't emit members of a specialized bound generic, because
1329+
// these can be reconstructed by substituting the "template parameters" in
1330+
// the unspecialized type. We make an exception for inline arrays, because
1331+
// DWARF has special support for arrays.
1332+
if (Type->isInlineArray() && !Type->hasTypeParameter() &&
1333+
!Type->hasPrimaryArchetype())
1334+
// Create the substituted type.
1335+
return createStructType(Type, Decl, Scope, File, Line, SizeInBits,
1336+
AlignInBits, Flags, MangledName,
1337+
UnsubstitutedDITy);
13381338

1339-
// Create the substituted type.
1340-
return createStructType(Type, Decl, Scope, File, Line, SizeInBits,
1341-
AlignInBits, Flags, MangledName, UnsubstitutedDITy);
1339+
// Create the substituted type (without members).
1340+
llvm::DIType *SpecializedDITy = createOpaqueStructWithSizedContainer(
1341+
Scope, Decl ? Decl->getNameStr() : "", File, Line, SizeInBits,
1342+
AlignInBits, Flags, MangledName, collectGenericParams(Type),
1343+
UnsubstitutedDITy);
1344+
DBuilder.replaceTemporary(std::move(FwdDecl), SpecializedDITy);
1345+
return SpecializedDITy;
13421346
}
13431347

13441348
/// Create debug information for an enum with a raw type (enum E : Int {}).
@@ -1600,6 +1604,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16001604

16011605
llvm::Metadata *Elements[] = {DBuilder.createMemberType(
16021606
Scope, "", File, 0, SizeInBits, AlignInBits, 0, Flags, UniqueType)};
1607+
// FIXME: It's a limitation of LLVM that a forward declaration cannot have a
1608+
// specificationOf, so this attritbute is put on the sized container type
1609+
// instead. This is confusing consumers, and LLDB has to go out of its way
1610+
// to parse these confusing types as intended.
16031611
return DBuilder.createStructType(
16041612
Scope, "", File, Line, SizeInBits, AlignInBits, Flags,
16051613
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
@@ -2338,7 +2346,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
23382346
if (!isa<llvm::DICompositeType>(CachedType))
23392347
return true;
23402348
bool IsUnsubstituted =
2341-
getUnsubstituedType(DbgTy.getType(), getMangledName(DbgTy).Canonical)
2349+
getUnsubstitutedType(DbgTy.getType(), getMangledName(DbgTy).Canonical)
23422350
.first;
23432351
std::optional<uint64_t> SizeInBits;
23442352
if (!IsUnsubstituted)

test/DebugInfo/BoundGenericStruct.swift

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

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

1717
// DWARF-DAG: ![[PARAMS]] = !{![[INTPARAM:[0-9]+]]}
1818
// DWARF-DAG: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
@@ -34,14 +34,16 @@ public let inner = S2<Double>.Inner(t:4.2)
3434
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
3535
// CHECK-SAME: flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift)
3636

37-
// 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]+]])
37+
// DWARF-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2V5InnerVySd_GD", scope: ![[SCOPE1:[0-9]+]], {{.*}}flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift, templateParams: ![[PARAMS2:[0-9]+]])
38+
3839
// DWARF-DAG: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
3940

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

44-
// DWARF-DAG: [[SPECIFICATION]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", {{.*}}runtimeLang: DW_LANG_Swift, identifier: "$s18BoundGenericStruct2S2V5InnerVyx_GD")
45+
// DWARF-DAG: ![[SPECIFICATION:[0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", {{.*}}elements: ![[ELEMENTS1:[0-9]+]], runtimeLang: DW_LANG_Swift, identifier: "$s18BoundGenericStruct2S2V5InnerVyx_GD")
46+
// DWARF-DAG: !DICompositeType(tag: DW_TAG_structure_type, {{.*}}line: 26, size: 64, {{.*}}specification: ![[SPECIFICATION]]
4547

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

test/DebugInfo/embedded-recur-c-types.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ typedef struct S2 {
2323

2424
public var v: UnsafeMutablePointer<S1_t>? = nil
2525

26-
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, {{.*}} identifier: "$eSpySo4S1_taGD"
27-
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, {{.*}} identifier: "$eSpySo2S2VGD"
26+
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, {{.*}}name: "$eSpySo4S1_taGD"
27+
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, {{.*}}name: "$eSpySo2S2VGD"

test/DebugInfo/typealias-recursive.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ struct Traits32: TraitsProtocol {
1616
let v : MyClass<Traits32>? = nil
1717

1818

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

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

26-
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", {{.*}}templateParams: ![[PARAMS:[0-9]+]], identifier: "$s4main7MyClassCyAA8Traits32VGD", specification: ![[SPEC:[0-9]+]])
23+
// CHECK-DAG: ![[CONTAINER:.*]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}line: 7, {{.*}}elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, specification: ![[SPEC:[0-9]+]])
24+
// CHECK-DAG: ![[ELTS]] = !{![[MEMBER:[0-9]+]]}
25+
// CHECK-DAG: ![[MEMBER]] = !DIDerivedType(tag: DW_TAG_member, {{.*}}baseType: ![[UNSIZED:[0-9]+]]
26+
// CHECK-DAG: ![[UNSIZED]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s4main7MyClassCyAA8Traits32VGD", {{.*}}flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift, templateParams: ![[PARAMS:[0-9]+]])
2727
// CHECK-DAG: ![[PARAMS]] = !{![[PARAM:[0-9]+]]}
2828
// CHECK-DAG: ![[PARAM]] = !DITemplateTypeParameter(type: ![[TRAITS32:[0-9]+]])
2929
// CHECK-DAG: ![[TRAITS32]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Traits32"

test/DebugInfo/typealias_indirect.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
// we cannot preserve that LocalAlias = Bool.
66

77
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10ClassAliasaD"{{.*}}baseType: ![[LOCAL_BOOLTY:[0-9]+]]
8-
// CHECK: ![[LOCAL_BOOLTY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass", {{.*}}identifier: "$s1a7MyClassCyAA10LocalAliasaSbGD"
8+
// CHECK: ![[LOCAL_BOOLTY]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, specification: ![[SPEC:[0-9]+]])
9+
// CHECK-DAG: ![[ELTS]] = !{![[MEMBER:[0-9]+]]}
10+
// CHECK-DAG: ![[MEMBER]] = !DIDerivedType(tag: DW_TAG_member, {{.*}}baseType: ![[UNSIZED:[0-9]+]]
11+
// CHECK-DAG: ![[UNSIZED]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s1a7MyClassCyAA10LocalAliasaSbGD"
12+
// CHECK-DAG: ![[SPEC]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"{{.*}}identifier: "$s1a7MyClassCyxq_GD")
913

1014
// FIXME: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10LocalAliasaD", {{.*}}baseType: ![[BASETY:[0-9]+]]
1115
// FIXME: ![[BASETY]]{{.*}}$sSbD

0 commit comments

Comments
 (0)