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