Skip to content

Commit b3ac2f8

Browse files
authored
Merge pull request #60248 from apple/egorzhdan/cxx-template-inst-missing
[cxx-interop] Make sure to print template instantiations in the module interface
2 parents 7f41010 + 900ca68 commit b3ac2f8

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,22 +1927,35 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table,
19271927
// possible to find these decls during deserialization. For any C++ typedef
19281928
// that defines a name for a class template instantiation (e.g. std::string),
19291929
// import the mangled name of this instantiation, and add it to the table.
1930+
auto addTemplateSpecialization =
1931+
[&](clang::ClassTemplateSpecializationDecl *specializationDecl) {
1932+
auto name = nameImporter.importName(specializationDecl, currentVersion);
1933+
1934+
// Avoid adding duplicate entries into the table.
1935+
auto existingEntries =
1936+
table.lookup(DeclBaseName(name.getDeclName().getBaseName()),
1937+
name.getEffectiveContext());
1938+
if (existingEntries.empty()) {
1939+
table.addEntry(name.getDeclName(), specializationDecl,
1940+
name.getEffectiveContext());
1941+
}
1942+
};
19301943
if (auto typedefNameDecl = dyn_cast<clang::TypedefNameDecl>(named)) {
19311944
auto underlyingDecl = typedefNameDecl->getUnderlyingType()->getAsTagDecl();
19321945

19331946
if (auto specializationDecl =
19341947
dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(
19351948
underlyingDecl)) {
1936-
auto name = nameImporter.importName(specializationDecl, currentVersion);
1937-
1938-
// Avoid adding duplicate entries into the table.
1939-
auto existingEntries =
1940-
table.lookup(DeclBaseName(name.getDeclName().getBaseName()),
1941-
name.getEffectiveContext());
1942-
if (existingEntries.empty()) {
1943-
table.addEntry(name.getDeclName(), specializationDecl,
1944-
name.getEffectiveContext());
1945-
}
1949+
addTemplateSpecialization(specializationDecl);
1950+
}
1951+
}
1952+
if (auto valueDecl = dyn_cast<clang::ValueDecl>(named)) {
1953+
auto valueTypeDecl = valueDecl->getType()->getAsTagDecl();
1954+
1955+
if (auto specializationDecl =
1956+
dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(
1957+
valueTypeDecl)) {
1958+
addTemplateSpecialization(specializationDecl);
19461959
}
19471960
}
19481961

test/Interop/Cxx/templates/Inputs/member-templates.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,11 @@ struct HasStaticMemberTemplates {
4343
template <class T> static T removeReference(T &a) { return a; }
4444
};
4545

46+
template <typename T>
47+
struct MyTemplatedStruct {};
48+
49+
struct HasTemplatedField {
50+
MyTemplatedStruct<int> x;
51+
};
52+
4653
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_MEMBER_TEMPLATES_H

test/Interop/Cxx/templates/member-templates-module-interface.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,12 @@
2626
// CHECK: static func addTwoTemplates<T, U>(_ a: T, _ b: U) -> T
2727
// CHECK: static func removeReference<T>(_ a: inout T) -> T
2828
// CHECK: }
29+
30+
// CHECK: struct __CxxTemplateInst17MyTemplatedStructIiE {
31+
// CHECK: init()
32+
// CHECK: }
33+
34+
// CHECK: struct HasTemplatedField {
35+
// CHECK: init(x: __CxxTemplateInst17MyTemplatedStructIiE)
36+
// CHECK: var x: __CxxTemplateInst17MyTemplatedStructIiE
37+
// CHECK: }

0 commit comments

Comments
 (0)