Skip to content

Commit dca3e14

Browse files
authored
Merge pull request #78691 from augusto2112/rec-deb-info-embed
[DebugInfo] Fix recursively generating debug info for same type
2 parents bdfb609 + aa6b5c2 commit dca3e14

File tree

2 files changed

+130
-128
lines changed

2 files changed

+130
-128
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 103 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,28 +1092,30 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
10921092
return DITy;
10931093
}
10941094

1095-
llvm::TempDIType createStructForwardDecl(
1096-
DebugTypeInfo DbgTy, NominalTypeDecl *Decl, llvm::DIScope *Scope,
1097-
llvm::DIFile *File, unsigned Line, unsigned SizeInBits,
1098-
llvm::DINode::DIFlags Flags, StringRef UniqueID, StringRef Name) {
1099-
// Forward declare this first because types may be recursive.
1100-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1101-
llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
1102-
llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, Flags, UniqueID));
1103-
1095+
/// Creates a temporary replaceable forward decl to protect against recursion.
1096+
llvm::TempDIType createTemporaryReplaceableForwardDecl(
1097+
TypeBase *Type, llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
1098+
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1099+
StringRef MangledName, StringRef Name) {
11041100
#ifndef NDEBUG
1105-
if (UniqueID.empty())
1101+
if (MangledName.empty())
11061102
assert(!Name.empty() &&
11071103
"no mangled name and no human readable name given");
11081104
else
1109-
assert((UniqueID.starts_with("_T") ||
1110-
UniqueID.starts_with(MANGLING_PREFIX_STR) ||
1111-
UniqueID.starts_with(MANGLING_PREFIX_EMBEDDED_STR)) &&
1105+
assert(swift::Demangle::isMangledName(MangledName) &&
11121106
"UID is not a mangled name");
11131107
#endif
1108+
auto ReplaceableType = DBuilder.createReplaceableCompositeType(
1109+
llvm::dwarf::DW_TAG_structure_type, "", Scope, File, Line,
1110+
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1111+
MangledName);
1112+
auto FwdDecl = llvm::TempDIType(ReplaceableType);
11141113

11151114
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1116-
DITypeCache[DbgTy.getType()] = TH;
1115+
DITypeCache[Type] = TH;
1116+
if (auto UID = ReplaceableType->getRawIdentifier())
1117+
DIRefMap[UID] = llvm::TrackingMDNodeRef(TH);
1118+
11171119
return FwdDecl;
11181120
}
11191121

@@ -1124,8 +1126,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11241126
llvm::DINode::DIFlags Flags, llvm::DIType *DerivedFrom,
11251127
unsigned RuntimeLang, StringRef UniqueID) {
11261128
StringRef Name = Decl->getName().str();
1127-
auto FwdDecl = createStructForwardDecl(DbgTy, Decl, Scope, File, Line,
1128-
SizeInBits, Flags, UniqueID, Name);
1129+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1130+
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1131+
UniqueID, Name);
11291132
// Collect the members.
11301133
SmallVector<llvm::Metadata *, 16> Elements;
11311134
unsigned OffsetInBits = 0;
@@ -1171,9 +1174,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11711174
unsigned SizeInBits = 0;
11721175
unsigned AlignInBits = 0;
11731176
StringRef Name = Decl->getName().str();
1174-
auto FwdDecl = createStructForwardDecl(DbgTy, Decl, Scope, File, Line,
1175-
SizeInBits, Flags, UniqueID, Name);
1176-
1177+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1178+
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1179+
UniqueID, Name);
11771180
// Collect the members.
11781181
SmallVector<llvm::Metadata *, 16> Elements;
11791182
for (VarDecl *VD : Decl->getStoredProperties()) {
@@ -1215,12 +1218,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12151218
return createUnsubstitutedVariantType(DbgTy, Decl, MangledName, Scope,
12161219
File, 0, Flags);
12171220
}
1218-
auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
1219-
llvm::dwarf::DW_TAG_structure_type, "", Scope, File, 0,
1220-
llvm::dwarf::DW_LANG_Swift, 0, 0, llvm::DINode::FlagZero, MangledName));
1221-
1222-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1223-
DITypeCache[EnumTy] = TH;
1221+
StringRef Name = Decl->getName().str();
1222+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1223+
EnumTy, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1224+
Name);
12241225
// Force the creation of the unsubstituted type, don't create it
12251226
// directly so it goes through all the caching/verification logic.
12261227
auto unsubstitutedDbgTy = getOrCreateType(DbgTy);
@@ -1231,78 +1232,71 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12311232
return DIType;
12321233
}
12331234

