@@ -42,74 +42,25 @@ ValueDecl *getKnownSingleDecl(ASTContext &SwiftContext, StringRef DeclName) {
4242 return decls[0 ];
4343}
4444
45- class SwiftifyInfoPrinter {
46- public:
45+ struct SwiftifyInfoPrinter {
4746 static const ssize_t SELF_PARAM_INDEX = -2 ;
4847 static const ssize_t RETURN_VALUE_INDEX = -1 ;
4948 clang::ASTContext &ctx;
5049 ASTContext &SwiftContext;
51- llvm::raw_ostream &out;
50+ llvm::raw_svector_ostream &out;
5251 MacroDecl &SwiftifyImportDecl;
5352 bool firstParam = true ;
54- llvm::StringMap<std::string> typeMapping;
53+ llvm::StringMap<std::string> & typeMapping;
5554
55+ protected:
5656 SwiftifyInfoPrinter (clang::ASTContext &ctx, ASTContext &SwiftContext,
57- llvm::raw_ostream &out, MacroDecl &SwiftifyImportDecl)
57+ llvm::raw_svector_ostream &out,
58+ MacroDecl &SwiftifyImportDecl,
59+ llvm::StringMap<std::string> &typeMapping)
5860 : ctx(ctx), SwiftContext(SwiftContext), out(out),
59- SwiftifyImportDecl (SwiftifyImportDecl) {
60- out << " (" ;
61- }
62- ~SwiftifyInfoPrinter () { out << " )" ; }
63-
64- void printCountedBy (const clang::CountAttributedType *CAT,
65- ssize_t pointerIndex) {
66- printSeparator ();
67- clang::Expr *countExpr = CAT->getCountExpr ();
68- bool isSizedBy = CAT->isCountInBytes ();
69- out << " ." ;
70- if (isSizedBy)
71- out << " sizedBy" ;
72- else
73- out << " countedBy" ;
74- out << " (pointer: " ;
75- printParamOrReturn (pointerIndex);
76- out << " , " ;
77- if (isSizedBy)
78- out << " size" ;
79- else
80- out << " count" ;
81- out << " : \" " ;
82- countExpr->printPretty (
83- out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
84- out << " \" )" ;
85- }
86-
87- void printNonEscaping (int idx) {
88- printSeparator ();
89- out << " .nonescaping(pointer: " ;
90- printParamOrReturn (idx);
91- out << " )" ;
92- }
93-
94- void printLifetimeboundReturn (int idx, bool borrow) {
95- printSeparator ();
96- out << " .lifetimeDependence(dependsOn: " ;
97- printParamOrReturn (idx);
98- out << " , pointer: .return, type: " ;
99- out << (borrow ? " .borrow" : " .copy" );
100- out << " )" ;
101- }
102-
103- bool registerStdSpanTypeMapping (Type swiftType, const clang::QualType clangType) {
104- const auto *decl = clangType->getAsTagDecl ();
105- if (decl && decl->isInStdNamespace () && decl->getName () == " span" ) {
106- typeMapping.insert (std::make_pair (
107- swiftType->getString (), swiftType->getDesugaredType ()->getString ()));
108- return true ;
109- }
110- return false ;
111- }
61+ SwiftifyImportDecl (SwiftifyImportDecl), typeMapping(typeMapping) {}
11262
63+ public:
11364 void printTypeMapping () {
11465 printSeparator ();
11566 out << " typeMappings: [" ;
@@ -130,7 +81,6 @@ class SwiftifyInfoPrinter {
13081 out << " spanAvailability: " ;
13182 printAvailabilityOfType (" Span" );
13283 }
133-
13484private:
13585 bool hasMacroParameter (StringRef ParamName) {
13686 for (auto *Param : *SwiftifyImportDecl.parameterList )
@@ -160,6 +110,63 @@ class SwiftifyInfoPrinter {
160110 firstParam = false ;
161111 }
162112 }
113+ };
114+
115+ struct SwiftifyInfoFunctionPrinter : public SwiftifyInfoPrinter {
116+ SwiftifyInfoFunctionPrinter (clang::ASTContext &ctx, ASTContext &SwiftContext,
117+ llvm::raw_svector_ostream &out,
118+ MacroDecl &SwiftifyImportDecl,
119+ llvm::StringMap<std::string> &typeMapping)
120+ : SwiftifyInfoPrinter(ctx, SwiftContext, out, SwiftifyImportDecl, typeMapping) {}
121+
122+ void printCountedBy (const clang::CountAttributedType *CAT,
123+ ssize_t pointerIndex) {
124+ printSeparator ();
125+ clang::Expr *countExpr = CAT->getCountExpr ();
126+ bool isSizedBy = CAT->isCountInBytes ();
127+ out << " ." ;
128+ if (isSizedBy)
129+ out << " sizedBy" ;
130+ else
131+ out << " countedBy" ;
132+ out << " (pointer: " ;
133+ printParamOrReturn (pointerIndex);
134+ out << " , " ;
135+ if (isSizedBy)
136+ out << " size" ;
137+ else
138+ out << " count" ;
139+ out << " : \" " ;
140+ countExpr->printPretty (
141+ out, {}, {ctx.getLangOpts ()}); // TODO: map clang::Expr to Swift Expr
142+ out << " \" )" ;
143+ }
144+
145+ void printNonEscaping (int idx) {
146+ printSeparator ();
147+ out << " .nonescaping(pointer: " ;
148+ printParamOrReturn (idx);
149+ out << " )" ;
150+ }
151+
152+ void printLifetimeboundReturn (int idx, bool borrow) {
153+ printSeparator ();
154+ out << " .lifetimeDependence(dependsOn: " ;
155+ printParamOrReturn (idx);
156+ out << " , pointer: .return, type: " ;
157+ out << (borrow ? " .borrow" : " .copy" );
158+ out << " )" ;
159+ }
160+
161+ bool registerStdSpanTypeMapping (Type swiftType, const clang::QualType clangType) {
162+ const auto *decl = clangType->getAsTagDecl ();
163+ if (decl && decl->isInStdNamespace () && decl->getName () == " span" ) {
164+ typeMapping.insert (std::make_pair (
165+ swiftType->getString (), swiftType->getDesugaredType ()->getString ()));
166+ return true ;
167+ }
168+ return false ;
169+ }
163170
164171private:
165172 void printParamOrReturn (ssize_t pointerIndex) {
@@ -315,7 +322,7 @@ static size_t getNumParams(const clang::FunctionDecl* D) {
315322
316323template <typename T>
317324static bool swiftifyImpl (ClangImporter::Implementation &Self,
318- SwiftifyInfoPrinter &printer,
325+ SwiftifyInfoFunctionPrinter &printer,
319326 const AbstractFunctionDecl *MappedDecl,
320327 const T *ClangDecl) {
321328 DLOG (" Checking " << *ClangDecl << " for bounds and lifetime info\n " );
@@ -451,28 +458,29 @@ class SwiftifyProtocolInfoPrinter : public SwiftifyInfoPrinter {
451458public:
452459 SwiftifyProtocolInfoPrinter (ClangImporter::Implementation &ImporterImpl,
453460 clang::ASTContext &ctx, ASTContext &SwiftContext,
454- llvm::raw_ostream &out,
455- MacroDecl &SwiftifyImportDecl)
456- : SwiftifyInfoPrinter(ctx, SwiftContext, out, SwiftifyImportDecl),
461+ llvm::raw_svector_ostream &out,
462+ MacroDecl &SwiftifyImportDecl,
463+ llvm::StringMap<std::string> &typeMapping)
464+ : SwiftifyInfoPrinter(ctx, SwiftContext, out, SwiftifyImportDecl, typeMapping),
457465 ImporterImpl (ImporterImpl) {}
458466
459467 bool printMethod (const FuncDecl *Method) {
460- // don't emit .method() if we know it's going to be empty
461468 auto ClangDecl = dyn_cast_or_null<clang::ObjCMethodDecl>(Method->getClangDecl ());
462469 if (!ClangDecl)
463470 return false ;
464471
465- printSeparator ();
466- out << " .method(signature: \" " ;
467- printMethodSignature (Method);
468- out << " \" , paramInfo: [" ;
469- // reset firstParam inside paramInfo array. At this point firstParam will
470- // always be false, so no need to save the current value.
471- ASSERT (!firstParam);
472- firstParam = true ;
473- bool hadAttributes = swiftifyImpl (ImporterImpl, *this , Method, ClangDecl);
474- firstParam = false ;
475- out << " ])" ;
472+ llvm::SmallString<128 > paramInfoString;
473+ llvm::raw_svector_ostream tmpOut (paramInfoString);
474+
475+ SwiftifyInfoFunctionPrinter methodPrinter (ctx, SwiftContext, tmpOut,
476+ SwiftifyImportDecl, typeMapping);
477+ bool hadAttributes = swiftifyImpl (ImporterImpl, methodPrinter, Method, ClangDecl);
478+ if (hadAttributes) {
479+ printSeparator ();
480+ out << " .method(signature: \" " ;
481+ printMethodSignature (Method);
482+ out << " \" , paramInfo: [" << paramInfoString << " ])" ;
483+ }
476484 return hadAttributes;
477485 }
478486
@@ -507,13 +515,16 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
507515 llvm::SmallString<128 > MacroString;
508516 {
509517 llvm::raw_svector_ostream out (MacroString);
510- out << " @_SwiftifyImport" ;
518+ out << " @_SwiftifyImport( " ;
511519
512- SwiftifyInfoPrinter printer (getClangASTContext (), SwiftContext, out, *SwiftifyImportDecl);
520+ llvm::StringMap<std::string> typeMapping;
521+ SwiftifyInfoFunctionPrinter printer (getClangASTContext (), SwiftContext, out,
522+ *SwiftifyImportDecl, typeMapping);
513523 if (!swiftifyImpl (*this , printer, MappedDecl, ClangDecl))
514524 return ;
515525 printer.printAvailability ();
516526 printer.printTypeMapping ();
527+ out << " )" ;
517528 }
518529
519530 DLOG (" Attaching safe interop macro: " << MacroString << " \n " );
@@ -553,11 +564,13 @@ void ClangImporter::Implementation::swiftifyProtocol(
553564 llvm::SmallString<128 > MacroString;
554565 {
555566 llvm::raw_svector_ostream out (MacroString);
556- out << " @_SwiftifyImportProtocol" ;
567+ out << " @_SwiftifyImportProtocol( " ;
557568
558569 bool hasBoundsAttributes = false ;
570+ llvm::StringMap<std::string> typeMapping;
559571 SwiftifyProtocolInfoPrinter printer (*this , getClangASTContext (),
560- SwiftContext, out, *SwiftifyImportDecl);
572+ SwiftContext, out, *SwiftifyImportDecl,
573+ typeMapping);
561574 for (Decl *SwiftMember :
562575 cast<IterableDeclContext>(MappedDecl)->getAllMembers ()) {
563576 FuncDecl *SwiftDecl = dyn_cast<FuncDecl>(SwiftMember);
@@ -570,6 +583,7 @@ void ClangImporter::Implementation::swiftifyProtocol(
570583 return ;
571584 printer.printAvailability ();
572585 printer.printTypeMapping ();
586+ out << " )" ;
573587 }
574588
575589 DLOG (" Attaching safe interop macro: " << MacroString << " \n " );
0 commit comments