Skip to content

Commit 90e4a98

Browse files
authored
[cxx-interop] Use the name of the typedef when an unnamed class is used as a template argument (#76844)
This fixes a bug where IRGen would try to use the same name for two different protocol witness methods. rdar://134149098
1 parent c874e6f commit 90e4a98

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

lib/ClangImporter/ClangClassTemplateNamePrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ struct TemplateInstantiationNamePrinter
6666
std::string VisitRecordType(const clang::RecordType *type) {
6767
auto tagDecl = type->getAsTagDecl();
6868
if (auto namedArg = dyn_cast_or_null<clang::NamedDecl>(tagDecl)) {
69+
if (auto typeDefDecl = tagDecl->getTypedefNameForAnonDecl())
70+
namedArg = typeDefDecl;
6971
llvm::SmallString<128> storage;
7072
llvm::raw_svector_ostream buffer(storage);
7173
nameImporter->importName(namedArg, version, clang::DeclarationName())

test/Interop/Cxx/class/Inputs/protocol-conformance.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,21 @@ struct HasStaticOperatorCall {
7676
static int operator()(int x) { return x * 2; }
7777
};
7878

79+
typedef struct {
80+
int a;
81+
} Anon0;
82+
83+
typedef struct {
84+
int a;
85+
} Anon1;
86+
87+
template <class T>
88+
struct S {
89+
~S() {}
90+
int method0();
91+
};
92+
93+
using AnonType0 = S<Anon0>;
94+
using AnonType1 = S<Anon1>;
95+
7996
#endif // TEST_INTEROP_CXX_CLASS_INPUTS_PROTOCOL_CONFORMANCE_H

test/Interop/Cxx/class/protocol-conformance-irgen.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,39 @@ protocol HasReturn42 {
1111
// CHECK: [[OUT:%.*]] = call i32 @{{_ZN18ConformsToProtocol8return42Ev|"\?return42@ConformsToProtocol@@QEAAHXZ"}}(ptr
1212
// CHECK: ret i32 [[OUT]]
1313

14+
// CHECK: define hidden swiftcc i32 @"$sSo0014SAnon0_wuJCavaV4mainE7method0s5Int32VyF"(
15+
// CHECK: ret i32 123
16+
17+
// CHECK: define internal swiftcc i32 @"$sSo0014SAnon0_wuJCavaV4main1PA2cDP7method0s5Int32VyFTW"(
18+
// CHECK: %[[V1:.*]] = call swiftcc i32 @"$sSo0014SAnon0_wuJCavaV4mainE7method0s5Int32VyF"(
19+
// CHECK: ret i32 %[[V1]]
20+
21+
// CHECK: define hidden swiftcc i32 @"$sSo0014SAnon1_wuJCavaV4mainE7method0s5Int32VyF"(
22+
// CHECK: ret i32 234
23+
24+
// CHECK: define internal swiftcc i32 @"$sSo0014SAnon1_wuJCavaV4main1PA2cDP7method0s5Int32VyFTW"(
25+
// CHECK: %[[V1:.*]] = call swiftcc i32 @"$sSo0014SAnon1_wuJCavaV4mainE7method0s5Int32VyF"(
26+
// CHECK: ret i32 %[[V1]]
27+
1428
// CHECK: define {{.*}}%swift.metadata_response @"$sSo18ConformsToProtocolVMa"({{i64|i32}} [[ARG:%.*]])
1529
// CHECK: load ptr, ptr @"$sSo18ConformsToProtocolVML"
1630
// CHECK: call swiftcc %swift.metadata_response @swift_getForeignTypeMetadata({{i64|i32}} [[ARG]]
1731
// CHECK: ret %swift.metadata_response
1832

1933
extension ConformsToProtocol : HasReturn42 {}
34+
35+
protocol P {
36+
func method0() -> Int32
37+
}
38+
39+
extension AnonType0 : P {
40+
func method0() -> Int32 {
41+
return 123
42+
}
43+
}
44+
45+
extension AnonType1 : P {
46+
func method0() -> Int32 {
47+
return 234
48+
}
49+
}

0 commit comments

Comments
 (0)