Skip to content

Commit 85faa52

Browse files
authoredFeb 3, 2025
Merge pull request swiftlang#79085 from adrian-prantl/143833326
[Debug info] Emit bound generic class type parameters when emitting A…
2 parents 40deafb + 91b6162 commit 85faa52

File tree

6 files changed

+88
-82
lines changed

6 files changed

+88
-82
lines changed
 

‎lib/IRGen/DebugTypeInfo.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,12 @@ TypeDecl *DebugTypeInfo::getDecl() const {
179179
return nullptr;
180180
}
181181

182-
bool DebugTypeInfo::isForwardDecl() const {
183-
return isNull() || (!isa<TypeAliasType>(getType()));
184-
}
185-
186182
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
187183
LLVM_DUMP_METHOD void DebugTypeInfo::dump() const {
188184
llvm::errs() << "[";
189185
llvm::errs() << "Alignment " << Align.getValue() << "] ";
190186
if (auto *Type = getType())
191187
Type->dump(llvm::errs());
192-
193-
if (isForwardDecl())
194-
llvm::errs() << "forward-declared\n";
195188
}
196189
#endif
197190

‎lib/IRGen/DebugTypeInfo.h

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ class DebugTypeInfo {
9797

9898
Alignment getAlignment() const { return Align; }
9999
bool isNull() const { return !Type; }
100-
bool isForwardDecl() const;
101100
bool isMetadataType() const { return IsMetadataType; }
102101
bool hasDefaultAlignment() const { return DefaultAlignment; }
103102
bool isFixedBuffer() const { return IsFixedBuffer; }

‎lib/IRGen/IRGenDebugInfo.cpp

+70-60
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,26 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
11971197
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
11981198
DBuilder.getOrCreateArray(Elements), RuntimeLang, nullptr, UniqueID);
11991199
DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
1200-
return DITy;;
1200+
return DITy;
1201+
}
1202+
1203+
std::pair<bool, Type>
1204+
getUnsubstituedType(Type Ty, StringRef MangledName) {
1205+
if (!Ty)
1206+
return {false,{}};
1207+
// Go from Pair<Int, Double> to Pair<T, U>.
1208+
auto *Decl = Ty->getNominalOrBoundGenericNominal();
1209+
if (!Decl)
1210+
return {false, {}};
1211+
// Go from Pair<Int, Double> to Pair<T, U>.
1212+
Type InterfaceTy = Decl->getDeclaredInterfaceType();
1213+
Type UnsubstitutedTy = Decl->mapTypeIntoContext(InterfaceTy);
1214+
1215+
Mangle::ASTMangler Mangler(IGM.Context);
1216+
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
1217+
UnsubstitutedTy->mapTypeOutOfContext(), {});
1218+
bool IsUnsubstituted = (DeclTypeMangledName == MangledName);
1219+
return {IsUnsubstituted, UnsubstitutedTy};
12011220
}
12021221

12031222
llvm::DIType *
@@ -1206,36 +1225,32 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12061225
unsigned SizeInBits, unsigned AlignInBits,
12071226
llvm::DIScope *Scope, llvm::DIFile *File,
12081227
unsigned Line, llvm::DINode::DIFlags Flags) {
1209-
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
1210-
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
1211-
1212-
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
1228+
auto [IsUnsubstituted, UnsubstitutedTy] =
1229+
getUnsubstituedType(EnumTy, MangledName);
1230+
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
12131231
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
1214-
Mangle::ASTMangler Mangler(IGM.Context);
1215-
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
1216-
UnsubstitutedTy->mapTypeOutOfContext(), {});
1217-
if (DeclTypeMangledName == MangledName) {
1218-
return createUnsubstitutedVariantType(DbgTy, Decl, MangledName, Scope,
1219-
File, 0, Flags);
1220-
}
1232+
if (IsUnsubstituted)
1233+
return createUnsubstitutedVariantType(UnsubstitutedDbgTy, Decl,
1234+
MangledName, Scope, File, 0, Flags);
1235+
12211236
StringRef Name = Decl->getName().str();
12221237
auto FwdDecl = createTemporaryReplaceableForwardDecl(
12231238
EnumTy, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
12241239
Name);
12251240
// Force the creation of the unsubstituted type, don't create it
12261241
// directly so it goes through all the caching/verification logic.
1227-
auto unsubstitutedDbgTy = getOrCreateType(DbgTy);
1242+
auto UnsubstitutedDITy = getOrCreateType(UnsubstitutedDbgTy);
12281243
auto DIType = createOpaqueStruct(
12291244
Scope, "", File, 0, SizeInBits, AlignInBits, Flags, MangledName,
1230-
collectGenericParams(EnumTy), unsubstitutedDbgTy);
1245+
collectGenericParams(EnumTy), UnsubstitutedDITy);
12311246
DBuilder.replaceTemporary(std::move(FwdDecl), DIType);
12321247
return DIType;
12331248
}
12341249

