@@ -531,10 +531,10 @@ class CFunctionSignatureTypePrinter
531531
532532ClangRepresentation
533533DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
534- Type ty, OptionalTypeKind optKind, ModuleDecl *moduleContext ,
535- OutputLanguageMode outputLang) {
534+ raw_ostream &stream, Type ty, OptionalTypeKind optKind,
535+ ModuleDecl *moduleContext, OutputLanguageMode outputLang) {
536536 CFunctionSignatureTypePrinter typePrinter (
537- os , cPrologueOS, typeMapping, outputLang, interopContext,
537+ stream , cPrologueOS, typeMapping, outputLang, interopContext,
538538 CFunctionSignatureTypePrinterModifierDelegate (), moduleContext,
539539 declPrinter, FunctionSignatureTypeUse::ReturnType);
540540 // Param for indirect return cannot be marked as inout
@@ -703,12 +703,14 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
703703 const AbstractFunctionDecl *FD, const LoweredFunctionSignature &signature,
704704 StringRef name, Type resultTy, FunctionSignatureKind kind,
705705 FunctionSignatureModifiers modifiers) {
706+ std::string functionSignature;
707+ llvm::raw_string_ostream functionSignatureOS (functionSignature);
706708 // Print any template and requires clauses for the
707709 // C++ class context to which this C++ member will belong to.
708710 if (const auto *typeDecl = modifiers.qualifierContext ) {
709711 assert (kind == FunctionSignatureKind::CxxInlineThunk);
710- ClangSyntaxPrinter (os). printNominalTypeOutsideMemberDeclTemplateSpecifiers (
711- typeDecl);
712+ ClangSyntaxPrinter (functionSignatureOS)
713+ . printNominalTypeOutsideMemberDeclTemplateSpecifiers ( typeDecl);
712714 }
713715 if (FD->isGeneric ()) {
714716 auto Signature = FD->getGenericSignature ().getCanonicalSignature ();
@@ -717,7 +719,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
717719
718720 // Print the template and requires clauses for this function.
719721 if (kind == FunctionSignatureKind::CxxInlineThunk)
720- ClangSyntaxPrinter (os ).printGenericSignature (Signature);
722+ ClangSyntaxPrinter (functionSignatureOS ).printGenericSignature (Signature);
721723 }
722724 if (const auto *enumDecl = FD->getDeclContext ()->getSelfEnumDecl ()) {
723725 // We cannot emit functions with the same name as an enum case yet, the resulting header
@@ -743,31 +745,31 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
743745 // FIXME: add support for noescape and PrintMultiPartType,
744746 // see DeclAndTypePrinter::print.
745747 CFunctionSignatureTypePrinter typePrinter (
746- os , cPrologueOS, typeMapping, outputLang, interopContext, delegate ,
747- emittedModule, declPrinter);
748+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
749+ interopContext, delegate, emittedModule, declPrinter);
748750 auto result = typePrinter.visit (ty, optionalKind, isInOutParam);
749751
750752 if (!name.empty ()) {
751- os << ' ' ;
752- ClangSyntaxPrinter (os ).printIdentifier (name);
753+ functionSignatureOS << ' ' ;
754+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (name);
753755 }
754756 return result;
755757 };
756758
757759 // Print any modifiers before the signature.
758760 if (modifiers.isStatic ) {
759761 assert (!modifiers.isConst );
760- os << " static " ;
762+ functionSignatureOS << " static " ;
761763 }
762764 if (modifiers.isInline )
763- ClangSyntaxPrinter (os ).printInlineForThunk ();
765+ ClangSyntaxPrinter (functionSignatureOS ).printInlineForThunk ();
764766
765767 ClangRepresentation resultingRepresentation =
766768 ClangRepresentation::representable;
767769
768770 // Print out the return type.
769771 if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
770- os << " swift::ThrowingResult<" ;
772+ functionSignatureOS << " swift::ThrowingResult<" ;
771773 if (kind == FunctionSignatureKind::CFunctionProto) {
772774 // First, verify that the C++ return type is representable.
773775 {
@@ -794,19 +796,20 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
794796 return ClangRepresentation::unsupported;
795797
796798 if (!directResultType) {
797- os << " void" ;
799+ functionSignatureOS << " void" ;
798800 } else {
799801 if (!printDirectReturnOrParamCType (
800- *directResultType, resultTy, emittedModule, os, cPrologueOS ,
801- typeMapping, interopContext, [&]() {
802+ *directResultType, resultTy, emittedModule, functionSignatureOS ,
803+ cPrologueOS, typeMapping, interopContext, [&]() {
802804 OptionalTypeKind retKind;
803805 Type objTy;
804806 std::tie (objTy, retKind) =
805807 DeclAndTypePrinter::getObjectTypeAndOptionality (FD,
806808 resultTy);
807809
808810 auto s = printClangFunctionReturnType (
809- objTy, retKind, emittedModule, outputLang);
811+ functionSignatureOS, objTy, retKind, emittedModule,
812+ outputLang);
810813 assert (!s.isUnsupported ());
811814 }))
812815 return ClangRepresentation::unsupported;
@@ -817,19 +820,19 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
817820 std::tie (objTy, retKind) =
818821 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
819822 if (resultingRepresentation
820- .merge (printClangFunctionReturnType (objTy, retKind, emittedModule,
821- outputLang))
823+ .merge (printClangFunctionReturnType (
824+ functionSignatureOS, objTy, retKind, emittedModule, outputLang))
822825 .isUnsupported ())
823826 return resultingRepresentation;
824827 }
825828 if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
826- os << " >" ;
827- os << ' ' ;
829+ functionSignatureOS << " >" ;
830+ functionSignatureOS << ' ' ;
828831 if (const auto *typeDecl = modifiers.qualifierContext )
829- ClangSyntaxPrinter (os). printNominalTypeQualifier (
830- typeDecl, typeDecl->getModuleContext ());
831- ClangSyntaxPrinter (os ).printIdentifier (name);
832- os << ' (' ;
832+ ClangSyntaxPrinter (functionSignatureOS)
833+ . printNominalTypeQualifier ( typeDecl, typeDecl->getModuleContext ());
834+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (name);
835+ functionSignatureOS << ' (' ;
833836
834837 bool HasParams = false ;
835838
@@ -855,7 +858,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
855858 bool needsComma = false ;
856859 auto emitNewParam = [&]() {
857860 if (needsComma)
858- os << " , " ;
861+ functionSignatureOS << " , " ;
859862 needsComma = true ;
860863 };
861864 auto printParamName = [&](const ParamDecl ¶m) {
@@ -864,8 +867,8 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
864867 if (param.isSelfParameter ())
865868 paramName = " _self" ;
866869 if (!paramName.empty ()) {
867- os << ' ' ;
868- ClangSyntaxPrinter (os ).printIdentifier (paramName);
870+ functionSignatureOS << ' ' ;
871+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (paramName);
869872 }
870873 };
871874 auto printParamCType = [&](const ParamDecl ¶m) {
@@ -875,9 +878,9 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
875878 DeclAndTypePrinter::getObjectTypeAndOptionality (
876879 ¶m, param.getInterfaceType ());
877880 CFunctionSignatureTypePrinter typePrinter (
878- os , cPrologueOS, typeMapping, outputLang, interopContext ,
879- CFunctionSignatureTypePrinterModifierDelegate (), emittedModule ,
880- declPrinter);
881+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
882+ interopContext, CFunctionSignatureTypePrinterModifierDelegate (),
883+ emittedModule, declPrinter);
881884 auto s = typePrinter.visit (ty, optionalKind, param.isInOut ());
882885 assert (!s.isUnsupported ());
883886 };
@@ -886,22 +889,22 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
886889 &indirectResult) {
887890 emitNewParam ();
888891 if (indirectResult.hasSRet ())
889- os << " SWIFT_INDIRECT_RESULT " ;
892+ functionSignatureOS << " SWIFT_INDIRECT_RESULT " ;
890893 // FIXME: it would be nice to print out the C struct type here.
891- os << " void * _Nonnull" ;
894+ functionSignatureOS << " void * _Nonnull" ;
892895 },
893896 [&](const LoweredFunctionSignature::DirectParameter ¶m) {
894897 emitNewParam ();
895898 printDirectReturnOrParamCType (
896- param, param.getParamDecl ().getInterfaceType (), emittedModule, os,
897- cPrologueOS, typeMapping, interopContext,
899+ param, param.getParamDecl ().getInterfaceType (), emittedModule,
900+ functionSignatureOS, cPrologueOS, typeMapping, interopContext,
898901 [&]() { printParamCType (param.getParamDecl ()); });
899902 printParamName (param.getParamDecl ());
900903 },
901904 [&](const LoweredFunctionSignature::IndirectParameter ¶m) {
902905 emitNewParam ();
903906 if (param.getParamDecl ().isSelfParameter ())
904- os << " SWIFT_CONTEXT " ;
907+ functionSignatureOS << " SWIFT_CONTEXT " ;
905908 bool isConst =
906909 !param.getParamDecl ().isInOut () &&
907910 !(param.getParamDecl ().isSelfParameter () &&
@@ -910,7 +913,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
910913 .getInterfaceType ()
911914 ->isAnyClassReferenceType ());
912915 if (isConst)
913- os << " const " ;
916+ functionSignatureOS << " const " ;
914917 if (isKnownCType (param.getParamDecl ().getInterfaceType (),
915918 typeMapping) ||
916919 (!param.getParamDecl ().getInterfaceType ()->hasTypeParameter () &&
@@ -919,76 +922,86 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
919922 ->isAnyClassReferenceType ()))
920923 printParamCType (param.getParamDecl ());
921924 else
922- os << " void * _Nonnull" ;
925+ functionSignatureOS << " void * _Nonnull" ;
923926 printParamName (param.getParamDecl ());
924927 },
925928 [&](const LoweredFunctionSignature::GenericRequirementParameter
926929 &genericRequirementParam) {
927930 emitNewParam ();
928- os << " void * _Nonnull " ;
931+ functionSignatureOS << " void * _Nonnull " ;
929932 auto reqt = genericRequirementParam.getRequirement ();
930933 if (reqt.isAnyWitnessTable ())
931- ClangSyntaxPrinter (os).printBaseName (reqt.getProtocol ());
934+ ClangSyntaxPrinter (functionSignatureOS)
935+ .printBaseName (reqt.getProtocol ());
932936 else
933937 assert (reqt.isAnyMetadata ());
934938 },
935939 [&](const LoweredFunctionSignature::MetadataSourceParameter
936940 &metadataSrcParam) {
937941 emitNewParam ();
938- os << " void * _Nonnull " ;
942+ functionSignatureOS << " void * _Nonnull " ;
939943 },
940944 [&](const LoweredFunctionSignature::ContextParameter &) {
941945 emitNewParam ();
942- os << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
946+ functionSignatureOS << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
943947 },
944948 [&](const LoweredFunctionSignature::ErrorResultValue &) {
945949 emitNewParam ();
946- os << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
950+ functionSignatureOS
951+ << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
947952 });
948953 if (needsComma == false )
949954 // Emit 'void' in an empty parameter list for C function declarations.
950- os << " void" ;
951- os << ' )' ;
955+ functionSignatureOS << " void" ;
956+ functionSignatureOS << ' )' ;
957+ if (!resultingRepresentation.isUnsupported ())
958+ os << functionSignatureOS.str ();
952959 return resultingRepresentation;
953960 }
954961
955962 // Print out the C++ parameter types.
956963 auto params = FD->getParameters ();
957964 if (params->size ()) {
958965 if (HasParams)
959- os << " , " ;
966+ functionSignatureOS << " , " ;
960967 HasParams = true ;
961968 size_t paramIndex = 1 ;
962- llvm::interleaveComma (*params, os, [&](const ParamDecl *param) {
963- OptionalTypeKind argKind;
964- Type objTy;
965- std::tie (objTy, argKind) =
966- DeclAndTypePrinter::getObjectTypeAndOptionality (
967- param, param->getInterfaceType ());
968- std::string paramName =
969- param->getName ().empty () ? " " : param->getName ().str ().str ();
970- renameCxxParameterIfNeeded (FD, paramName);
971- // Always emit a named parameter for the C++ inline thunk to ensure it
972- // can be referenced in the body.
973- if (kind == FunctionSignatureKind::CxxInlineThunk && paramName.empty ()) {
974- llvm::raw_string_ostream os (paramName);
975- os << " _" << paramIndex;
976- }
977- resultingRepresentation.merge (
978- print (objTy, argKind, paramName, param->isInOut ()));
979- ++paramIndex;
980- });
981- if (resultingRepresentation.isUnsupported ())
969+ llvm::interleaveComma (
970+ *params, functionSignatureOS, [&](const ParamDecl *param) {
971+ OptionalTypeKind argKind;
972+ Type objTy;
973+ std::tie (objTy, argKind) =
974+ DeclAndTypePrinter::getObjectTypeAndOptionality (
975+ param, param->getInterfaceType ());
976+ std::string paramName =
977+ param->getName ().empty () ? " " : param->getName ().str ().str ();
978+ renameCxxParameterIfNeeded (FD, paramName);
979+ // Always emit a named parameter for the C++ inline thunk to ensure it
980+ // can be referenced in the body.
981+ if (kind == FunctionSignatureKind::CxxInlineThunk &&
982+ paramName.empty ()) {
983+ llvm::raw_string_ostream os (paramName);
984+ os << " _" << paramIndex;
985+ }
986+ resultingRepresentation.merge (
987+ print (objTy, argKind, paramName, param->isInOut ()));
988+ ++paramIndex;
989+ });
990+ if (resultingRepresentation.isUnsupported ()) {
982991 return resultingRepresentation;
992+ }
983993 }
984- os << ' )' ;
994+ functionSignatureOS << ' )' ;
985995 if (modifiers.isConst )
986- os << " const" ;
996+ functionSignatureOS << " const" ;
987997 if (modifiers.isNoexcept )
988- os << " noexcept" ;
998+ functionSignatureOS << " noexcept" ;
989999 if (modifiers.hasSymbolUSR )
990- ClangSyntaxPrinter (os).printSymbolUSRAttribute (
991- modifiers.symbolUSROverride ? modifiers.symbolUSROverride : FD);
1000+ ClangSyntaxPrinter (functionSignatureOS)
1001+ .printSymbolUSRAttribute (
1002+ modifiers.symbolUSROverride ? modifiers.symbolUSROverride : FD);
1003+ if (!resultingRepresentation.isUnsupported ())
1004+ os << functionSignatureOS.str ();
9921005 return resultingRepresentation;
9931006}
9941007
@@ -1474,8 +1487,9 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
14741487 std::tie (objTy, retKind) =
14751488 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
14761489
1477- auto s = printClangFunctionReturnType (objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1478- OutputLanguageMode::Cxx);
1490+ auto s = printClangFunctionReturnType (
1491+ os, objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1492+ OutputLanguageMode::Cxx);
14791493 os << " >(swift::Error(opaqueError));\n " ;
14801494 os << " #endif\n " ;
14811495
@@ -1484,7 +1498,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
14841498 os << " \n " ;
14851499 os << " return SWIFT_RETURN_THUNK(" ;
14861500 printClangFunctionReturnType (
1487- objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1501+ os, objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
14881502 OutputLanguageMode::Cxx);
14891503 os << " , returnValue);\n " ;
14901504 }
0 commit comments