@@ -3755,9 +3755,35 @@ namespace {
37553755 std::optional<ImportedName> correctSwiftName,
37563756 std::optional<AccessorInfo> accessorInfo,
37573757 const clang::FunctionTemplateDecl *funcTemplate = nullptr ) {
3758+
37583759 if (decl->isDeleted ())
37593760 return nullptr ;
37603761
3762+ // For now, we don't support non-subscript operators which are templated
3763+ bool isOperator = decl->getDeclName ().getNameKind () ==
3764+ clang::DeclarationName::CXXOperatorName;
3765+ bool isNonSubscriptOperator =
3766+ isOperator && (decl->getDeclName ().getCXXOverloadedOperator () !=
3767+ clang::OO_Subscript);
3768+ if (isNonSubscriptOperator && decl->isTemplated ())
3769+ return nullptr ;
3770+
3771+ if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
3772+ // Don't import copy constructor or move constructor -- these will be
3773+ // provided through the value witness table.
3774+ if (ctordecl->isCopyConstructor () || ctordecl->isMoveConstructor ())
3775+ return nullptr ;
3776+
3777+ // Don't import the generic ctors of std::span, rely on the ctors that
3778+ // we instantiate when conforming to the overlay. These generic ctors
3779+ // can cause crashes in codegen.
3780+ // FIXME: figure out why.
3781+ const auto *parent = ctordecl->getParent ();
3782+ if (funcTemplate && parent->isInStdNamespace () &&
3783+ parent->getIdentifier () && parent->getName () == " span" )
3784+ return nullptr ;
3785+ }
3786+
37613787 if (Impl.SwiftContext .LangOpts .EnableCXXInterop &&
37623788 !isa<clang::CXXMethodDecl>(decl)) {
37633789 // Do not import math functions from the C++ standard library, as
@@ -3796,56 +3822,10 @@ namespace {
37963822 }
37973823 }
37983824
3799- auto dc =
3800- Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
3801- if (!dc)
3802- return nullptr ;
3803-
3804- // We may have already imported this function decl before we imported the
3805- // parent record. In such a case it's important we don't re-import.
3806- auto known = Impl.ImportedDecls .find ({decl, getVersion ()});
3807- if (known != Impl.ImportedDecls .end ()) {
3808- return known->second ;
3809- }
3810-
3811- bool isOperator = decl->getDeclName ().getNameKind () ==
3812- clang::DeclarationName::CXXOperatorName;
3813- bool isNonSubscriptOperator =
3814- isOperator && (decl->getDeclName ().getCXXOverloadedOperator () !=
3815- clang::OO_Subscript);
3816-
3817- // For now, we don't support non-subscript operators which are templated
3818- if (isNonSubscriptOperator && decl->isTemplated ()) {
3819- return nullptr ;
3820- }
3821-
3822- DeclName name = accessorInfo ? DeclName () : importedName.getDeclName ();
3823- auto selfIdx = importedName.getSelfIndex ();
3824-
3825- auto templateParamTypeUsedInSignature =
3826- [decl](clang::TemplateTypeParmDecl *type) -> bool {
3827- // TODO(https://github.com/apple/swift/issues/56206): We will want to update this to handle dependent types when those are supported.
3828- if (hasSameUnderlyingType (decl->getReturnType ().getTypePtr (), type))
3829- return true ;
3830-
3831- for (unsigned i : range (0 , decl->getNumParams ())) {
3832- if (hasSameUnderlyingType (
3833- decl->getParamDecl (i)->getType ().getTypePtr (), type))
3834- return true ;
3835- }
3836-
3837- return false ;
3838- };
3839-
3840- ImportedType importedType;
3841- bool selfIsInOut = false ;
3842- ParameterList *bodyParams = nullptr ;
3843- GenericParamList *genericParams = nullptr ;
3844- SmallVector<GenericTypeParamDecl *, 4 > templateParams;
3825+ llvm::SmallSet<clang::NamedDecl *, 4 > unusedTemplateParams;
38453826 if (funcTemplate) {
3846- unsigned i = 0 ;
3847- for (auto param : *funcTemplate->getTemplateParameters ()) {
3848- auto templateTypeParam = cast<clang::TemplateTypeParmDecl>(param);
3827+ for (auto *param : *funcTemplate->getTemplateParameters ()) {
3828+ auto *templateTypeParam = cast<clang::TemplateTypeParmDecl>(param);
38493829 // If the template type parameter isn't used in the signature then we
38503830 // won't be able to deduce what it is when the function template is
38513831 // called in Swift code. This is OK if there's a defaulted type we can
@@ -3856,38 +3836,58 @@ namespace {
38563836 // If the defaulted template type parameter is used in the signature,
38573837 // then still add a generic so that it can be overrieded.
38583838 // TODO(https://github.com/apple/swift/issues/57184): In the future we might want to import two overloads in this case so that the default type could still be used.
3859- if (templateTypeParam->hasDefaultArgument () &&
3860- !templateParamTypeUsedInSignature (templateTypeParam)) {
3839+ auto usedInSignature = [&]() -> bool {
3840+ if (hasSameUnderlyingType (decl->getReturnType ().getTypePtr (),
3841+ templateTypeParam))
3842+ return true ;
3843+ for (unsigned i : range (0 , decl->getNumParams ())) {
3844+ if (hasSameUnderlyingType (
3845+ decl->getParamDecl (i)->getType ().getTypePtr (),
3846+ templateTypeParam))
3847+ return true ;
3848+ }
3849+ return false ;
3850+ };
3851+
3852+ if (templateTypeParam->hasDefaultArgument () && !usedInSignature ()) {
38613853 // We do not yet support instantiation of default values of template
38623854 // parameters when the function template is instantiated, so do not
38633855 // import the function template if the template parameter has
38643856 // dependent default value.
3865- auto &defaultArgument =
3866- templateTypeParam-> getDefaultArgument () .getArgument ();
3867- if (defaultArgument .isDependent ())
3857+ if (templateTypeParam-> getDefaultArgument ()
3858+ .getArgument ()
3859+ .isDependent ())
38683860 return nullptr ;
3869- continue ;
3861+ unusedTemplateParams. insert (param) ;
38703862 }
3871-
3872- auto *typeParam = Impl.createDeclWithClangNode <GenericTypeParamDecl>(
3873- param, AccessLevel::Public, dc,
3874- Impl.SwiftContext .getIdentifier (param->getName ()),
3875- /* nameLoc*/ Impl.importSourceLoc (param->getLocation ()),
3876- /* specifierLoc*/ SourceLoc (),
3877- /* depth*/ 0 , /* index*/ i, GenericTypeParamKind::Type);
3878- templateParams.push_back (typeParam);
3879- (void )++i;
38803863 }
3881- if (!templateParams.empty ())
3882- genericParams = GenericParamList::create (
3883- Impl.SwiftContext , SourceLoc (), templateParams, SourceLoc ());
3864+ }
3865+
3866+ auto dc =
3867+ Impl.importDeclContextOf (decl, importedName.getEffectiveContext ());
3868+ if (!dc)
3869+ return nullptr ;
3870+
3871+ // We may have already imported this function decl before we imported the
3872+ // parent record. In such a case it's important we don't re-import.
3873+ auto known = Impl.ImportedDecls .find ({decl, getVersion ()});
3874+ if (known != Impl.ImportedDecls .end ()) {
3875+ return known->second ;
3876+ }
3877+
3878+ DeclName name = accessorInfo ? DeclName () : importedName.getDeclName ();
3879+ auto selfIdx = importedName.getSelfIndex ();
3880+
3881+ if (auto *method = dyn_cast<clang::CXXMethodDecl>(decl);
3882+ method && method->isStatic () && name.getBaseName ().isConstructor ()) {
3883+ return importGlobalAsInitializer (
3884+ decl, name, dc, importedName.getInitKind (), correctSwiftName);
38843885 }
38853886
38863887 if (!dc->isModuleScopeContext () && !isClangNamespace (dc) &&
38873888 !isa<clang::CXXMethodDecl>(decl)) {
3888- // Handle initializers.
38893889 if (name.getBaseName ().isConstructor ()) {
3890- assert (!accessorInfo);
3890+ ASSERT (!accessorInfo && " accessor should not be constructor() " );
38913891 return importGlobalAsInitializer (decl, name, dc,
38923892 importedName.getInitKind (),
38933893 correctSwiftName);
@@ -3906,6 +3906,36 @@ namespace {
39063906 Impl.diagnose ({}, diag::note_while_importing, decl->getName ());
39073907 return nullptr ;
39083908 }
3909+ }
3910+
3911+ SmallVector<GenericTypeParamDecl *, 4 > templateParams;
3912+ if (funcTemplate) {
3913+ unsigned i = 0 ;
3914+ for (auto *param : *funcTemplate->getTemplateParameters ()) {
3915+ if (unusedTemplateParams.contains (param))
3916+ continue ;
3917+ auto *typeParam = Impl.createDeclWithClangNode <GenericTypeParamDecl>(
3918+ param, AccessLevel::Public, dc,
3919+ Impl.SwiftContext .getIdentifier (param->getName ()),
3920+ /* nameLoc*/ Impl.importSourceLoc (param->getLocation ()),
3921+ /* specifierLoc*/ SourceLoc (),
3922+ /* depth*/ 0 , /* index*/ i, GenericTypeParamKind::Type);
3923+ templateParams.push_back (typeParam);
3924+ (void )++i;
3925+ }
3926+ }
3927+ auto getGenericParams = [&]() -> GenericParamList * {
3928+ if (templateParams.empty ())
3929+ return nullptr ;
3930+ return GenericParamList::create (Impl.SwiftContext , SourceLoc (),
3931+ templateParams, SourceLoc ());
3932+ };
3933+
3934+ ImportedType resultType;
3935+ bool selfIsInOut = false ;
3936+ ParameterList *bodyParams = nullptr ;
3937+ if (!dc->isModuleScopeContext () && !isClangNamespace (dc) &&
3938+ !isa<clang::CXXMethodDecl>(decl)) {
39093939
39103940 // There is an inout 'self' when the parameter is a pointer to a
39113941 // non-const instance of the type we're importing onto. Importing this
@@ -3946,12 +3976,12 @@ namespace {
39463976 return nullptr ;
39473977
39483978 if (decl->getReturnType ()->isScalarType ())
3949- importedType =
3979+ resultType =
39503980 Impl.importFunctionReturnType (dc, decl, allowNSUIntegerAsInt);
39513981 } else {
39523982 // Import the function type. If we have parameters, make sure their
39533983 // names get into the resulting function type.
3954- importedType = Impl.importFunctionParamsAndReturnType (
3984+ resultType = Impl.importFunctionParamsAndReturnType (
39553985 dc, decl, {decl->param_begin (), decl->param_size ()},
39563986 decl->isVariadic (), isInSystemModule (dc), name, bodyParams,
39573987 templateParams);
@@ -3992,35 +4022,15 @@ namespace {
39924022 }
39934023
39944024 auto loc = Impl.importSourceLoc (decl->getLocation ());
4025+ // FIXME: Poor location info.
4026+ auto nameLoc = Impl.importSourceLoc (decl->getLocation ());
39954027
39964028 ClangNode clangNode = decl;
39974029 if (funcTemplate)
39984030 clangNode = funcTemplate;
39994031
4000- // FIXME: Poor location info.
4001- auto nameLoc = Impl.importSourceLoc (decl->getLocation ());
4002-
4003- if (auto method = dyn_cast<clang::CXXMethodDecl>(decl);
4004- method && method->isStatic () && name.getBaseName ().isConstructor ()) {
4005- return importGlobalAsInitializer (
4006- decl, name, dc, importedName.getInitKind (), correctSwiftName);
4007- }
40084032 AbstractFunctionDecl *result = nullptr ;
40094033 if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
4010- // Don't import copy constructor or move constructor -- these will be
4011- // provided through the value witness table.
4012- if (ctordecl->isCopyConstructor () || ctordecl->isMoveConstructor ())
4013- return nullptr ;
4014-
4015- // Don't import the generic ctors of std::span, rely on the ctors that
4016- // we instantiate when conforming to the overlay. These generic ctors
4017- // can cause crashes in codegen.
4018- // FIXME: figure out why.
4019- const auto *parent = ctordecl->getParent ();
4020- if (funcTemplate && parent->isInStdNamespace () &&
4021- parent->getIdentifier () && parent->getName () == " span" )
4022- return nullptr ;
4023-
40244034 DeclName ctorName (Impl.SwiftContext , DeclBaseName::createConstructor (),
40254035 bodyParams);
40264036 result = Impl.createDeclWithClangNode <ConstructorDecl>(
@@ -4029,20 +4039,18 @@ namespace {
40294039 /* failable=*/ false , /* FailabilityLoc=*/ SourceLoc (),
40304040 /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
40314041 /* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
4032- /* ThrownType=*/ TypeLoc (), bodyParams, genericParams , dc);
4042+ /* ThrownType=*/ TypeLoc (), bodyParams, getGenericParams () , dc);
40334043 } else {
4034- auto resultTy = importedType.getType ();
4035-
4036- FuncDecl *func = createFuncOrAccessor (
4037- Impl, loc, accessorInfo, name, nameLoc, genericParams, bodyParams,
4038- resultTy,
4044+ auto *func = createFuncOrAccessor (
4045+ Impl, loc, accessorInfo, name, nameLoc, getGenericParams (),
4046+ bodyParams, resultType.getType (),
40394047 /* async=*/ false , /* throws=*/ false , dc, clangNode);
40404048 result = func;
40414049
40424050 if (!dc->isModuleScopeContext ()) {
4043- if (selfIsInOut)
4051+ if (selfIsInOut) {
40444052 func->setSelfAccessKind (SelfAccessKind::Mutating);
4045- else {
4053+ } else {
40464054 if (getImplicitObjectParamAnnotation<clang::LifetimeBoundAttr>(
40474055 decl))
40484056 func->setSelfAccessKind (SelfAccessKind::Borrowing);
@@ -4075,7 +4083,7 @@ namespace {
40754083 result->setIsDynamic (false );
40764084
40774085 Impl.recordImplicitUnwrapForDecl (result,
4078- importedType .isImplicitlyUnwrapped ());
4086+ resultType .isImplicitlyUnwrapped ());
40794087
40804088 if (dc->getSelfClassDecl ())
40814089 // FIXME: only if the class itself is not marked final
0 commit comments