@@ -26,20 +26,6 @@ using namespace swift;
2626
2727namespace {
2828
29- class ClangFunctionSignatureTypePrinter : private ClangSyntaxPrinter {
30- public:
31- ClangFunctionSignatureTypePrinter (raw_ostream &os) : ClangSyntaxPrinter(os) {}
32-
33- void printIfSimpleType (StringRef name, bool canBeNullable,
34- Optional<OptionalTypeKind> optionalKind) {
35- os << name;
36- if (canBeNullable)
37- printNullability (optionalKind);
38- }
39-
40- void printVoidType () { os << " void" ; }
41- };
42-
4329// Prints types in the C function signature that corresponds to the
4430// native Swift function/method.
4531class CFunctionSignatureTypePrinter
@@ -55,16 +41,9 @@ class CFunctionSignatureTypePrinter
5541
5642 bool printIfKnownSimpleType (const TypeDecl *typeDecl,
5743 Optional<OptionalTypeKind> optionalKind) {
58- if (languageMode == OutputLanguageMode::Cxx) {
59- auto knownTypeInfo = typeMapping.getKnownCxxTypeInfo (typeDecl);
60- if (!knownTypeInfo)
61- return false ;
62- os << knownTypeInfo->name ;
63- if (knownTypeInfo->canBeNullable )
64- printNullability (optionalKind);
65- return true ;
66- }
67- auto knownTypeInfo = typeMapping.getKnownCTypeInfo (typeDecl);
44+ auto knownTypeInfo = languageMode == OutputLanguageMode::Cxx
45+ ? typeMapping.getKnownCxxTypeInfo (typeDecl)
46+ : typeMapping.getKnownCTypeInfo (typeDecl);
6847 if (!knownTypeInfo)
6948 return false ;
7049 os << knownTypeInfo->name ;
@@ -116,15 +95,17 @@ class CFunctionSignatureTypePrinter
11695
11796} // end namespace
11897
119- void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl (
120- FuncDecl *FD, StringRef name, Type resultTy) {
98+ void DeclAndTypeClangFunctionPrinter::printFunctionSignature (
99+ FuncDecl *FD, StringRef name, Type resultTy, FunctionSignatureKind kind) {
100+ OutputLanguageMode outputLang = kind == FunctionSignatureKind::CFunctionProto
101+ ? OutputLanguageMode::ObjC
102+ : OutputLanguageMode::Cxx;
121103 // FIXME: Might need a PrintMultiPartType here.
122- auto print = [this ](Type ty, Optional<OptionalTypeKind> optionalKind,
123- StringRef name) {
104+ auto print = [&, this ](Type ty, Optional<OptionalTypeKind> optionalKind,
105+ StringRef name) {
124106 // FIXME: add support for noescape and PrintMultiPartType,
125107 // see DeclAndTypePrinter::print.
126- CFunctionSignatureTypePrinter typePrinter (os, typeMapping,
127- OutputLanguageMode::ObjC);
108+ CFunctionSignatureTypePrinter typePrinter (os, typeMapping, outputLang);
128109 typePrinter.visit (ty, optionalKind);
129110
130111 if (!name.empty ()) {
@@ -134,59 +115,12 @@ void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCFunctionDecl(
134115 };
135116
136117 // Print out the return type.
137- OptionalTypeKind kind ;
118+ OptionalTypeKind retKind ;
138119 Type objTy;
139- std::tie (objTy, kind ) =
120+ std::tie (objTy, retKind ) =
140121 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
141- CFunctionSignatureTypePrinter typePrinter (os, typeMapping,
142- OutputLanguageMode::ObjC);
143- typePrinter.visit (objTy, kind);
144-
145- os << ' ' << name << ' (' ;
146-
147- // Print out the parameter types.
148- auto params = FD->getParameters ();
149- if (params->size ()) {
150- llvm::interleaveComma (*params, os, [&](const ParamDecl *param) {
151- OptionalTypeKind kind;
152- Type objTy;
153- std::tie (objTy, kind) = DeclAndTypePrinter::getObjectTypeAndOptionality (
154- param, param->getInterfaceType ());
155- StringRef paramName =
156- param->getName ().empty () ? " " : param->getName ().str ();
157- print (objTy, kind, paramName);
158- });
159- } else {
160- os << " void" ;
161- }
162- os << ' )' ;
163- }
164-
165- void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCxxFunctionDecl (
166- FuncDecl *FD, StringRef name, Type resultTy) {
167- // FIXME: Might need a PrintMultiPartType here.
168- auto print = [this ](Type ty, Optional<OptionalTypeKind> optionalKind,
169- StringRef name) {
170- // FIXME: add support for noescape and PrintMultiPartType,
171- // see DeclAndTypePrinter::print.
172- CFunctionSignatureTypePrinter typePrinter (os, typeMapping,
173- OutputLanguageMode::Cxx);
174- typePrinter.visit (ty, optionalKind);
175-
176- if (!name.empty ()) {
177- os << ' ' ;
178- ClangSyntaxPrinter (os).printIdentifier (name);
179- }
180- };
181-
182- // Print out the return type.
183- OptionalTypeKind kind;
184- Type objTy;
185- std::tie (objTy, kind) =
186- DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
187- CFunctionSignatureTypePrinter typePrinter (os, typeMapping,
188- OutputLanguageMode::Cxx);
189- typePrinter.visit (objTy, kind);
122+ CFunctionSignatureTypePrinter typePrinter (os, typeMapping, outputLang);
123+ typePrinter.visit (objTy, retKind);
190124
191125 os << ' ' << name << ' (' ;
192126
@@ -195,19 +129,25 @@ void DeclAndTypeClangFunctionPrinter::printFunctionDeclAsCxxFunctionDecl(
195129 if (params->size ()) {
196130 size_t paramIndex = 1 ;
197131 llvm::interleaveComma (*params, os, [&](const ParamDecl *param) {
198- OptionalTypeKind kind ;
132+ OptionalTypeKind argKind ;
199133 Type objTy;
200- std::tie (objTy, kind) = DeclAndTypePrinter::getObjectTypeAndOptionality (
201- param, param->getInterfaceType ());
134+ std::tie (objTy, argKind) =
135+ DeclAndTypePrinter::getObjectTypeAndOptionality (
136+ param, param->getInterfaceType ());
202137 std::string paramName =
203138 param->getName ().empty () ? " " : param->getName ().str ().str ();
204- if (paramName.empty ()) {
139+ // Always emit a named parameter for the C++ inline thunk to ensure it can
140+ // be referenced in the body.
141+ if (kind == FunctionSignatureKind::CxxInlineThunk && paramName.empty ()) {
205142 llvm::raw_string_ostream os (paramName);
206143 os << " _" << paramIndex;
207144 }
208- print (objTy, kind , paramName);
145+ print (objTy, argKind , paramName);
209146 ++paramIndex;
210147 });
148+ } else if (kind == FunctionSignatureKind::CFunctionProto) {
149+ // Emit 'void' in an empty parameter list for C function declarations.
150+ os << " void" ;
211151 }
212152 os << ' )' ;
213153}
0 commit comments