Skip to content

Commit 9a7f5c8

Browse files
authored
Merge pull request #41569 from zoecarver/fix-class-template-metadata-issue
2 parents 7ad9d89 + 2749026 commit 9a7f5c8

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,14 @@ namespace {
11701170
// declaration's name as the ABI name.
11711171
} else if (auto clangDecl =
11721172
Mangle::ASTMangler::getClangDeclForMangling(Type)) {
1173-
abiName = clangDecl->getName();
1173+
// Class template specializations need to use their mangled name so
1174+
// that each specialization gets its own metadata. A class template
1175+
// specialization's Swift name will always be the mangled name, so just
1176+
// use that.
1177+
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(clangDecl))
1178+
abiName = Type->getName().str();
1179+
else
1180+
abiName = clangDecl->getName();
11741181

11751182
// Typedefs and compatibility aliases that have been promoted to
11761183
// their own nominal types need to be marked specially.

test/Interop/Cxx/templates/dependent-types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ DependentTypesTestSuite.test("Multiple dependent arguments (inferred type).") {
4343
}
4444

4545
DependentTypesTestSuite.test("Multiple dependent arguments (not inferred).") {
46-
let m = multipleDependentArgs(M<Int>(value: 42), M<CInt>(value: 0), T: Int.self, U: Int.self) as! M<Int>
46+
let m = multipleDependentArgs(M<Int>(value: 42), M<CInt>(value: 0), T: Int.self, U: CInt.self) as! M<Int>
4747
expectEqual(m.getValue(), 42)
4848
}
4949

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef TEST_INTEROP_CXX_VALUE_WITNESS_TABLE_INPUTS_CLASS_TEMPLATE_METADATA_H
2+
#define TEST_INTEROP_CXX_VALUE_WITNESS_TABLE_INPUTS_CLASS_TEMPLATE_METADATA_H
3+
4+
template<class T>
5+
struct ClassTemplate {};
6+
7+
using Spec1 = ClassTemplate<int>;
8+
using Spec2 = ClassTemplate<Spec1>;
9+
10+
#endif // TEST_INTEROP_CXX_VALUE_WITNESS_TABLE_INPUTS_CLASS_TEMPLATE_METADATA_H

test/Interop/Cxx/value-witness-table/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ module CopyConstructors {
1212
header "copy-constructors.h"
1313
requires cplusplus
1414
}
15+
16+
module ClassTemplateMetadata {
17+
header "class-template-metadata.h"
18+
requires cplusplus
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-cxx-interop)
2+
//
3+
// REQUIRES: executable_test
4+
5+
import ClassTemplateMetadata
6+
import StdlibUnittest
7+
8+
var ClassTemplateMetadataTestSuite = TestSuite("Class Template Metadata")
9+
10+
func cmpMetadata<T, U>(_ _: T, _ _: U) -> Bool { "\(T.self)" == "\(U.self)" }
11+
12+
ClassTemplateMetadataTestSuite.test("Different specializations of a class template have different metadata.") {
13+
let a = Spec1()
14+
let b = Spec2()
15+
16+
expectFalse(cmpMetadata(a, b))
17+
expectTrue(cmpMetadata(a, a))
18+
}
19+
20+
runAllTests()

0 commit comments

Comments
 (0)