@@ -109,6 +109,8 @@ class DeclAndTypePrinter::Implementation
109
109
110
110
SmallVector<const FunctionType *, 4 > openFunctionTypes;
111
111
112
+ std::string outOfLineDefinitions;
113
+
112
114
ASTContext &getASTContext () const {
113
115
return owningPrinter.M .getASTContext ();
114
116
}
@@ -211,6 +213,7 @@ class DeclAndTypePrinter::Implementation
211
213
template <bool AllowDelayed = false , typename R>
212
214
void printMembers (R &&members) {
213
215
bool protocolMembersOptional = false ;
216
+ assert (outOfLineDefinitions.empty ());
214
217
for (const Decl *member : members) {
215
218
auto VD = dyn_cast<ValueDecl>(member);
216
219
if (!VD || !shouldInclude (VD) || isa<TypeDecl>(VD))
@@ -226,6 +229,9 @@ class DeclAndTypePrinter::Implementation
226
229
protocolMembersOptional = !protocolMembersOptional;
227
230
os << (protocolMembersOptional ? " @optional\n " : " @required\n " );
228
231
}
232
+ // Limit C++ decls for now.
233
+ if (outputLang == OutputLanguageMode::Cxx && !isa<VarDecl>(VD))
234
+ continue ;
229
235
ASTVisitor::visit (const_cast <ValueDecl*>(VD));
230
236
}
231
237
}
@@ -336,7 +342,12 @@ class DeclAndTypePrinter::Implementation
336
342
ClangValueTypePrinter printer (os, owningPrinter.prologueOS ,
337
343
owningPrinter.typeMapping ,
338
344
owningPrinter.interopContext );
339
- printer.printValueTypeDecl (SD);
345
+ std::string outOfLineMemberDefinition;
346
+
347
+ printer.printValueTypeDecl (
348
+ SD, /* bodyPrinter=*/ [&]() { printMembers (SD->getMembers ()); });
349
+ os << outOfLineDefinitions;
350
+ outOfLineDefinitions.clear ();
340
351
}
341
352
342
353
void visitExtensionDecl (ExtensionDecl *ED) {
@@ -514,6 +525,46 @@ class DeclAndTypePrinter::Implementation
514
525
bool isClassMethod,
515
526
bool isNSUIntegerSubscript = false ) {
516
527
printDocumentationComment (AFD);
528
+
529
+ Optional<ForeignAsyncConvention> asyncConvention =
530
+ AFD->getForeignAsyncConvention ();
531
+ Optional<ForeignErrorConvention> errorConvention =
532
+ AFD->getForeignErrorConvention ();
533
+ Type rawMethodTy = AFD->getMethodInterfaceType ();
534
+ auto methodTy = rawMethodTy->castTo <FunctionType>();
535
+ auto resultTy =
536
+ getForeignResultType (AFD, methodTy, asyncConvention, errorConvention);
537
+
538
+ if (outputLang == OutputLanguageMode::Cxx) {
539
+ // FIXME: can this ever fail?
540
+ auto *typeDeclContext = cast<NominalTypeDecl>(AFD->getParent ());
541
+
542
+ std::string cFuncDecl;
543
+ llvm::raw_string_ostream cFuncPrologueOS (cFuncDecl);
544
+ auto funcABI = Implementation (cFuncPrologueOS, owningPrinter, outputLang)
545
+ .printSwiftABIFunctionSignatureAsCxxFunction (
546
+ AFD, methodTy,
547
+ /* selfTypeDeclContext=*/ typeDeclContext);
548
+ owningPrinter.prologueOS << cFuncPrologueOS.str ();
549
+
550
+ DeclAndTypeClangFunctionPrinter declPrinter (os, owningPrinter.prologueOS ,
551
+ owningPrinter.typeMapping ,
552
+ owningPrinter.interopContext );
553
+ declPrinter.printCxxPropertyAccessorMethod (
554
+ typeDeclContext, AFD, funcABI.getSymbolName (), resultTy,
555
+ /* isDefinition=*/ false );
556
+
557
+ llvm::raw_string_ostream defOS (outOfLineDefinitions);
558
+ DeclAndTypeClangFunctionPrinter defPrinter (
559
+ defOS, owningPrinter.prologueOS , owningPrinter.typeMapping ,
560
+ owningPrinter.interopContext );
561
+ defPrinter.printCxxPropertyAccessorMethod (
562
+ typeDeclContext, AFD, funcABI.getSymbolName (), resultTy,
563
+ /* isDefinition=*/ true );
564
+
565
+ return ;
566
+ }
567
+
517
568
if (isClassMethod)
518
569
os << " + (" ;
519
570
else
@@ -527,15 +578,6 @@ class DeclAndTypePrinter::Implementation
527
578
}
528
579
}
529
580
530
- Optional<ForeignAsyncConvention> asyncConvention
531
- = AFD->getForeignAsyncConvention ();
532
- Optional<ForeignErrorConvention> errorConvention
533
- = AFD->getForeignErrorConvention ();
534
- Type rawMethodTy = AFD->getMethodInterfaceType ();
535
- auto methodTy = rawMethodTy->castTo <FunctionType>();
536
- auto resultTy = getForeignResultType (
537
- AFD, methodTy, asyncConvention, errorConvention);
538
-
539
581
// Constructors and methods returning DynamicSelf return
540
582
// instancetype.
541
583
if (isa<ConstructorDecl>(AFD) ||
@@ -796,7 +838,8 @@ class DeclAndTypePrinter::Implementation
796
838
}
797
839
798
840
struct FuncionSwiftABIInformation {
799
- FuncionSwiftABIInformation (FuncDecl *FD, Mangle::ASTMangler &mangler) {
841
+ FuncionSwiftABIInformation (AbstractFunctionDecl *FD,
842
+ Mangle::ASTMangler &mangler) {
800
843
isCDecl = FD->getAttrs ().hasAttribute <CDeclAttr>();
801
844
if (!isCDecl) {
802
845
auto mangledName = mangler.mangleAnyDecl (FD, /* prefix=*/ true );
@@ -818,8 +861,9 @@ class DeclAndTypePrinter::Implementation
818
861
};
819
862
820
863
// Print out the extern C Swift ABI function signature.
821
- FuncionSwiftABIInformation
822
- printSwiftABIFunctionSignatureAsCxxFunction (FuncDecl *FD) {
864
+ FuncionSwiftABIInformation printSwiftABIFunctionSignatureAsCxxFunction (
865
+ AbstractFunctionDecl *FD, Optional<FunctionType *> givenFuncType = None,
866
+ Optional<NominalTypeDecl *> selfTypeDeclContext = None) {
823
867
assert (outputLang == OutputLanguageMode::Cxx);
824
868
Optional<ForeignAsyncConvention> asyncConvention =
825
869
FD->getForeignAsyncConvention ();
@@ -828,7 +872,9 @@ class DeclAndTypePrinter::Implementation
828
872
assert (!FD->getGenericSignature () &&
829
873
" top-level generic functions not supported here" );
830
874
// FIXME (Alex): Make type adjustments for C++.
831
- auto funcTy = FD->getInterfaceType ()->castTo <FunctionType>();
875
+ auto funcTy = givenFuncType
876
+ ? *givenFuncType
877
+ : FD->getInterfaceType ()->castTo <FunctionType>();
832
878
auto resultTy =
833
879
getForeignResultType (FD, funcTy, asyncConvention, errorConvention);
834
880
@@ -840,9 +886,17 @@ class DeclAndTypePrinter::Implementation
840
886
DeclAndTypeClangFunctionPrinter funcPrinter (os, owningPrinter.prologueOS ,
841
887
owningPrinter.typeMapping ,
842
888
owningPrinter.interopContext );
889
+ llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 1 >
890
+ additionalParams;
891
+ if (selfTypeDeclContext) {
892
+ additionalParams.push_back (
893
+ {DeclAndTypeClangFunctionPrinter::AdditionalParam::Role::Self,
894
+ (*selfTypeDeclContext)->getDeclaredType ()});
895
+ }
843
896
funcPrinter.printFunctionSignature (
844
897
FD, funcABI.getSymbolName (), resultTy,
845
- DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto);
898
+ DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto,
899
+ additionalParams);
846
900
// Swift functions can't throw exceptions, we can only
847
901
// throw them from C++ when emitting C++ inline thunks for the Swift
848
902
// functions.
@@ -1179,6 +1233,18 @@ class DeclAndTypePrinter::Implementation
1179
1233
assert (VD->getDeclContext ()->isTypeContext () &&
1180
1234
" cannot handle global variables right now" );
1181
1235
1236
+ if (outputLang == OutputLanguageMode::Cxx) {
1237
+ // FIXME: Documentation.
1238
+ // FIXME: availability.
1239
+ // FIXME: support static properties.
1240
+ if (VD->isStatic ())
1241
+ return ;
1242
+ // Explicitly look at each accessor here: see visitAccessorDecl.
1243
+ auto *getter = VD->getOpaqueAccessor (AccessorKind::Get);
1244
+ printAbstractFunctionAsMethod (getter, /* isStatic=*/ false );
1245
+ return ;
1246
+ }
1247
+
1182
1248
printDocumentationComment (VD);
1183
1249
1184
1250
if (VD->isStatic ()) {
0 commit comments