@@ -86,7 +86,7 @@ struct CFunctionSignatureTypePrinterModifierDelegate {
8686// Prints types in the C function signature that corresponds to the
8787// native Swift function/method.
8888class CFunctionSignatureTypePrinter
89- : public TypeVisitor<CFunctionSignatureTypePrinter, void ,
89+ : public TypeVisitor<CFunctionSignatureTypePrinter, ClangRepresentation ,
9090 Optional<OptionalTypeKind>, bool >,
9191 private ClangSyntaxPrinter {
9292public:
@@ -123,68 +123,79 @@ class CFunctionSignatureTypePrinter
123123 return true ;
124124 }
125125
126- void visitType (TypeBase *Ty, Optional<OptionalTypeKind> optionalKind,
127- bool isInOutParam) {
126+ ClangRepresentation visitType (TypeBase *Ty,
127+ Optional<OptionalTypeKind> optionalKind,
128+ bool isInOutParam) {
128129 assert (Ty->getDesugaredType () == Ty && " unhandled sugared type" );
129130 os << " /* " ;
130131 Ty->print (os);
131132 os << " */" ;
133+ return ClangRepresentation::unsupported;
132134 }
133135
134- void visitTupleType (TupleType *TT, Optional<OptionalTypeKind> optionalKind,
135- bool isInOutParam) {
136+ ClangRepresentation visitTupleType (TupleType *TT,
137+ Optional<OptionalTypeKind> optionalKind,
138+ bool isInOutParam) {
136139 assert (TT->getNumElements () == 0 );
137140 // FIXME: Handle non-void type.
138141 os << " void" ;
142+ return ClangRepresentation::representable;
139143 }
140144
141- void visitTypeAliasType (TypeAliasType *aliasTy,
142- Optional<OptionalTypeKind> optionalKind,
143- bool isInOutParam) {
145+ ClangRepresentation
146+ visitTypeAliasType (TypeAliasType *aliasTy,
147+ Optional<OptionalTypeKind> optionalKind,
148+ bool isInOutParam) {
144149 const TypeAliasDecl *alias = aliasTy->getDecl ();
145150 if (printIfKnownSimpleType (alias, optionalKind, isInOutParam))
146- return ;
151+ return ClangRepresentation::representable ;
147152
148- visitPart (aliasTy->getSinglyDesugaredType (), optionalKind, isInOutParam);
153+ return visitPart (aliasTy->getSinglyDesugaredType (), optionalKind,
154+ isInOutParam);
149155 }
150156
151- void visitClassType (ClassType *CT, Optional<OptionalTypeKind> optionalKind,
152- bool isInOutParam) {
157+ ClangRepresentation visitClassType (ClassType *CT,
158+ Optional<OptionalTypeKind> optionalKind,
159+ bool isInOutParam) {
153160 // FIXME: handle optionalKind.
154161 if (languageMode != OutputLanguageMode::Cxx) {
155162 if (modifiersDelegate.prefixIndirectlyPassedParamTypeInC )
156163 (*modifiersDelegate.prefixIndirectlyPassedParamTypeInC )(os);
157164 os << " void * _Nonnull" ;
158165 if (isInOutParam)
159166 os << " * _Nonnull" ;
160- return ;
167+ return ClangRepresentation::representable ;
161168 }
162169 if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
163170 os << " const " ;
164171 ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
165172 if (typeUseKind == FunctionSignatureTypeUse::ParamType)
166173 os << " &" ;
174+ return ClangRepresentation::representable;
167175 }
168176
169- void visitEnumType (EnumType *ET, Optional<OptionalTypeKind> optionalKind,
170- bool isInOutParam) {
171- visitValueType (ET, optionalKind, isInOutParam);
177+ ClangRepresentation visitEnumType (EnumType *ET,
178+ Optional<OptionalTypeKind> optionalKind,
179+ bool isInOutParam) {
180+ return visitValueType (ET, optionalKind, isInOutParam);
172181 }
173182
174- void visitStructType (StructType *ST, Optional<OptionalTypeKind> optionalKind,
175- bool isInOutParam) {
176- visitValueType (ST, optionalKind, isInOutParam);
183+ ClangRepresentation visitStructType (StructType *ST,
184+ Optional<OptionalTypeKind> optionalKind,
185+ bool isInOutParam) {
186+ return visitValueType (ST, optionalKind, isInOutParam);
177187 }
178188
179- void visitValueType (NominalType *NT, Optional<OptionalTypeKind> optionalKind,
180- bool isInOutParam) {
189+ ClangRepresentation visitValueType (NominalType *NT,
190+ Optional<OptionalTypeKind> optionalKind,
191+ bool isInOutParam) {
181192 assert (isa<StructType>(NT) || isa<EnumType>(NT));
182193 const auto *decl = NT->getNominalOrBoundGenericNominal ();
183194 assert (isa<StructDecl>(decl) || isa<EnumDecl>(decl));
184195
185196 // Handle known type names.
186197 if (printIfKnownSimpleType (decl, optionalKind, isInOutParam))
187- return ;
198+ return ClangRepresentation::representable ;
188199 // FIXME: Handle optional structures.
189200 if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
190201 if (languageMode != OutputLanguageMode::Cxx &&
@@ -207,6 +218,7 @@ class CFunctionSignatureTypePrinter
207218 } else
208219 ClangValueTypePrinter (os, cPrologueOS, typeMapping, interopContext)
209220 .printValueTypeReturnType (decl, languageMode, moduleContext);
221+ return ClangRepresentation::representable;
210222 }
211223
212224 bool printIfKnownGenericStruct (const BoundGenericStructType *BGT,
@@ -233,38 +245,43 @@ class CFunctionSignatureTypePrinter
233245 return true ;
234246 }
235247
236- void visitBoundGenericStructType (BoundGenericStructType *BGT,
237- Optional<OptionalTypeKind> optionalKind,
238- bool isInOutParam) {
248+ ClangRepresentation
249+ visitBoundGenericStructType (BoundGenericStructType *BGT,
250+ Optional<OptionalTypeKind> optionalKind,
251+ bool isInOutParam) {
239252 if (printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
240- return ;
253+ return ClangRepresentation::representable;
254+ return ClangRepresentation::unsupported;
241255 }
242256
243- void visitGenericTypeParamType (GenericTypeParamType *genericTpt,
244- Optional<OptionalTypeKind> optionalKind,
245- bool isInOutParam) {
257+ ClangRepresentation
258+ visitGenericTypeParamType (GenericTypeParamType *genericTpt,
259+ Optional<OptionalTypeKind> optionalKind,
260+ bool isInOutParam) {
246261 // FIXME: handle optionalKind.
247262 if (typeUseKind == FunctionSignatureTypeUse::ReturnType) {
248263 // generic is always returned indirectly in C signature.
249264 assert (languageMode == OutputLanguageMode::Cxx);
250265 os << genericTpt->getName ();
251- return ;
266+ return ClangRepresentation::representable ;
252267 }
253268 if (!isInOutParam)
254269 os << " const " ;
255270 if (languageMode == OutputLanguageMode::Cxx) {
256271 // Pass a reference to a template type.
257272 os << genericTpt->getName ();
258273 os << " &" ;
259- return ;
274+ return ClangRepresentation::representable ;
260275 }
261276 // Pass an opaque param in C mode.
262277 os << " void * _Nonnull" ;
278+ return ClangRepresentation::representable;
263279 }
264280
265- void visitPart (Type Ty, Optional<OptionalTypeKind> optionalKind,
266- bool isInOutParam) {
267- TypeVisitor::visit (Ty, optionalKind, isInOutParam);
281+ ClangRepresentation visitPart (Type Ty,
282+ Optional<OptionalTypeKind> optionalKind,
283+ bool isInOutParam) {
284+ return TypeVisitor::visit (Ty, optionalKind, isInOutParam);
268285 }
269286
270287private:
@@ -279,18 +296,19 @@ class CFunctionSignatureTypePrinter
279296
280297} // end namespace
281298
282- void DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
299+ ClangRepresentation
300+ DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
283301 Type ty, OptionalTypeKind optKind, ModuleDecl *moduleContext,
284302 OutputLanguageMode outputLang) {
285303 CFunctionSignatureTypePrinter typePrinter (
286304 os, cPrologueOS, typeMapping, outputLang, interopContext,
287305 CFunctionSignatureTypePrinterModifierDelegate (), moduleContext,
288306 FunctionSignatureTypeUse::ReturnType);
289307 // Param for indirect return cannot be marked as inout
290- typePrinter.visit (ty, optKind, /* isInOutParam=*/ false );
308+ return typePrinter.visit (ty, optKind, /* isInOutParam=*/ false );
291309}
292310
293- void DeclAndTypeClangFunctionPrinter::printFunctionSignature (
311+ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature (
294312 const AbstractFunctionDecl *FD, StringRef name, Type resultTy,
295313 FunctionSignatureKind kind, ArrayRef<AdditionalParam> additionalParams,
296314 FunctionSignatureModifiers modifiers) {
@@ -321,19 +339,21 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
321339 auto print =
322340 [&, this ](Type ty, Optional<OptionalTypeKind> optionalKind,
323341 StringRef name, bool isInOutParam,
324- CFunctionSignatureTypePrinterModifierDelegate delegate = {}) {
325- // FIXME: add support for noescape and PrintMultiPartType,
326- // see DeclAndTypePrinter::print.
327- CFunctionSignatureTypePrinter typePrinter (os, cPrologueOS, typeMapping,
328- outputLang, interopContext,
329- delegate, emittedModule);
330- typePrinter.visit (ty, optionalKind, isInOutParam);
331-
332- if (!name.empty ()) {
333- os << ' ' ;
334- ClangSyntaxPrinter (os).printIdentifier (name);
335- }
336- };
342+ CFunctionSignatureTypePrinterModifierDelegate delegate = {})
343+ -> ClangRepresentation {
344+ // FIXME: add support for noescape and PrintMultiPartType,
345+ // see DeclAndTypePrinter::print.
346+ CFunctionSignatureTypePrinter typePrinter (os, cPrologueOS, typeMapping,
347+ outputLang, interopContext,
348+ delegate, emittedModule);
349+ auto result = typePrinter.visit (ty, optionalKind, isInOutParam);
350+
351+ if (!name.empty ()) {
352+ os << ' ' ;
353+ ClangSyntaxPrinter (os).printIdentifier (name);
354+ }
355+ return result;
356+ };
337357
338358 // Print any modifiers before the signature.
339359 if (modifiers.isStatic ) {
@@ -343,6 +363,9 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
343363 if (modifiers.isInline )
344364 os << " inline " ;
345365
366+ ClangRepresentation resultingRepresentation =
367+ ClangRepresentation::representable;
368+
346369 // Print out the return type.
347370 bool isIndirectReturnType =
348371 kind == FunctionSignatureKind::CFunctionProto &&
@@ -355,7 +378,11 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
355378 Type objTy;
356379 std::tie (objTy, retKind) =
357380 DeclAndTypePrinter::getObjectTypeAndOptionality (FD, resultTy);
358- printClangFunctionReturnType (objTy, retKind, emittedModule, outputLang);
381+ if (resultingRepresentation
382+ .merge (printClangFunctionReturnType (objTy, retKind, emittedModule,
383+ outputLang))
384+ .isUnsupported ())
385+ return resultingRepresentation;
359386 } else {
360387 os << " void" ;
361388 }
@@ -398,9 +425,12 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
398425 llvm::raw_string_ostream os (paramName);
399426 os << " _" << paramIndex;
400427 }
401- print (objTy, argKind, paramName, param->isInOut ());
428+ resultingRepresentation.merge (
429+ print (objTy, argKind, paramName, param->isInOut ()));
402430 ++paramIndex;
403431 });
432+ if (resultingRepresentation.isUnsupported ())
433+ return resultingRepresentation;
404434 }
405435 if (additionalParams.size ()) {
406436 assert (kind == FunctionSignatureKind::CFunctionProto);
@@ -419,8 +449,9 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
419449 (*delegate.prefixIndirectlyPassedParamTypeInC )(os);
420450 os << " void * _Nonnull _self" ;
421451 } else {
422- print (param.type , OptionalTypeKind::OTK_None, " _self" ,
423- /* isInOut*/ false , delegate);
452+ resultingRepresentation.merge (
453+ print (param.type , OptionalTypeKind::OTK_None, " _self" ,
454+ /* isInOut*/ false , delegate));
424455 }
425456 } else if (param.role == AdditionalParam::Role::Error) {
426457 os << " SWIFT_ERROR_RESULT " ;
@@ -440,6 +471,7 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
440471 os << ' )' ;
441472 if (modifiers.isConst )
442473 os << " const" ;
474+ return resultingRepresentation;
443475}
444476
445477void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse (
0 commit comments