60
60
#include " clang/AST/Decl.h"
61
61
#include " clang/AST/DeclCXX.h"
62
62
#include " clang/AST/DeclObjCCommon.h"
63
+ #include " clang/AST/PrettyPrinter.h"
63
64
#include " clang/AST/Type.h"
64
65
#include " clang/Basic/Specifiers.h"
65
66
#include " clang/Basic/TargetInfo.h"
71
72
#include " llvm/ADT/SmallString.h"
72
73
#include " llvm/ADT/Statistic.h"
73
74
#include " llvm/ADT/StringExtras.h"
75
+ #include " llvm/ADT/StringMap.h"
74
76
#include " llvm/ADT/StringSwitch.h"
75
77
#include " llvm/Support/Path.h"
76
78
77
79
#include < algorithm>
80
+ #include < utility>
78
81
79
82
#define DEBUG_TYPE " Clang module importer"
80
83
@@ -130,6 +133,7 @@ createFuncOrAccessor(ClangImporter::Implementation &impl, SourceLoc funcLoc,
130
133
impl.importSwiftAttrAttributes (decl);
131
134
if (hasBoundsAnnotation)
132
135
impl.importBoundsAttributes (decl);
136
+ impl.importSpanAttributes (decl);
133
137
134
138
return decl;
135
139
}
@@ -8685,11 +8689,7 @@ class SwiftifyInfoPrinter {
8685
8689
8686
8690
void printCountedBy (const clang::CountAttributedType *CAT,
8687
8691
size_t pointerIndex) {
8688
- if (!firstParam) {
8689
- out << " , " ;
8690
- } else {
8691
- firstParam = false ;
8692
- }
8692
+ printSeparator ();
8693
8693
clang::Expr *countExpr = CAT->getCountExpr ();
8694
8694
bool isSizedBy = CAT->isCountInBytes ();
8695
8695
out << " ." ;
@@ -8707,9 +8707,76 @@ class SwiftifyInfoPrinter {
8707
8707
out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
8708
8708
out << " \" )" ;
8709
8709
}
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
+ }
8710
8737
};
8711
8738
} // namespace
8712
8739
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
+
8713
8780
void ClangImporter::Implementation::importBoundsAttributes (
8714
8781
FuncDecl *MappedDecl) {
8715
8782
assert (SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers));
0 commit comments