@@ -201,6 +201,23 @@ class CFunctionSignatureTypePrinter
201
201
optionalKind, isInOutParam);
202
202
}
203
203
204
+ ClangRepresentation visitGenericArgs (ArrayRef<Type> genericArgs) {
205
+ if (genericArgs.empty ())
206
+ return ClangRepresentation::representable;
207
+ os << ' <' ;
208
+ llvm::SaveAndRestore<FunctionSignatureTypeUse> typeUseNormal (
209
+ typeUseKind, FunctionSignatureTypeUse::TypeReference);
210
+ decltype (modifiersDelegate) emptyModifiersDelegate;
211
+ llvm::SaveAndRestore<decltype (modifiersDelegate)> modReset (
212
+ modifiersDelegate, emptyModifiersDelegate);
213
+ ClangRepresentation result = ClangRepresentation::representable;
214
+ llvm::interleaveComma (genericArgs, os, [&](Type t) {
215
+ result.merge (visitPart (t, None, false ));
216
+ });
217
+ os << ' >' ;
218
+ return result;
219
+ }
220
+
204
221
ClangRepresentation visitValueType (const NominalTypeDecl *decl,
205
222
NominalType *NT,
206
223
Optional<OptionalTypeKind> optionalKind,
@@ -218,6 +235,12 @@ class CFunctionSignatureTypePrinter
218
235
// exposed.
219
236
// FIXME: Handle optional structures.
220
237
if (typeUseKind == FunctionSignatureTypeUse::ParamType) {
238
+ if (languageMode != OutputLanguageMode::Cxx && !genericArgs.empty ()) {
239
+ // FIXME: what about concrete generic type.
240
+ // FIXME: inout.
241
+ os << " const void * _Nonnull" ;
242
+ return ClangRepresentation::representable;
243
+ }
221
244
if (languageMode != OutputLanguageMode::Cxx &&
222
245
(decl->isResilient () ||
223
246
(NT && interopContext.getIrABIDetails ().shouldPassIndirectly (NT)))) {
@@ -230,10 +253,18 @@ class CFunctionSignatureTypePrinter
230
253
os << " const void * _Nonnull" ;
231
254
}
232
255
233
- } else {
256
+ } else if (languageMode != OutputLanguageMode::Cxx) {
234
257
ClangValueTypePrinter (os, cPrologueOS, typeMapping, interopContext)
235
258
.printValueTypeParameterType (decl, languageMode, moduleContext,
236
259
isInOutParam);
260
+ } else {
261
+ if (!isInOutParam) {
262
+ os << " const " ;
263
+ }
264
+ ClangSyntaxPrinter (os).printPrimaryCxxTypeName (decl, moduleContext);
265
+ auto result = visitGenericArgs (genericArgs);
266
+ os << ' &' ;
267
+ return result;
237
268
}
238
269
} else {
239
270
ClangValueTypePrinter (os, cPrologueOS, typeMapping, interopContext)
@@ -244,20 +275,7 @@ class CFunctionSignatureTypePrinter
244
275
ClangValueTypePrinter::TypeUseKind::CxxTypeName)
245
276
: ClangValueTypePrinter::TypeUseKind::CxxTypeName,
246
277
moduleContext);
247
- if (!genericArgs.empty ()) {
248
- os << ' <' ;
249
- llvm::SaveAndRestore<FunctionSignatureTypeUse> typeUseNormal (
250
- typeUseKind, FunctionSignatureTypeUse::TypeReference);
251
- decltype (modifiersDelegate) emptyModifiersDelegate;
252
- llvm::SaveAndRestore<decltype (modifiersDelegate)> modReset (
253
- modifiersDelegate, emptyModifiersDelegate);
254
- ClangRepresentation result = ClangRepresentation::representable;
255
- llvm::interleaveComma (genericArgs, os, [&](Type t) {
256
- result.merge (visitPart (t, None, false ));
257
- });
258
- os << ' >' ;
259
- return result;
260
- }
278
+ return visitGenericArgs (genericArgs);
261
279
}
262
280
return ClangRepresentation::representable;
263
281
}
@@ -538,9 +556,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
538
556
auto namePrinter = [&]() { ClangSyntaxPrinter (os).printIdentifier (name); };
539
557
if (!isKnownCxxType (type, typeMapping) &&
540
558
!hasKnownOptionalNullableCxxMapping (type)) {
541
- if (type->getAs <ArchetypeType>() && type->getAs <ArchetypeType>()
542
- ->getInterfaceType ()
543
- ->is <GenericTypeParamType>()) {
559
+ if (type->is <GenericTypeParamType>()) {
544
560
os << " swift::" << cxx_synthesis::getCxxImplNamespaceName ()
545
561
<< " ::getOpaquePointer(" ;
546
562
namePrinter ();
@@ -558,9 +574,24 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
558
574
if ((isa<StructDecl>(decl) || isa<EnumDecl>(decl))) {
559
575
ClangValueTypePrinter (os, cPrologueOS, typeMapping, interopContext)
560
576
.printParameterCxxToCUseScaffold (
561
- isIndirect || decl->isResilient () ||
577
+ isIndirect || decl->isResilient () || isGenericType (type) ||
562
578
interopContext.getIrABIDetails ().shouldPassIndirectly (type),
563
- decl, moduleContext, namePrinter, isInOut,
579
+ decl, moduleContext,
580
+ [&]() {
581
+ CFunctionSignatureTypePrinterModifierDelegate delegate;
582
+ delegate.mapValueTypeUseKind = [](ClangValueTypePrinter::
583
+ TypeUseKind kind) {
584
+ return ClangValueTypePrinter::TypeUseKind::CxxImplTypeName;
585
+ };
586
+ CFunctionSignatureTypePrinter typePrinter (
587
+ os, cPrologueOS, typeMapping, OutputLanguageMode::Cxx,
588
+ interopContext, delegate, moduleContext, declPrinter,
589
+ FunctionSignatureTypeUse::TypeReference);
590
+ auto result =
591
+ typePrinter.visit (type, None, /* isInOut=*/ false );
592
+ assert (!result.isUnsupported ());
593
+ },
594
+ namePrinter, isInOut,
564
595
/* isSelf=*/ paramRole &&
565
596
*paramRole == AdditionalParam::Role::Self);
566
597
return ;
@@ -576,7 +607,7 @@ void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse(
576
607
577
608
void DeclAndTypeClangFunctionPrinter::printCxxToCFunctionParameterUse (
578
609
const ParamDecl *param, StringRef name) {
579
- printCxxToCFunctionParameterUse (param->getType (), name,
610
+ printCxxToCFunctionParameterUse (param->getInterfaceType (), name,
580
611
param->getModuleContext (), param->isInOut ());
581
612
}
582
613
0 commit comments