@@ -476,6 +476,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
476476
477477 // / Return the size reported by a type.
478478 static unsigned getSizeInBits (llvm::DIType *Ty) {
479+ if (!Ty)
480+ return 0 ;
479481 // Follow derived types until we reach a type that
480482 // reports back a size.
481483 while (isa<llvm::DIDerivedType>(Ty) && !Ty->getSizeInBits ()) {
@@ -1103,20 +1105,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11031105 BumpAllocatedString (CanonicalName)};
11041106 }
11051107
1106- llvm::DIDerivedType *createMemberType (DebugTypeInfo DbgTy, StringRef Name,
1107- unsigned &OffsetInBits,
1108- llvm::DIScope *Scope,
1109- llvm::DIFile *File,
1110- llvm::DINode::DIFlags Flags) {
1111- unsigned SizeOfByte = CI.getTargetInfo ().getCharWidth ();
1112- auto *Ty = getOrCreateType (DbgTy);
1113- auto SizeInBits = getSizeInBits (Ty);
1114- auto *DITy = DBuilder.createMemberType (
1115- Scope, Name, File, 0 , SizeInBits, 0 , OffsetInBits, Flags, Ty);
1108+ llvm::DIDerivedType *
1109+ createMemberType (llvm::DIType *DITy, StringRef Name, unsigned &OffsetInBits,
1110+ unsigned AlignInBits, llvm::DIScope *Scope,
1111+ llvm::DIFile *File, llvm::DINode::DIFlags Flags) {
1112+ auto SizeInBits = getSizeInBits (DITy);
1113+ llvm::DIDerivedType *DIMemberTy = DBuilder.createMemberType (
1114+ Scope, Name, File, 0 , SizeInBits, 0 , OffsetInBits, Flags, DITy);
11161115 OffsetInBits += SizeInBits;
1117- OffsetInBits = llvm::alignTo (OffsetInBits,
1118- SizeOfByte * DbgTy. getAlignment (). getValue () );
1119- return DITy ;
1116+ if (AlignInBits)
1117+ OffsetInBits = llvm::alignTo (OffsetInBits, AlignInBits );
1118+ return DIMemberTy ;
11201119 }
11211120
11221121 // / Creates a temporary replaceable forward decl to protect against recursion.
@@ -1125,12 +1124,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11251124 unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
11261125 StringRef MangledName, StringRef Name) {
11271126#ifndef NDEBUG
1128- if (MangledName.empty ())
1129- assert (!Name.empty () &&
1130- " no mangled name and no human readable name given" );
1131- else
1132- assert (swift::Demangle::isMangledName (MangledName) &&
1133- " UID is not a mangled name" );
1127+ {
1128+ if (MangledName.empty ())
1129+ assert (!Name.empty () &&
1130+ " no mangled name and no human readable name given" );
1131+ else
1132+ assert (swift::Demangle::isMangledName (MangledName) &&
1133+ " UID is not a mangled name" );
1134+ auto UID = llvm::MDString::get (IGM.getLLVMContext (), MangledName);
1135+ assert (DIRefMap.count (UID) == 0 && " type is already cached" );
1136+ }
11341137#endif
11351138 auto ReplaceableType = DBuilder.createReplaceableCompositeType (
11361139 llvm::dwarf::DW_TAG_structure_type, " " , Scope, File, Line,
@@ -1146,6 +1149,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11461149 return FwdDecl;
11471150 }
11481151
1152+ using TrackingDIType = llvm::TypedTrackingMDRef<llvm::DIType>;
1153+ struct MemberDIType {
1154+ StringRef Name;
1155+ unsigned AlignInBits;
1156+ TrackingDIType DIType;
1157+ MemberDIType (StringRef Name, unsigned AlignInBits, llvm::DIType *DIType)
1158+ : Name(Name), AlignInBits(AlignInBits), DIType(DIType) {}
1159+ };
1160+
1161+ unsigned getByteSize () { return CI.getTargetInfo ().getCharWidth (); }
1162+
11491163 llvm::DICompositeType *createStructType (
11501164 NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
11511165 llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
@@ -1156,28 +1170,36 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11561170 Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
11571171 Name);
11581172 // Collect the members.
1159- SmallVector<llvm::Metadata *, 16 > Elements;
1160- unsigned OffsetInBits = 0 ;
1173+ SmallVector<MemberDIType, 16 > MemberTypes;
11611174 for (VarDecl *VD : Decl->getStoredProperties ()) {
11621175 auto memberTy = Type->getTypeOfMember (VD);
11631176 if (auto DbgTy = CompletedDebugTypeInfo::getFromTypeInfo (
11641177 memberTy,
11651178 IGM.getTypeInfoForUnlowered (
11661179 IGM.getSILTypes ().getAbstractionPattern (VD), memberTy),
11671180 IGM))
1168- Elements.push_back (createMemberType (*DbgTy, VD->getName ().str (),
1169- OffsetInBits, Scope, File, Flags));
1181+ MemberTypes.emplace_back (VD->getName ().str (),
1182+ getByteSize () *
1183+ DbgTy->getAlignment ().getValue (),
1184+ getOrCreateType (*DbgTy));
11701185 else
11711186 // Without complete type info we can only create a forward decl.
11721187 return DBuilder.createForwardDecl (
11731188 llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
11741189 llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 );
11751190 }
11761191
1192+ SmallVector<llvm::Metadata *, 16 > Members;
1193+ unsigned OffsetInBits = 0 ;
1194+ for (auto &Member : MemberTypes)
1195+ Members.push_back (createMemberType (Member.DIType , Member.Name ,
1196+ OffsetInBits, Member.AlignInBits ,
1197+ Scope, File, Flags));
1198+
11771199 llvm::DINodeArray BoundParams = collectGenericParams (Type);
11781200 llvm::DICompositeType *DITy = createStruct (
11791201 Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1180- DBuilder.getOrCreateArray (Elements ), BoundParams, SpecificationOf);
1202+ DBuilder.getOrCreateArray (Members ), BoundParams, SpecificationOf);
11811203 return DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
11821204 }
11831205
@@ -1203,24 +1225,32 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12031225 DbgTy.getType (), Scope, File, Line, SizeInBits, AlignInBits, Flags,
12041226 UniqueID, Name);
12051227 // Collect the members.
1206- SmallVector<llvm::Metadata * , 16 > Elements ;
1228+ SmallVector<MemberDIType , 16 > MemberTypes ;
12071229 for (VarDecl *VD : Decl->getStoredProperties ()) {
1208- auto memberTy =
1209- UnsubstitutedType->getTypeOfMember (VD);
1230+ Type memberTy = UnsubstitutedType->getTypeOfMember (VD);
12101231 auto DbgTy = DebugTypeInfo::getFromTypeInfo (
12111232 memberTy,
12121233 IGM.getTypeInfoForUnlowered (
12131234 IGM.getSILTypes ().getAbstractionPattern (VD), memberTy),
12141235 IGM);
1236+ MemberTypes.emplace_back (VD->getName ().str (),
1237+ getByteSize () * DbgTy.getAlignment ().getValue (),
1238+ getOrCreateType (DbgTy));
1239+ }
1240+ SmallVector<llvm::Metadata *, 16 > Members;
1241+ for (auto &Member : MemberTypes) {
12151242 unsigned OffsetInBits = 0 ;
1216- llvm::DIType *DITy = createMemberType (DbgTy, VD->getName ().str (),
1217- OffsetInBits, Scope, File, Flags);
1218- Elements.push_back (DITy);
1243+ auto *member = createMemberType (Member.DIType , Member.Name ,
1244+ OffsetInBits, Member.AlignInBits ,
1245+ Scope, File, Flags);
1246+ member->dump ();
1247+ Members.push_back (member);
12191248 }
12201249
12211250 llvm::DICompositeType *DITy = DBuilder.createStructType (
12221251 Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
1223- DBuilder.getOrCreateArray (Elements), RuntimeLang, nullptr , UniqueID);
1252+ DBuilder.getOrCreateArray (Members), RuntimeLang, nullptr , UniqueID);
1253+ DITy->dump ();
12241254 return DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
12251255 }
12261256
@@ -1290,20 +1320,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12901320 if (!Decl)
12911321 return nullptr ;
12921322
1293- // This temporary forward decl seems to be redundant. Can it be removed?
1294- StringRef Name = Decl->getName ().str ();
1295- auto FwdDecl = createTemporaryReplaceableForwardDecl (
1296- Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1297- Name);
1298-
12991323 auto [IsUnsubstitued, UnsubstitutedType] =
13001324 getUnsubstitutedType (Type, MangledName);
13011325 auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo (
13021326 UnsubstitutedType, IGM.getTypeInfoForUnlowered (UnsubstitutedType), IGM);
1303- if (IsUnsubstitued)
1327+ if (IsUnsubstitued) {
13041328 return createUnsubstitutedGenericStructOrClassType (
13051329 UnsubstitutedDbgTy, Decl, UnsubstitutedType, Scope, File, Line, Flags,
13061330 nullptr , llvm::dwarf::DW_LANG_Swift, MangledName);
1331+ }
13071332
13081333 // Force the creation of the unsubstituted type, don't create it
13091334 // directly so it goes through all the caching/verification logic.
@@ -1338,7 +1363,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13381363 Scope, Decl ? Decl->getNameStr () : " " , File, Line, SizeInBits,
13391364 AlignInBits, Flags, MangledName, collectGenericParams (Type),
13401365 UnsubstitutedDITy);
1341- return DBuilder. replaceTemporary ( std::move (FwdDecl), SpecializedDITy) ;
1366+ return SpecializedDITy;
13421367 }
13431368
13441369 // / Create debug information for an enum with a raw type (enum E : Int {}).
@@ -1410,7 +1435,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14101435 auto FwdDecl = createTemporaryReplaceableForwardDecl (
14111436 DbgTy.getType (), Scope, File, Line, SizeInBits, AlignInBits, Flags,
14121437 MangledName, Name);
1413- SmallVector<llvm::Metadata *, 16 > Elements;
1438+
1439+ SmallVector<MemberDIType, 16 > MemberTypes;
14141440 for (auto *ElemDecl : Decl->getAllElements ()) {
14151441 std::optional<CompletedDebugTypeInfo> ElemDbgTy;
14161442 if (auto PayloadTy = ElemDecl->getPayloadInterfaceType ()) {
@@ -1429,23 +1455,27 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14291455 llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
14301456 llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 , MangledName);
14311457 }
1432- unsigned Offset = 0 ;
1433- auto MTy =
1434- createMemberType (*ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
1435- Offset, Scope, File, Flags);
1436- Elements.push_back (MTy);
1458+ MemberTypes.emplace_back (ElemDecl->getBaseIdentifier ().str (),
1459+ getByteSize () *
1460+ ElemDbgTy->getAlignment ().getValue (),
1461+ TrackingDIType (getOrCreateType (*ElemDbgTy)));
14371462 } else {
14381463 // A variant with no payload.
1439- auto MTy = DBuilder.createMemberType (
1440- Scope, ElemDecl->getBaseIdentifier ().str (), File, 0 , 0 , 0 , 0 , Flags,
1441- nullptr );
1442- Elements.push_back (MTy);
1464+ MemberTypes.emplace_back (ElemDecl->getBaseIdentifier ().str (), 0 ,
1465+ nullptr );
14431466 }
14441467 }
1468+ SmallVector<llvm::Metadata *, 16 > Members;
1469+ for (auto &Member : MemberTypes) {
1470+ unsigned Offset = 0 ;
1471+ Members.push_back (createMemberType (Member.DIType , Member.Name , Offset,
1472+ Member.AlignInBits , Scope, File,
1473+ Flags));
1474+ }
14451475
14461476 auto VPTy = DBuilder.createVariantPart (
14471477 Scope, {}, File, Line, SizeInBits, AlignInBits, Flags, nullptr ,
1448- DBuilder.getOrCreateArray (Elements ), /* UniqueIdentifier=*/ " " );
1478+ DBuilder.getOrCreateArray (Members ), /* UniqueIdentifier=*/ " " );
14491479
14501480 llvm::DICompositeType *DITy = DBuilder.createStructType (
14511481 Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, nullptr ,
@@ -1474,31 +1504,35 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14741504 DbgTy.getType (), Scope, File, Line, SizeInBits, AlignInBits, Flags,
14751505 MangledName, Name);
14761506
1477- SmallVector<llvm::Metadata * , 16 > Elements ;
1507+ SmallVector<MemberDIType , 16 > MemberTypes ;
14781508 for (auto *ElemDecl : Decl->getAllElements ()) {
14791509 std::optional<DebugTypeInfo> ElemDbgTy;
14801510 if (auto PayloadTy = ElemDecl->getPayloadInterfaceType ()) {
14811511 // A variant case which carries a payload.
14821512 PayloadTy = ElemDecl->getParentEnum ()->mapTypeIntoContext (PayloadTy);
14831513 ElemDbgTy = DebugTypeInfo::getFromTypeInfo (
14841514 PayloadTy, IGM.getTypeInfoForUnlowered (PayloadTy), IGM);
1485- unsigned Offset = 0 ;
1486- auto MTy =
1487- createMemberType (*ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
1488- Offset, Scope, File, Flags);
1489- Elements.push_back (MTy);
1515+ MemberTypes.emplace_back (ElemDecl->getBaseIdentifier ().str (),
1516+ getByteSize () *
1517+ ElemDbgTy->getAlignment ().getValue (),
1518+ TrackingDIType (getOrCreateType (*ElemDbgTy)));
14901519 } else {
14911520 // A variant with no payload.
1492- auto MTy = DBuilder.createMemberType (
1493- Scope, ElemDecl->getBaseIdentifier ().str (), File, 0 , 0 , 0 , 0 , Flags,
1494- nullptr );
1495- Elements.push_back (MTy);
1521+ MemberTypes.emplace_back (ElemDecl->getBaseIdentifier ().str (), 0 ,
1522+ nullptr );
14961523 }
14971524 }
1525+ SmallVector<llvm::Metadata *, 16 > Members;
1526+ for (auto &Member : MemberTypes) {
1527+ unsigned Offset = 0 ;
1528+ Members.push_back (createMemberType (Member.DIType , Member.Name , Offset,
1529+ Member.AlignInBits , Scope, File,
1530+ Flags));
1531+ }
14981532
14991533 auto VPTy = DBuilder.createVariantPart (Scope, {}, File, Line, SizeInBits,
15001534 AlignInBits, Flags, nullptr ,
1501- DBuilder.getOrCreateArray (Elements ));
1535+ DBuilder.getOrCreateArray (Members ));
15021536
15031537 llvm::DICompositeType *DITy = DBuilder.createStructType (
15041538 Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, nullptr ,
@@ -1721,31 +1755,37 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
17211755 unsigned SizeInBits, unsigned AlignInBits,
17221756 llvm::DINode::DIFlags Flags,
17231757 StringRef MangledName) {
1758+ auto FwdDecl = createTemporaryReplaceableForwardDecl (
1759+ DbgTy.getType (), Scope, MainFile, 0 , SizeInBits, AlignInBits, Flags,
1760+ MangledName, MangledName);
1761+
17241762 TypeBase *BaseTy = DbgTy.getType ();
17251763 auto *TupleTy = BaseTy->castTo <TupleType>();
17261764
1727- SmallVector<llvm::Metadata *, 16 > Elements;
1728- unsigned OffsetInBits = 0 ;
1765+ SmallVector<MemberDIType, 16 > MemberTypes;
17291766 auto genericSig = IGM.getCurGenericContext ();
17301767 for (auto ElemTy : TupleTy->getElementTypes ()) {
17311768 auto &elemTI = IGM.getTypeInfoForUnlowered (
17321769 AbstractionPattern (genericSig, ElemTy->getCanonicalType ()), ElemTy);
17331770 auto DbgTy =
17341771 DebugTypeInfo::getFromTypeInfo (ElemTy, elemTI, IGM);
1735- Elements.push_back (
1736- createMemberType (DbgTy, " " , OffsetInBits, Scope, MainFile, Flags));
1772+ MemberTypes.emplace_back (" " ,
1773+ getByteSize () * DbgTy.getAlignment ().getValue (),
1774+ getOrCreateType (DbgTy));
17371775 }
1776+ SmallVector<llvm::Metadata *, 16 > Members;
1777+ unsigned OffsetInBits = 0 ;
1778+ for (auto &Member : MemberTypes)
1779+ Members.emplace_back (createMemberType (Member.DIType , Member.Name ,
1780+ OffsetInBits, Member.AlignInBits ,
1781+ Scope, MainFile, Flags));
17381782 // FIXME: assert that SizeInBits == OffsetInBits.
17391783
1740- auto FwdDecl = createTemporaryReplaceableForwardDecl (
1741- DbgTy.getType (), Scope, MainFile, 0 , SizeInBits, AlignInBits, Flags,
1742- MangledName, MangledName);
1743-
17441784 llvm::DICompositeType *DITy = DBuilder.createStructType (
17451785 Scope, MangledName, MainFile, 0 , SizeInBits, AlignInBits, Flags,
17461786 nullptr , // DerivedFrom
1747- DBuilder.getOrCreateArray (Elements ), llvm::dwarf::DW_LANG_Swift,
1748- nullptr , MangledName);
1787+ DBuilder.getOrCreateArray (Members ), llvm::dwarf::DW_LANG_Swift, nullptr ,
1788+ MangledName);
17491789
17501790 return DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
17511791 }
@@ -2606,12 +2646,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
26062646 auto *DITy = cast<llvm::DIType>(CachedTy);
26072647 assert (sanityCheckCachedType (DbgTy, DITy));
26082648 return DITy;
2649+ } else {
2650+ UID = llvm::MDString::get (IGM.getLLVMContext (), Mangled.Canonical );
2651+ if (llvm::Metadata *CachedTy = DIRefMap.lookup (UID))
2652+ return cast<llvm::DIType>(CachedTy);
26092653 }
26102654 }
26112655
26122656 Scope = updateScope (Scope, DbgTy);
26132657 StringRef MangledName =
26142658 !Mangled.Sugared .empty () ? Mangled.Sugared : Mangled.Canonical ;
2659+
26152660 StringRef Name = MangledName;
26162661 if (auto *Decl = DbgTy.getDecl ())
26172662 Name = Decl->getName ().str ();
@@ -2637,7 +2682,6 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
26372682 }
26382683 llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
26392684
2640-
26412685 if (!shouldCacheDIType (DITy, DbgTy))
26422686 return DITy;
26432687
0 commit comments