Skip to content

Commit 957db2c

Browse files
committed
[ClangImporter] Merge paths for std::span and __counted_by
importBoundsAttributes and importSpanAttributes are merged into a single function named swiftify. This allows us to not have to duplicate the effort of attaching _SwiftifyImport macros, but is also necessary to allow importing a function with both __counted_by and std::span types.
1 parent 84c30b5 commit 957db2c

File tree

6 files changed

+132
-145
lines changed

6 files changed

+132
-145
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 64 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
90118987
static bool isUsingMacroName(clang::SourceManager &SM,
90128988
clang::SourceLocation loc,
90138989
StringRef MacroName) {

0 commit comments

Comments
 (0)