@@ -186,15 +186,34 @@ class CFunctionSignatureTypePrinter
186
186
auto knownTypeInfo = getKnownTypeInfo (typeDecl, typeMapping, languageMode);
187
187
if (!knownTypeInfo)
188
188
return false ;
189
- os << knownTypeInfo->name ;
190
- if (knownTypeInfo->canBeNullable ) {
191
- printNullability (optionalKind);
192
- }
189
+ bool shouldPrintOptional = optionalKind && *optionalKind != OTK_None &&
190
+ !knownTypeInfo->canBeNullable ;
191
+ if (!isInOutParam && shouldPrintOptional &&
192
+ typeUseKind == FunctionSignatureTypeUse::ParamType)
193
+ os << " const " ;
194
+ printOptional (shouldPrintOptional ? optionalKind : llvm::None, [&]() {
195
+ os << knownTypeInfo->name ;
196
+ if (knownTypeInfo->canBeNullable ) {
197
+ printNullability (optionalKind);
198
+ }
199
+ });
200
+ if (!isInOutParam && shouldPrintOptional &&
201
+ typeUseKind == FunctionSignatureTypeUse::ParamType)
202
+ os << ' &' ;
193
203
if (isInOutParam)
194
204
printInoutTypeModifier ();
195
205
return true ;
196
206
}
197
207
208
+ void printOptional (Optional<OptionalTypeKind> optionalKind,
209
+ llvm::function_ref<void ()> body) {
210
+ if (!optionalKind || optionalKind == OTK_None)
211
+ return body ();
212
+ os << " Swift::Optional<" ;
213
+ body ();
214
+ os << ' >' ;
215
+ }
216
+
198
217
ClangRepresentation visitType (TypeBase *Ty,
199
218
Optional<OptionalTypeKind> optionalKind,
200
219
bool isInOutParam) {
@@ -211,6 +230,9 @@ class CFunctionSignatureTypePrinter
211
230
if (TT->getNumElements () > 0 )
212
231
// FIXME: Handle non-void type.
213
232
return ClangRepresentation::unsupported;
233
+ // FIXME: how to support `()` parameters.
234
+ if (typeUseKind != FunctionSignatureTypeUse::ReturnType)
235
+ return ClangRepresentation::unsupported;
214
236
os << " void" ;
215
237
return ClangRepresentation::representable;
216
238
}
@@ -238,14 +260,18 @@ class CFunctionSignatureTypePrinter
238
260
bool isInOutParam) {
239
261
// FIXME: handle optionalKind.
240
262
if (languageMode != OutputLanguageMode::Cxx) {
241
- os << " void * _Nonnull" ;
263
+ os << " void * "
264
+ << (!optionalKind || *optionalKind == OTK_None ? " _Nonnull"
265
+ : " _Nullable" );
242
266
if (isInOutParam)
243
267
os << " * _Nonnull" ;
244
268
return ClangRepresentation::representable;
245
269
}
246
270
if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
247
271
os << " const " ;
248
- ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
272
+ printOptional (optionalKind, [&]() {
273
+ ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
274
+ });
249
275
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
250
276
os << " &" ;
251
277
return ClangRepresentation::representable;
@@ -295,9 +321,6 @@ class CFunctionSignatureTypePrinter
295
321
if (!declPrinter.shouldInclude (decl))
296
322
return ClangRepresentation::unsupported; // FIXME: propagate why it's not
297
323
// exposed.
298
- // FIXME: Support Optional<T>.
299
- if (optionalKind && *optionalKind != OTK_None)
300
- return ClangRepresentation::unsupported;
301
324
// Only C++ mode supports struct types.
302
325
if (languageMode != OutputLanguageMode::Cxx)
303
326
return ClangRepresentation::unsupported;
@@ -309,22 +332,27 @@ class CFunctionSignatureTypePrinter
309
332
if (typeUseKind == FunctionSignatureTypeUse::ParamType &&
310
333
!isInOutParam)
311
334
os << " const " ;
312
- handler.printTypeName (os);
335
+ printOptional (optionalKind, [&]() { handler.printTypeName (os); } );
313
336
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
314
337
os << ' &' ;
315
338
return ClangRepresentation::representable;
316
339
}
317
340
318
- // FIXME: Handle optional structures.
319
341
if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
320
342
if (!isInOutParam) {
321
343
os << " const " ;
322
344
}
323
- ClangSyntaxPrinter (os).printPrimaryCxxTypeName (decl, moduleContext);
324
- auto result = visitGenericArgs (genericArgs);
345
+ ClangRepresentation result = ClangRepresentation::representable;
346
+ printOptional (optionalKind, [&]() {
347
+ ClangSyntaxPrinter (os).printPrimaryCxxTypeName (decl, moduleContext);
348
+ result = visitGenericArgs (genericArgs);
349
+ });
325
350
os << ' &' ;
326
351
return result;
327
- } else {
352
+ }
353
+
354
+ ClangRepresentation result = ClangRepresentation::representable;
355
+ printOptional (optionalKind, [&]() {
328
356
ClangValueTypePrinter printer (os, cPrologueOS, interopContext);
329
357
printer.printValueTypeReturnType (
330
358
decl, languageMode,
@@ -333,9 +361,9 @@ class CFunctionSignatureTypePrinter
333
361
ClangValueTypePrinter::TypeUseKind::CxxTypeName)
334
362
: ClangValueTypePrinter::TypeUseKind::CxxTypeName,
335
363
moduleContext);
336
- return visitGenericArgs (genericArgs);
337
- }
338
- return ClangRepresentation::representable ;
364
+ result = visitGenericArgs (genericArgs);
365
+ });
366
+ return result ;
339
367
}
340
368
341
369
Optional<ClangRepresentation>
@@ -393,13 +421,10 @@ class CFunctionSignatureTypePrinter
393
421
visitGenericTypeParamType (GenericTypeParamType *genericTpt,
394
422
Optional<OptionalTypeKind> optionalKind,
395
423
bool isInOutParam) {
396
- // FIXME: Support Optional<T>.
397
- if (optionalKind && *optionalKind != OTK_None)
398
- return ClangRepresentation::unsupported;
399
424
bool isParam = typeUseKind == FunctionSignatureTypeUse::ParamType;
400
425
if (isParam && !isInOutParam)
401
426
os << " const " ;
402
- // FIXME: handle optionalKind.
427
+
403
428
if (languageMode != OutputLanguageMode::Cxx) {
404
429
// Note: This can happen for UnsafeMutablePointer<T>.
405
430
if (typeUseKind != FunctionSignatureTypeUse::ParamType)
@@ -409,7 +434,9 @@ class CFunctionSignatureTypePrinter
409
434
os << " void * _Nonnull" ;
410
435
return ClangRepresentation::representable;
411
436
}
412
- ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
437
+ printOptional (optionalKind, [&]() {
438
+ ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
439
+ });
413
440
// Pass a reference to the template type.
414
441
if (isParam)
415
442
os << ' &' ;
0 commit comments