@@ -114,8 +114,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
114
114
std::optional<AccessorInfo> accessorInfo, DeclName name,
115
115
SourceLoc nameLoc, GenericParamList *genericParams,
116
116
ParameterList *bodyParams, Type resultTy, bool async,
117
- bool throws, DeclContext *dc, ClangNode clangNode,
118
- bool hasBoundsAnnotation) {
117
+ bool throws, DeclContext *dc, ClangNode clangNode) {
119
118
FuncDecl *decl;
120
119
if (accessorInfo) {
121
120
decl = AccessorDecl::create (
@@ -131,9 +130,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
131
130
genericParams, dc, clangNode);
132
131
}
133
132
impl.importSwiftAttrAttributes (decl);
134
- if (hasBoundsAnnotation)
135
- impl.importBoundsAttributes (decl);
136
- impl.importSpanAttributes (decl);
133
+ impl.swiftify (decl);
137
134
138
135
return decl;
139
136
}
@@ -3381,8 +3378,7 @@ namespace {
3381
3378
}
3382
3379
return Impl.importFunctionParameterList (
3383
3380
dc, decl, nonSelfParams, decl->isVariadic (), allowNSUIntegerAsInt,
3384
- argNames, genericParams, /* resultType=*/ nullptr ,
3385
- /* hasBoundsAnnotatedParam=*/ nullptr );
3381
+ argNames, genericParams, /* resultType=*/ nullptr );
3386
3382
}
3387
3383
3388
3384
Decl *
@@ -3812,7 +3808,6 @@ namespace {
3812
3808
3813
3809
bool importFuncWithoutSignature =
3814
3810
isa<clang::CXXMethodDecl>(decl) && Impl.importSymbolicCXXDecls ;
3815
- bool hasBoundsAnnotation = false ;
3816
3811
if (!dc->isModuleScopeContext () && !isa<clang::CXXMethodDecl>(decl)) {
3817
3812
// Handle initializers.
3818
3813
if (name.getBaseName ().isConstructor ()) {
@@ -3909,7 +3904,7 @@ namespace {
3909
3904
importedType = Impl.importFunctionParamsAndReturnType (
3910
3905
dc, decl, {decl->param_begin (), decl->param_size ()},
3911
3906
decl->isVariadic (), isInSystemModule (dc), name, bodyParams,
3912
- templateParams, &hasBoundsAnnotation );
3907
+ templateParams);
3913
3908
}
3914
3909
3915
3910
if (auto *mdecl = dyn_cast<clang::CXXMethodDecl>(decl)) {
@@ -3975,11 +3970,10 @@ namespace {
3975
3970
} else {
3976
3971
auto resultTy = importedType.getType ();
3977
3972
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);
3983
3977
result = func;
3984
3978
3985
3979
if (!dc->isModuleScopeContext ()) {
@@ -5068,14 +5062,12 @@ namespace {
5068
5062
}
5069
5063
}
5070
5064
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);
5079
5071
5080
5072
result->setAccess (decl->isDirectMethod () ? AccessLevel::Public
5081
5073
: getOverridableAccessLevel (dc));
@@ -6737,7 +6729,7 @@ Decl *SwiftDeclConverter::importGlobalAsInitializer(
6737
6729
parameterList = Impl.importFunctionParameterList (
6738
6730
dc, decl, {decl->param_begin (), decl->param_end ()}, decl->isVariadic (),
6739
6731
allowNSUIntegerAsInt, argNames, /* genericParams=*/ {},
6740
- /* resultType=*/ nullptr , /* hasBoundsAnnotatedParam= */ nullptr );
6732
+ /* resultType=*/ nullptr );
6741
6733
6742
6734
if (name && parameterList && argNames.size () != parameterList->size ()) {
6743
6735
// Remember that the name has changed.
@@ -8828,6 +8820,8 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
8828
8820
namespace {
8829
8821
class SwiftifyInfoPrinter {
8830
8822
public:
8823
+ static const ssize_t SELF_PARAM_INDEX = -2 ;
8824
+ static const ssize_t RETURN_VALUE_INDEX = -1 ;
8831
8825
clang::ASTContext &ctx;
8832
8826
llvm::raw_ostream &out;
8833
8827
bool firstParam = true ;
@@ -8899,17 +8893,17 @@ class SwiftifyInfoPrinter {
8899
8893
}
8900
8894
8901
8895
void printParamOrReturn (ssize_t pointerIndex) {
8902
- if (pointerIndex == - 2 )
8896
+ if (pointerIndex == SELF_PARAM_INDEX )
8903
8897
out << " .self" ;
8904
- else if (pointerIndex == - 1 )
8898
+ else if (pointerIndex == RETURN_VALUE_INDEX )
8905
8899
out << " .return" ;
8906
8900
else
8907
8901
out << " .param(" << pointerIndex + 1 << " )" ;
8908
8902
}
8909
8903
};
8910
8904
} // namespace
8911
8905
8912
- void ClangImporter::Implementation::importSpanAttributes (FuncDecl *MappedDecl) {
8906
+ void ClangImporter::Implementation::swiftify (FuncDecl *MappedDecl) {
8913
8907
if (!SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers))
8914
8908
return ;
8915
8909
auto ClangDecl =
@@ -8918,96 +8912,81 @@ void ClangImporter::Implementation::importSpanAttributes(FuncDecl *MappedDecl) {
8918
8912
return ;
8919
8913
8920
8914
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.
8921
8919
bool attachMacro = false ;
8922
8920
{
8923
8921
llvm::raw_svector_ostream out (MacroString);
8924
8922
llvm::StringMap<std::string> typeMapping;
8925
8923
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 ;
8933
8934
};
8934
8935
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);
8947
8946
if (SwiftDeclConverter::getImplicitObjectParamAnnotation<
8948
8947
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 ;
8952
8952
}
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 ();
8956
8955
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 ;
8964
8960
}
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>()) {
8968
8967
printer.printNonEscaping (index);
8969
- registerSwiftifyMacro (swiftParam, param) ;
8968
+ paramHasLifetimeInfo = true ;
8970
8969
}
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 ;
8971
8980
}
8981
+ if (returnIsStdSpan && returnHasLifetimeInfo)
8982
+ attachMacro = true ;
8972
8983
printer.printTypeMapping (typeMapping);
8973
8984
}
8974
8985
8975
8986
if (attachMacro)
8976
8987
importNontrivialAttribute (MappedDecl, MacroString);
8977
8988
}
8978
8989
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
-
9011
8990
static bool isUsingMacroName (clang::SourceManager &SM,
9012
8991
clang::SourceLocation loc,
9013
8992
StringRef MacroName) {
0 commit comments