@@ -295,7 +295,9 @@ class CFunctionSignatureTypePrinter
295295 if (!declPrinter.shouldInclude (decl))
296296 return ClangRepresentation::unsupported; // FIXME: propagate why it's not
297297 // exposed.
298-
298+ // FIXME: Support Optional<T>.
299+ if (optionalKind && *optionalKind != OTK_None)
300+ return ClangRepresentation::unsupported;
299301 // Only C++ mode supports struct types.
300302 if (languageMode != OutputLanguageMode::Cxx)
301303 return ClangRepresentation::unsupported;
@@ -337,36 +339,45 @@ class CFunctionSignatureTypePrinter
337339 return ClangRepresentation::representable;
338340 }
339341
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) {
343346 auto bgsTy = Type (const_cast <BoundGenericStructType *>(BGT));
344347 bool isConst;
345348 if (bgsTy->isUnsafePointer ())
346349 isConst = true ;
347350 else if (bgsTy->isUnsafeMutablePointer ())
348351 isConst = false ;
349352 else
350- return false ;
353+ return None ;
351354
352355 auto args = BGT->getGenericArgs ();
353356 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;
355365 if (isConst)
356366 os << " const" ;
357367 os << " *" ;
358368 printNullability (optionalKind);
359369 if (isInOutParam)
360370 printInoutTypeModifier ();
361- return true ;
371+ return ClangRepresentation (ClangRepresentation::representable) ;
362372 }
363373
364374 ClangRepresentation
365375 visitBoundGenericStructType (BoundGenericStructType *BGT,
366376 Optional<OptionalTypeKind> optionalKind,
367377 bool isInOutParam) {
368- if (printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
369- return ClangRepresentation::representable;
378+ if (auto result =
379+ printIfKnownGenericStruct (BGT, optionalKind, isInOutParam))
380+ return *result;
370381 return visitValueType (BGT, BGT->getDecl (), optionalKind, isInOutParam,
371382 BGT->getGenericArgs ());
372383 }
@@ -375,11 +386,17 @@ class CFunctionSignatureTypePrinter
375386 visitGenericTypeParamType (GenericTypeParamType *genericTpt,
376387 Optional<OptionalTypeKind> optionalKind,
377388 bool isInOutParam) {
389+ // FIXME: Support Optional<T>.
390+ if (optionalKind && *optionalKind != OTK_None)
391+ return ClangRepresentation::unsupported;
378392 bool isParam = typeUseKind == FunctionSignatureTypeUse::ParamType;
379393 if (isParam && !isInOutParam)
380394 os << " const " ;
381395 // FIXME: handle optionalKind.
382396 if (languageMode != OutputLanguageMode::Cxx) {
397+ // Note: This can happen for UnsafeMutablePointer<T>.
398+ if (typeUseKind != FunctionSignatureTypeUse::ParamType)
399+ return ClangRepresentation::unsupported;
383400 assert (typeUseKind == FunctionSignatureTypeUse::ParamType);
384401 // Pass an opaque param in C mode.
385402 os << " void * _Nonnull" ;
@@ -1194,9 +1211,11 @@ void DeclAndTypeClangFunctionPrinter::printCxxPropertyAccessorMethod(
11941211bool DeclAndTypeClangFunctionPrinter::hasKnownOptionalNullableCxxMapping (
11951212 Type type) {
11961213 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+ }
12001219 }
12011220 }
12021221 return false ;
0 commit comments