@@ -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.
@@ -8909,7 +8901,7 @@ class SwiftifyInfoPrinter {
89098901};
89108902} // namespace
89118903
8912- void ClangImporter::Implementation::importSpanAttributes (FuncDecl *MappedDecl) {
8904+ void ClangImporter::Implementation::swiftify (FuncDecl *MappedDecl) {
89138905 if (!SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers))
89148906 return ;
89158907 auto ClangDecl =
@@ -8918,96 +8910,80 @@ void ClangImporter::Implementation::importSpanAttributes(FuncDecl *MappedDecl) {
89188910 return ;
89198911
89208912 llvm::SmallString<128 > MacroString;
8913+ // We only attach the macro if it will produce an overload. Any __counted_by
8914+ // will produce an overload, since UnsafeBufferPointer is still an improvement
8915+ // over UnsafePointer, but std::span will only produce an overload if it also
8916+ // has lifetime information, since std::span already contains bounds info.
89218917 bool attachMacro = false ;
89228918 {
89238919 llvm::raw_svector_ostream out (MacroString);
89248920 llvm::StringMap<std::string> typeMapping;
89258921
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 ;
8922+ auto registerStdSpanTypeMapping =
8923+ [&typeMapping](Type swiftType, const clang::QualType clangType) {
8924+ const auto *decl = clangType->getAsTagDecl ();
8925+ if (decl && decl->isInStdNamespace () && decl->getName () == " span" ) {
8926+ typeMapping.insert (
8927+ std::make_pair (swiftType->getString (),
8928+ swiftType->getDesugaredType ()->getString ()));
8929+ return true ;
8930+ }
8931+ return false ;
89338932 };
89348933 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 ()));
8934+ bool returnIsStdSpan = registerStdSpanTypeMapping (
8935+ MappedDecl->getResultInterfaceType (), ClangDecl->getReturnType ());
8936+ if (auto CAT =
8937+ ClangDecl->getReturnType ()->getAs <clang::CountAttributedType>()) {
8938+ printer.printCountedBy (CAT, -1 );
8939+ attachMacro = true ;
89448940 }
8941+ bool returnHasLifetimeInfo = false ;
89458942 bool lifetimeDependenceOn = MappedDecl->getASTContext ().LangOpts .hasFeature (
89468943 Feature::LifetimeDependence);
89478944 if (SwiftDeclConverter::getImplicitObjectParamAnnotation<
89488945 clang::LifetimeBoundAttr>(ClangDecl) &&
8949- lifetimeDependenceOn && returnIsSpan ) {
8946+ lifetimeDependenceOn) {
89508947 printer.printLifetimeboundReturn (-2 , true );
8951- attachMacro = true ;
8948+ returnHasLifetimeInfo = true ;
89528949 }
8953- for (auto [index, param] : llvm::enumerate (ClangDecl->parameters ())) {
8954- auto paramTy = param->getType ();
8955- const auto *decl = paramTy->getAsTagDecl ();
8950+ for (auto [index, clangParam] : llvm::enumerate (ClangDecl->parameters ())) {
8951+ auto clangParamTy = clangParam->getType ();
89568952 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);
8953+ bool paramHasBoundsInfo = false ;
8954+ if (auto CAT = clangParamTy->getAs <clang::CountAttributedType>()) {
8955+ printer.printCountedBy (CAT, index);
8956+ attachMacro = paramHasBoundsInfo = true ;
89648957 }
8965- if (!isSpan)
8966- continue ;
8967- if (param->hasAttr <clang::NoEscapeAttr>()) {
8958+ bool paramIsStdSpan = registerStdSpanTypeMapping (
8959+ swiftParam->getInterfaceType (), clangParamTy);
8960+ paramHasBoundsInfo |= paramIsStdSpan;
8961+
8962+ bool paramHasLifetimeInfo = false ;
8963+ if (clangParam->hasAttr <clang::NoEscapeAttr>()) {
89688964 printer.printNonEscaping (index);
8969- registerSwiftifyMacro (swiftParam, param) ;
8965+ paramHasLifetimeInfo = true ;
89708966 }
8967+ if (clangParam->hasAttr <clang::LifetimeBoundAttr>() &&
8968+ lifetimeDependenceOn) {
8969+ printer.printLifetimeboundReturn (
8970+ index, !paramHasBoundsInfo &&
8971+ swiftParam->getInterfaceType ()->isEscapable ());
8972+ paramHasLifetimeInfo = true ;
8973+ returnHasLifetimeInfo = true ;
8974+ }
8975+ if (paramIsStdSpan && paramHasLifetimeInfo)
8976+ attachMacro = true ;
89718977 }
8978+ if (returnIsStdSpan && returnHasLifetimeInfo)
8979+ attachMacro = true ;
89728980 printer.printTypeMapping (typeMapping);
89738981 }
89748982
89758983 if (attachMacro)
89768984 importNontrivialAttribute (MappedDecl, MacroString);
89778985}
89788986
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-
90118987static bool isUsingMacroName (clang::SourceManager &SM,
90128988 clang::SourceLocation loc,
90138989 StringRef MacroName) {
0 commit comments