12351250
/// Create a DICompositeType from a specialized struct. A specialized type
12361251
/// is a generic type, or a child type whose parent is generic.
12371252
llvm::DIType *createSpecializedStructOrClassType(
1238-
NominalOrBoundGenericNominalType *Type, NominalTypeDecl *Decl,
1253+
NominalOrBoundGenericNominalType *Type,
12391254
llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
12401255
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
12411256
StringRef MangledName, bool IsClass = false) {
@@ -1249,28 +1264,26 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12491264
// When emitting debug information for a type such as Pair<Int, Double>,
12501265
// emit a description of all the fields for Pair<T, U>, and emit the regular
12511266
// debug information for Pair<Int, Double>.
1267+
auto *Decl = Type->getNominalOrBoundGenericNominal();
1268+
if (!Decl)
1269+
return nullptr;
12521270
StringRef Name = Decl->getName().str();
12531271
auto FwdDecl = createTemporaryReplaceableForwardDecl(
12541272
Type, Scope, File, Line, SizeInBits, AlignInBits, Flags, MangledName,
12551273
Name);
12561274

1257-
// Go from Pair<Int, Double> to Pair<T, U>.
1258-
auto UnsubstitutedTy = Decl->getDeclaredInterfaceType();
1259-
UnsubstitutedTy = Decl->mapTypeIntoContext(UnsubstitutedTy);
1260-
1261-
auto DbgTy = DebugTypeInfo::getFromTypeInfo(
1262-
UnsubstitutedTy, IGM.getTypeInfoForUnlowered(UnsubstitutedTy), IGM);
1263-
Mangle::ASTMangler Mangler(IGM.Context);
1264-
std::string DeclTypeMangledName = Mangler.mangleTypeForDebugger(
1265-
UnsubstitutedTy->mapTypeOutOfContext(), {});
1266-
if (DeclTypeMangledName == MangledName) {
1275+
auto [IsUnsubstitued, UnsubstitutedType] =
1276+
getUnsubstituedType(Type, MangledName);
1277+
auto UnsubstitutedDbgTy = DebugTypeInfo::getFromTypeInfo(
1278+
UnsubstitutedType, IGM.getTypeInfoForUnlowered(UnsubstitutedType), IGM);
1279+
if (IsUnsubstitued)
12671280
return createUnsubstitutedGenericStructOrClassType(
1268-
DbgTy, Decl, UnsubstitutedTy, Scope, File, Line, Flags, nullptr,
1269-
llvm::dwarf::DW_LANG_Swift, DeclTypeMangledName);
1270-
}
1281+
UnsubstitutedDbgTy, Decl, UnsubstitutedType, Scope, File, Line, Flags,
1282+
nullptr, llvm::dwarf::DW_LANG_Swift, MangledName);
1283+
12711284
// Force the creation of the unsubstituted type, don't create it
12721285
// directly so it goes through all the caching/verification logic.
1273-
auto UnsubstitutedType = getOrCreateType(DbgTy);
1286+
auto UnsubstitutedDITy = getOrCreateType(UnsubstitutedDbgTy);
12741287

12751288
if (auto *ClassTy = llvm::dyn_cast<BoundGenericClassType>(Type)) {
12761289
auto SuperClassTy = ClassTy->getSuperclass();
@@ -1280,19 +1293,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
12801293

12811294
llvm::DIType *SuperClassDITy = getOrCreateType(SuperClassDbgTy);
12821295
assert(SuperClassDITy && "getOrCreateType should never return null!");
1283-
DBuilder.createInheritance(UnsubstitutedType, SuperClassDITy, 0, 0,
1296+
DBuilder.createInheritance(UnsubstitutedDITy, SuperClassDITy, 0, 0,
12841297
llvm::DINode::FlagZero);
12851298
}
1286-
1287-
auto *OpaqueType = createPointerSizedStruct(
1288-
Scope, Decl ? Decl->getNameStr() : MangledName, File, 0, Flags,
1289-
MangledName, UnsubstitutedType);
1290-
return OpaqueType;
12911299
}
12921300

