@@ -114,8 +114,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
114114 std::optional<AccessorInfo> accessorInfo, DeclName name,
115115 SourceLoc nameLoc, GenericParamList *genericParams,
116116 ParameterList *bodyParams, Type resultTy, bool async,
117- bool throws, DeclContext *dc, ClangNode clangNode,
118- bool hasBoundsAnnotation) {
117+ bool throws, DeclContext *dc, ClangNode clangNode) {
119118 FuncDecl *decl;
120119 if (accessorInfo) {
121120 decl = AccessorDecl::create (
@@ -131,9 +130,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
131130 genericParams, dc, clangNode);
132131 }
133132 impl.importSwiftAttrAttributes (decl);
134- if (hasBoundsAnnotation)
135- impl.importBoundsAttributes (decl);
136- impl.importSpanAttributes (decl);
133+ impl.swiftify (decl);
137134
138135 return decl;
139136}
@@ -3381,8 +3378,7 @@ namespace {
33813378 }
33823379 return Impl.importFunctionParameterList (
33833380 dc, decl, nonSelfParams, decl->isVariadic (), allowNSUIntegerAsInt,
3384- argNames, genericParams, /* resultType=*/ nullptr ,
3385- /* hasBoundsAnnotatedParam=*/ nullptr );
3381+ argNames, genericParams, /* resultType=*/ nullptr );
33863382 }
33873383
33883384 Decl *
@@ -3812,7 +3808,6 @@ namespace {
38123808
38133809 bool importFuncWithoutSignature =
38143810 isa<clang::CXXMethodDecl>(decl) && Impl.importSymbolicCXXDecls ;
3815- bool hasBoundsAnnotation = false ;
38163811 if (!dc->isModuleScopeContext () && !isa<clang::CXXMethodDecl>(decl)) {
38173812 // Handle initializers.
38183813 if (name.getBaseName ().isConstructor ()) {
@@ -3909,7 +3904,7 @@ namespace {
39093904 importedType = Impl.importFunctionParamsAndReturnType (
39103905 dc, decl, {decl->param_begin (), decl->param_size ()},
39113906 decl->isVariadic (), isInSystemModule (dc), name, bodyParams,
3912- templateParams, &hasBoundsAnnotation );
3907+ templateParams);
39133908 }
39143909
39153910 if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
@@ -3975,11 +3970,10 @@ namespace {
39753970 } else {
39763971 auto resultTy = importedType.getType ();
39773972
3978- FuncDecl *func =
3979- createFuncOrAccessor (Impl, loc, accessorInfo, name, nameLoc,
3980- genericParams, bodyParams, resultTy,
3981- /* async=*/ false , /* throws=*/ false , dc,
3982- clangNode, hasBoundsAnnotation);
3973+ FuncDecl *func = createFuncOrAccessor (
3974+ Impl, loc, accessorInfo, name, nameLoc, genericParams, bodyParams,
3975+ resultTy,
3976+ /* async=*/ false , /* throws=*/ false , dc, clangNode);
39833977 result = func;
39843978
39853979 if (!dc->isModuleScopeContext ()) {
@@ -5068,14 +5062,12 @@ namespace {
50685062 }
50695063 }
50705064
5071- bool hasBoundsAnnotation =
5072- false ; // currently only implemented for functions
5073- auto result = createFuncOrAccessor (
5074- Impl,
5075- /* funcLoc*/ SourceLoc (), accessorInfo, importedName.getDeclName (),
5076- /* nameLoc*/ SourceLoc (),
5077- /* genericParams=*/ nullptr , bodyParams, resultTy, async, throws, dc,
5078- decl, hasBoundsAnnotation);
5065+ auto result = createFuncOrAccessor (Impl,
5066+ /* funcLoc*/ SourceLoc (), accessorInfo,
5067+ importedName.getDeclName (),
5068+ /* nameLoc*/ SourceLoc (),
5069+ /* genericParams=*/ nullptr , bodyParams,
5070+ resultTy, async, throws, dc, decl);
50795071
50805072 result->setAccess (decl->isDirectMethod () ? AccessLevel::Public
50815073 : getOverridableAccessLevel (dc));
@@ -6737,7 +6729,7 @@ Decl *SwiftDeclConverter::importGlobalAsInitializer(
67376729 parameterList = Impl.importFunctionParameterList (
67386730 dc, decl, {decl->param_begin (), decl->param_end ()}, decl->isVariadic (),
67396731 allowNSUIntegerAsInt, argNames, /* genericParams=*/ {},
6740- /* resultType=*/ nullptr , /* hasBoundsAnnotatedParam= */ nullptr );
6732+ /* resultType=*/ nullptr );
67416733
67426734 if (name && parameterList && argNames.size () != parameterList->size ()) {
67436735 // Remember that the name has changed.
@@ -8828,6 +8820,8 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
88288820namespace {
88298821class SwiftifyInfoPrinter {
88308822public:
8823+ static const ssize_t SELF_PARAM_INDEX = -2 ;
8824+ static const ssize_t RETURN_VALUE_INDEX = -1 ;
88318825 clang::ASTContext &ctx;
88328826 llvm::raw_ostream &out;
88338827 bool firstParam = true ;
@@ -8899,17 +8893,17 @@ class SwiftifyInfoPrinter {
88998893 }
89008894
89018895 void printParamOrReturn (ssize_t pointerIndex) {
8902- if (pointerIndex == - 2 )
8896+ if (pointerIndex == SELF_PARAM_INDEX )
89038897 out << " .self" ;
8904- else if (pointerIndex == - 1 )
8898+ else if (pointerIndex == RETURN_VALUE_INDEX )
89058899 out << " .return" ;
89068900 else
89078901 out << " .param(" << pointerIndex + 1 << " )" ;
89088902 }
89098903};
89108904} // namespace
89118905
8912- void ClangImporter::Implementation::importSpanAttributes (FuncDecl *MappedDecl) {
8906+ void ClangImporter::Implementation::swiftify (FuncDecl *MappedDecl) {
89138907 if (!SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers))
89148908 return ;
89158909 auto ClangDecl =
@@ -8918,96 +8912,81 @@ void ClangImporter::Implementation::importSpanAttributes(FuncDecl *MappedDecl) {
89188912 return ;
89198913
89208914 llvm::SmallString<128 > MacroString;
8915+ // We only attach the macro if it will produce an overload. Any __counted_by
8916+ // will produce an overload, since UnsafeBufferPointer is still an improvement
8917+ // over UnsafePointer, but std::span will only produce an overload if it also
8918+ // has lifetime information, since std::span already contains bounds info.
89218919 bool attachMacro = false ;
89228920 {
89238921 llvm::raw_svector_ostream out (MacroString);
89248922 llvm::StringMap<std::string> typeMapping;
89258923
8926- auto registerSwiftifyMacro =
8927- [&typeMapping, &attachMacro](ParamDecl *swiftParam,
8928- const clang::ParmVarDecl *param) {
8929- typeMapping.insert (std::make_pair (
8930- swiftParam->getInterfaceType ()->getString (),
8931- swiftParam->getInterfaceType ()->getDesugaredType ()->getString ()));
8932- attachMacro = true ;
8924+ auto registerStdSpanTypeMapping =
8925+ [&typeMapping](Type swiftType, const clang::QualType clangType) {
8926+ const auto *decl = clangType->getAsTagDecl ();
8927+ if (decl && decl->isInStdNamespace () && decl->getName () == " span" ) {
8928+ typeMapping.insert (
8929+ std::make_pair (swiftType->getString (),
8930+ swiftType->getDesugaredType ()->getString ()));
8931+ return true ;
8932+ }
8933+ return false ;
89338934 };
89348935 SwiftifyInfoPrinter printer (getClangASTContext (), out);
8935- auto retDecl = ClangDecl->getReturnType ()->getAsTagDecl ();
8936- bool returnIsSpan =
8937- retDecl && retDecl->isInStdNamespace () && retDecl->getName () == " span" ;
8938- if (returnIsSpan) {
8939- typeMapping.insert (
8940- std::make_pair (MappedDecl->getResultInterfaceType ()->getString (),
8941- MappedDecl->getResultInterfaceType ()
8942- ->getDesugaredType ()
8943- ->getString ()));
8944- }
8945- bool lifetimeDependenceOn = MappedDecl->getASTContext ().LangOpts .hasFeature (
8946- Feature::LifetimeDependence);
8936+ bool returnIsStdSpan = registerStdSpanTypeMapping (
8937+ MappedDecl->getResultInterfaceType (), ClangDecl->getReturnType ());
8938+ if (auto CAT =
8939+ ClangDecl->getReturnType ()->getAs <clang::CountAttributedType>()) {
8940+ printer.printCountedBy (CAT, SwiftifyInfoPrinter::RETURN_VALUE_INDEX);
8941+ attachMacro = true ;
8942+ }
8943+ bool returnHasLifetimeInfo = false ;
8944+ bool lifetimeDependenceOn =
8945+ SwiftContext.LangOpts .hasFeature (Feature::LifetimeDependence);
89478946 if (SwiftDeclConverter::getImplicitObjectParamAnnotation<
89488947 clang::LifetimeBoundAttr>(ClangDecl) &&
8949- lifetimeDependenceOn && returnIsSpan) {
8950- printer.printLifetimeboundReturn (-2 , true );
8951- attachMacro = true ;
8948+ lifetimeDependenceOn) {
8949+ printer.printLifetimeboundReturn (SwiftifyInfoPrinter::SELF_PARAM_INDEX,
8950+ true );
8951+ returnHasLifetimeInfo = true ;
89528952 }
8953- for (auto [index, param] : llvm::enumerate (ClangDecl->parameters ())) {
8954- auto paramTy = param->getType ();
8955- const auto *decl = paramTy->getAsTagDecl ();
8953+ for (auto [index, clangParam] : llvm::enumerate (ClangDecl->parameters ())) {
8954+ auto clangParamTy = clangParam->getType ();
89568955 auto swiftParam = MappedDecl->getParameters ()->get (index);
8957- bool isSpan =
8958- decl && decl->isInStdNamespace () && decl->getName () == " span" ;
8959- if (param->hasAttr <clang::LifetimeBoundAttr>() && lifetimeDependenceOn &&
8960- (isSpan || returnIsSpan)) {
8961- printer.printLifetimeboundReturn (
8962- index, !isSpan && swiftParam->getInterfaceType ()->isEscapable ());
8963- registerSwiftifyMacro (swiftParam, param);
8956+ bool paramHasBoundsInfo = false ;
8957+ if (auto CAT = clangParamTy->getAs <clang::CountAttributedType>()) {
8958+ printer.printCountedBy (CAT, index);
8959+ attachMacro = paramHasBoundsInfo = true ;
89648960 }
8965- if (!isSpan)
8966- continue ;
8967- if (param->hasAttr <clang::NoEscapeAttr>()) {
8961+ bool paramIsStdSpan = registerStdSpanTypeMapping (
8962+ swiftParam->getInterfaceType (), clangParamTy);
8963+ paramHasBoundsInfo |= paramIsStdSpan;
8964+
8965+ bool paramHasLifetimeInfo = false ;
8966+ if (clangParam->hasAttr <clang::NoEscapeAttr>()) {
89688967 printer.printNonEscaping (index);
8969- registerSwiftifyMacro (swiftParam, param) ;
8968+ paramHasLifetimeInfo = true ;
89708969 }
8970+ if (clangParam->hasAttr <clang::LifetimeBoundAttr>() &&
8971+ lifetimeDependenceOn) {
8972+ printer.printLifetimeboundReturn (
8973+ index, !paramHasBoundsInfo &&
8974+ swiftParam->getInterfaceType ()->isEscapable ());
8975+ paramHasLifetimeInfo = true ;
8976+ returnHasLifetimeInfo = true ;
8977+ }
8978+ if (paramIsStdSpan && paramHasLifetimeInfo)
8979+ attachMacro = true ;
89718980 }
8981+ if (returnIsStdSpan && returnHasLifetimeInfo)
8982+ attachMacro = true ;
89728983 printer.printTypeMapping (typeMapping);
89738984 }
89748985
89758986 if (attachMacro)
89768987 importNontrivialAttribute (MappedDecl, MacroString);
89778988}
89788989
8979- void ClangImporter::Implementation::importBoundsAttributes (
8980- FuncDecl *MappedDecl) {
8981- assert (SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers));
8982- auto ClangDecl =
8983- dyn_cast_or_null<clang::FunctionDecl>(MappedDecl->getClangDecl ());
8984- // any function with safe pointer imports should have a clang decl
8985- assert (ClangDecl);
8986- if (!ClangDecl)
8987- return ;
8988-
8989- llvm::SmallString<128 > MacroString;
8990- {
8991- llvm::raw_svector_ostream out (MacroString);
8992-
8993- SwiftifyInfoPrinter printer (getClangASTContext (), out);
8994- for (auto [index, param] : llvm::enumerate (ClangDecl->parameters ())) {
8995- if (auto CAT = param->getType ()->getAs <clang::CountAttributedType>()) {
8996- printer.printCountedBy (CAT, index);
8997- if (param->hasAttr <clang::NoEscapeAttr>()) {
8998- printer.printNonEscaping (index);
8999- }
9000- }
9001- }
9002- if (auto CAT =
9003- ClangDecl->getReturnType ()->getAs <clang::CountAttributedType>()) {
9004- printer.printCountedBy (CAT, -1 );
9005- }
9006- }
9007-
9008- importNontrivialAttribute (MappedDecl, MacroString);
9009- }
9010-
90118990static bool isUsingMacroName (clang::SourceManager &SM,
90128991 clang::SourceLocation loc,
90138992 StringRef MacroName) {
0 commit comments