@@ -1157,23 +1157,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1157
1157
return DITy;;
1158
1158
}
1159
1159
1160
- llvm::DIType *createFullDebugInfoGenericForStructOrClassType (
1161
- BoundGenericType *Type, NominalTypeDecl *Decl, llvm::DIScope *Scope,
1162
- llvm::DIFile *File, unsigned Line, unsigned SizeInBits,
1163
- unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1164
- StringRef MangledName, bool IsClass = false ) {
1165
- // To emit full debug info for generic types, the strategy is to emit
1166
- // full debug info for the type with archetypes, and still emit opaque
1167
- // debug information for the specialized type. For example, given:
1168
- // struct Pair<T, U> {
1169
- // let t : T
1170
- // let u: U
1171
- // }
1172
- // When emitting debug information for a type such as Pair<Int, Double>,
1173
- // emit full debug info for Pair<T, U>, and emit the regular debug
1174
- // information for Pair<Int, Double>.
1175
-
1176
- // Go from Pair<Int, Double> to Pair<T, U>.
1160
+ llvm::DIType *
1161
+ createSpecializedEnumType (NominalOrBoundGenericNominalType *EnumTy,
1162
+ EnumDecl *Decl, StringRef MangledName,
1163
+ unsigned SizeInBits, unsigned AlignInBits,
1164
+ llvm::DIScope *Scope, llvm::DIFile *File,
1165
+ unsigned Line, llvm::DINode::DIFlags Flags) {
1177
1166
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
1178
1167
UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
1179
1168
@@ -1183,39 +1172,99 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1183
1172
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
1184
1173
UnsubstitutedTy->mapTypeOutOfContext (), {});
1185
1174
if (DeclTypeMangledName == MangledName) {
1186
- return createUnsubstitutedGenericStructOrClassType (
1187
- DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, SizeInBits,
1188
- AlignInBits, Flags, nullptr , llvm::dwarf::DW_LANG_Swift,
1189
- DeclTypeMangledName);
1175
+ return createUnsubstitutedVariantType (DbgTy, Decl, MangledName,
1176
+ SizeInBits, AlignInBits, Scope,
1177
+ File, 0 , Flags);
1190
1178
}
1179
+ auto FwdDecl = llvm::TempDIType (DBuilder.createReplaceableCompositeType (
1180
+ llvm::dwarf::DW_TAG_structure_type, " " , Scope, File, 0 ,
1181
+ llvm::dwarf::DW_LANG_Swift, 0 , 0 , llvm::DINode::FlagZero, MangledName));
1182
+
1183
+ auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1184
+ DITypeCache[EnumTy] = TH;
1191
1185
// Force the creation of the unsubstituted type, don't create it
1192
1186
// directly so it goes through all the caching/verification logic.
1193
- auto UnsubstitutedType = getOrCreateType (DbgTy);
1194
-
1195
- if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
1196
- auto SuperClassTy = ClassTy->getSuperclass ();
1197
- if (SuperClassTy) {
1198
- auto SuperClassDbgTy = DebugTypeInfo::getFromTypeInfo (
1199
- SuperClassTy, IGM.getTypeInfoForUnlowered (SuperClassTy), IGM);
1200
-
1201
- llvm::DIType *SuperClassDITy = getOrCreateType (SuperClassDbgTy);
1202
- assert (SuperClassDITy && " getOrCreateType should never return null!" );
1203
- DBuilder.createInheritance (UnsubstitutedType, SuperClassDITy, 0 , 0 ,
1204
- llvm::DINode::FlagZero);
1205
- }
1206
-
1207
- auto *OpaqueType = createPointerSizedStruct (
1208
- Scope, Decl ? Decl->getNameStr () : MangledName, File, 0 , Flags,
1209
- MangledName, UnsubstitutedType);
1210
- return OpaqueType;
1211
- }
1212
-
1213
- auto *OpaqueType = createOpaqueStruct (
1214
- Scope, " " , File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1215
- collectGenericParams (Type), UnsubstitutedType);
1187
+ auto unsubstitutedDbgTy = getOrCreateType (DbgTy);
1188
+ auto DIType = createOpaqueStruct (
1189
+ Scope, " " , File, 0 , SizeInBits, AlignInBits, Flags, MangledName,
1190
+ collectGenericParams (EnumTy), unsubstitutedDbgTy);
1191
+ DBuilder.replaceTemporary (std::move (FwdDecl), DIType);
1192
+ return DIType;
1193
+ }
1194
+
1195
+ // / Create a DICompositeType from a specialized struct. A specialized type
1196
+ // / is a generic type, or a child type whose parent is generic.
1197
+ llvm::DIType *
1198
+ createSpecializedStructOrClassType (NominalOrBoundGenericNominalType *Type,
1199
+ NominalTypeDecl *Decl, llvm::DIScope *Scope,
1200
+ llvm::DIFile *File, unsigned Line,
1201
+ unsigned SizeInBits, unsigned AlignInBits,
1202
+ llvm::DINode::DIFlags Flags,
1203
+ StringRef MangledName,
1204
+ bool IsClass = false ) {
1205
+ // To emit debug info of the DwarfTypes level for generic types, the strategy
1206
+ // is to emit a description of all the fields for the type with archetypes,
1207
+ // and still the same debug info as the ASTTypes level for the specialized
1208
+ // type. For example, given:
1209
+ // struct Pair<T, U> {
1210
+ // let t: T
1211
+ // let u: U
1212
+ // }
1213
+ // When emitting debug information for a type such as Pair<Int, Double>,
1214
+ // emit a description of all the fields for Pair<T, U>, and emit the regular
1215
+ // debug information for Pair<Int, Double>.
1216
+
1217
+ auto FwdDecl = llvm::TempDIType (DBuilder.createReplaceableCompositeType (
1218
+ llvm::dwarf::DW_TAG_structure_type, " " , Scope, File, Line,
1219
+ llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 , Flags, MangledName));
1220
+
1221
+ auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1222
+ DITypeCache[Type] = TH;
1223
+
1224
+ // Go from Pair<Int, Double> to Pair<T, U>.
1225
+ auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
1226
+ UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
1227
+
1228
+ auto DbgTy = DebugTypeInfo::getFromTypeInfo (
1229
+ UnsubstitutedTy, IGM.getTypeInfoForUnlowered (UnsubstitutedTy), IGM);
1230
+ Mangle::ASTMangler Mangler;
1231
+ std::string DeclTypeMangledName =
1232
+ Mangler.mangleTypeForDebugger (UnsubstitutedTy->mapTypeOutOfContext (), {});
1233
+ if (DeclTypeMangledName == MangledName) {
1234
+ return createUnsubstitutedGenericStructOrClassType (
1235
+ DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, SizeInBits,
1236
+ AlignInBits, Flags, nullptr , llvm::dwarf::DW_LANG_Swift,
1237
+ DeclTypeMangledName);
1238
+ }
1239
+ // Force the creation of the unsubstituted type, don't create it
1240
+ // directly so it goes through all the caching/verification logic.
1241
+ auto UnsubstitutedType = getOrCreateType (DbgTy);
1242
+
1243
+ if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
1244
+ auto SuperClassTy = ClassTy->getSuperclass ();
1245
+ if (SuperClassTy) {
1246
+ auto SuperClassDbgTy = DebugTypeInfo::getFromTypeInfo (
1247
+ SuperClassTy, IGM.getTypeInfoForUnlowered (SuperClassTy), IGM);
1248
+
1249
+ llvm::DIType *SuperClassDITy = getOrCreateType (SuperClassDbgTy);
1250
+ assert (SuperClassDITy && " getOrCreateType should never return null!" );
1251
+ DBuilder.createInheritance (UnsubstitutedType, SuperClassDITy, 0 , 0 ,
1252
+ llvm::DINode::FlagZero);
1253
+ }
1254
+
1255
+ auto *OpaqueType = createPointerSizedStruct (
1256
+ Scope, Decl ? Decl->getNameStr () : MangledName, File, 0 , Flags,
1257
+ MangledName, UnsubstitutedType);
1216
1258
return OpaqueType;
1217
1259
}
1218
1260
1261
+ auto *OpaqueType = createOpaqueStruct (
1262
+ Scope, " " , File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1263
+ collectGenericParams (Type), UnsubstitutedType);
1264
+ DBuilder.replaceTemporary (std::move (FwdDecl), OpaqueType);
1265
+ return OpaqueType;
1266
+ }
1267
+
1219
1268
// / Create debug information for an enum with a raw type (enum E : Int {}).
1220
1269
llvm::DICompositeType *createRawEnumType (CompletedDebugTypeInfo DbgTy,
1221
1270
EnumDecl *Decl,
@@ -1441,17 +1490,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1441
1490
// / Collect the type parameters of a bound generic type. This is needed to
1442
1491
// / anchor any typedefs that may appear in parameters so they can be
1443
1492
// / resolved in the debugger without needing to query the Swift module.
1444
- llvm::DINodeArray collectGenericParams (BoundGenericType *BGT) {
1493
+ llvm::DINodeArray
1494
+ collectGenericParams (NominalOrBoundGenericNominalType *BGT) {
1495
+
1496
+ // Collect the generic args from the type and its parent.
1497
+ std::vector<Type> GenericArgs;
1498
+ Type CurrentType = BGT;
1499
+ while (CurrentType && CurrentType->getAnyNominal ()) {
1500
+ if (auto *BGT = llvm::dyn_cast<BoundGenericType>(CurrentType))
1501
+ GenericArgs.insert (GenericArgs.end (), BGT->getGenericArgs ().begin (),
1502
+ BGT->getGenericArgs ().end ());
1503
+ CurrentType = CurrentType->getNominalParent ();
1504
+ }
1505
+
1445
1506
SmallVector<llvm::Metadata *, 16 > TemplateParams;
1446
- for (auto Param : BGT-> getGenericArgs () ) {
1507
+ for (auto Arg : GenericArgs ) {
1447
1508
DebugTypeInfo ParamDebugType;
1448
1509
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1449
- // For full debug info don't generate just a forward declaration for
1450
- // the generic type parameters.
1510
+ // For the DwarfTypes level don't generate just a forward declaration
1511
+ // for the generic type parameters.
1451
1512
ParamDebugType = DebugTypeInfo::getFromTypeInfo (
1452
- Param , IGM.getTypeInfoForUnlowered (Param ), IGM);
1513
+ Arg , IGM.getTypeInfoForUnlowered (Arg ), IGM);
1453
1514
else
1454
- ParamDebugType = DebugTypeInfo::getForwardDecl (Param );
1515
+ ParamDebugType = DebugTypeInfo::getForwardDecl (Arg );
1455
1516
1456
1517
TemplateParams.push_back (DBuilder.createTemplateTypeParameter (
1457
1518
TheCU, " " , getOrCreateType (ParamDebugType), false ));
@@ -1625,7 +1686,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1625
1686
createMemberType (DbgTy, " " , OffsetInBits, Scope, MainFile, Flags));
1626
1687
}
1627
1688
// FIXME: assert that SizeInBits == OffsetInBits.
1628
- SizeInBits = OffsetInBits;
1629
1689
1630
1690
auto FwdDecl = llvm::TempDINode (DBuilder.createReplaceableCompositeType (
1631
1691
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0 ,
@@ -1786,10 +1846,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1786
1846
// don't want a whitespace change to an secondary file trigger a
1787
1847
// recompilation of the debug info of a primary source file.
1788
1848
unsigned FwdDeclLine = 0 ;
1789
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1849
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1850
+ if (StructTy->isSpecialized ())
1851
+ return createSpecializedStructOrClassType (
1852
+ StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1853
+ Flags, MangledName);
1790
1854
return createStructType (DbgTy, Decl, StructTy, Scope, L.File , L.Line ,
1791
1855
SizeInBits, AlignInBits, Flags, nullptr ,
1792
1856
llvm::dwarf::DW_LANG_Swift, MangledName);
1857
+ }
1793
1858
StringRef Name = Decl->getName ().str ();
1794
1859
if (!SizeInBitsOrNull)
1795
1860
return DBuilder.createForwardDecl (
@@ -1814,6 +1879,11 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1814
1879
assert (SizeInBits ==
1815
1880
CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
1816
1881
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1882
+ if (ClassTy->isSpecialized ())
1883
+ return createSpecializedStructOrClassType (
1884
+ ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1885
+ Flags, MangledName);
1886
+
1817
1887
auto *DIType = createStructType (
1818
1888
DbgTy, Decl, ClassTy, Scope, File, L.Line , SizeInBits, AlignInBits,
1819
1889
Flags, nullptr , llvm::dwarf::DW_LANG_Swift, MangledName);
@@ -1875,7 +1945,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1875
1945
auto L = getFileAndLocation (Decl);
1876
1946
unsigned FwdDeclLine = 0 ;
1877
1947
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1878
- return createFullDebugInfoGenericForStructOrClassType (
1948
+ return createSpecializedStructOrClassType (
1879
1949
StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1880
1950
Flags, MangledName);
1881
1951
@@ -1892,7 +1962,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1892
1962
unsigned FwdDeclLine = 0 ;
1893
1963
1894
1964
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1895
- return createFullDebugInfoGenericForStructOrClassType (
1965
+ return createSpecializedStructOrClassType (
1896
1966
ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1897
1967
Flags, MangledName);
1898
1968
@@ -2011,10 +2081,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2011
2081
auto *Decl = EnumTy->getDecl ();
2012
2082
auto L = getFileAndLocation (Decl);
2013
2083
unsigned FwdDeclLine = 0 ;
2014
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
2084
+ if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
2085
+ if (EnumTy->isSpecialized ())
2086
+ return createSpecializedEnumType (EnumTy, Decl, MangledName,
2087
+ SizeInBits, AlignInBits, Scope, File,
2088
+ FwdDeclLine, Flags);
2089
+
2015
2090
if (CompletedDbgTy)
2016
2091
return createEnumType (*CompletedDbgTy, Decl, MangledName, AlignInBits,
2017
2092
Scope, L.File , L.Line , Flags);
2093
+ }
2018
2094
return createOpaqueStruct (Scope, Decl->getName ().str (), L.File ,
2019
2095
FwdDeclLine, SizeInBits, AlignInBits, Flags,
2020
2096
MangledName);
@@ -2027,25 +2103,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2027
2103
unsigned FwdDeclLine = 0 ;
2028
2104
2029
2105
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
2030
- auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
2031
- UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
2032
-
2033
- auto DbgTy = DebugTypeInfo::getFromTypeInfo (
2034
- UnsubstitutedTy, IGM.getTypeInfoForUnlowered (UnsubstitutedTy), IGM);
2035
- Mangle::ASTMangler Mangler;
2036
- std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
2037
- UnsubstitutedTy->mapTypeOutOfContext (), {});
2038
- if (DeclTypeMangledName == MangledName) {
2039
- return createUnsubstitutedVariantType (DbgTy, Decl, MangledName,
2040
- SizeInBits, AlignInBits, Scope, File,
2041
- FwdDeclLine, Flags);
2042
- }
2043
- // Force the creation of the unsubstituted type, don't create it
2044
- // directly so it goes through all the caching/verification logic.
2045
- auto unsubstitutedDbgTy = getOrCreateType (DbgTy);
2046
- return createOpaqueStruct (
2047
- Scope, " " , L.File , FwdDeclLine, SizeInBits, AlignInBits, Flags,
2048
- MangledName, collectGenericParams (EnumTy), unsubstitutedDbgTy);
2106
+ if (EnumTy->isSpecialized ())
2107
+ return createSpecializedEnumType (EnumTy, Decl, MangledName,
2108
+ SizeInBits, AlignInBits, Scope, File,
2109
+ FwdDeclLine, Flags);
2110
+ if (CompletedDbgTy)
2111
+ return createEnumType (*CompletedDbgTy, Decl, MangledName, AlignInBits,
2112
+ Scope, L.File , L.Line , Flags);
2049
2113
}
2050
2114
return createOpaqueStructWithSizedContainer (
2051
2115
Scope, Decl->getName ().str (), L.File , FwdDeclLine, SizeInBits,
@@ -2184,6 +2248,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2184
2248
#ifndef NDEBUG
2185
2249
// / Verify that the size of this type matches the one of the cached type.
2186
2250
bool sanityCheckCachedType (DebugTypeInfo DbgTy, llvm::DIType *CachedType) {
2251
+ // If this is a temporary, we're in the middle of creating a recursive type,
2252
+ // so skip the sanity check.
2253
+ if (CachedType->isTemporary ())
2254
+ return true ;
2187
2255
if (DbgTy.isForwardDecl ())
2188
2256
return true ;
2189
2257
auto CompletedDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (
0 commit comments