@@ -92,6 +92,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
9292 llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
9393 llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
9494 TrackingDIRefMap DIRefMap;
95+ TrackingDIRefMap InnerTypeCache;
9596 // / @}
9697
9798 // / A list of replaceable fwddecls that need to be RAUWed at the end.
@@ -765,7 +766,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
765766 }
766767
767768 StringRef getMangledName (DebugTypeInfo DbgTy) {
768- if (DbgTy.IsMetadataType )
769+ if (DbgTy.isMetadataType () )
769770 return MetadataTypeDeclCache.find (DbgTy.getDecl ()->getName ().str ())
770771 ->getKey ();
771772
@@ -829,12 +830,12 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
829830 llvm::DINode::DIFlags Flags) {
830831 unsigned SizeOfByte = CI.getTargetInfo ().getCharWidth ();
831832 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);
835836 OffsetInBits += getSizeInBits (Ty);
836- OffsetInBits =
837- llvm::alignTo (OffsetInBits, SizeOfByte * DbgTy.align .getValue ());
837+ OffsetInBits = llvm::alignTo (OffsetInBits,
838+ SizeOfByte * DbgTy.getAlignment () .getValue ());
838839 return DITy;
839840 }
840841
@@ -929,8 +930,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
929930 // one of the raw type as long as it is large enough to hold
930931 // all enum values. Use the raw type for the debug type, but
931932 // 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 );
934936 else if (auto ArgTy = ElemDecl->getArgumentInterfaceType ()) {
935937 // A discriminated union. This should really be described as a
936938 // DW_TAG_variant_type. For now only describing the data.
@@ -941,12 +943,13 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
941943 // Discriminated union case without argument. Fallback to Int
942944 // as the element type; there is no storage here.
943945 Type IntTy = IGM.Context .getIntDecl ()->getDeclaredType ();
944- ElemDbgTy = DebugTypeInfo (IntTy, DbgTy.StorageType , Size (0 ),
946+ ElemDbgTy = DebugTypeInfo (IntTy, DbgTy.getStorageType () , Size (0 ),
945947 Alignment (1 ), true , false );
946948 }
947949 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);
950953 Elements.push_back (MTy);
951954 }
952955 return DBuilder.getOrCreateArray (Elements);
@@ -958,7 +961,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
958961 llvm::DIFile *File, unsigned Line,
959962 llvm::DINode::DIFlags Flags) {
960963 unsigned SizeOfByte = CI.getTargetInfo ().getCharWidth ();
961- unsigned SizeInBits = DbgTy.size .getValue () * SizeOfByte;
964+ unsigned SizeInBits = DbgTy.getSize () .getValue () * SizeOfByte;
962965 // Default, since Swift doesn't allow specifying a custom alignment.
963966 unsigned AlignInBits = 0 ;
964967
@@ -982,16 +985,17 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
982985 }
983986
984987 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 ());
987991 return getOrCreateType (BlandDbgTy);
988992 }
989993
990994 uint64_t getSizeOfBasicType (DebugTypeInfo DbgTy) {
991995 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 ()
995999 : IGM.DataLayout .getSmallestLegalIntType (
9961000 IGM.getLLVMContext (), BitWidth);
9971001
@@ -1003,23 +1007,44 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
10031007 return BitWidth;
10041008 }
10051009
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+
10061022 // / Create a sized container for a sizeless type. Used to represent
10071023 // / BoundGenericEnums that may have different sizes depending on what they are
10081024 // / bound to, but still share a mangled name.
10091025 llvm::DIType *createOpaqueStructWithSizedContainer (
10101026 llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
10111027 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+
10191045 llvm::Metadata *Elements[] = {
10201046 DBuilder.createMemberType (Scope, " " , File, 0 , SizeInBits,
10211047 AlignInBits, 0 , Flags, UniqueType)};
1022-
10231048 return DBuilder.createStructType (
10241049 Scope, " " , File, Line, SizeInBits, AlignInBits, Flags,
10251050 /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
@@ -1188,9 +1213,10 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11881213 // emitting the storage size of the struct, but it may be necessary
11891214 // to emit the (target!) size of the underlying basic type.
11901215 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;
11941220 unsigned Encoding = 0 ;
11951221 llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
11961222
@@ -1332,7 +1358,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13321358 auto L = getDebugLoc (*this , Decl);
13331359 return createOpaqueStructWithSizedContainer (
13341360 Scope, Decl ? Decl->getNameStr () : " " , File, L.Line , SizeInBits,
1335- AlignInBits, Flags, MangledName);
1361+ AlignInBits, Flags, MangledName, collectGenericParams (StructTy) );
13361362 }
13371363
13381364 case TypeKind::BoundGenericClass: {
@@ -1441,7 +1467,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14411467 auto *File = getOrCreateFile (L.Filename );
14421468 return createOpaqueStructWithSizedContainer (
14431469 Scope, Decl->getName ().str (), File, L.Line , SizeInBits, AlignInBits,
1444- Flags, MangledName);
1470+ Flags, MangledName, collectGenericParams (EnumTy) );
14451471 }
14461472
14471473 case TypeKind::BuiltinVector: {
@@ -1480,9 +1506,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14801506 auto File = getOrCreateFile (L.Filename );
14811507 // For TypeAlias types, the DeclContext for the aliased type is
14821508 // 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 );
14861512 return DBuilder.createTypedef (getOrCreateType (AliasedDbgTy), MangledName,
14871513 File, L.Line , Scope);
14881514 }
@@ -1637,8 +1663,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16371663 if (Decl->isOutermostPrivateOrFilePrivateScope ())
16381664 Scope = getFilePrivateScope (Scope, Decl);
16391665
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+ }
16401678 llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
16411679
1680+ // Don't cache a type alias to a forward declaration either.
1681+ if (DbgTy.isForwardDecl ())
1682+ return DITy;
1683+
16421684 // Incrementally build the DIRefMap.
16431685 if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
16441686#ifndef NDEBUG
@@ -2178,11 +2220,11 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
21782220 return ;
21792221
21802222 // We cannot yet represent opened existentials.
2181- if (DbgTy.Type ->hasOpenedExistential ())
2223+ if (DbgTy.getType () ->hasOpenedExistential ())
21822224 return ;
21832225
2184- if (!DbgTy.size )
2185- DbgTy.size = getStorageSize (IGM.DataLayout , Storage);
2226+ if (!DbgTy.getSize () )
2227+ DbgTy.setSize ( getStorageSize (IGM.DataLayout , Storage) );
21862228
21872229 auto *Scope = dyn_cast_or_null<llvm::DILocalScope>(getOrCreateScope (DS));
21882230 assert (Scope && " variable has no local scope" );
0 commit comments