@@ -1155,23 +1155,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11551155 return DITy;;
11561156 }
11571157
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) {
11751164 auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
11761165 UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
11771166
@@ -1181,39 +1170,99 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11811170 std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
11821171 UnsubstitutedTy->mapTypeOutOfContext (), {});
11831172 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);
11881176 }
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;
11891183 // Force the creation of the unsubstituted type, don't create it
11901184 // 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);
12141256 return OpaqueType;
12151257 }
12161258
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+
12171266 // / Create debug information for an enum with a raw type (enum E : Int {}).
12181267 llvm::DICompositeType *createRawEnumType (CompletedDebugTypeInfo DbgTy,
12191268 EnumDecl *Decl,
@@ -1439,17 +1488,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14391488 // / Collect the type parameters of a bound generic type. This is needed to
14401489 // / anchor any typedefs that may appear in parameters so they can be
14411490 // / 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+
14431504 SmallVector<llvm::Metadata *, 16 > TemplateParams;
1444- for (auto Param : BGT-> getGenericArgs () ) {
1505+ for (auto Arg : GenericArgs ) {
14451506 DebugTypeInfo ParamDebugType;
14461507 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.
14491510 ParamDebugType = DebugTypeInfo::getFromTypeInfo (
1450- Param , IGM.getTypeInfoForUnlowered (Param ), IGM);
1511+ Arg , IGM.getTypeInfoForUnlowered (Arg ), IGM);
14511512 else
1452- ParamDebugType = DebugTypeInfo::getForwardDecl (Param );
1513+ ParamDebugType = DebugTypeInfo::getForwardDecl (Arg );
14531514
14541515 TemplateParams.push_back (DBuilder.createTemplateTypeParameter (
14551516 TheCU, " " , getOrCreateType (ParamDebugType), false ));
@@ -1623,7 +1684,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16231684 createMemberType (DbgTy, " " , OffsetInBits, Scope, MainFile, Flags));
16241685 }
16251686 // FIXME: assert that SizeInBits == OffsetInBits.
1626- SizeInBits = OffsetInBits;
16271687
16281688 auto FwdDecl = llvm::TempDINode (DBuilder.createReplaceableCompositeType (
16291689 llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0 ,
@@ -1784,10 +1844,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17841844 // don't want a whitespace change to an secondary file trigger a
17851845 // recompilation of the debug info of a primary source file.
17861846 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);
17881852 return createStructType (DbgTy, Decl, StructTy, Scope, L.File , L.Line ,
17891853 SizeInBits, AlignInBits, Flags, nullptr ,
17901854 llvm::dwarf::DW_LANG_Swift, MangledName);
1855+ }
17911856 StringRef Name = Decl->getName ().str ();
17921857 if (!SizeInBitsOrNull)
17931858 return DBuilder.createForwardDecl (
@@ -1812,6 +1877,11 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18121877 assert (SizeInBits ==
18131878 CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
18141879 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+
18151885 auto *DIType = createStructType (
18161886 DbgTy, Decl, ClassTy, Scope, File, L.Line , SizeInBits, AlignInBits,
18171887 Flags, nullptr , llvm::dwarf::DW_LANG_Swift, MangledName);
@@ -1873,7 +1943,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18731943 auto L = getFileAndLocation (Decl);
18741944 unsigned FwdDeclLine = 0 ;
18751945 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1876- return createFullDebugInfoGenericForStructOrClassType (
1946+ return createSpecializedStructOrClassType (
18771947 StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
18781948 Flags, MangledName);
18791949
@@ -1890,7 +1960,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18901960 unsigned FwdDeclLine = 0 ;
18911961
18921962 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1893- return createFullDebugInfoGenericForStructOrClassType (
1963+ return createSpecializedStructOrClassType (
18941964 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
18951965 Flags, MangledName);
18961966
@@ -2009,10 +2079,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
20092079 auto *Decl = EnumTy->getDecl ();
20102080 auto L = getFileAndLocation (Decl);
20112081 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+
20132088 if (CompletedDbgTy)
20142089 return createEnumType (*CompletedDbgTy, Decl, MangledName, AlignInBits,
20152090 Scope, L.File , L.Line , Flags);
2091+ }
20162092 return createOpaqueStruct (Scope, Decl->getName ().str (), L.File ,
20172093 FwdDeclLine, SizeInBits, AlignInBits, Flags,
20182094 MangledName);
@@ -2025,25 +2101,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
20252101 unsigned FwdDeclLine = 0 ;
20262102
20272103 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);
20472111 }
20482112 return createOpaqueStructWithSizedContainer (
20492113 Scope, Decl->getName ().str (), L.File , FwdDeclLine, SizeInBits,
@@ -2182,6 +2246,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
21822246#ifndef NDEBUG
21832247 // / Verify that the size of this type matches the one of the cached type.
21842248 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 ;
21852253 if (DbgTy.isForwardDecl ())
21862254 return true ;
21872255 auto CompletedDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (
0 commit comments