@@ -86,7 +86,7 @@ struct CFunctionSignatureTypePrinterModifierDelegate {
86
86
// Prints types in the C function signature that corresponds to the
87
87
// native Swift function/method.
88
88
class CFunctionSignatureTypePrinter
89
- : public TypeVisitor<CFunctionSignatureTypePrinter, void ,
89
+ : public TypeVisitor<CFunctionSignatureTypePrinter, ClangRepresentation ,
90
90
Optional<OptionalTypeKind>, bool >,
91
91
private ClangSyntaxPrinter {
92
92
public:
@@ -123,68 +123,79 @@ class CFunctionSignatureTypePrinter
123
123
return true ;
124
124
}
125
125
126
- void visitType (TypeBase *Ty, Optional<OptionalTypeKind> optionalKind,
127
- bool isInOutParam) {
126
+ ClangRepresentation visitType (TypeBase *Ty,
127
+ Optional<OptionalTypeKind> optionalKind,
128
+ bool isInOutParam) {
128
129
assert (Ty->getDesugaredType () == Ty && " unhandled sugared type" );
129
130
os << " /* " ;
130
131
Ty->print (os);
131
132
os << " */" ;
133
+ return ClangRepresentation::unsupported;
132
134
}
133
135
134
- void visitTupleType (TupleType *TT, Optional<OptionalTypeKind> optionalKind,
135
- bool isInOutParam) {
136
+ ClangRepresentation visitTupleType (TupleType *TT,
137
+ Optional<OptionalTypeKind> optionalKind,
138
+ bool isInOutParam) {
136
139
assert (TT->getNumElements () == 0 );
137
140
// FIXME: Handle non-void type.
138
141
os << " void" ;
142
+ return ClangRepresentation::representable;
139
143
}
140
144
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) {
144
149
const TypeAliasDecl *alias = aliasTy->getDecl ();
145
150
if (printIfKnownSimpleType (alias, optionalKind, isInOutParam))
146
- return ;
151
+ return ClangRepresentation::representable ;
147
152
148
- visitPart (aliasTy->getSinglyDesugaredType (), optionalKind, isInOutParam);
153
+ return visitPart (aliasTy->getSinglyDesugaredType (), optionalKind,
154
+ isInOutParam);
149
155
}
150
156
151
- void visitClassType (ClassType *CT, Optional<OptionalTypeKind> optionalKind,
152
- bool isInOutParam) {
157
+ ClangRepresentation visitClassType (ClassType *CT,
158
+ Optional<OptionalTypeKind> optionalKind,
159
+ bool isInOutParam) {
153
160
// FIXME: handle optionalKind.
154
161
if (languageMode != OutputLanguageMode::Cxx) {
155
162
if (modifiersDelegate.prefixIndirectlyPassedParamTypeInC )
156
163
(*modifiersDelegate.prefixIndirectlyPassedParamTypeInC )(os);
157
164
os << " void * _Nonnull" ;
158
165
if (isInOutParam)
159
166
os << " * _Nonnull" ;
160
- return ;
167
+ return ClangRepresentation::representable ;
161
168
}
162
169
if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
163
170
os << " const " ;
164
171
ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
165
172
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
166
173
os << " &" ;
174
+ return ClangRepresentation::representable;
167
175
}
168
176
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);
172
181
}
173
182
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);
177
187
}
178
188
179
- void visitValueType (NominalType *NT, Optional<OptionalTypeKind> optionalKind,
180
- bool isInOutParam) {
189
+ ClangRepresentation visitValueType (NominalType *NT,
190
+ Optional<OptionalTypeKind> optionalKind,
191
+ bool isInOutParam) {
181
192
assert (isa<StructType>(NT) || isa<EnumType>(NT));
182
193
const auto *decl = NT->getNominalOrBoundGenericNominal ();
183
194
assert (isa<StructDecl>(decl) || isa<EnumDecl>(decl));
184
195
185
196
// Handle known type names.
186
197
if (printIfKnownSimpleType (decl, optionalKind, isInOutParam))
187
- return ;
198
+ return ClangRepresentation::representable ;
188
199
// FIXME: Handle optional structures.
189
200
if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
190
201
if (languageMode != OutputLanguageMode::Cxx &&
@@ -207,6 +218,7 @@ class CFunctionSignatureTypePrinter
207
218
} else
208
219
ClangValueTypePrinter (os, cPrologueOS, typeMapping, interopContext)
209
220
.printValueTypeReturnType (decl, languageMode, moduleContext);
221
+ return ClangRepresentation::representable;
210
222
}
211
223
212
224
bool printIfKnownGenericStruct (const BoundGenericStructType *BGT,
@@ -233,38 +245,43 @@ class CFunctionSignatureTypePrinter
233
245
return true ;
234
246
}
235
247
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) {
239
252
if (printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
240
- return ;
253
+ return ClangRepresentation::representable;
254
+ return ClangRepresentation::unsupported;
241
255
}
242
256
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) {
246
261
// FIXME: handle optionalKind.
247
262
if (typeUseKind == FunctionSignatureTypeUse::ReturnType) {
248
263
// generic is always returned indirectly in C signature.
249
264
assert (languageMode == OutputLanguageMode::Cxx);
250
265
os << genericTpt->getName ();
251
- return ;
266
+ return ClangRepresentation::representable ;
252
267
}
253
268
if (!isInOutParam)
254
269
os << " const " ;
255
270
if (languageMode == OutputLanguageMode::Cxx) {
256
271
// Pass a reference to a template type.
257
272
os << genericTpt->getName ();
258
273
os << " &" ;
259
- return ;
274
+ return ClangRepresentation::representable ;
260
275
}
261
276
// Pass an opaque param in C mode.
262
277
os << " void * _Nonnull" ;
278
+ return ClangRepresentation::representable;
263
279
}
264
280
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);
268
285
}
269
286
270
287
private:
@@ -279,18 +296,19 @@ class CFunctionSignatureTypePrinter
279
296
280
297
} // end namespace
281
298
282
- void DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
299
+ ClangRepresentation
300
+ DeclAndTypeClangFunctionPrinter::printClangFunctionReturnType (
283
301
Type ty, OptionalTypeKind optKind, ModuleDecl *moduleContext,
284
302
OutputLanguageMode outputLang) {
285
303
CFunctionSignatureTypePrinter typePrinter (
286
304
os, cPrologueOS, typeMapping, outputLang, interopContext,
287
305
CFunctionSignatureTypePrinterModifierDelegate (), moduleContext,
288
306
FunctionSignatureTypeUse::ReturnType);
289
307
// Param for indirect return cannot be marked as inout
290
- typePrinter.visit (ty, optKind, /* isInOutParam=*/ false );
308
+ return typePrinter.visit (ty, optKind, /* isInOutParam=*/ false );
291
309
}
292
310
293
- void DeclAndTypeClangFunctionPrinter::printFunctionSignature (
311
+ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature (
294
312
const AbstractFunctionDecl *FD, StringRef name, Type resultTy,
295
313
FunctionSignatureKind kind, ArrayRef<AdditionalParam> additionalParams,
296
314
FunctionSignatureModifiers modifiers) {
@@ -321,19 +339,21 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
321
339
auto print =
322
340
[&, this ](Type ty, Optional<OptionalTypeKind> optionalKind,
323
341
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
+ };
337
357
338
358
// Print any modifiers before the signature.
339
359
if (modifiers.isStatic ) {
@@ -343,6 +363,9 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
343
363
if (modifiers.isInline )
344
364
os << " inline " ;
345
365
366
+ ClangRepresentation resultingRepresentation =
367
+ ClangRepresentation::representable;
368
+
346
369
// Print out the return type.
347
370
bool isIndirectReturnType =
348
371
kind == FunctionSignatureKind::CFunctionProto &&
@@ -355,7 +378,11 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
355
378
Type objTy;
356
379
std::tie (objTy, retKind) =
357
380
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;
359
386
} else {
360
387
os << " void" ;
361
388
}
@@ -398,9 +425,12 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
398
425
llvm::raw_string_ostream os (paramName);
399
426
os << " _" << paramIndex;
400
427
}
401
- print (objTy, argKind, paramName, param->isInOut ());
428
+ resultingRepresentation.merge (
429
+ print (objTy, argKind, paramName, param->isInOut ()));
402
430
++paramIndex;
403
431
});
432
+ if (resultingRepresentation.isUnsupported ())
433
+ return resultingRepresentation;
404
434
}
405
435
if (additionalParams.size ()) {
406
436
assert (kind == FunctionSignatureKind::CFunctionProto);
@@ -419,8 +449,9 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
419
449
(*delegate.prefixIndirectlyPassedParamTypeInC )(os);
420
450
os << " void * _Nonnull _self" ;
421
451
} 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));
424
455
}
425
456
} else if (param.role == AdditionalParam::Role::Error) {
426
457
os << " SWIFT_ERROR_RESULT " ;
@@ -440,6 +471,7 @@ void DeclAndTypeClangFunctionPrinter::printFunctionSignature(
440
471
os << ' )' ;
441
472
if (modifiers.isConst )
442
473
os << " const" ;
474
+ return resultingRepresentation;
443
475
}
444
476
445
477
void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse (
0 commit comments