@@ -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.
@@ -1003,23 +1004,44 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1003
1004
return BitWidth;
1004
1005
}
1005
1006
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
+
1006
1019
// / Create a sized container for a sizeless type. Used to represent
1007
1020
// / BoundGenericEnums that may have different sizes depending on what they are
1008
1021
// / bound to, but still share a mangled name.
1009
1022
llvm::DIType *createOpaqueStructWithSizedContainer (
1010
1023
llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
1011
1024
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
+
1019
1042
llvm::Metadata *Elements[] = {
1020
1043
DBuilder.createMemberType (Scope, " " , File, 0 , SizeInBits,
1021
1044
AlignInBits, 0 , Flags, UniqueType)};
1022
-
1023
1045
return DBuilder.createStructType (
1024
1046
Scope, " " , File, Line, SizeInBits, AlignInBits, Flags,
1025
1047
/* DerivedFrom */ nullptr , DBuilder.getOrCreateArray (Elements),
@@ -1332,7 +1354,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1332
1354
auto L = getDebugLoc (*this , Decl);
1333
1355
return createOpaqueStructWithSizedContainer (
1334
1356
Scope, Decl ? Decl->getNameStr () : " " , File, L.Line , SizeInBits,
1335
- AlignInBits, Flags, MangledName);
1357
+ AlignInBits, Flags, MangledName, collectGenericParams (StructTy) );
1336
1358
}
1337
1359
1338
1360
case TypeKind::BoundGenericClass: {
@@ -1441,7 +1463,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1441
1463
auto *File = getOrCreateFile (L.Filename );
1442
1464
return createOpaqueStructWithSizedContainer (
1443
1465
Scope, Decl->getName ().str (), File, L.Line , SizeInBits, AlignInBits,
1444
- Flags, MangledName);
1466
+ Flags, MangledName, collectGenericParams (EnumTy) );
1445
1467
}
1446
1468
1447
1469
case TypeKind::BuiltinVector: {
@@ -1637,8 +1659,24 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1637
1659
if (Decl->isOutermostPrivateOrFilePrivateScope ())
1638
1660
Scope = getFilePrivateScope (Scope, Decl);
1639
1661
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
+ }
1640
1674
llvm::DIType *DITy = createType (DbgTy, MangledName, Scope, getFile (Scope));
1641
1675
1676
+ // Don't cache a type alias to a forward declaration either.
1677
+ if (DbgTy.isForwardDecl ())
1678
+ return DITy;
1679
+
1642
1680
// Incrementally build the DIRefMap.
1643
1681
if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
1644
1682
#ifndef NDEBUG
0 commit comments