@@ -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,10 @@ class DeclAndTypePrinter::Implementation
336
342
ClangValueTypePrinter printer (os, owningPrinter.prologueOS ,
337
343
owningPrinter.typeMapping ,
338
344
owningPrinter.interopContext );
339
- printer.printValueTypeDecl (SD);
345
+ printer.printValueTypeDecl (
346
+ SD, /* bodyPrinter=*/ [&]() { printMembers (SD->getMembers ()); });
347
+ os << outOfLineDefinitions;
348
+ outOfLineDefinitions.clear ();
340
349
}
341
350
342
351
void visitExtensionDecl (ExtensionDecl *ED) {
@@ -514,6 +523,45 @@ class DeclAndTypePrinter::Implementation
514
523
bool isClassMethod,
515
524
bool isNSUIntegerSubscript = false ) {
516
525
printDocumentationComment (AFD);
526
+
527
+ Optional<ForeignAsyncConvention> asyncConvention =
528
+ AFD->getForeignAsyncConvention ();
529
+ Optional<ForeignErrorConvention> errorConvention =
530
+ AFD->getForeignErrorConvention ();
531
+ Type rawMethodTy = AFD->getMethodInterfaceType ();
532
+ auto methodTy = rawMethodTy->castTo <FunctionType>();
533
+ auto resultTy =
534
+ getForeignResultType (AFD, methodTy, asyncConvention, errorConvention);
535
+
536
+ if (outputLang == OutputLanguageMode::Cxx) {
537
+ auto *typeDeclContext = cast<NominalTypeDecl>(AFD->getParent ());
538
+
539
+ std::string cFuncDecl;
540
+ llvm::raw_string_ostream cFuncPrologueOS (cFuncDecl);
541
+ auto funcABI = Implementation (cFuncPrologueOS, owningPrinter, outputLang)
542
+ .printSwiftABIFunctionSignatureAsCxxFunction (
543
+ AFD, methodTy,
544
+ /* selfTypeDeclContext=*/ typeDeclContext);
545
+ owningPrinter.prologueOS << cFuncPrologueOS.str ();
546
+
547
+ DeclAndTypeClangFunctionPrinter declPrinter (os, owningPrinter.prologueOS ,
548
+ owningPrinter.typeMapping ,
549
+ owningPrinter.interopContext );
550
+ declPrinter.printCxxPropertyAccessorMethod (
551
+ typeDeclContext, AFD, funcABI.getSymbolName (), resultTy,
552
+ /* isDefinition=*/ false );
553
+
554
+ llvm::raw_string_ostream defOS (outOfLineDefinitions);
555
+ DeclAndTypeClangFunctionPrinter defPrinter (
556
+ defOS, owningPrinter.prologueOS , owningPrinter.typeMapping ,
557
+ owningPrinter.interopContext );
558
+ defPrinter.printCxxPropertyAccessorMethod (
559
+ typeDeclContext, AFD, funcABI.getSymbolName (), resultTy,
560
+ /* isDefinition=*/ true );
561
+
562
+ return ;
563
+ }
564
+
517
565
if (isClassMethod)
518
566
os << " + (" ;
519
567
else
@@ -527,15 +575,6 @@ class DeclAndTypePrinter::Implementation
527
575
}
528
576
}
529
577
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
578
// Constructors and methods returning DynamicSelf return
540
579
// instancetype.
541
580
if (isa<ConstructorDecl>(AFD) ||
@@ -796,7 +835,8 @@ class DeclAndTypePrinter::Implementation
796
835
}
797
836
798
837
struct FuncionSwiftABIInformation {
799
- FuncionSwiftABIInformation (FuncDecl *FD, Mangle::ASTMangler &mangler) {
838
+ FuncionSwiftABIInformation (AbstractFunctionDecl *FD,
839
+ Mangle::ASTMangler &mangler) {
800
840
isCDecl = FD->getAttrs ().hasAttribute <CDeclAttr>();
801
841
if (!isCDecl) {
802
842
auto mangledName = mangler.mangleAnyDecl (FD, /* prefix=*/ true );
@@ -818,8 +858,9 @@ class DeclAndTypePrinter::Implementation
818
858
};
819
859
820
860
// Print out the extern C Swift ABI function signature.
821
- FuncionSwiftABIInformation
822
- printSwiftABIFunctionSignatureAsCxxFunction (FuncDecl *FD) {
861
+ FuncionSwiftABIInformation printSwiftABIFunctionSignatureAsCxxFunction (
862
+ AbstractFunctionDecl *FD, Optional<FunctionType *> givenFuncType = None,
863
+ Optional<NominalTypeDecl *> selfTypeDeclContext = None) {
823
864
assert (outputLang == OutputLanguageMode::Cxx);
824
865
Optional<ForeignAsyncConvention> asyncConvention =
825
866
FD->getForeignAsyncConvention ();
@@ -828,7 +869,9 @@ class DeclAndTypePrinter::Implementation
828
869
assert (!FD->getGenericSignature () &&
829
870
" top-level generic functions not supported here" );
830
871
// FIXME (Alex): Make type adjustments for C++.
831
- auto funcTy = FD->getInterfaceType ()->castTo <FunctionType>();
872
+ auto funcTy = givenFuncType
873
+ ? *givenFuncType
874
+ : FD->getInterfaceType ()->castTo <FunctionType>();
832
875
auto resultTy =
833
876
getForeignResultType (FD, funcTy, asyncConvention, errorConvention);
834
877
@@ -840,9 +883,17 @@ class DeclAndTypePrinter::Implementation
840
883
DeclAndTypeClangFunctionPrinter funcPrinter (os, owningPrinter.prologueOS ,
841
884
owningPrinter.typeMapping ,
842
885
owningPrinter.interopContext );
886
+ llvm::SmallVector<DeclAndTypeClangFunctionPrinter::AdditionalParam, 1 >
887
+ additionalParams;
888
+ if (selfTypeDeclContext) {
889
+ additionalParams.push_back (
890
+ {DeclAndTypeClangFunctionPrinter::AdditionalParam::Role::Self,
891
+ (*selfTypeDeclContext)->getDeclaredType ()});
892
+ }
843
893
funcPrinter.printFunctionSignature (
844
894
FD, funcABI.getSymbolName (), resultTy,
845
- DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto);
895
+ DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto,
896
+ additionalParams);
846
897
// Swift functions can't throw exceptions, we can only
847
898
// throw them from C++ when emitting C++ inline thunks for the Swift
848
899
// functions.
@@ -1186,6 +1237,17 @@ class DeclAndTypePrinter::Implementation
1186
1237
assert (VD->getDeclContext ()->isTypeContext () &&
1187
1238
" cannot handle global variables right now" );
1188
1239
1240
+ if (outputLang == OutputLanguageMode::Cxx) {
1241
+ // FIXME: Documentation.
1242
+ // FIXME: availability.
1243
+ // FIXME: support static properties.
1244
+ if (VD->isStatic ())
1245
+ return ;
1246
+ auto *getter = VD->getOpaqueAccessor (AccessorKind::Get);
1247
+ printAbstractFunctionAsMethod (getter, /* isStatic=*/ false );
1248
+ return ;
1249
+ }
1250
+
1189
1251
printDocumentationComment (VD);
1190
1252
1191
1253
if (VD->isStatic ()) {
0 commit comments