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}
@@ -8698,11 +8702,7 @@ class SwiftifyInfoPrinter {
86988702
86998703 void printCountedBy (const clang::CountAttributedType *CAT,
87008704 size_t pointerIndex) {
8701- if (!firstParam) {
8702- out << " , " ;
8703- } else {
8704- firstParam = false ;
8705- }
8705+ printSeparator ();
87068706 clang::Expr *countExpr = CAT->getCountExpr ();
87078707 bool isSizedBy = CAT->isCountInBytes ();
87088708 out << " ." ;
@@ -8720,9 +8720,76 @@ class SwiftifyInfoPrinter {
87208720 out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
87218721 out << " \" )" ;
87228722 }
8723+
8724+ void printNonEscaping (int idx) {
8725+ printSeparator ();
8726+ out << " .nonescaping(pointer: " << idx << " )" ;
8727+ }
8728+
8729+ void printTypeMapping (const llvm::StringMap<std::string> &mapping) {
8730+ printSeparator ();
8731+ out << " typeMappings: [" ;
8732+ if (mapping.empty ()) {
8733+ out << " :]" ;
8734+ return ;
8735+ }
8736+ llvm::interleaveComma (mapping, out, [&](const auto &entry) {
8737+ out << ' "' << entry.getKey () << " \" : \" " << entry.getValue () << ' "' ;
8738+ });
8739+ out << " ]" ;
8740+ }
8741+
8742+ private:
8743+ void printSeparator () {
8744+ if (!firstParam) {
8745+ out << " , " ;
8746+ } else {
8747+ firstParam = false ;
8748+ }
8749+ }
87238750};
87248751} // namespace
87258752
8753+ void ClangImporter::Implementation::importSpanAttributes (FuncDecl *MappedDecl) {
8754+ if (!SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers))
8755+ return ;
8756+ auto ClangDecl =
8757+ dyn_cast_or_null<clang::FunctionDecl>(MappedDecl->getClangDecl ());
8758+ if (!ClangDecl)
8759+ return ;
8760+
8761+ llvm::SmallString<128 > MacroString;
8762+ bool attachMacro = false ;
8763+ {
8764+ llvm::raw_svector_ostream out (MacroString);
8765+ llvm::StringMap<std::string> typeMapping;
8766+
8767+ SwiftifyInfoPrinter printer (getClangASTContext (), out);
8768+ for (auto [index, param] : llvm::enumerate (ClangDecl->parameters ())) {
8769+ auto paramTy = param->getType ();
8770+ const auto *decl = paramTy->getAsTagDecl ();
8771+ if (!decl || !decl->isInStdNamespace ())
8772+ continue ;
8773+ if (decl->getName () != " span" )
8774+ continue ;
8775+ if (param->hasAttr <clang::NoEscapeAttr>()) {
8776+ printer.printNonEscaping (index + 1 );
8777+ clang::PrintingPolicy policy (param->getASTContext ().getLangOpts ());
8778+ policy.SuppressTagKeyword = true ;
8779+ auto param = MappedDecl->getParameters ()->get (index);
8780+ typeMapping.insert (std::make_pair (
8781+ paramTy.getAsString (policy),
8782+ param->getInterfaceType ()->getDesugaredType ()->getString ()));
8783+ attachMacro = true ;
8784+ }
8785+ }
8786+ printer.printTypeMapping (typeMapping);
8787+ }
8788+
8789+ if (attachMacro)
8790+ importNontrivialAttribute (MappedDecl, MacroString);
8791+ }
8792+
87268793void ClangImporter::Implementation::importBoundsAttributes (
87278794 FuncDecl *MappedDecl) {
87288795 assert (SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers));
0 commit comments