@@ -1226,8 +1226,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1226
1226
return DITy;
1227
1227
}
1228
1228
1229
- std::pair<bool , Type>
1230
- getUnsubstituedType (Type Ty, StringRef MangledName) {
1229
+ std::pair<bool , Type> getUnsubstitutedType (Type Ty, StringRef MangledName) {
1231
1230
if (!Ty)
1232
1231
return {false ,{}};
1233
1232
// Go from Pair<Int, Double> to Pair<T, U>.
@@ -1252,7 +1251,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1252
1251
llvm::DIScope *Scope, llvm::DIFile *File,
1253
1252
unsigned Line, llvm::DINode::DIFlags Flags) {
1254
1253
auto [IsUnsubstituted, UnsubstitutedTy] =
1255
- getUnsubstituedType (EnumTy, MangledName);
1254
+ getUnsubstitutedType (EnumTy, MangledName);
1256
1255
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo (
1257
1256
UnsubstitutedTy, IGM.getTypeInfoForUnlowered (UnsubstitutedTy), IGM);
1258
1257
if (IsUnsubstituted)
@@ -1301,7 +1300,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1301
1300
Name);
1302
1301
1303
1302
auto [IsUnsubstitued, UnsubstitutedType] =
1304
- getUnsubstituedType (Type, MangledName);
1303
+ getUnsubstitutedType (Type, MangledName);
1305
1304
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo (
1306
1305
UnsubstitutedType, IGM.getTypeInfoForUnlowered (UnsubstitutedType), IGM);
1307
1306
if (IsUnsubstitued)
@@ -1326,19 +1325,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1326
1325
}
1327
1326
}
1328
1327
1329
- // Recursive types such as `class A<B> { let a : A<A<B>> }` would produce an
1330
- // infinite chain of expansions for the type of `a`. Break these cycles by
1331
- // emitting any bound generics that still have type parameters as forward
1332
- // declarations.
1333
- if (Type->hasTypeParameter () || Type->hasPrimaryArchetype ())
1334
- return createOpaqueStructWithSizedContainer (
1335
- Scope, Decl ? Decl->getNameStr () : " " , File, Line, SizeInBits,
1336
- AlignInBits, Flags, MangledName, collectGenericParams (Type, true ),
1337
- UnsubstitutedDITy);
1328
+ // Generally, we don't emit members of a specialized bound generic, because
1329
+ // these can be reconstructed by substituting the "template parameters" in
1330
+ // the unspecialized type. We make an exception for inline arrays, because
1331
+ // DWARF has special support for arrays.
1332
+ if (Type->isInlineArray () && !Type->hasTypeParameter () &&
1333
+ !Type->hasPrimaryArchetype ())
1334
+ // Create the substituted type.
1335
+ return createStructType (Type, Decl, Scope, File, Line, SizeInBits,
1336
+ AlignInBits, Flags, MangledName,
1337
+ UnsubstitutedDITy);
1338
1338
1339
- // Create the substituted type.
1340
- return createStructType (Type, Decl, Scope, File, Line, SizeInBits,
1341
- AlignInBits, Flags, MangledName, UnsubstitutedDITy);
1339
+ // Create the substituted type (without members).
1340
+ llvm::DIType *SpecializedDITy = createOpaqueStructWithSizedContainer (
1341
+ Scope, Decl ? Decl->getNameStr () : " " , File, Line, SizeInBits,
1342
+ AlignInBits, Flags, MangledName, collectGenericParams (Type),
1343
+ UnsubstitutedDITy);
1344
+ DBuilder.replaceTemporary (std::move (FwdDecl), SpecializedDITy);
1345
+ return SpecializedDITy;
1342
1346
}
1343
1347
1344
1348
// / Create debug information for an enum with a raw type (enum E : Int {}).
@@ -1600,6 +1604,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1600
1604
1601
1605
llvm::Metadata *Elements[] = {DBuilder.createMemberType (
1602
1606
Scope, " " , File, 0 , SizeInBits, AlignInBits, 0 , Flags, UniqueType)};
1607
+ // FIXME: It's a limitation of LLVM that a forward declaration cannot have a
1608
+ // specificationOf, so this attritbute is put on the sized container type
1609
+ // instead. This is confusing consumers, and LLDB has to go out of its way
1610
+ // to parse these confusing types as intended.
1603
1611
return DBuilder.createStructType (
1604
1612
Scope, " " , File, Line, SizeInBits, AlignInBits, Flags,
1605
1613
/* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
@@ -2338,7 +2346,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
2338
2346
if (!isa<llvm::DICompositeType>(CachedType))
2339
2347
return true ;
2340
2348
bool IsUnsubstituted =
2341
- getUnsubstituedType (DbgTy.getType (), getMangledName (DbgTy).Canonical )
2349
+ getUnsubstitutedType (DbgTy.getType (), getMangledName (DbgTy).Canonical )
2342
2350
.first ;
2343
2351
std::optional<uint64_t > SizeInBits;
2344
2352
if (!IsUnsubstituted)
0 commit comments