@@ -109,6 +109,8 @@ class DeclAndTypePrinter::Implementation
109109
110110 SmallVector<const FunctionType *, 4 > openFunctionTypes;
111111
112+ std::string outOfLineDefinitions;
113+
112114 ASTContext &getASTContext () const {
113115 return owningPrinter.M .getASTContext ();
114116 }
@@ -211,6 +213,7 @@ class DeclAndTypePrinter::Implementation
211213 template <bool AllowDelayed = false , typename R>
212214 void printMembers (R &&members) {
213215 bool protocolMembersOptional = false ;
216+ assert (outOfLineDefinitions.empty ());
214217 for (const Decl *member : members) {
215218 auto VD = dyn_cast<ValueDecl>(member);
216219 if (!VD || !shouldInclude (VD) || isa<TypeDecl>(VD))
@@ -226,6 +229,9 @@ class DeclAndTypePrinter::Implementation
226229 protocolMembersOptional = !protocolMembersOptional;
227230 os << (protocolMembersOptional ? " @optional\n " : " @required\n " );
228231 }
232+ // Limit C++ decls for now.
233+ if (outputLang == OutputLanguageMode::Cxx && !isa<VarDecl>(VD))
234+ continue ;
229235 ASTVisitor::visit (const_cast <ValueDecl*>(VD));
230236 }
231237 }
@@ -336,7 +342,10 @@ class DeclAndTypePrinter::Implementation
336342 ClangValueTypePrinter printer (os, owningPrinter.prologueOS ,
337343 owningPrinter.typeMapping ,
338344 owningPrinter.interopContext );
339- printer.printValueTypeDecl (SD);
345+ printer.printValueTypeDecl (
346+ SD, /* bodyPrinter=*/ [&]() { printMembers (SD->getMembers ()); });
347+ os << outOfLineDefinitions;
348+ outOfLineDefinitions.clear ();
340349 }
341350
342351 void visitExtensionDecl (ExtensionDecl *ED) {
@@ -514,6 +523,45 @@ class DeclAndTypePrinter::Implementation
514523 bool isClassMethod,
515524 bool isNSUIntegerSubscript = false ) {
516525 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+
517565 if (isClassMethod)
518566 os << " + (" ;
519567 else
@@ -527,15 +575,6 @@ class DeclAndTypePrinter::Implementation
527575 }
528576 }
529577
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-
539578 // Constructors and methods returning DynamicSelf return
540579 // instancetype.
541580 if (isa<ConstructorDecl>(AFD) ||
@@ -796,7 +835,8 @@ class DeclAndTypePrinter::Implementation
796835 }
797836
798837 struct FuncionSwiftABIInformation {
799- FuncionSwiftABIInformation (FuncDecl *FD, Mangle::ASTMangler &mangler) {
838+ FuncionSwiftABIInformation (AbstractFunctionDecl *FD,
839+ Mangle::ASTMangler &mangler) {
800840 isCDecl = FD->getAttrs ().hasAttribute <CDeclAttr>();
801841 if (!isCDecl) {
802842 auto mangledName = mangler.mangleAnyDecl (FD, /* prefix=*/ true );
@@ -818,8 +858,9 @@ class DeclAndTypePrinter::Implementation
818858 };
819859
820860 // 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) {
823864 assert (outputLang == OutputLanguageMode::Cxx);
824865 Optional<ForeignAsyncConvention> asyncConvention =
825866 FD->getForeignAsyncConvention ();
@@ -828,7 +869,9 @@ class DeclAndTypePrinter::Implementation
828869 assert (!FD->getGenericSignature () &&
829870 " top-level generic functions not supported here" );
830871 // 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>();
832875 auto resultTy =
833876 getForeignResultType (FD, funcTy, asyncConvention, errorConvention);
834877
@@ -840,9 +883,17 @@ class DeclAndTypePrinter::Implementation
840883 DeclAndTypeClangFunctionPrinter funcPrinter (os, owningPrinter.prologueOS ,
841884 owningPrinter.typeMapping ,
842885 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+ }
843893 funcPrinter.printFunctionSignature (
844894 FD, funcABI.getSymbolName (), resultTy,
845- DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto);
895+ DeclAndTypeClangFunctionPrinter::FunctionSignatureKind::CFunctionProto,
896+ additionalParams);
846897 // Swift functions can't throw exceptions, we can only
847898 // throw them from C++ when emitting C++ inline thunks for the Swift
848899 // functions.
@@ -1186,6 +1237,17 @@ class DeclAndTypePrinter::Implementation
11861237 assert (VD->getDeclContext ()->isTypeContext () &&
11871238 " cannot handle global variables right now" );
11881239
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+
11891251 printDocumentationComment (VD);
11901252
11911253 if (VD->isStatic ()) {
0 commit comments