Skip to content

Commit 4820838

Browse files
authored
Merge pull request #58543 from apple/egorzhdan/cxx-template-inst-lookup
[cxx-interop] Fix lookup of class template instantiations
2 parents 51edb8f + c952fc1 commit 4820838

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4330,9 +4330,15 @@ ClangDirectLookupRequest::evaluate(Evaluator &evaluator,
43304330
if (auto spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(clangDecl))
43314331
return lookupInClassTemplateSpecialization(ctx, spec, desc.name);
43324332

4333-
auto *clangModule =
4334-
getClangOwningModule(clangDecl, clangDecl->getASTContext());
4335-
auto *lookupTable = ctx.getClangModuleLoader()->findLookupTable(clangModule);
4333+
SwiftLookupTable *lookupTable = nullptr;
4334+
if (isa<clang::NamespaceDecl>(clangDecl)) {
4335+
// DeclContext of a namespace imported into Swift is the __ObjC module.
4336+
lookupTable = ctx.getClangModuleLoader()->findLookupTable(nullptr);
4337+
} else {
4338+
auto *clangModule =
4339+
getClangOwningModule(clangDecl, clangDecl->getASTContext());
4340+
lookupTable = ctx.getClangModuleLoader()->findLookupTable(clangModule);
4341+
}
43364342

43374343
auto foundDecls = lookupTable->lookup(
43384344
SerializedSwiftName(desc.name.getBaseName()), EffectiveClangContext());

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,6 +1922,30 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table,
19221922
}
19231923
}
19241924

1925+
// Class template instantiations are imported lazily, however, the lookup
1926+
// table must include their mangled name (__CxxTemplateInst...) to make it
1927+
// possible to find these decls during deserialization. For any C++ typedef
1928+
// that defines a name for a class template instantiation (e.g. std::string),
1929+
// import the mangled name of this instantiation, and add it to the table.
1930+
if (auto typedefNameDecl = dyn_cast<clang::TypedefNameDecl>(named)) {
1931+
auto underlyingDecl = typedefNameDecl->getUnderlyingType()->getAsTagDecl();
1932+
1933+
if (auto specializationDecl =
1934+
dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(
1935+
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+
}
1946+
}
1947+
}
1948+
19251949
// Walk the members of any context that can have nested members.
19261950
if (isa<clang::TagDecl>(named) || isa<clang::ObjCInterfaceDecl>(named) ||
19271951
isa<clang::ObjCProtocolDecl>(named) ||

0 commit comments

Comments
 (0)