@@ -525,10 +525,10 @@ class CFunctionSignatureTypePrinter
525
525
526
526
ClangRepresentation
527
527
DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
528
- Type ty, OptionalTypeKind optKind, ModuleDecl *moduleContext ,
529
- OutputLanguageMode outputLang) {
528
+ raw_ostream &stream, Type ty, OptionalTypeKind optKind,
529
+ ModuleDecl *moduleContext, OutputLanguageMode outputLang) {
530
530
CFunctionSignatureTypePrinter typePrinter (
531
- os , cPrologueOS, typeMapping, outputLang, interopContext,
531
+ stream , cPrologueOS, typeMapping, outputLang, interopContext,
532
532
CFunctionSignatureTypePrinterModifierDelegate (), moduleContext,
533
533
declPrinter, FunctionSignatureTypeUse::ReturnType);
534
534
// Param for indirect return cannot be marked as inout
@@ -697,12 +697,14 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
697
697
const AbstractFunctionDecl *FD, const LoweredFunctionSignature &signature,
698
698
StringRef name, Type resultTy, FunctionSignatureKind kind,
699
699
FunctionSignatureModifiers modifiers) {
700
+ std::string functionSignature;
701
+ llvm::raw_string_ostream functionSignatureOS (functionSignature);
700
702
// Print any template and requires clauses for the
701
703
// C++ class context to which this C++ member will belong to.
702
704
if (const auto *typeDecl = modifiers.qualifierContext ) {
703
705
assert (kind == FunctionSignatureKind::CxxInlineThunk);
704
- ClangSyntaxPrinter (os). printNominalTypeOutsideMemberDeclTemplateSpecifiers (
705
- typeDecl);
706
+ ClangSyntaxPrinter (functionSignatureOS)
707
+ . printNominalTypeOutsideMemberDeclTemplateSpecifiers ( typeDecl);
706
708
}
707
709
if (FD->isGeneric ()) {
708
710
auto Signature = FD->getGenericSignature ().getCanonicalSignature ();
@@ -711,7 +713,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
711
713
712
714
// Print the template and requires clauses for this function.
713
715
if (kind == FunctionSignatureKind::CxxInlineThunk)
714
- ClangSyntaxPrinter (os ).printGenericSignature (Signature);
716
+ ClangSyntaxPrinter (functionSignatureOS ).printGenericSignature (Signature);
715
717
}
716
718
if (const auto *enumDecl = FD->getDeclContext ()->getSelfEnumDecl ()) {
717
719
// We cannot emit functions with the same name as an enum case yet, the resulting header
@@ -737,31 +739,31 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
737
739
// FIXME: add support for noescape and PrintMultiPartType,
738
740
// see DeclAndTypePrinter::print.
739
741
CFunctionSignatureTypePrinter typePrinter (
740
- os , cPrologueOS, typeMapping, outputLang, interopContext, delegate ,
741
- emittedModule, declPrinter);
742
+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
743
+ interopContext, delegate, emittedModule, declPrinter);
742
744
auto result = typePrinter.visit (ty, optionalKind, isInOutParam);
743
745
744
746
if (!name.empty ()) {
745
- os << ' ' ;
746
- ClangSyntaxPrinter (os ).printIdentifier (name);
747
+ functionSignatureOS << ' ' ;
748
+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (name);
747
749
}
748
750
return result;
749
751
};
750
752
751
753
// Print any modifiers before the signature.
752
754
if (modifiers.isStatic ) {
753
755
assert (!modifiers.isConst );
754
- os << " static " ;
756
+ functionSignatureOS << " static " ;
755
757
}
756
758
if (modifiers.isInline )
757
- ClangSyntaxPrinter (os ).printInlineForThunk ();
759
+ ClangSyntaxPrinter (functionSignatureOS ).printInlineForThunk ();
758
760
759
761
ClangRepresentation resultingRepresentation =
760
762
ClangRepresentation::representable;
761
763
762
764
// Print out the return type.
763
765
if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
764
- os << " swift::ThrowingResult<" ;
766
+ functionSignatureOS << " swift::ThrowingResult<" ;
765
767
if (kind == FunctionSignatureKind::CFunctionProto) {
766
768
// First, verify that the C++ return type is representable.
767
769
{
@@ -788,19 +790,20 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
788
790
return ClangRepresentation::unsupported;
789
791
790
792
if (!directResultType) {
791
- os << " void" ;
793
+ functionSignatureOS << " void" ;
792
794
} else {
793
795
if (!printDirectReturnOrParamCType (
794
- *directResultType, resultTy, emittedModule, os, cPrologueOS ,
795
- typeMapping, interopContext, [&]() {
796
+ *directResultType, resultTy, emittedModule, functionSignatureOS ,
797
+ cPrologueOS, typeMapping, interopContext, [&]() {
796
798
OptionalTypeKind retKind;
797
799
Type objTy;
798
800
std::tie (objTy, retKind) =
799
801
DeclAndTypePrinter::getObjectTypeAndOptionality (FD,
800
802
resultTy);
801
803
802
804
auto s = printClangFunctionReturnType (
803
- objTy, retKind, emittedModule, outputLang);
805
+ functionSignatureOS, objTy, retKind, emittedModule,
806
+ outputLang);
804
807
assert (!s.isUnsupported ());
805
808
}))
806
809
return ClangRepresentation::unsupported;
@@ -811,19 +814,19 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
811
814
std::tie (objTy, retKind) =
812
815
DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
813
816
if (resultingRepresentation
814
- .merge (printClangFunctionReturnType (objTy, retKind, emittedModule,
815
- outputLang))
817
+ .merge (printClangFunctionReturnType (
818
+ functionSignatureOS, objTy, retKind, emittedModule, outputLang))
816
819
.isUnsupported ())
817
820
return resultingRepresentation;
818
821
}
819
822
if (FD->hasThrows () && outputLang == OutputLanguageMode::Cxx)
820
- os << " >" ;
821
- os << ' ' ;
823
+ functionSignatureOS << " >" ;
824
+ functionSignatureOS << ' ' ;
822
825
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 << ' (' ;
827
830
828
831
bool HasParams = false ;
829
832
@@ -849,7 +852,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
849
852
bool needsComma = false ;
850
853
auto emitNewParam = [&]() {
851
854
if (needsComma)
852
- os << " , " ;
855
+ functionSignatureOS << " , " ;
853
856
needsComma = true ;
854
857
};
855
858
auto printParamName = [&](const ParamDecl ¶m) {
@@ -858,8 +861,8 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
858
861
if (param.isSelfParameter ())
859
862
paramName = " _self" ;
860
863
if (!paramName.empty ()) {
861
- os << ' ' ;
862
- ClangSyntaxPrinter (os ).printIdentifier (paramName);
864
+ functionSignatureOS << ' ' ;
865
+ ClangSyntaxPrinter (functionSignatureOS ).printIdentifier (paramName);
863
866
}
864
867
};
865
868
auto printParamCType = [&](const ParamDecl ¶m) {
@@ -869,9 +872,9 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
869
872
DeclAndTypePrinter::getObjectTypeAndOptionality (
870
873
¶m, param.getInterfaceType ());
871
874
CFunctionSignatureTypePrinter typePrinter (
872
- os , cPrologueOS, typeMapping, outputLang, interopContext ,
873
- CFunctionSignatureTypePrinterModifierDelegate (), emittedModule ,
874
- declPrinter);
875
+ functionSignatureOS , cPrologueOS, typeMapping, outputLang,
876
+ interopContext, CFunctionSignatureTypePrinterModifierDelegate (),
877
+ emittedModule, declPrinter);
875
878
auto s = typePrinter.visit (ty, optionalKind, param.isInOut ());
876
879
assert (!s.isUnsupported ());
877
880
};
@@ -880,22 +883,22 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
880
883
&indirectResult) {
881
884
emitNewParam ();
882
885
if (indirectResult.hasSRet ())
883
- os << " SWIFT_INDIRECT_RESULT " ;
886
+ functionSignatureOS << " SWIFT_INDIRECT_RESULT " ;
884
887
// FIXME: it would be nice to print out the C struct type here.
885
- os << " void * _Nonnull" ;
888
+ functionSignatureOS << " void * _Nonnull" ;
886
889
},
887
890
[&](const LoweredFunctionSignature::DirectParameter ¶m) {
888
891
emitNewParam ();
889
892
printDirectReturnOrParamCType (
890
- param, param.getParamDecl ().getInterfaceType (), emittedModule, os,
891
- cPrologueOS, typeMapping, interopContext,
893
+ param, param.getParamDecl ().getInterfaceType (), emittedModule,
894
+ functionSignatureOS, cPrologueOS, typeMapping, interopContext,
892
895
[&]() { printParamCType (param.getParamDecl ()); });
893
896
printParamName (param.getParamDecl ());
894
897
},
895
898
[&](const LoweredFunctionSignature::IndirectParameter ¶m) {
896
899
emitNewParam ();
897
900
if (param.getParamDecl ().isSelfParameter ())
898
- os << " SWIFT_CONTEXT " ;
901
+ functionSignatureOS << " SWIFT_CONTEXT " ;
899
902
bool isConst =
900
903
!param.getParamDecl ().isInOut () &&
901
904
!(param.getParamDecl ().isSelfParameter () &&
@@ -904,7 +907,7 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
904
907
.getInterfaceType ()
905
908
->isAnyClassReferenceType ());
906
909
if (isConst)
907
- os << " const " ;
910
+ functionSignatureOS << " const " ;
908
911
if (isKnownCType (param.getParamDecl ().getInterfaceType (),
909
912
typeMapping) ||
910
913
(!param.getParamDecl ().getInterfaceType ()->hasTypeParameter () &&
@@ -913,76 +916,86 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
913
916
->isAnyClassReferenceType ()))
914
917
printParamCType (param.getParamDecl ());
915
918
else
916
- os << " void * _Nonnull" ;
919
+ functionSignatureOS << " void * _Nonnull" ;
917
920
printParamName (param.getParamDecl ());
918
921
},
919
922
[&](const LoweredFunctionSignature::GenericRequirementParameter
920
923
&genericRequirementParam) {
921
924
emitNewParam ();
922
- os << " void * _Nonnull " ;
925
+ functionSignatureOS << " void * _Nonnull " ;
923
926
auto reqt = genericRequirementParam.getRequirement ();
924
927
if (reqt.isAnyWitnessTable ())
925
- ClangSyntaxPrinter (os).printBaseName (reqt.getProtocol ());
928
+ ClangSyntaxPrinter (functionSignatureOS)
929
+ .printBaseName (reqt.getProtocol ());
926
930
else
927
931
assert (reqt.isAnyMetadata ());
928
932
},
929
933
[&](const LoweredFunctionSignature::MetadataSourceParameter
930
934
&metadataSrcParam) {
931
935
emitNewParam ();
932
- os << " void * _Nonnull " ;
936
+ functionSignatureOS << " void * _Nonnull " ;
933
937
},
934
938
[&](const LoweredFunctionSignature::ContextParameter &) {
935
939
emitNewParam ();
936
- os << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
940
+ functionSignatureOS << " SWIFT_CONTEXT void * _Nonnull _ctx" ;
937
941
},
938
942
[&](const LoweredFunctionSignature::ErrorResultValue &) {
939
943
emitNewParam ();
940
- os << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
944
+ functionSignatureOS
945
+ << " SWIFT_ERROR_RESULT void * _Nullable * _Nullable _error" ;
941
946
});
942
947
if (needsComma == false )
943
948
// 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 ();
946
953
return resultingRepresentation;
947
954
}
948
955
949
956
// Print out the C++ parameter types.
950
957
auto params = FD->getParameters ();
951
958
if (params->size ()) {
952
959
if (HasParams)
953
- os << " , " ;
960
+ functionSignatureOS << " , " ;
954
961
HasParams = true ;
955
962
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 ()) {
976
985
return resultingRepresentation;
986
+ }
977
987
}
978
- os << ' )' ;
988
+ functionSignatureOS << ' )' ;
979
989
if (modifiers.isConst )
980
- os << " const" ;
990
+ functionSignatureOS << " const" ;
981
991
if (modifiers.isNoexcept )
982
- os << " noexcept" ;
992
+ functionSignatureOS << " noexcept" ;
983
993
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 ();
986
999
return resultingRepresentation;
987
1000
}
988
1001
@@ -1468,8 +1481,9 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
1468
1481
std::tie (objTy, retKind) =
1469
1482
DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
1470
1483
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);
1473
1487
os << " >(swift::Error(opaqueError));\n " ;
1474
1488
os << " #endif\n " ;
1475
1489
@@ -1478,7 +1492,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
1478
1492
os << " \n " ;
1479
1493
os << " return SWIFT_RETURN_THUNK(" ;
1480
1494
printClangFunctionReturnType (
1481
- objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1495
+ os, objTy, retKind, const_cast <ModuleDecl *>(moduleContext),
1482
1496
OutputLanguageMode::Cxx);
1483
1497
os << " , returnValue);\n " ;
1484
1498
}
0 commit comments