@@ -92,6 +92,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
92
92
llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
93
93
llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
94
94
TrackingDIRefMap DIRefMap;
95
+ TrackingDIRefMap InnerTypeCache;
95
96
// / @}
96
97
97
98
// / A list of replaceable fwddecls that need to be RAUWed at the end.
@@ -765,7 +766,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
765
766
}
766
767
767
768
StringRef getMangledName (DebugTypeInfo DbgTy) {
768
- if (DbgTy.IsMetadataType )
769
+ if (DbgTy.isMetadataType () )
769
770
return MetadataTypeDeclCache.find (DbgTy.getDecl ()->getName ().str ())
770
771
->getKey ();
771
772
@@ -829,12 +830,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
829
830
llvm::DINode::DIFlags Flags) {
830
831
unsigned SizeOfByte = CI.getTargetInfo ().getCharWidth ();
831
832
auto *Ty = getOrCreateType (DbgTy);
832
- auto *DITy = DBuilder.createMemberType (Scope, Name, File, 0 ,
833
- SizeOfByte * DbgTy.size .getValue (),
834
- 0 , OffsetInBits, Flags, Ty);
833
+ auto *DITy = DBuilder.createMemberType (
834
+ Scope, Name, File, 0 , SizeOfByte * DbgTy.getSize () .getValue (), 0 ,
835
+ OffsetInBits, Flags, Ty);
835
836
OffsetInBits += getSizeInBits (Ty);
836
- OffsetInBits =
837
- llvm::alignTo (OffsetInBits, SizeOfByte * DbgTy.align .getValue ());
837
+ OffsetInBits = llvm::alignTo (OffsetInBits,
838
+ SizeOfByte * DbgTy.getAlignment () .getValue ());
838
839
return DITy;
839
840
}
840
841
@@ -929,8 +930,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
929
930
// one of the raw type as long as it is large enough to hold
930
931
// all enum values. Use the raw type for the debug type, but
931
932
// the storage size from the enum.
932
- ElemDbgTy = DebugTypeInfo (ED->getRawType (), DbgTy.StorageType ,
933
- DbgTy.size , DbgTy.align , true , false );
933
+ ElemDbgTy =
934
+ DebugTypeInfo (ED->getRawType (), DbgTy.getStorageType (),
935
+ DbgTy.getSize (), DbgTy.getAlignment (), true , false );
934
936
else if (auto ArgTy = ElemDecl->getArgumentInterfaceType ()) {
935
937
// A discriminated union. This should really be described as a
936
938
// DW_TAG_variant_type. For now only describing the data.
@@ -941,12 +943,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
941
943
// Discriminated union case without argument. Fallback to Int
942
944
// as the element type; there is no storage here.
943
945
Type IntTy = IGM.Context .getIntDecl ()->getDeclaredType ();
944
- ElemDbgTy = DebugTypeInfo (IntTy, DbgTy.StorageType , Size (0 ),
946
+ ElemDbgTy = DebugTypeInfo (IntTy, DbgTy.getStorageType () , Size (0 ),
945
947
Alignment (1 ), true , false );
946
948
}
947
949
unsigned Offset = 0 ;
948
- auto MTy = createMemberType (ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
949
- Offset, Scope, File, Flags);
950
+ auto MTy =
951
+ createMemberType (ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
952
+ Offset, Scope, File, Flags);
950
953
Elements.push_back (MTy);
951
954
}
952
955
return DBuilder.getOrCreateArray (Elements);
@@ -958,7 +961,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
958
961
llvm::DIFile *File, unsigned Line,
959
962
llvm::DINode::DIFlags Flags) {
960
963
unsigned SizeOfByte = CI.getTargetInfo ().getCharWidth ();
961
- unsigned SizeInBits = DbgTy.size .getValue () * SizeOfByte;
964
+ unsigned SizeInBits = DbgTy.getSize () .getValue () * SizeOfByte;
962
965
// Default, since Swift doesn't allow specifying a custom alignment.
963
966
unsigned AlignInBits = 0 ;
964
967
@@ -982,16 +985,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
982
985
}
983
986
984
987
llvm::DIType *getOrCreateDesugaredType (Type Ty, DebugTypeInfo DbgTy) {
985
- DebugTypeInfo BlandDbgTy (Ty, DbgTy.StorageType , DbgTy.size , DbgTy.align ,
986
- DbgTy.DefaultAlignment , DbgTy.IsMetadataType );
988
+ DebugTypeInfo BlandDbgTy (Ty, DbgTy.getStorageType (), DbgTy.getSize (),
989
+ DbgTy.getAlignment (), DbgTy.hasDefaultAlignment (),
990
+ DbgTy.isMetadataType ());
987
991
return getOrCreateType (BlandDbgTy);
988
992
}
989
993
990
994
uint64_t getSizeOfBasicType (DebugTypeInfo DbgTy) {
991
995
uint64_t SizeOfByte = CI.getTargetInfo ().getCharWidth ();
992
- uint64_t BitWidth = DbgTy.size .getValue () * SizeOfByte;
993
- llvm::Type *StorageType = DbgTy.StorageType
994
- ? DbgTy.StorageType
996
+ uint64_t BitWidth = DbgTy.getSize () .getValue () * SizeOfByte;
997
+ llvm::Type *StorageType = DbgTy.getStorageType ()
998
+ ? DbgTy.getStorageType ()
995
999
: IGM.DataLayout .getSmallestLegalIntType (
996
1000
IGM.getLLVMContext (), BitWidth);
997
1001
@@ -1003,23 +1007,44 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1003
1007
return BitWidth;
1004
1008
}
1005
1009
1010
+ // / Collect the type parameters of a bound generic type. This is needed to
1011
+ // / anchor any typedefs that may appear in parameters so they can be
1012
+ // / resolved in the debugger without needing to query the Swift module.
1013
+ llvm::DINodeArray collectGenericParams (BoundGenericType *BGT) {
1014
+ SmallVector<llvm::Metadata *, 16 > TemplateParams;
1015
+ for (auto Param : BGT->getGenericArgs ()) {
1016
+ TemplateParams.push_back (DBuilder.createTemplateTypeParameter (
1017
+ TheCU, " " , getOrCreateType (DebugTypeInfo::getForwardDecl (Param))));
1018
+ }
1019
+ return DBuilder.getOrCreateArray (TemplateParams);
1020
+ }
1021
+
1006
1022
// / Create a sized container for a sizeless type. Used to represent
1007
1023
// / BoundGenericEnums that may have different sizes depending on what they are
1008
1024
// / bound to, but still share a mangled name.
1009
1025
llvm::DIType *createOpaqueStructWithSizedContainer (
1010
1026
llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
1011
1027
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
1012
- StringRef MangledName) {
1013
- // Let the MDNode folding set do the work of uniquing the inner type. This
1014
- // should be cheap.
1015
- llvm::DICompositeType *UniqueType = DBuilder.createStructType (
1016
- Scope, Name, File, Line, 0 , 0 , Flags, nullptr ,
1017
- DBuilder.getOrCreateArray (ArrayRef<llvm::Metadata *>()),
1018
- llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1028
+ StringRef MangledName, llvm::DINodeArray BoundParams) {
1029
+ // This uses a separate cache and not DIRefMap for the inner type to avoid
1030
+ // associating the anonymous container (which is specific to the
1031
+ // variable/storage and not the type) with the MangledName.
1032
+ llvm::DICompositeType *UniqueType = nullptr ;
1033
+ auto *UID = llvm::MDString::get (IGM.getLLVMContext (), MangledName);
1034
+ if (llvm::Metadata *V = InnerTypeCache.lookup (UID))
1035
+ UniqueType = cast<llvm::DICompositeType>(V);
1036
+ else {
1037
+ UniqueType = DBuilder.createStructType (
1038
+ Scope, Name, File, Line, 0 , 0 , Flags, nullptr , nullptr ,
1039
+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1040
+ if (BoundParams)
1041
+ DBuilder.replaceArrays (UniqueType, nullptr , BoundParams);
1042
+ InnerTypeCache[UID] = llvm::TrackingMDNodeRef (UniqueType);
1043
+ }
1044
+
1019
1045
llvm::Metadata *Elements[] = {
1020
1046
DBuilder.createMemberType (Scope, " " , File, 0 , SizeInBits,
1021
1047
AlignInBits, 0 , Flags, UniqueType)};
1022
-
1023
1048
return DBuilder.createStructType (
1024
1049
Scope, " " , File, Line, SizeInBits, AlignInBits, Flags,
1025
1050
/* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
@@ -1188,9 +1213,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1188
1213
// emitting the storage size of the struct, but it may be necessary
1189
1214
// to emit the (target!) size of the underlying basic type.
1190
1215
uint64_t SizeOfByte = CI.getTargetInfo ().getCharWidth ();
1191
- uint64_t SizeInBits = DbgTy.size .getValue () * SizeOfByte;
1192
- unsigned AlignInBits =
1193
- DbgTy.DefaultAlignment ? 0 : DbgTy.align .getValue () * SizeOfByte;
1216
+ uint64_t SizeInBits = DbgTy.getSize ().getValue () * SizeOfByte;
1217
+ unsigned AlignInBits = DbgTy.hasDefaultAlignment ()
1218
+ ? 0
1219
+ : DbgTy.getAlignment ().getValue () * SizeOfByte;
1194
1220
unsigned Encoding = 0 ;
1195
1221
llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
1196
1222
@@ -1332,7 +1358,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1332
1358
auto L = getDebugLoc (*this , Decl);
1333
1359
return createOpaqueStructWithSizedContainer (
1334
1360
Scope, Decl ? Decl->getNameStr () : " " , File, L.Line , SizeInBits,
1335
- AlignInBits, Flags, MangledName);
1361
+ AlignInBits, Flags, MangledName, collectGenericParams (StructTy) );
1336
1362
}
1337
1363
1338
1364
case TypeKind::BoundGenericClass: {
@@ -1441,7 +1467,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1441
1467
auto *File = getOrCreateFile (L.Filename );
1442
1468
return createOpaqueStructWithSizedContainer (
1443
1469
Scope, Decl->getName ().str (), File, L.Line , SizeInBits, AlignInBits,
1444
- Flags, MangledName);
1470
+ Flags, MangledName, collectGenericParams (EnumTy) );
1445
1471
}
1446
1472
1447
1473
case TypeKind::BuiltinVector: {
@@ -1480,9 +1506,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1480
1506
auto File = getOrCreateFile (L.Filename );
1481
1507
// For TypeAlias types, the DeclContext for the aliased type is
1482
1508
// in the decl of the alias type.
1483
- DebugTypeInfo AliasedDbgTy (AliasedTy, DbgTy.StorageType , DbgTy. size ,
1484
- DbgTy.align , DbgTy.DefaultAlignment ,
1485
- false );
1509
+ DebugTypeInfo AliasedDbgTy (AliasedTy, DbgTy.getStorageType () ,
1510
+ DbgTy.getSize () , DbgTy.getAlignment () ,
1511
+ DbgTy. hasDefaultAlignment (), false );
1486
1512
return DBuilder.createTypedef (getOrCreateType (AliasedDbgTy), MangledName,
1487
1513
File, L.Line , Scope);
1488
1514
}
@@ -1637,8 +1663,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1637
1663
if (Decl->isOutermostPrivateOrFilePrivateScope ())
1638
1664
Scope = getFilePrivateScope (Scope, Decl);
1639
1665
1666
+ // If this is a forward decl, create one for this mangled name and don't
1667
+ // cache it.
1668
+ if (DbgTy.isForwardDecl () && !isa<TypeAliasType>(DbgTy.getType ())) {
1669
+ auto *FwdDecl = DBuilder.createReplaceableCompositeType (
1670
+ llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0 , 0 ,
1671
+ llvm::dwarf::DW_LANG_Swift, 0 , 0 , llvm::DINode::FlagFwdDecl,
1672
+ MangledName);
1673
+ ReplaceMap.emplace_back (
1674
+ std::piecewise_construct, std::make_tuple (DbgTy.getType ()),
1675
+ std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
1676
+ return FwdDecl;
1677
+ }
1640
1678
llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
1641
1679
1680
+ // Don't cache a type alias to a forward declaration either.
1681
+ if (DbgTy.isForwardDecl ())
1682
+ return DITy;
1683
+
1642
1684
// Incrementally build the DIRefMap.
1643
1685
if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
1644
1686
#ifndef NDEBUG
@@ -2178,11 +2220,11 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
2178
2220
return ;
2179
2221
2180
2222
// We cannot yet represent opened existentials.
2181
- if (DbgTy.Type ->hasOpenedExistential ())
2223
+ if (DbgTy.getType () ->hasOpenedExistential ())
2182
2224
return ;
2183
2225
2184
- if (!DbgTy.size )
2185
- DbgTy.size = getStorageSize (IGM.DataLayout , Storage);
2226
+ if (!DbgTy.getSize () )
2227
+ DbgTy.setSize ( getStorageSize (IGM.DataLayout , Storage) );
2186
2228
2187
2229
auto *Scope = dyn_cast_or_null<llvm::DILocalScope>(getOrCreateScope (DS));
2188
2230
assert (Scope && " variable has no local scope" );
0 commit comments