[cxx-interop] Move incomplete template specialization check

We were only previously doing this check when we had a typedef,
because that is the scenario where we encountered this issue.

This patch moves the check closer to where we would actually instantiate
the template, so that these cases can be stopped in more situations.
This commit is contained in:
John Hui
2025-12-11 18:01:32 -08:00
parent ef9e3efaaf
commit bb5bb97958
3 changed files with 31 additions and 18 deletions

View File

@@ -1501,23 +1501,6 @@ namespace {
// or the original C type.
clang::QualType ClangType = Decl->getUnderlyingType();
// Prevent import of typedefs to forward-declared explicit template
// specializations, which would trigger assertion in Clang.
if (auto *templateSpec = dyn_cast<clang::TemplateSpecializationType>(
importer::desugarIfElaborated(ClangType).getTypePtr())) {
if (auto *recordType =
templateSpec->desugar()->getAs<clang::RecordType>()) {
if (auto *spec = dyn_cast<clang::ClassTemplateSpecializationDecl>(
recordType->getDecl())) {
if (spec->getSpecializationKind() ==
clang::TSK_ExplicitSpecialization &&
!spec->isCompleteDefinition()) {
return nullptr;
}
}
}
}
SwiftType = Impl.importTypeIgnoreIUO(
ClangType, ImportTypeKind::Typedef,
ImportDiagnosticAdder(Impl, Decl, Decl->getLocation()),
@@ -3346,6 +3329,15 @@ namespace {
decl->getName() == "_Expr" || decl->getName() == "__val_expr"))
return nullptr;
// Don't even try to specialize/import this template if it's
// a forward-declared specialization like this:
//
// template <> struct MyTemplate<int>;
//
if (decl->getSpecializationKind() == clang::TSK_ExplicitSpecialization &&
!decl->isCompleteDefinition())
return nullptr;
// `decl->getDefinition()` can return nullptr before the call to sema and
// return its definition afterwards.
clang::Sema &clangSema = Impl.getClangSema();