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