@@ -1197,7 +1197,26 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1197
1197
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
1198
1198
DBuilder.getOrCreateArray (Elements), RuntimeLang, nullptr , UniqueID );
1199
1199
DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
1200
- return DITy;;
1200
+ return DITy;
1201
+ }
1202
+
1203
+ std::pair<bool , Type>
1204
+ getUnsubstituedType (Type Ty, StringRef MangledName) {
1205
+ if (!Ty)
1206
+ return {false ,{}};
1207
+ // Go from Pair<Int, Double> to Pair<T, U>.
1208
+ auto *Decl = Ty->getNominalOrBoundGenericNominal ();
1209
+ if (!Decl)
1210
+ return {false , {}};
1211
+ // Go from Pair<Int, Double> to Pair<T, U>.
1212
+ Type InterfaceTy = Decl->getDeclaredInterfaceType ();
1213
+ Type UnsubstitutedTy = Decl->mapTypeIntoContext (InterfaceTy);
1214
+
1215
+ Mangle::ASTMangler Mangler (IGM.Context );
1216
+ std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
1217
+ UnsubstitutedTy->mapTypeOutOfContext (), {});
1218
+ bool IsUnsubstituted = (DeclTypeMangledName == MangledName);
1219
+ return {IsUnsubstituted, UnsubstitutedTy};
1201
1220
}
1202
1221
1203
1222
llvm::DIType *
@@ -1206,36 +1225,32 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1206
1225
unsigned SizeInBits, unsigned AlignInBits,
1207
1226
llvm::DIScope *Scope, llvm::DIFile *File,
1208
1227
unsigned Line, llvm::DINode::DIFlags Flags) {
1209
- auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
1210
- UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
1211
-
1212
- auto DbgTy = DebugTypeInfo::getFromTypeInfo (
1228
+ auto [IsUnsubstituted, UnsubstitutedTy] =
1229
+ getUnsubstituedType (EnumTy, MangledName);
1230
+ auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo (
1213
1231
UnsubstitutedTy, IGM.getTypeInfoForUnlowered (UnsubstitutedTy), IGM);
1214
- Mangle::ASTMangler Mangler (IGM.Context );
1215
- std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
1216
- UnsubstitutedTy->mapTypeOutOfContext (), {});
1217
- if (DeclTypeMangledName == MangledName) {
1218
- return createUnsubstitutedVariantType (DbgTy, Decl, MangledName, Scope,
1219
- File, 0 , Flags);
1220
- }
1232
+ if (IsUnsubstituted)
1233
+ return createUnsubstitutedVariantType (UnsubstitutedDbgTy, Decl,
1234
+ MangledName, Scope, File, 0 , Flags);
1235
+
1221
1236
StringRef Name = Decl->getName ().str ();
1222
1237
auto FwdDecl = createTemporaryReplaceableForwardDecl (
1223
1238
EnumTy, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1224
1239
Name);
1225
1240
// Force the creation of the unsubstituted type, don't create it
1226
1241
// directly so it goes through all the caching/verification logic.
1227
- auto unsubstitutedDbgTy = getOrCreateType (DbgTy );
1242
+ auto UnsubstitutedDITy = getOrCreateType (UnsubstitutedDbgTy );
1228
1243
auto DIType = createOpaqueStruct (
1229
1244
Scope, " " , File, 0 , SizeInBits, AlignInBits, Flags, MangledName,
1230
- collectGenericParams (EnumTy), unsubstitutedDbgTy );
1245
+ collectGenericParams (EnumTy), UnsubstitutedDITy );
1231
1246
DBuilder.replaceTemporary (std::move (FwdDecl), DIType);
1232
1247
return DIType;
1233
1248
}
1234
1249
1235
1250
// / Create a DICompositeType from a specialized struct. A specialized type
1236
1251
// / is a generic type, or a child type whose parent is generic.
1237
1252
llvm::DIType *createSpecializedStructOrClassType (
1238
- NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
1253
+ NominalOrBoundGenericNominalType *Type,
1239
1254
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
1240
1255
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1241
1256
StringRef MangledName, bool IsClass = false ) {
@@ -1249,28 +1264,26 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1249
1264
// When emitting debug information for a type such as Pair<Int, Double>,
1250
1265
// emit a description of all the fields for Pair<T, U>, and emit the regular
1251
1266
// debug information for Pair<Int, Double>.
1267
+ auto *Decl = Type->getNominalOrBoundGenericNominal ();
1268
+ if (!Decl)
1269
+ return nullptr ;
1252
1270
StringRef Name = Decl->getName ().str ();
1253
1271
auto FwdDecl = createTemporaryReplaceableForwardDecl (
1254
1272
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1255
1273
Name);
1256
1274
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) {
1275
+ auto [IsUnsubstitued, UnsubstitutedType] =
1276
+ getUnsubstituedType (Type, MangledName);
1277
+ auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo (
1278
+ UnsubstitutedType, IGM.getTypeInfoForUnlowered (UnsubstitutedType), IGM);
1279
+ if (IsUnsubstitued)
1267
1280
return createUnsubstitutedGenericStructOrClassType (
1268
- DbgTy , Decl, UnsubstitutedTy , Scope, File, Line, Flags, nullptr ,
1269
- llvm::dwarf::DW_LANG_Swift, DeclTypeMangledName );
1270
- }
1281
+ UnsubstitutedDbgTy , Decl, UnsubstitutedType , Scope, File, Line, Flags,
1282
+ nullptr , llvm::dwarf::DW_LANG_Swift, MangledName );
1283
+
1271
1284
// Force the creation of the unsubstituted type, don't create it
1272
1285
// directly so it goes through all the caching/verification logic.
1273
- auto UnsubstitutedType = getOrCreateType (DbgTy );
1286
+ auto UnsubstitutedDITy = getOrCreateType (UnsubstitutedDbgTy );
1274
1287
1275
1288
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
1276
1289
auto SuperClassTy = ClassTy->getSuperclass ();
@@ -1280,19 +1293,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1280
1293
1281
1294
llvm::DIType *SuperClassDITy = getOrCreateType (SuperClassDbgTy);
1282
1295
assert (SuperClassDITy && " getOrCreateType should never return null!" );
1283
- DBuilder.createInheritance (UnsubstitutedType , SuperClassDITy, 0 , 0 ,
1296
+ DBuilder.createInheritance (UnsubstitutedDITy , SuperClassDITy, 0 , 0 ,
1284
1297
llvm::DINode::FlagZero);
1285
1298
}
1286
-
1287
- auto *OpaqueType = createPointerSizedStruct (
1288
- Scope, Decl ? Decl->getNameStr () : MangledName, File, 0 , Flags,
1289
- MangledName, UnsubstitutedType);
1290
- return OpaqueType;
1291
1299
}
1292
1300
1293
- auto *OpaqueType = createOpaqueStruct (
1294
- Scope, " " , File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1295
- collectGenericParams (Type), UnsubstitutedType);
1301
+ auto *OpaqueType =
1302
+ createOpaqueStruct (Scope, Decl ? Decl->getNameStr () : " " , File, Line,
1303
+ SizeInBits, AlignInBits, Flags, MangledName,
1304
+ collectGenericParams (Type), UnsubstitutedDITy);
1296
1305
DBuilder.replaceTemporary (std::move (FwdDecl), OpaqueType);
1297
1306
return OpaqueType;
1298
1307
}
@@ -1865,7 +1874,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1865
1874
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1866
1875
if (StructTy->isSpecialized ())
1867
1876
return createSpecializedStructOrClassType (
1868
- StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1877
+ StructTy, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1869
1878
Flags, MangledName);
1870
1879
return createStructType (DbgTy, Decl, StructTy, Scope, L.File , L.Line ,
1871
1880
SizeInBits, AlignInBits, Flags, nullptr ,
@@ -1898,7 +1907,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1898
1907
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
1899
1908
if (ClassTy->isSpecialized ())
1900
1909
return createSpecializedStructOrClassType (
1901
- ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1910
+ ClassTy, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1902
1911
Flags, MangledName);
1903
1912
1904
1913
auto *DIType = createStructType (
@@ -1964,7 +1973,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1964
1973
unsigned FwdDeclLine = 0 ;
1965
1974
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1966
1975
return createSpecializedStructOrClassType (
1967
- StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1976
+ StructTy, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1968
1977
Flags, MangledName);
1969
1978
1970
1979
return createOpaqueStructWithSizedContainer (
@@ -1977,20 +1986,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1977
1986
auto *ClassTy = BaseTy->castTo <BoundGenericClassType>();
1978
1987
auto *Decl = ClassTy->getDecl ();
1979
1988
auto L = getFileAndLocation (Decl);
1980
- unsigned FwdDeclLine = 0 ;
1981
-
1982
- if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1983
- return createSpecializedStructOrClassType (
1984
- ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
1985
- Flags, MangledName);
1986
-
1987
- // TODO: We may want to peek at Decl->isObjC() and set this
1988
- // attribute accordingly.
1989
- assert (SizeInBits ==
1990
- CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
1991
- return createPointerSizedStruct (
1992
- Scope, Decl ? Decl->getNameStr () : MangledName, L.File , FwdDeclLine,
1993
- Flags, MangledName, SpecificationOf);
1989
+ return createSpecializedStructOrClassType (ClassTy, Scope, L.File ,
1990
+ L.Line , SizeInBits, AlignInBits,
1991
+ Flags, MangledName);
1994
1992
}
1995
1993
1996
1994
case TypeKind::Pack:
@@ -2174,8 +2172,14 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2174
2172
AliasedTy, DbgTy.getAlignment (), DbgTy.hasDefaultAlignment (),
2175
2173
/* IsMetadataType = */ false , DbgTy.isFixedBuffer (),
2176
2174
DbgTy.getNumExtraInhabitants ());
2177
- return DBuilder.createTypedef (getOrCreateType (AliasedDbgTy), MangledName,
2178
- L.File , 0 , Scope);
2175
+ auto *TypeDef = DBuilder.createTypedef (getOrCreateType (AliasedDbgTy),
2176
+ MangledName, L.File , 0 , Scope);
2177
+ // Bound generic types don't reference their type parameters in ASTTypes
2178
+ // mode, so we need to artificially keep typealiases alive, since they can
2179
+ // appear in reflection metadata.
2180
+ if (Opts.DebugInfoLevel < IRGenDebugInfoLevel::DwarfTypes)
2181
+ DBuilder.retainType (TypeDef);
2182
+ return TypeDef;
2179
2183
}
2180
2184
2181
2185
case TypeKind::Locatable: {
@@ -2269,10 +2273,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2269
2273
// so skip the sanity check.
2270
2274
if (CachedType->isTemporary ())
2271
2275
return true ;
2276
+ if (!isa<llvm::DICompositeType>(CachedType))
2277
+ return true ;
2278
+ bool IsUnsubstituted =
2279
+ getUnsubstituedType (DbgTy.getType (), getMangledName (DbgTy)).first ;
2272
2280
std::optional<uint64_t > SizeInBits;
2273
- std::optional<CompletedDebugTypeInfo> CompletedDbgTy = completeType (DbgTy);
2274
- if (CompletedDbgTy)
2275
- SizeInBits = CompletedDbgTy->getSizeInBits ();
2281
+ if (!IsUnsubstituted)
2282
+ if (auto CompletedDbgTy = completeType (DbgTy))
2283
+ SizeInBits = CompletedDbgTy->getSizeInBits ();
2284
+
2276
2285
unsigned CachedSizeInBits = getSizeInBits (CachedType);
2277
2286
if (SizeInBits && CachedSizeInBits != *SizeInBits) {
2278
2287
// Note that CachedSizeInBits && !SizeInBits may happen and is benign,
@@ -2511,6 +2520,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2511
2520
// winning over a full definition.
2512
2521
auto *FwdDecl = DBuilder.createReplaceableCompositeType (
2513
2522
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0 , 0 ,
2523
+
2514
2524
llvm::dwarf::DW_LANG_Swift);
2515
2525
FwdDeclTypes.emplace_back (
2516
2526
std::piecewise_construct, std::make_tuple (MangledName),
0 commit comments