@@ -295,7 +295,9 @@ class CFunctionSignatureTypePrinter
295
295
if (!declPrinter.shouldInclude (decl))
296
296
return ClangRepresentation::unsupported; // FIXME: propagate why it's not
297
297
// exposed.
298
-
298
+ // FIXME: Support Optional<T>.
299
+ if (optionalKind && *optionalKind != OTK_None)
300
+ return ClangRepresentation::unsupported;
299
301
// Only C++ mode supports struct types.
300
302
if (languageMode != OutputLanguageMode::Cxx)
301
303
return ClangRepresentation::unsupported;
@@ -337,36 +339,45 @@ class CFunctionSignatureTypePrinter
337
339
return ClangRepresentation::representable;
338
340
}
339
341
340
- bool printIfKnownGenericStruct (const BoundGenericStructType *BGT,
341
- Optional<OptionalTypeKind> optionalKind,
342
- bool isInOutParam) {
342
+ Optional<ClangRepresentation>
343
+ printIfKnownGenericStruct (const BoundGenericStructType *BGT,
344
+ Optional<OptionalTypeKind> optionalKind,
345
+ bool isInOutParam) {
343
346
auto bgsTy = Type (const_cast <BoundGenericStructType *>(BGT));
344
347
bool isConst;
345
348
if (bgsTy->isUnsafePointer ())
346
349
isConst = true ;
347
350
else if (bgsTy->isUnsafeMutablePointer ())
348
351
isConst = false ;
349
352
else
350
- return false ;
353
+ return None ;
351
354
352
355
auto args = BGT->getGenericArgs ();
353
356
assert (args.size () == 1 );
354
- visitPart (args.front (), OTK_None, /* isInOutParam=*/ false );
357
+ llvm::SaveAndRestore<FunctionSignatureTypeUse> typeUseNormal (
358
+ typeUseKind, FunctionSignatureTypeUse::TypeReference);
359
+ // FIXME: We can definitely support pointers to known Clang types.
360
+ if (!isKnownCType (args.front (), typeMapping))
361
+ return ClangRepresentation (ClangRepresentation::unsupported);
362
+ auto partRepr = visitPart (args.front (), OTK_None, /* isInOutParam=*/ false );
363
+ if (partRepr.isUnsupported ())
364
+ return partRepr;
355
365
if (isConst)
356
366
os << " const" ;
357
367
os << " *" ;
358
368
printNullability (optionalKind);
359
369
if (isInOutParam)
360
370
printInoutTypeModifier ();
361
- return true ;
371
+ return ClangRepresentation (ClangRepresentation::representable) ;
362
372
}
363
373
364
374
ClangRepresentation
365
375
visitBoundGenericStructType (BoundGenericStructType *BGT,
366
376
Optional<OptionalTypeKind> optionalKind,
367
377
bool isInOutParam) {
368
- if (printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
369
- return ClangRepresentation::representable;
378
+ if (auto result =
379
+ printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
380
+ return *result;
370
381
return visitValueType (BGT, BGT->getDecl (), optionalKind, isInOutParam,
371
382
BGT->getGenericArgs ());
372
383
}
@@ -375,11 +386,17 @@ class CFunctionSignatureTypePrinter
375
386
visitGenericTypeParamType (GenericTypeParamType *genericTpt,
376
387
Optional<OptionalTypeKind> optionalKind,
377
388
bool isInOutParam) {
389
+ // FIXME: Support Optional<T>.
390
+ if (optionalKind && *optionalKind != OTK_None)
391
+ return ClangRepresentation::unsupported;
378
392
bool isParam = typeUseKind == FunctionSignatureTypeUse::ParamType;
379
393
if (isParam && !isInOutParam)
380
394
os << " const " ;
381
395
// FIXME: handle optionalKind.
382
396
if (languageMode != OutputLanguageMode::Cxx) {
397
+ // Note: This can happen for UnsafeMutablePointer<T>.
398
+ if (typeUseKind != FunctionSignatureTypeUse::ParamType)
399
+ return ClangRepresentation::unsupported;
383
400
assert (typeUseKind == FunctionSignatureTypeUse::ParamType);
384
401
// Pass an opaque param in C mode.
385
402
os << " void * _Nonnull" ;
@@ -1194,9 +1211,11 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
1194
1211
bool DeclAndTypeClangFunctionPrinter::hasKnownOptionalNullableCxxMapping (
1195
1212
Type type) {
1196
1213
if (auto optionalObjectType = type->getOptionalObjectType ()) {
1197
- if (auto typeInfo = typeMapping.getKnownCxxTypeInfo (
1198
- optionalObjectType->getNominalOrBoundGenericNominal ())) {
1199
- return typeInfo->canBeNullable ;
1214
+ if (optionalObjectType->getNominalOrBoundGenericNominal ()) {
1215
+ if (auto typeInfo = typeMapping.getKnownCxxTypeInfo (
1216
+ optionalObjectType->getNominalOrBoundGenericNominal ())) {
1217
+ return typeInfo->canBeNullable ;
1218
+ }
1200
1219
}
1201
1220
}
1202
1221
return false ;
0 commit comments