@@ -1092,28 +1092,30 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1092
1092
return DITy;
1093
1093
}
1094
1094
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) {
1104
1100
#ifndef NDEBUG
1105
- if (UniqueID .empty ())
1101
+ if (MangledName .empty ())
1106
1102
assert (!Name.empty () &&
1107
1103
" no mangled name and no human readable name given" );
1108
1104
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) &&
1112
1106
" UID is not a mangled name" );
1113
1107
#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);
1114
1113
1115
1114
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
+
1117
1119
return FwdDecl;
1118
1120
}
1119
1121
@@ -1124,8 +1126,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1124
1126
llvm::DINode::DIFlags Flags, llvm::DIType *DerivedFrom,
1125
1127
unsigned RuntimeLang, StringRef UniqueID) {
1126
1128
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);
1129
1132
// Collect the members.
1130
1133
SmallVector<llvm::Metadata *, 16 > Elements;
1131
1134
unsigned OffsetInBits = 0 ;
@@ -1171,9 +1174,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1171
1174
unsigned SizeInBits = 0 ;
1172
1175
unsigned AlignInBits = 0 ;
1173
1176
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);
1177
1180
// Collect the members.
1178
1181
SmallVector<llvm::Metadata *, 16 > Elements;
1179
1182
for (VarDecl *VD : Decl->getStoredProperties ()) {
@@ -1215,12 +1218,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1215
1218
return createUnsubstitutedVariantType (DbgTy, Decl, MangledName, Scope,
1216
1219
File, 0 , Flags);
1217
1220
}
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);
1224
1225
// Force the creation of the unsubstituted type, don't create it
1225
1226
// directly so it goes through all the caching/verification logic.
1226
1227
auto unsubstitutedDbgTy = getOrCreateType (DbgTy);
@@ -1231,78 +1232,71 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1231
1232
return DIType;
1232
1233
}
1233
1234
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 );
1296
1297
return OpaqueType;
1297
1298
}
1298
1299
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
-
1306
1300
// / Create debug information for an enum with a raw type (enum E : Int {}).
1307
1301
llvm::DICompositeType *createRawEnumType (CompletedDebugTypeInfo DbgTy,
1308
1302
EnumDecl *Decl,
@@ -1319,13 +1313,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1319
1313
// Default, since Swift doesn't allow specifying a custom alignment.
1320
1314
unsigned AlignInBits = 0 ;
1321
1315
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);
1329
1319
1330
1320
auto RawType = Decl->getRawType ();
1331
1321
auto &TI = IGM.getTypeInfoForUnlowered (RawType);
@@ -1373,14 +1363,10 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1373
1363
1374
1364
// A variant part should actually be a child to a DW_TAG_structure_type
1375
1365
// 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;
1383
1366
1367
+ auto FwdDecl = createTemporaryReplaceableForwardDecl (
1368
+ DbgTy.getType (), Scope, File, Line, SizeInBits, AlignInBits, Flags,
1369
+ MangledName, Name);
1384
1370
SmallVector<llvm::Metadata *, 16 > Elements;
1385
1371
for (auto *ElemDecl : Decl->getAllElements ()) {
1386
1372
std::optional<CompletedDebugTypeInfo> ElemDbgTy;
@@ -1437,13 +1423,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1437
1423
unsigned AlignInBits = 0 ;
1438
1424
// A variant part should actually be a child to a DW_TAG_structure_type
1439
1425
// 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);
1447
1429
1448
1430
SmallVector<llvm::Metadata *, 16 > Elements;
1449
1431
for (auto *ElemDecl : Decl->getAllElements ()) {
@@ -1655,13 +1637,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1655
1637
unsigned SizeInBits, unsigned AlignInBits,
1656
1638
llvm::DINode::DIFlags Flags,
1657
1639
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);
1665
1643
1666
1644
CanSILFunctionType FunTy;
1667
1645
TypeBase *BaseTy = DbgTy.getType ();
@@ -1720,12 +1698,9 @@ createSpecializedStructOrClassType(NominalOrBoundGenericNominalType *Type,
1720
1698
}
1721
1699
// FIXME: assert that SizeInBits == OffsetInBits.
1722
1700
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);
1729
1704
1730
1705
auto DITy = DBuilder.createStructType (
1731
1706
Scope, MangledName, MainFile, 0 , SizeInBits, AlignInBits, Flags,
0 commit comments