6060#include " clang/AST/Decl.h"
6161#include " clang/AST/DeclCXX.h"
6262#include " clang/AST/DeclObjCCommon.h"
63+ #include " clang/AST/PrettyPrinter.h"
6364#include " clang/AST/Type.h"
6465#include " clang/Basic/Specifiers.h"
6566#include " clang/Basic/TargetInfo.h"
7172#include " llvm/ADT/SmallString.h"
7273#include " llvm/ADT/Statistic.h"
7374#include " llvm/ADT/StringExtras.h"
75+ #include " llvm/ADT/StringMap.h"
7476#include " llvm/ADT/StringSwitch.h"
7577#include " llvm/Support/Path.h"
7678
7779#include < algorithm>
80+ #include < utility>
7881
7982#define DEBUG_TYPE " Clang module importer"
8083
@@ -130,6 +133,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
130133 impl.importSwiftAttrAttributes (decl);
131134 if (hasBoundsAnnotation)
132135 impl.importBoundsAttributes (decl);
136+ impl.importSpanAttributes (decl);
133137
134138 return decl;
135139}
@@ -8685,11 +8689,7 @@ class SwiftifyInfoPrinter {
86858689
86868690 void printCountedBy (const clang::CountAttributedType *CAT,
86878691 size_t pointerIndex) {
8688- if (!firstParam) {
8689- out << " , " ;
8690- } else {
8691- firstParam = false ;
8692- }
8692+ printSeparator ();
86938693 clang::Expr *countExpr = CAT->getCountExpr ();
86948694 bool isSizedBy = CAT->isCountInBytes ();
86958695 out << " ." ;
@@ -8707,9 +8707,76 @@ class SwiftifyInfoPrinter {
87078707 out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
87088708 out << " \" )" ;
87098709 }
8710+
8711+ void printNonEscaping (int idx) {
8712+ printSeparator ();
8713+ out << " .nonescaping(pointer: " << idx << " )" ;
8714+ }
8715+
8716+ void printTypeMapping (const llvm::StringMap<std::string> &mapping) {
8717+ printSeparator ();
8718+ out << " typeMappings: [" ;
8719+ if (mapping.empty ()) {
8720+ out << " :]" ;
8721+ return ;
8722+ }
8723+ llvm::interleaveComma (mapping, out, [&](const auto &entry) {
8724+ out << ' "' << entry.getKey () << " \" : \" " << entry.getValue () << ' "' ;
8725+ });
8726+ out << " ]" ;
8727+ }
8728+
8729+ private:
8730+ void printSeparator () {
8731+ if (!firstParam) {
8732+ out << " , " ;
8733+ } else {
8734+ firstParam = false ;
8735+ }
8736+ }
87108737};
87118738} // namespace
87128739
8740+ void ClangImporter::Implementation::importSpanAttributes (FuncDecl *MappedDecl) {
8741+ if (!SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers))
8742+ return ;
8743+ auto ClangDecl =
8744+ dyn_cast_or_null<clang::FunctionDecl>(MappedDecl->getClangDecl ());
8745+ if (!ClangDecl)
8746+ return ;
8747+
8748+ llvm::SmallString<128 > MacroString;
8749+ bool attachMacro = false ;
8750+ {
8751+ llvm::raw_svector_ostream out (MacroString);
8752+ llvm::StringMap<std::string> typeMapping;
8753+
8754+ SwiftifyInfoPrinter printer (getClangASTContext (), out);
8755+ for (auto [index, param] : llvm::enumerate (ClangDecl->parameters ())) {
8756+ auto paramTy = param->getType ();
8757+ const auto *decl = paramTy->getAsTagDecl ();
8758+ if (!decl || !decl->isInStdNamespace ())
8759+ continue ;
8760+ if (decl->getName () != " span" )
8761+ continue ;
8762+ if (param->hasAttr <clang::NoEscapeAttr>()) {
8763+ printer.printNonEscaping (index + 1 );
8764+ clang::PrintingPolicy policy (param->getASTContext ().getLangOpts ());
8765+ policy.SuppressTagKeyword = true ;
8766+ auto param = MappedDecl->getParameters ()->get (index);
8767+ typeMapping.insert (std::make_pair (
8768+ paramTy.getAsString (policy),
8769+ param->getInterfaceType ()->getDesugaredType ()->getString ()));
8770+ attachMacro = true ;
8771+ }
8772+ }
8773+ printer.printTypeMapping (typeMapping);
8774+ }
8775+
8776+ if (attachMacro)
8777+ importNontrivialAttribute (MappedDecl, MacroString);
8778+ }
8779+
87138780void ClangImporter::Implementation::importBoundsAttributes (
87148781 FuncDecl *MappedDecl) {
87158782 assert (SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers));
0 commit comments