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
}
@@ -8698,11 +8702,7 @@ class SwiftifyInfoPrinter {
8698
8702
8699
8703
void printCountedBy (const clang::CountAttributedType *CAT,
8700
8704
size_t pointerIndex) {
8701
- if (!firstParam) {
8702
- out << " , " ;
8703
- } else {
8704
- firstParam = false ;
8705
- }
8705
+ printSeparator ();
8706
8706
clang::Expr *countExpr = CAT->getCountExpr ();
8707
8707
bool isSizedBy = CAT->isCountInBytes ();
8708
8708
out << " ." ;
@@ -8720,9 +8720,76 @@ class SwiftifyInfoPrinter {
8720
8720
out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
8721
8721
out << " \" )" ;
8722
8722
}
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
+ }
8723
8750
};
8724
8751
} // namespace
8725
8752
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
+
8726
8793
void ClangImporter::Implementation::importBoundsAttributes (
8727
8794
FuncDecl *MappedDecl) {
8728
8795
assert (SwiftContext.LangOpts .hasFeature (Feature::SafeInteropWrappers));
0 commit comments