1293-
auto *OpaqueType = createOpaqueStruct(
1294-
Scope, "", File, Line, SizeInBits, AlignInBits, Flags, MangledName,
1295-
collectGenericParams(Type), UnsubstitutedType);
1301+
auto *OpaqueType =
1302+
createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : "", File, Line,
1303+
SizeInBits, AlignInBits, Flags, MangledName,
1304+
collectGenericParams(Type), UnsubstitutedDITy);
12961305
DBuilder.replaceTemporary(std::move(FwdDecl), OpaqueType);
12971306
return OpaqueType;
12981307
}
@@ -1865,7 +1874,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18651874
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
18661875
if (StructTy->isSpecialized())
18671876
return createSpecializedStructOrClassType(
1868-
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
1877+
StructTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
18691878
Flags, MangledName);
18701879
return createStructType(DbgTy, Decl, StructTy, Scope, L.File, L.Line,
18711880
SizeInBits, AlignInBits, Flags, nullptr,
@@ -1898,7 +1907,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
18981907
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
18991908
if (ClassTy->isSpecialized())
19001909
return createSpecializedStructOrClassType(
1901-
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
1910+
ClassTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
19021911
Flags, MangledName);
19031912

19041913
auto *DIType = createStructType(
@@ -1964,7 +1973,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
19641973
unsigned FwdDeclLine = 0;
19651974
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
19661975
return createSpecializedStructOrClassType(
1967-
StructTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
1976+
StructTy, Scope, L.File, L.Line, SizeInBits, AlignInBits,
19681977
Flags, MangledName);
19691978

19701979
return createOpaqueStructWithSizedContainer(
@@ -1977,20 +1986,9 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
19771986
auto *ClassTy = BaseTy->castTo<BoundGenericClassType>();
19781987
auto *Decl = ClassTy->getDecl();
19791988
auto L = getFileAndLocation(Decl);
1980-
unsigned FwdDeclLine = 0;
1981-
1982-
if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
1983-
return createSpecializedStructOrClassType(
1984-
ClassTy, Decl, Scope, L.File, L.Line, SizeInBits, AlignInBits,
1985-
Flags, MangledName);
1986-
1987-
// TODO: We may want to peek at Decl->isObjC() and set this
1988-
// attribute accordingly.
1989-
assert(SizeInBits ==
1990-
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default));
1991-
return createPointerSizedStruct(
1992-
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
1993-
Flags, MangledName, SpecificationOf);
1989+
return createSpecializedStructOrClassType(ClassTy, Scope, L.File,
1990+
L.Line, SizeInBits, AlignInBits,
1991+
Flags, MangledName);
19941992
}
19951993

19961994
case TypeKind::Pack:
@@ -2174,8 +2172,14 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
21742172
AliasedTy, DbgTy.getAlignment(), DbgTy.hasDefaultAlignment(),
21752173
/* IsMetadataType = */ false, DbgTy.isFixedBuffer(),
21762174
DbgTy.getNumExtraInhabitants());
2177-
return DBuilder.createTypedef(getOrCreateType(AliasedDbgTy), MangledName,
2178-
L.File, 0, Scope);
2175+
auto *TypeDef = DBuilder.createTypedef(getOrCreateType(AliasedDbgTy),
2176+
MangledName, L.File, 0, Scope);
2177+
// Bound generic types don't reference their type parameters in ASTTypes
2178+
// mode, so we need to artificially keep typealiases alive, since they can
2179+
// appear in reflection metadata.
2180+
if (Opts.DebugInfoLevel < IRGenDebugInfoLevel::DwarfTypes)
2181+
DBuilder.retainType(TypeDef);
2182+
return TypeDef;
21792183
}
21802184

