@@ -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.
@@ -1003,23 +1004,44 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
10031004 return BitWidth;
10041005 }
10051006
1007+ // / Collect the type parameters of a bound generic type. This is needed to
1008+ // / anchor any typedefs that may appear in parameters so they can be
1009+ // / resolved in the debugger without needing to query the Swift module.
1010+ llvm::DINodeArray collectGenericParams (BoundGenericType *BGT) {
1011+ SmallVector<llvm::Metadata *, 16 > TemplateParams;
1012+ for (auto Param : BGT->getGenericArgs ()) {
1013+ TemplateParams.push_back (DBuilder.createTemplateTypeParameter (
1014+ TheCU, " " , getOrCreateType (DebugTypeInfo::getForwardDecl (Param))));
1015+ }
1016+ return DBuilder.getOrCreateArray (TemplateParams);
1017+ }
1018+
10061019 // / Create a sized container for a sizeless type. Used to represent
10071020 // / BoundGenericEnums that may have different sizes depending on what they are
10081021 // / bound to, but still share a mangled name.
10091022 llvm::DIType *createOpaqueStructWithSizedContainer (
10101023 llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
10111024 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);
1025+ StringRef MangledName, llvm::DINodeArray BoundParams) {
1026+ // This uses a separate cache and not DIRefMap for the inner type to avoid
1027+ // associating the anonymous container (which is specific to the
1028+ // variable/storage and not the type) with the MangledName.
1029+ llvm::DICompositeType *UniqueType = nullptr ;
1030+ auto *UID = llvm::MDString::get (IGM.getLLVMContext (), MangledName);
1031+ if (llvm::Metadata *V = InnerTypeCache.lookup (UID))
1032+ UniqueType = cast<llvm::DICompositeType>(V);
1033+ else {
1034+ UniqueType = DBuilder.createStructType (
1035+ Scope, Name, File, Line, 0 , 0 , Flags, nullptr , nullptr ,
1036+ llvm::dwarf::DW_LANG_Swift, nullptr , MangledName);
1037+ if (BoundParams)
1038+ DBuilder.replaceArrays (UniqueType, nullptr , BoundParams);
1039+ InnerTypeCache[UID] = llvm::TrackingMDNodeRef (UniqueType);
1040+ }
1041+
10191042 llvm::Metadata *Elements[] = {
10201043 DBuilder.createMemberType (Scope, " " , File, 0 , SizeInBits,
10211044 AlignInBits, 0 , Flags, UniqueType)};
1022-
10231045 return DBuilder.createStructType (
10241046 Scope, " " , File, Line, SizeInBits, AlignInBits, Flags,
10251047 /* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
@@ -1332,7 +1354,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
13321354 auto L = getDebugLoc (*this , Decl);
13331355 return createOpaqueStructWithSizedContainer (
13341356 Scope, Decl ? Decl->getNameStr () : " " , File, L.Line , SizeInBits,
1335- AlignInBits, Flags, MangledName);
1357+ AlignInBits, Flags, MangledName, collectGenericParams (StructTy) );
13361358 }
13371359
13381360 case TypeKind::BoundGenericClass: {
@@ -1441,7 +1463,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
14411463 auto *File = getOrCreateFile (L.Filename );
14421464 return createOpaqueStructWithSizedContainer (
14431465 Scope, Decl->getName ().str (), File, L.Line , SizeInBits, AlignInBits,
1444- Flags, MangledName);
1466+ Flags, MangledName, collectGenericParams (EnumTy) );
14451467 }
14461468
14471469 case TypeKind::BuiltinVector: {
@@ -1637,8 +1659,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
16371659 if (Decl->isOutermostPrivateOrFilePrivateScope ())
16381660 Scope = getFilePrivateScope (Scope, Decl);
16391661
1662+ // If this is a forward decl, create one for this mangled name and don't
1663+ // cache it.
1664+ if (DbgTy.isForwardDecl () && !isa<TypeAliasType>(DbgTy.getType ())) {
1665+ auto *FwdDecl = DBuilder.createReplaceableCompositeType (
1666+ llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0 , 0 ,
1667+ llvm::dwarf::DW_LANG_Swift, 0 , 0 , llvm::DINode::FlagFwdDecl,
1668+ MangledName);
1669+ ReplaceMap.emplace_back (
1670+ std::piecewise_construct, std::make_tuple (DbgTy.getType ()),
1671+ std::make_tuple (static_cast <llvm::Metadata *>(FwdDecl)));
1672+ return FwdDecl;
1673+ }
16401674 llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
16411675
1676+ // Don't cache a type alias to a forward declaration either.
1677+ if (DbgTy.isForwardDecl ())
1678+ return DITy;
1679+
16421680 // Incrementally build the DIRefMap.
16431681 if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
16441682#ifndef NDEBUG
0 commit comments