1234-
/// Create a DICompositeType from a specialized struct. A specialized type
1235-
/// is a generic type, or a child type whose parent is generic.
1236-
llvm::DIType *
1237-
createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1238-
NominalTypeDecl *Decl, llvm::DIScope *Scope,
1239-
llvm::DIFile *File, unsigned Line,
1240-
unsigned SizeInBits, unsigned AlignInBits,
1241-
llvm::DINode::DIFlags Flags,
1242-
StringRef MangledName,
1243-
bool IsClass = false) {
1244-
// To emit debug info of the DwarfTypes level for generic types, the strategy
1245-
// is to emit a description of all the fields for the type with archetypes,
1246-
// and still the same debug info as the ASTTypes level for the specialized
1247-
// type. For example, given:
1248-
// struct Pair<T, U> {
1249-
// let t: T
1250-
// let u: U
1251-
// }
1252-
// When emitting debug information for a type such as Pair<Int, Double>,
1253-
// emit a description of all the fields for Pair<T, U>, and emit the regular
1254-
// debug information for Pair<Int, Double>.
1255-
1256-
auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
1257-
llvm::dwarf::DW_TAG_structure_type, "", Scope, File, Line,
1258-
llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, Flags, MangledName));
1259-
1260-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1261-
DITypeCache[Type] = TH;
1262-
1263-
// Go from Pair<Int, Double> to Pair<T, U>.
1264-
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
1265-
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
1266-
1267-
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
1268-
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
1269-
Mangle::ASTMangler Mangler(IGM.Context);
1270-
std::string DeclTypeMangledName =
1271-
Mangler.mangleTypeForDebugger(UnsubstitutedTy->mapTypeOutOfContext(), {});
1272-
if (DeclTypeMangledName == MangledName) {
1273-
return createUnsubstitutedGenericStructOrClassType(
1274-
DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, Flags, nullptr,
1275-
llvm::dwarf::DW_LANG_Swift, DeclTypeMangledName);
1276-
}
1277-
// Force the creation of the unsubstituted type, don't create it
1278-
// directly so it goes through all the caching/verification logic.
1279-
auto UnsubstitutedType = getOrCreateType(DbgTy);
1280-
1281-
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
1282-
auto SuperClassTy = ClassTy->getSuperclass();
1283-
if (SuperClassTy) {
1284-
auto SuperClassDbgTy = DebugTypeInfo::getFromTypeInfo(
1285-
SuperClassTy, IGM.getTypeInfoForUnlowered(SuperClassTy), IGM);
1286-
1287-
llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy);
1288-
assert(SuperClassDITy && "getOrCreateType should never return null!");
1289-
DBuilder.createInheritance(UnsubstitutedType, SuperClassDITy, 0, 0,
1290-
llvm::DINode::FlagZero);
1291-
}
1292-
1293-
auto *OpaqueType = createPointerSizedStruct(
1294-
Scope, Decl ? Decl->getNameStr() : MangledName, File, 0, Flags,
1295-
MangledName, UnsubstitutedType);
1235+
/// Create a DICompositeType from a specialized struct. A specialized type
1236+
/// is a generic type, or a child type whose parent is generic.
1237+
llvm::DIType *createSpecializedStructOrClassType(
1238+
NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
1239+
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
1240+
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1241+
StringRef MangledName, bool IsClass = false) {
1242+
// To emit debug info of the DwarfTypes level for generic types, the
1243+
// strategy is to emit a description of all the fields for the type with
1244+
// archetypes, and still the same debug info as the ASTTypes level for the
1245+
// specialized type. For example, given: struct Pair<T, U> {
1246+
// let t: T
1247+
// let u: U
1248+
// }
1249+
// When emitting debug information for a type such as Pair<Int, Double>,
1250+
// emit a description of all the fields for Pair<T, U>, and emit the regular
1251+
// debug information for Pair<Int, Double>.
1252+
StringRef Name = Decl->getName().str();
1253+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1254+
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1255+
Name);
1256+
1257+
// Go from Pair<Int, Double> to Pair<T, U>.
1258+
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
1259+
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
1260+
1261+
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
1262+
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
1263+
Mangle::ASTMangler Mangler(IGM.Context);
1264+
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
1265+
UnsubstitutedTy->mapTypeOutOfContext(), {});
1266+
if (DeclTypeMangledName == MangledName) {
1267+
return createUnsubstitutedGenericStructOrClassType(
1268+
DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, Flags, nullptr,
1269+
llvm::dwarf::DW_LANG_Swift, DeclTypeMangledName);
1270+
}
1271+
// Force the creation of the unsubstituted type, don't create it
1272+
// directly so it goes through all the caching/verification logic.
1273+
auto UnsubstitutedType = getOrCreateType(DbgTy);
1274+
1275+
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
1276+
auto SuperClassTy = ClassTy->getSuperclass();
1277+
if (SuperClassTy) {
1278+
auto SuperClassDbgTy = DebugTypeInfo::getFromTypeInfo(
1279+
SuperClassTy, IGM.getTypeInfoForUnlowered(SuperClassTy), IGM);
1280+
1281+
llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy);
1282+
assert(SuperClassDITy && "getOrCreateType should never return null!");
1283+
DBuilder.createInheritance(UnsubstitutedType, SuperClassDITy, 0, 0,
1284+
llvm::DINode::FlagZero);
1285+
}
1286+
1287+
auto *OpaqueType = createPointerSizedStruct(
1288+
Scope, Decl ? Decl->getNameStr() : MangledName, File, 0, Flags,
1289+
MangledName, UnsubstitutedType);
1290+
return OpaqueType;
1291+
}
1292+
1293+
auto *OpaqueType = createOpaqueStruct(
1294+
Scope, "", File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1295+
collectGenericParams(Type), UnsubstitutedType);
1296+
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
12961297
return OpaqueType;
12971298
}
12981299