21812185
case TypeKind::Locatable: {
@@ -2269,10 +2273,15 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
22692273
// so skip the sanity check.
22702274
if (CachedType->isTemporary())
22712275
return true;
2276+
if (!isa<llvm::DICompositeType>(CachedType))
2277+
return true;
2278+
bool IsUnsubstituted =
2279+
getUnsubstituedType(DbgTy.getType(), getMangledName(DbgTy)).first;
22722280
std::optional<uint64_t> SizeInBits;
2273-
std::optional<CompletedDebugTypeInfo> CompletedDbgTy = completeType(DbgTy);
2274-
if (CompletedDbgTy)
2275-
SizeInBits = CompletedDbgTy->getSizeInBits();
2281+
if (!IsUnsubstituted)
2282+
if (auto CompletedDbgTy = completeType(DbgTy))
2283+
SizeInBits = CompletedDbgTy->getSizeInBits();
2284+
22762285
unsigned CachedSizeInBits = getSizeInBits(CachedType);
22772286
if (SizeInBits && CachedSizeInBits != *SizeInBits) {
22782287
// Note that CachedSizeInBits && !SizeInBits may happen and is benign,
@@ -2511,6 +2520,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
25112520
// winning over a full definition.
25122521
auto *FwdDecl = DBuilder.createReplaceableCompositeType(
25132522
llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, 0, 0,
2523+
25142524
llvm::dwarf::DW_LANG_Swift);
25152525
FwdDeclTypes.emplace_back(
25162526
std::piecewise_construct, std::make_tuple(MangledName),

‎test/ClangImporter/objc_ir.swift

+9-9
Original file line numberDiff line numberDiff line change
@@ -351,14 +351,14 @@ func testBlocksWithGenerics(hba: HasBlockArray) -> Any {
351351

352352
// CHECK: attributes [[NOUNWIND]] = { nounwind memory(read) }
353353

354-
// CHECK: ![[SWIFT_NAME_ALIAS_VAR]] = !DILocalVariable(name: "obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
355-
// CHECK: ![[LET_SWIFT_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
356-
// CHECK: ![[SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo14SwiftNameAliasaD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
354+
// CHECK-DAG: ![[SWIFT_NAME_ALIAS_VAR]] = !DILocalVariable(name: "obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 328, type: ![[LET_SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
355+
// CHECK-DAG: ![[LET_SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_NAME_ALIAS_TYPE:[0-9]+]])
356+
// CHECK-DAG: ![[SWIFT_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo14SwiftNameAliasaD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
357357

358-
// CHECK: ![[SWIFT_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
359-
// CHECK: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
360-
// CHECK: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo21SwiftGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
358+
// CHECK-DAG: ![[SWIFT_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
359+
// CHECK-DAG: ![[LET_SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
360+
// CHECK-DAG: ![[SWIFT_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo21SwiftGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
361361

362-
// CHECK: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "constr_generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
363-
// CHECK: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
364-
// CHECK: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo27SwiftConstrGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})
362+
// CHECK-DAG: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_VAR]] = !DILocalVariable(name: "constr_generic_obj", arg: 1, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
363+
// CHECK-DAG: ![[LET_SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE:[0-9]+]])
364+
// CHECK-DAG: ![[SWIFT_CONSTR_GENERIC_NAME_ALIAS_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$sSo27SwiftConstrGenericNameAliasaySo8NSNumberCGD", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, baseType: !{{[0-9]+}})

‎test/DebugInfo/BoundGenericStruct.swift

+1-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ public let s = S<Int>(t: 0)
1212
// CHECK: ![[INTPARAM]] = !DITemplateTypeParameter(type: ![[INT:[0-9]+]])
1313
// CHECK: ![[INT]] = !DICompositeType(tag: DW_TAG_structure_type, {{.*}}identifier: "$sSiD"
1414

15-
1615
// DWARF: !DICompositeType(tag: DW_TAG_structure_type,
1716
// DWARF-SAME: templateParams: ![[PARAMS:[0-9]+]]
1817
// DWARF-SAME: identifier: "$s18BoundGenericStruct1SVySiGD"
@@ -40,10 +39,7 @@ public let inner = S2<Double>.Inner(t:4.2)
4039
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
4140
// CHECK-SAME: flags: DIFlagFwdDecl, runtimeLang: DW_LANG_Swift)
4241

43-
// DWARF: !DICompositeType(tag: DW_TAG_structure_type, scope: ![[SCOPE1:[0-9]+]],
44-
// DWARF-SAME: size: 64, {{.*}}, templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD"
45-
// DWARF-SAME: specification: ![[SPECIFICATION:[0-9]+]]
46-
42+
// DWARF: !DICompositeType(tag: DW_TAG_structure_type, name: "Inner", scope: ![[SCOPE1:[0-9]+]],{{.*}} size: 64, {{.*}}, templateParams: ![[PARAMS2:[0-9]+]], identifier: "$s18BoundGenericStruct2S2V5InnerVySd_GD",{{.*}} specification: ![[SPECIFICATION:[0-9]+]]
4743
// DWARF: ![[SCOPE1]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s18BoundGenericStruct2S2VyxGD",
4844

4945
// DWARF: ![[PARAMS2]] = !{![[PARAMS3:[0-9]+]]}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -parse-as-library -module-name a -g -o - | %FileCheck %s
2+
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "$s1a10LocalAliasaD", {{.*}}baseType: ![[BASETY:[0-9]+]]
3+
// CHECK: ![[BASETY]]{{.*}}$sSbD
4+
public class MyClass<A, B> {}
5+
public typealias LocalAlias = Bool
6+
public typealias ClassAlias = MyClass<LocalAlias, Bool>
7+
public func use(cls: ClassAlias?) {}
8+

0 commit comments

Comments
 (0)