@@ -1157,23 +1157,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11571157 return DITy;;
11581158 }
11591159
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) {
11771166 auto UnsubstitutedTy = Decl->getDeclaredInterfaceType ();
11781167 UnsubstitutedTy = Decl->mapTypeIntoContext (UnsubstitutedTy);
11791168
@@ -1183,39 +1172,99 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11831172 std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger (
11841173 UnsubstitutedTy->mapTypeOutOfContext (), {});
11851174 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);
11901178 }
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;
11911185 // Force the creation of the unsubstituted type, don't create it
11921186 // 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);
12161258 return OpaqueType;
12171259 }
12181260
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+
12191268 // / Create debug information for an enum with a raw type (enum E : Int {}).
12201269 llvm::DICompositeType *createRawEnumType (CompletedDebugTypeInfo DbgTy,
12211270 EnumDecl *Decl,
@@ -1441,17 +1490,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14411490 // / Collect the type parameters of a bound generic type. This is needed to
14421491 // / anchor any typedefs that may appear in parameters so they can be
14431492 // / 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+
14451506 SmallVector<llvm::Metadata *, 16 > TemplateParams;
1446- for (auto Param : BGT-> getGenericArgs () ) {
1507+ for (auto Arg : GenericArgs ) {
14471508 DebugTypeInfo ParamDebugType;
14481509 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.
14511512 ParamDebugType = DebugTypeInfo::getFromTypeInfo (
1452- Param , IGM.getTypeInfoForUnlowered (Param ), IGM);
1513+ Arg , IGM.getTypeInfoForUnlowered (Arg ), IGM);
14531514 else
1454- ParamDebugType = DebugTypeInfo::getForwardDecl (Param );
1515+ ParamDebugType = DebugTypeInfo::getForwardDecl (Arg );
14551516
14561517 TemplateParams.push_back (DBuilder.createTemplateTypeParameter (
14571518 TheCU, " " , getOrCreateType (ParamDebugType), false ));
@@ -1625,7 +1686,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16251686 createMemberType (DbgTy, " " , OffsetInBits, Scope, MainFile, Flags));
16261687 }
16271688 // FIXME: assert that SizeInBits == OffsetInBits.
1628- SizeInBits = OffsetInBits;
16291689
16301690 auto FwdDecl = llvm::TempDINode (DBuilder.createReplaceableCompositeType (
16311691 llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0 ,
@@ -1786,10 +1846,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17861846 // don't want a whitespace change to an secondary file trigger a
17871847 // recompilation of the debug info of a primary source file.
17881848 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);
17901854 return createStructType (DbgTy, Decl, StructTy, Scope, L.File , L.Line ,
17911855 SizeInBits, AlignInBits, Flags, nullptr ,
17921856 llvm::dwarf::DW_LANG_Swift, MangledName);
1857+ }
17931858 StringRef Name = Decl->getName ().str ();
17941859 if (!SizeInBitsOrNull)
17951860 return DBuilder.createForwardDecl (
@@ -1814,6 +1879,11 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18141879 assert (SizeInBits ==
18151880 CI.getTargetInfo ().getPointerWidth (clang::LangAS::Default));
18161881 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+
18171887 auto *DIType = createStructType (
18181888 DbgTy, Decl, ClassTy, Scope, File, L.Line , SizeInBits, AlignInBits,
18191889 Flags, nullptr , llvm::dwarf::DW_LANG_Swift, MangledName);
@@ -1875,7 +1945,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18751945 auto L = getFileAndLocation (Decl);
18761946 unsigned FwdDeclLine = 0 ;
18771947 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1878- return createFullDebugInfoGenericForStructOrClassType (
1948+ return createSpecializedStructOrClassType (
18791949 StructTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
18801950 Flags, MangledName);
18811951
@@ -1892,7 +1962,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18921962 unsigned FwdDeclLine = 0 ;
18931963
18941964 if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1895- return createFullDebugInfoGenericForStructOrClassType (
1965+ return createSpecializedStructOrClassType (
18961966 ClassTy, Decl, Scope, L.File , L.Line , SizeInBits, AlignInBits,
18971967 Flags, MangledName);
18981968
@@ -2011,10 +2081,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
20112081 auto *Decl = EnumTy->getDecl ();
20122082 auto L = getFileAndLocation (Decl);
20132083 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+
20152090 if (CompletedDbgTy)
20162091 return createEnumType (*CompletedDbgTy, Decl, MangledName, AlignInBits,
20172092 Scope, L.File , L.Line , Flags);
2093+ }
20182094 return createOpaqueStruct (Scope, Decl->getName ().str (), L.File ,
20192095 FwdDeclLine, SizeInBits, AlignInBits, Flags,
20202096 MangledName);
@@ -2027,25 +2103,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
20272103 unsigned FwdDeclLine = 0 ;
20282104
20292105 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);
20492113 }
20502114 return createOpaqueStructWithSizedContainer (
20512115 Scope, Decl->getName ().str (), L.File , FwdDeclLine, SizeInBits,
@@ -2184,6 +2248,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
21842248#ifndef NDEBUG
21852249 // / Verify that the size of this type matches the one of the cached type.
21862250 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 ;
21872255 if (DbgTy.isForwardDecl ())
21882256 return true ;
21892257 auto CompletedDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (
0 commit comments