1299-
auto *OpaqueType = createOpaqueStruct(
1300-
Scope, "", File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1301-
collectGenericParams(Type), UnsubstitutedType);
1302-
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
1303-
return OpaqueType;
1304-
}
1305-
13061300
/// Create debug information for an enum with a raw type (enum E : Int {}).
13071301
llvm::DICompositeType *createRawEnumType(CompletedDebugTypeInfo DbgTy,
13081302
EnumDecl *Decl,
@@ -1319,13 +1313,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
13191313
// Default, since Swift doesn't allow specifying a custom alignment.
13201314
unsigned AlignInBits = 0;
13211315

1322-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1323-
llvm::dwarf::DW_TAG_enumeration_type, MangledName, Scope, File, Line,
1324-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1325-
MangledName));
1326-
1327-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1328-
DITypeCache[DbgTy.getType()] = TH;
1316+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1317+
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1318+
MangledName, Name);
13291319

13301320
auto RawType = Decl->getRawType();
13311321
auto &TI = IGM.getTypeInfoForUnlowered(RawType);
@@ -1373,14 +1363,10 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
13731363

13741364
// A variant part should actually be a child to a DW_TAG_structure_type
13751365
// according to the DWARF spec.
1376-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1377-
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
1378-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1379-
MangledName));
1380-
1381-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1382-
DITypeCache[DbgTy.getType()] = TH;
13831366

1367+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1368+
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1369+
MangledName, Name);
13841370
SmallVector<llvm::Metadata *, 16> Elements;
13851371
for (auto *ElemDecl : Decl->getAllElements()) {
13861372
std::optional<CompletedDebugTypeInfo> ElemDbgTy;
@@ -1437,13 +1423,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
14371423
unsigned AlignInBits = 0;
14381424
// A variant part should actually be a child to a DW_TAG_structure_type
14391425
// according to the DWARF spec.
1440-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1441-
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
1442-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1443-
MangledName));
1444-
1445-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1446-
DITypeCache[DbgTy.getType()] = TH;
1426+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1427+
DbgTy.getType(), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1428+
MangledName, Name);
14471429

14481430
SmallVector<llvm::Metadata *, 16> Elements;
14491431
for (auto *ElemDecl : Decl->getAllElements()) {
@@ -1655,13 +1637,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
16551637
unsigned SizeInBits, unsigned AlignInBits,
16561638
llvm::DINode::DIFlags Flags,
16571639
StringRef MangledName) {
1658-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1659-
llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, MainFile, 0,
1660-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1661-
MangledName));
1662-
1663-
auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
1664-
DITypeCache[DbgTy.getType()] = TH;
1640+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1641+
DbgTy.getType(), Scope, MainFile, 0, SizeInBits, AlignInBits, Flags,
1642+
MangledName, MangledName);
16651643

16661644
CanSILFunctionType FunTy;
16671645
TypeBase *BaseTy = DbgTy.getType();
@@ -1720,12 +1698,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
17201698
}
17211699
// FIXME: assert that SizeInBits == OffsetInBits.
17221700

1723-
llvm::TempDICompositeType FwdDecl(DBuilder.createReplaceableCompositeType(
1724-
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0,
1725-
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1726-
MangledName));
1727-
1728-
DITypeCache[DbgTy.getType()] = llvm::TrackingMDNodeRef(FwdDecl.get());
1701+
auto FwdDecl = createTemporaryReplaceableForwardDecl(
1702+
DbgTy.getType(), Scope, MainFile, 0, SizeInBits, AlignInBits, Flags,
1703+
MangledName, MangledName);
17291704

17301705
auto DITy = DBuilder.createStructType(
17311706
Scope, MangledName, MainFile, 0, SizeInBits, AlignInBits, Flags,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %{python} %utils/split_file.py -o %t %s
3+
4+
// RUN: %target-swift-frontend %t/Main.swift -g -target %target-cpu-apple-macos14 -import-bridging-header %t/BridgingHeader.h -enable-experimental-feature Embedded -wmo -emit-ir -o - | %FileCheck %s
5+
6+
// REQUIRES: swift_in_compiler
7+
// REQUIRES: executable_test
8+
// REQUIRES: OS=macosx
9+
// REQUIRES: embedded_stdlib
10+
// REQUIRES: swift_feature_Embedded
11+
12+
// BEGIN BridgingHeader.h
13+
#pragma once
14+
typedef struct S2 S2_t;
15+
typedef struct S1 {
16+
struct S2 *other;
17+
} S1_t;
18+
typedef struct S2 {
19+
S1_t *producer_pool;
20+
} S2_t;
21+
22+
// BEGIN Main.swift
23+
24+
public var v: UnsafeMutablePointer<S1_t>? = nil
25+
26+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, {{.*}} identifier: "$eSpySo4S1_taGD"
27+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, {{.*}} identifier: "$eSpySo2S2VGD"

0 commit comments

Comments
 (0)