@@ -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) {
@@ -241,14 +260,18 @@ class CFunctionSignatureTypePrinter
241
260
bool isInOutParam) {
242
261
// FIXME: handle optionalKind.
243
262
if (languageMode != OutputLanguageMode::Cxx) {
244
- os << " void * _Nonnull" ;
263
+ os << " void * "
264
+ << (!optionalKind || *optionalKind == OTK_None ? " _Nonnull"
265
+ : " _Nullable" );
245
266
if (isInOutParam)
246
267
os << " * _Nonnull" ;
247
268
return ClangRepresentation::representable;
248
269
}
249
270
if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
250
271
os << " const " ;
251
- ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
272
+ printOptional (optionalKind, [&]() {
273
+ ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
274
+ });
252
275
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
253
276
os << " &" ;
254
277
return ClangRepresentation::representable;
@@ -298,9 +321,6 @@ class CFunctionSignatureTypePrinter
298
321
if (!declPrinter.shouldInclude (decl))
299
322
return ClangRepresentation::unsupported; // FIXME: propagate why it's not
300
323
// exposed.
301
- // FIXME: Support Optional<T>.
302
- if (optionalKind && *optionalKind != OTK_None)
303
- return ClangRepresentation::unsupported;
304
324
// Only C++ mode supports struct types.
305
325
if (languageMode != OutputLanguageMode::Cxx)
306
326
return ClangRepresentation::unsupported;
@@ -312,22 +332,27 @@ class CFunctionSignatureTypePrinter
312
332
if (typeUseKind == FunctionSignatureTypeUse::ParamType &&
313
333
!isInOutParam)
314
334
os << " const " ;
315
- handler.printTypeName (os);
335
+ printOptional (optionalKind, [&]() { handler.printTypeName (os); } );
316
336
if (typeUseKind == FunctionSignatureTypeUse::ParamType)
317
337
os << ' &' ;
318
338
return ClangRepresentation::representable;
319
339
}
320
340
321
- // FIXME: Handle optional structures.
322
341
if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
323
342
if (!isInOutParam) {
324
343
os << " const " ;
325
344
}
326
- ClangSyntaxPrinter (os).printPrimaryCxxTypeName (decl, moduleContext);
327
- auto result = visitGenericArgs (genericArgs);
345
+ ClangRepresentation result = ClangRepresentation::representable;
346
+ printOptional (optionalKind, [&]() {
347
+ ClangSyntaxPrinter (os).printPrimaryCxxTypeName (decl, moduleContext);
348
+ result = visitGenericArgs (genericArgs);
349
+ });
328
350
os << ' &' ;
329
351
return result;
330
- } else {
352
+ }
353
+
354
+ ClangRepresentation result = ClangRepresentation::representable;
355
+ printOptional (optionalKind, [&]() {
331
356
ClangValueTypePrinter printer (os, cPrologueOS, interopContext);
332
357
printer.printValueTypeReturnType (
333
358
decl, languageMode,
@@ -336,9 +361,9 @@ class CFunctionSignatureTypePrinter
336
361
ClangValueTypePrinter::TypeUseKind::CxxTypeName)
337
362
: ClangValueTypePrinter::TypeUseKind::CxxTypeName,
338
363
moduleContext);
339
- return visitGenericArgs (genericArgs);
340
- }
341
- return ClangRepresentation::representable ;
364
+ result = visitGenericArgs (genericArgs);
365
+ });
366
+ return result ;
342
367
}
343
368
344
369
Optional<ClangRepresentation>
@@ -396,13 +421,10 @@ class CFunctionSignatureTypePrinter
396
421
visitGenericTypeParamType (GenericTypeParamType *genericTpt,
397
422
Optional<OptionalTypeKind> optionalKind,
398
423
bool isInOutParam) {
399
- // FIXME: Support Optional<T>.
400
- if (optionalKind && *optionalKind != OTK_None)
401
- return ClangRepresentation::unsupported;
402
424
bool isParam = typeUseKind == FunctionSignatureTypeUse::ParamType;
403
425
if (isParam && !isInOutParam)
404
426
os << " const " ;
405
- // FIXME: handle optionalKind.
427
+
406
428
if (languageMode != OutputLanguageMode::Cxx) {
407
429
// Note: This can happen for UnsafeMutablePointer<T>.
408
430
if (typeUseKind != FunctionSignatureTypeUse::ParamType)
@@ -412,7 +434,9 @@ class CFunctionSignatureTypePrinter
412
434
os << " void * _Nonnull" ;
413
435
return ClangRepresentation::representable;
414
436
}
415
- ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
437
+ printOptional (optionalKind, [&]() {
438
+ ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
439
+ });
416
440
// Pass a reference to the template type.
417
441
if (isParam)
418
442
os << ' &' ;
0 commit comments