@@ -525,10 +525,10 @@ class CFunctionSignatureTypePrinter
525525
526526ClangRepresentation
527527DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
528- Type ty, OptionalTypeKind optKind, ModuleDecl *moduleContext ,
529- OutputLanguageMode outputLang) {
528+ raw_ostream &stream, Type ty, OptionalTypeKind optKind,
529+ ModuleDecl *moduleContext, OutputLanguageMode outputLang) {
530530 CFunctionSignatureTypePrinter typePrinter (
531- os , cPrologueOS, typeMapping, outputLang, interopContext,
531+ stream , cPrologueOS, typeMapping, outputLang, interopContext,
532532 CFunctionSignatureTypePrinterModifierDelegate (), moduleContext,
533533 declPrinter, FunctionSignatureTypeUse::ReturnType);
534534 // Param for indirect return cannot be marked as inout
@@ -697,12 +697,14 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
697697 const AbstractFunctionDecl *FD, const LoweredFunctionSignature &signature,
698698 StringRef name, Type resultTy, FunctionSignatureKind kind,
699699 FunctionSignatureModifiers modifiers) {
700+ std::string functionSignature;
701+ llvm::raw_string_ostream functionSignatureOS (functionSignature);
700702 // Print any template and requires clauses for the
701703 // C++ class context to which this C++ member will belong to.
702704 if (const auto *typeDecl = modifiers.qualifierContext ) {
703705 assert (kind == FunctionSignatureKind::CxxInlineThunk);
704- ClangSyntaxPrinter (os). printNominalTypeOutsideMemberDeclTemplateSpecifiers (
705- typeDecl);
706+ ClangSyntaxPrinter (functionSignatureOS)
707+ . printNominalTypeOutsideMemberDeclTemplateSpecifiers ( typeDecl);
706708 }
707709 if (FD->isGeneric ()) {
708710 auto Signature = FD->getGenericSignature ().getCanonicalSignature ();
@@ -711,7 +713,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
711713
712714 // Print the template and requires clauses for this function.
713715 if (kind == FunctionSignatureKind::CxxInlineThunk)
714- ClangSyntaxPrinter (os ).printGenericSignature (Signature);
716+ ClangSyntaxPrinter (functionSignatureOS ).printGenericSignature (Signature);
715717 }
716718 if (const auto *enumDecl = FD->getDeclContext ()->getSelfEnumDecl ()) {
717719 // We cannot emit functions with the same name as an enum case yet, the resulting header
@@ -737,31 +739,31 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
737739 // FIXME: add support for noescape and PrintMultiPartType,
738740 // see DeclAndTypePrinter::print.
739741 CFunctionSignatureTypePrinter typePrinter (
740- os , cPrologueOS, typeMapping, outputLang, interopContext, delegate ,
741- emittedModule, declPrinter);
742+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
743+ interopContext, delegate, emittedModule, declPrinter);
742744 auto result = typePrinter.visit (ty, optionalKind, isInOutParam);
743745
744746 if (!name.empty ()) {
745- os << ' ' ;
746- ClangSyntaxPrinter (os ).printIdentifier (name);
747+ functionSignatureOS << ' ' ;
748+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (name);
747749 }
748750 return result;
749751 };
750752
751753 // Print any modifiers before the signature.
752754 if (modifiers.isStatic ) {
753755 assert (!modifiers.isConst );
754- os << " static " ;
756+ functionSignatureOS << " static " ;
755757 }
756758 if (modifiers.isInline )
757- ClangSyntaxPrinter (os ).printInlineForThunk ();
759+ ClangSyntaxPrinter (functionSignatureOS ).printInlineForThunk ();
758760
759761 ClangRepresentation resultingRepresentation =
760762 ClangRepresentation::representable;
761763
762764 // Print out the return type.
763765 if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
764- os << " swift::ThrowingResult<" ;
766+ functionSignatureOS << " swift::ThrowingResult<" ;
765767 if (kind == FunctionSignatureKind::CFunctionProto) {
766768 // First, verify that the C++ return type is representable.
767769 {
@@ -788,19 +790,20 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
788790 return ClangRepresentation::unsupported;
789791
790792 if (!directResultType) {
791- os << " void" ;
793+ functionSignatureOS << " void" ;
792794 } else {
793795 if (!printDirectReturnOrParamCType (
794- *directResultType, resultTy, emittedModule, os, cPrologueOS ,
795- typeMapping, interopContext, [&]() {
796+ *directResultType, resultTy, emittedModule, functionSignatureOS ,
797+ cPrologueOS, typeMapping, interopContext, [&]() {
796798 OptionalTypeKind retKind;
797799 Type objTy;
798800 std::tie (objTy, retKind) =
799801 DeclAndTypePrinter::getObjectTypeAndOptionality (FD,
800802 resultTy);
801803
802804 auto s = printClangFunctionReturnType (
803- objTy, retKind, emittedModule, outputLang);
805+ functionSignatureOS, objTy, retKind, emittedModule,
806+ outputLang);
804807 assert (!s.isUnsupported ());
805808 }))
806809 return ClangRepresentation::unsupported;
@@ -811,19 +814,19 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
811814 std::tie (objTy, retKind) =
812815 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
813816 if (resultingRepresentation
814- .merge (printClangFunctionReturnType (objTy, retKind, emittedModule,
815- outputLang))
817+ .merge (printClangFunctionReturnType (
818+ functionSignatureOS, objTy, retKind, emittedModule, outputLang))
816819 .isUnsupported ())
817820 return resultingRepresentation;
818821 }
819822 if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
820- os << " >" ;
821- os << ' ' ;
823+ functionSignatureOS << " >" ;
824+ functionSignatureOS << ' ' ;
822825 if (const auto *typeDecl = modifiers.qualifierContext )
823- ClangSyntaxPrinter (os). printNominalTypeQualifier (
824- typeDecl, typeDecl->getModuleContext ());
825- ClangSyntaxPrinter (os ).printIdentifier (name);
826- os << ' (' ;
826+ ClangSyntaxPrinter (functionSignatureOS)
827+ . printNominalTypeQualifier ( typeDecl, typeDecl->getModuleContext ());
828+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (name);
829+ functionSignatureOS << ' (' ;
827830
828831 bool HasParams = false ;
829832
@@ -849,7 +852,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
849852 bool needsComma = false ;
850853 auto emitNewParam = [&]() {
851854 if (needsComma)
852- os << " , " ;
855+ functionSignatureOS << " , " ;
853856 needsComma = true ;
854857 };
855858 auto printParamName = [&](const ParamDecl ¶m) {
@@ -858,8 +861,8 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
858861 if (param.isSelfParameter ())
859862 paramName = " _self" ;
860863 if (!paramName.empty ()) {
861- os << ' ' ;
862- ClangSyntaxPrinter (os ).printIdentifier (paramName);
864+ functionSignatureOS << ' ' ;
865+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (paramName);
863866 }
864867 };
865868 auto printParamCType = [&](const ParamDecl ¶m) {
@@ -869,9 +872,9 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
869872 DeclAndTypePrinter::getObjectTypeAndOptionality (
870873 ¶m, param.getInterfaceType ());
871874 CFunctionSignatureTypePrinter typePrinter (
872- os , cPrologueOS, typeMapping, outputLang, interopContext ,
873- CFunctionSignatureTypePrinterModifierDelegate (), emittedModule ,
874- declPrinter);
875+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
876+ interopContext, CFunctionSignatureTypePrinterModifierDelegate (),
877+ emittedModule, declPrinter);
875878 auto s = typePrinter.visit (ty, optionalKind, param.isInOut ());
876879 assert (!s.isUnsupported ());
877880 };
@@ -880,22 +883,22 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
880883 &indirectResult) {
881884 emitNewParam ();
882885 if (indirectResult.hasSRet ())
883- os << " SWIFT_INDIRECT_RESULT " ;
886+ functionSignatureOS << " SWIFT_INDIRECT_RESULT " ;
884887 // FIXME: it would be nice to print out the C struct type here.
885- os << " void * _Nonnull" ;
888+ functionSignatureOS << " void * _Nonnull" ;
886889 },
887890 [&](const LoweredFunctionSignature::DirectParameter ¶m) {
888891 emitNewParam ();
889892 printDirectReturnOrParamCType (
890- param, param.getParamDecl ().getInterfaceType (), emittedModule, os,
891- cPrologueOS, typeMapping, interopContext,
893+ param, param.getParamDecl ().getInterfaceType (), emittedModule,
894+ functionSignatureOS, cPrologueOS, typeMapping, interopContext,
892895 [&]() { printParamCType (param.getParamDecl ()); });
893896 printParamName (param.getParamDecl ());
894897 },
895898 [&](const LoweredFunctionSignature::IndirectParameter ¶m) {
896899 emitNewParam ();
897900 if (param.getParamDecl ().isSelfParameter ())
898- os << " SWIFT_CONTEXT " ;
901+ functionSignatureOS << " SWIFT_CONTEXT " ;
899902 bool isConst =
900903 !param.getParamDecl ().isInOut () &&
901904 !(param.getParamDecl ().isSelfParameter () &&
@@ -904,7 +907,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
904907 .getInterfaceType ()
905908 ->isAnyClassReferenceType ());
906909 if (isConst)
907- os << " const " ;
910+ functionSignatureOS << " const " ;
908911 if (isKnownCType (param.getParamDecl ().getInterfaceType (),
909912 typeMapping) ||
910913 (!param.getParamDecl ().getInterfaceType ()->hasTypeParameter () &&
@@ -913,76 +916,86 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
913916 ->isAnyClassReferenceType ()))
914917 printParamCType (param.getParamDecl ());
915918 else
916- os << " void * _Nonnull" ;
919+ functionSignatureOS << " void * _Nonnull" ;
917920 printParamName (param.getParamDecl ());
918921 },
919922 [&](const LoweredFunctionSignature::GenericRequirementParameter
920923 &genericRequirementParam) {
921924 emitNewParam ();
922- os << " void * _Nonnull " ;
925+ functionSignatureOS << " void * _Nonnull " ;
923926 auto reqt = genericRequirementParam.getRequirement ();
924927 if (reqt.isAnyWitnessTable ())
925- ClangSyntaxPrinter (os).printBaseName (reqt.getProtocol ());
928+ ClangSyntaxPrinter (functionSignatureOS)
929+ .printBaseName (reqt.getProtocol ());
926930 else
927931 assert (reqt.isAnyMetadata ());
928932 },
929933 [&](const LoweredFunctionSignature::MetadataSourceParameter
930934 &metadataSrcParam) {
931935 emitNewParam ();
932- os << " void * _Nonnull " ;
936+ functionSignatureOS << " void * _Nonnull " ;
933937 },
934938 [&](const LoweredFunctionSignature::ContextParameter &) {
935939 emitNewParam ();
936- os << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
940+ functionSignatureOS << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
937941 },
938942 [&](const LoweredFunctionSignature::ErrorResultValue &) {
939943 emitNewParam ();
940- os << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
944+ functionSignatureOS
945+ << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
941946 });
942947 if (needsComma == false )
943948 // Emit 'void' in an empty parameter list for C function declarations.
944- os << " void" ;
945- os << ' )' ;
949+ functionSignatureOS << " void" ;
950+ functionSignatureOS << ' )' ;
951+ if (!resultingRepresentation.isUnsupported ())
952+ os << functionSignatureOS.str ();
946953 return resultingRepresentation;
947954 }
948955
949956 // Print out the C++ parameter types.
950957 auto params = FD->getParameters ();
951958 if (params->size ()) {
952959 if (HasParams)
953- os << " , " ;
960+ functionSignatureOS << " , " ;
954961 HasParams = true ;
955962 size_t paramIndex = 1 ;
956- llvm::interleaveComma (*params, os, [&](const ParamDecl *param) {
957- OptionalTypeKind argKind;
958- Type objTy;
959- std::tie (objTy, argKind) =
960- DeclAndTypePrinter::getObjectTypeAndOptionality (
961- param, param->getInterfaceType ());
962- std::string paramName =
963- param->getName ().empty () ? " " : param->getName ().str ().str ();
964- renameCxxParameterIfNeeded (FD, paramName);
965- // Always emit a named parameter for the C++ inline thunk to ensure it
966- // can be referenced in the body.
967- if (kind == FunctionSignatureKind::CxxInlineThunk && paramName.empty ()) {
968- llvm::raw_string_ostream os (paramName);
969- os << " _" << paramIndex;
970- }
971- resultingRepresentation.merge (
972- print (objTy, argKind, paramName, param->isInOut ()));
973- ++paramIndex;
974- });
975- if (resultingRepresentation.isUnsupported ())
963+ llvm::interleaveComma (
964+ *params, functionSignatureOS, [&](const ParamDecl *param) {
965+ OptionalTypeKind argKind;
966+ Type objTy;
967+ std::tie (objTy, argKind) =
968+ DeclAndTypePrinter::getObjectTypeAndOptionality (
969+ param, param->getInterfaceType ());
970+ std::string paramName =
971+ param->getName ().empty () ? " " : param->getName ().str ().str ();
972+ renameCxxParameterIfNeeded (FD, paramName);
973+ // Always emit a named parameter for the C++ inline thunk to ensure it
974+ // can be referenced in the body.
975+ if (kind == FunctionSignatureKind::CxxInlineThunk &&
976+ paramName.empty ()) {
977+ llvm::raw_string_ostream os (paramName);
978+ os << " _" << paramIndex;
979+ }
980+ resultingRepresentation.merge (
981+ print (objTy, argKind, paramName, param->isInOut ()));
982+ ++paramIndex;
983+ });
984+ if (resultingRepresentation.isUnsupported ()) {
976985 return resultingRepresentation;
986+ }
977987 }
978- os << ' )' ;
988+ functionSignatureOS << ' )' ;
979989 if (modifiers.isConst )
980- os << " const" ;
990+ functionSignatureOS << " const" ;
981991 if (modifiers.isNoexcept )
982- os << " noexcept" ;
992+ functionSignatureOS << " noexcept" ;
983993 if (modifiers.hasSymbolUSR )
984- ClangSyntaxPrinter (os).printSymbolUSRAttribute (
985- modifiers.symbolUSROverride ? modifiers.symbolUSROverride : FD);
994+ ClangSyntaxPrinter (functionSignatureOS)
995+ .printSymbolUSRAttribute (
996+ modifiers.symbolUSROverride ? modifiers.symbolUSROverride : FD);
997+ if (!resultingRepresentation.isUnsupported ())
998+ os << functionSignatureOS.str ();
986999 return resultingRepresentation;
9871000}
9881001
@@ -1468,8 +1481,9 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
14681481 std::tie (objTy, retKind) =
14691482 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
14701483
1471- auto s = printClangFunctionReturnType (objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1472- OutputLanguageMode::Cxx);
1484+ auto s = printClangFunctionReturnType (
1485+ os, objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1486+ OutputLanguageMode::Cxx);
14731487 os << " >(swift::Error(opaqueError));\n " ;
14741488 os << " #endif\n " ;
14751489
@@ -1478,7 +1492,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
14781492 os << " \n " ;
14791493 os << " return SWIFT_RETURN_THUNK(" ;
14801494 printClangFunctionReturnType (
1481- objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1495+ os, objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
14821496 OutputLanguageMode::Cxx);
14831497 os << " , returnValue);\n " ;
14841498 }
0 commit comments