@@ -186,15 +186,34 @@ class CFunctionSignatureTypePrinter
186186 auto knownTypeInfo = getKnownTypeInfo (typeDecl, typeMapping, languageMode);
187187 if (!knownTypeInfo)
188188 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 << ' &' ;
193203 if (isInOutParam)
194204 printInoutTypeModifier ();
195205 return true ;
196206 }
197207
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+
198217 ClangRepresentation visitType (TypeBase *Ty,
199218 Optional<OptionalTypeKind> optionalKind,
200219 bool isInOutParam) {
@@ -241,14 +260,18 @@ class CFunctionSignatureTypePrinter
241260 bool isInOutParam) {
242261 // FIXME: handle optionalKind.
243262 if (languageMode != OutputLanguageMode::Cxx) {
244- os << " void * _Nonnull" ;
263+ os << " void * "
264+ << (!optionalKind || *optionalKind == OTK_None ? " _Nonnull"
265+ : " _Nullable" );
245266 if (isInOutParam)
246267 os << " * _Nonnull" ;
247268 return ClangRepresentation::representable;
248269 }
249270 if (typeUseKind == FunctionSignatureTypeUse::ParamType && !isInOutParam)
250271 os << " const " ;
251- ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
272+ printOptional (optionalKind, [&]() {
273+ ClangSyntaxPrinter (os).printBaseName (CT->getDecl ());
274+ });
252275 if (typeUseKind == FunctionSignatureTypeUse::ParamType)
253276 os << " &" ;
254277 return ClangRepresentation::representable;
@@ -298,9 +321,6 @@ class CFunctionSignatureTypePrinter
298321 if (!declPrinter.shouldInclude (decl))
299322 return ClangRepresentation::unsupported; // FIXME: propagate why it's not
300323 // exposed.
301- // FIXME: Support Optional<T>.
302- if (optionalKind && *optionalKind != OTK_None)
303- return ClangRepresentation::unsupported;
304324 // Only C++ mode supports struct types.
305325 if (languageMode != OutputLanguageMode::Cxx)
306326 return ClangRepresentation::unsupported;
@@ -312,22 +332,27 @@ class CFunctionSignatureTypePrinter
312332 if (typeUseKind == FunctionSignatureTypeUse::ParamType &&
313333 !isInOutParam)
314334 os << " const " ;
315- handler.printTypeName (os);
335+ printOptional (optionalKind, [&]() { handler.printTypeName (os); } );
316336 if (typeUseKind == FunctionSignatureTypeUse::ParamType)
317337 os << ' &' ;
318338 return ClangRepresentation::representable;
319339 }
320340
321- // FIXME: Handle optional structures.
322341 if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
323342 if (!isInOutParam) {
324343 os << " const " ;
325344 }
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+ });
328350 os << ' &' ;
329351 return result;
330- } else {
352+ }
353+
354+ ClangRepresentation result = ClangRepresentation::representable;
355+ printOptional (optionalKind, [&]() {
331356 ClangValueTypePrinter printer (os, cPrologueOS, interopContext);
332357 printer.printValueTypeReturnType (
333358 decl, languageMode,
@@ -336,9 +361,9 @@ class CFunctionSignatureTypePrinter
336361 ClangValueTypePrinter::TypeUseKind::CxxTypeName)
337362 : ClangValueTypePrinter::TypeUseKind::CxxTypeName,
338363 moduleContext);
339- return visitGenericArgs (genericArgs);
340- }
341- return ClangRepresentation::representable ;
364+ result = visitGenericArgs (genericArgs);
365+ });
366+ return result ;
342367 }
343368
344369 Optional<ClangRepresentation>
@@ -396,13 +421,10 @@ class CFunctionSignatureTypePrinter
396421 visitGenericTypeParamType (GenericTypeParamType *genericTpt,
397422 Optional<OptionalTypeKind> optionalKind,
398423 bool isInOutParam) {
399- // FIXME: Support Optional<T>.
400- if (optionalKind && *optionalKind != OTK_None)
401- return ClangRepresentation::unsupported;
402424 bool isParam = typeUseKind == FunctionSignatureTypeUse::ParamType;
403425 if (isParam && !isInOutParam)
404426 os << " const " ;
405- // FIXME: handle optionalKind.
427+
406428 if (languageMode != OutputLanguageMode::Cxx) {
407429 // Note: This can happen for UnsafeMutablePointer<T>.
408430 if (typeUseKind != FunctionSignatureTypeUse::ParamType)
@@ -412,7 +434,9 @@ class CFunctionSignatureTypePrinter
412434 os << " void * _Nonnull" ;
413435 return ClangRepresentation::representable;
414436 }
415- ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
437+ printOptional (optionalKind, [&]() {
438+ ClangSyntaxPrinter (os).printGenericTypeParamTypeName (genericTpt);
439+ });
416440 // Pass a reference to the template type.
417441 if (isParam)
418442 os << ' &' ;
0 commit comments