Skip to content

Commit 0592894

Browse files
committed
[interop][SwiftToCxx] move generic additional type parameters into lowered function signature
1 parent 4520c52 commit 0592894

File tree

5 files changed

+105
-70
lines changed

5 files changed

+105
-70
lines changed

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,6 @@ class IRABIDetailsProvider {
6161
class ABIAdditionalParam {
6262
public:
6363
enum class ABIParameterRole {
64-
/// A parameter that corresponds to a generic requirement that must be
65-
/// fullfilled by a call to this function.
66-
GenericRequirement,
67-
/// A parameter that corresponds to a Swift type pointer sourced from a
68-
/// valid metadata source, like the type of another argument.
69-
GenericTypeMetadataSource,
7064
/// A parameter that corresponds to the 'self' parameter.
7165
Self,
7266
/// The Swift error parameter.
@@ -75,16 +69,6 @@ class IRABIDetailsProvider {
7569

7670
inline ABIParameterRole getRole() const { return role; }
7771

78-
inline GenericRequirement getGenericRequirement() {
79-
assert(role == ABIParameterRole::GenericRequirement);
80-
return *genericRequirement;
81-
}
82-
83-
inline CanType getMetadataSourceType() {
84-
assert(role == ABIParameterRole::GenericTypeMetadataSource);
85-
return canType;
86-
}
87-
8872
private:
8973
inline ABIAdditionalParam(
9074
ABIParameterRole role,
@@ -173,6 +157,30 @@ class IRABIDetailsProvider {
173157
friend class LoweredFunctionSignature;
174158
};
175159

160+
/// Represents a generic requirement paremeter that must be passed to the
161+
/// function.
162+
class GenericRequirementParameter {
163+
public:
164+
inline GenericRequirement getRequirement() const { return requirement; }
165+
166+
private:
167+
GenericRequirementParameter(const GenericRequirement &requirement);
168+
GenericRequirement requirement;
169+
friend class LoweredFunctionSignature;
170+
};
171+
172+
/// Represents a parameter which is a Swift type pointer sourced from a
173+
/// valid metadata source, like the type of another argument.
174+
class MetadataSourceParameter {
175+
public:
176+
inline CanType getType() const { return type; }
177+
178+
private:
179+
MetadataSourceParameter(const CanType &type);
180+
CanType type;
181+
friend class LoweredFunctionSignature;
182+
};
183+
176184
/// Returns lowered direct result details, or \c None if direct result is
177185
/// void.
178186
llvm::Optional<DirectResultType> getDirectResultType() const;
@@ -190,7 +198,11 @@ class IRABIDetailsProvider {
190198
indirectResultVisitor,
191199
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
192200
llvm::function_ref<void(const IndirectParameter &)>
193-
indirectParamVisitor);
201+
indirectParamVisitor,
202+
llvm::function_ref<void(const GenericRequirementParameter &)>
203+
genericRequirementVisitor,
204+
llvm::function_ref<void(const MetadataSourceParameter &)>
205+
metadataSourceVisitor);
194206

195207
/// FIXME: make private.
196208
SmallVector<ABIAdditionalParam, 1> additionalParams;
@@ -202,6 +214,7 @@ class IRABIDetailsProvider {
202214
const AbstractFunctionDecl *FD;
203215
IRABIDetailsProviderImpl &owner;
204216
const irgen::SignatureExpansionABIDetails &abiDetails;
217+
SmallVector<CanType, 1> metadataSourceTypes;
205218
friend class IRABIDetailsProviderImpl;
206219
};
207220

lib/IRGen/IRABIDetailsProvider.cpp

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,21 @@ class IRABIDetailsProviderImpl {
174174
SignatureExpansionABIDetails(Signature::getUncachedABIDetails(
175175
IGM, silFuncType, funcPointerKind));
176176

177-
return IRABIDetailsProvider::LoweredFunctionSignature(fd, *this,
178-
*abiDetails);
177+
auto result =
178+
IRABIDetailsProvider::LoweredFunctionSignature(fd, *this, *abiDetails);
179+
// Save metadata source types to avoid keeping the SIL func around.
180+
for (const auto &typeSource :
181+
abiDetails->polymorphicSignatureExpandedTypeSources) {
182+
typeSource.visit(
183+
[&](const GenericRequirement &reqt) {},
184+
[&](const MetadataSource &metadataSource) {
185+
auto index = metadataSource.getParamIndex();
186+
auto canType =
187+
silFuncType->getParameters()[index].getInterfaceType();
188+
result.metadataSourceTypes.push_back(canType);
189+
});
190+
}
191+
return result;
179192
}
180193

181194
llvm::SmallVector<IRABIDetailsProvider::ABIAdditionalParam, 1>
@@ -193,21 +206,6 @@ class IRABIDetailsProviderImpl {
193206

194207
using ABIAdditionalParam = IRABIDetailsProvider::ABIAdditionalParam;
195208
using ParamRole = ABIAdditionalParam::ABIParameterRole;
196-
for (const auto &typeSource :
197-
abiDetails.polymorphicSignatureExpandedTypeSources) {
198-
typeSource.visit(
199-
[&](const GenericRequirement &reqt) {
200-
params.push_back(ABIAdditionalParam(ParamRole::GenericRequirement,
201-
reqt, CanType()));
202-
},
203-
[&](const MetadataSource &metadataSource) {
204-
auto index = metadataSource.getParamIndex();
205-
auto canType =
206-
silFuncType->getParameters()[index].getInterfaceType();
207-
params.push_back(ABIAdditionalParam(
208-
ParamRole::GenericTypeMetadataSource, llvm::None, canType));
209-
});
210-
}
211209
// FIXME: remove second signature computation.
212210
auto signature = Signature::getUncached(IGM, silFuncType, funcPointerKind);
213211
for (auto attrSet : signature.getAttributes()) {
@@ -293,6 +291,14 @@ bool IRABIDetailsProvider::LoweredFunctionSignature::DirectParameter::
293291
return hasError;
294292
}
295293

294+
IRABIDetailsProvider::LoweredFunctionSignature::GenericRequirementParameter::
295+
GenericRequirementParameter(const GenericRequirement &requirement)
296+
: requirement(requirement) {}
297+
298+
IRABIDetailsProvider::LoweredFunctionSignature::MetadataSourceParameter::
299+
MetadataSourceParameter(const CanType &type)
300+
: type(type) {}
301+
296302
llvm::Optional<IRABIDetailsProvider::LoweredFunctionSignature::DirectResultType>
297303
IRABIDetailsProvider::LoweredFunctionSignature::getDirectResultType() const {
298304
if (!abiDetails.directResult)
@@ -309,7 +315,11 @@ IRABIDetailsProvider::LoweredFunctionSignature::getNumIndirectResultValues()
309315
void IRABIDetailsProvider::LoweredFunctionSignature::visitParameterList(
310316
llvm::function_ref<void(const IndirectResultValue &)> indirectResultVisitor,
311317
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
312-
llvm::function_ref<void(const IndirectParameter &)> indirectParamVisitor) {
318+
llvm::function_ref<void(const IndirectParameter &)> indirectParamVisitor,
319+
llvm::function_ref<void(const GenericRequirementParameter &)>
320+
genericRequirementVisitor,
321+
llvm::function_ref<void(const MetadataSourceParameter &)>
322+
metadataSourceVisitor) {
313323
// Indirect result values come before parameters.
314324
llvm::SmallVector<IndirectResultValue, 1> result;
315325
for (const auto &r : abiDetails.indirectResults)
@@ -355,7 +365,23 @@ void IRABIDetailsProvider::LoweredFunctionSignature::visitParameterList(
355365
currentSilParam == silParamMapping.size());
356366
else
357367
assert(currentSilParam == silParamMapping.size());
358-
// FIXME: Traverse generic requirements and other additional params.
368+
369+
// Generic requirements come next.
370+
size_t metadataSourceIndex = 0;
371+
for (const auto &typeSource :
372+
abiDetails.polymorphicSignatureExpandedTypeSources) {
373+
typeSource.visit(
374+
[&](const GenericRequirement &reqt) {
375+
genericRequirementVisitor(GenericRequirementParameter(reqt));
376+
},
377+
[&](const MetadataSource &metadataSource) {
378+
metadataSourceVisitor(MetadataSourceParameter(
379+
metadataSourceTypes[metadataSourceIndex]));
380+
++metadataSourceIndex;
381+
});
382+
}
383+
384+
// FIXME: Traverse other additional params.
359385
}
360386

361387
IRABIDetailsProvider::IRABIDetailsProvider(ModuleDecl &mod,

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,18 +1234,6 @@ class DeclAndTypePrinter::Implementation
12341234
for (auto param : ABIparams) {
12351235
using Role = IRABIDetailsProvider::ABIAdditionalParam::ABIParameterRole;
12361236
switch (param.getRole()) {
1237-
case Role::GenericRequirement:
1238-
params.push_back({DeclAndTypeClangFunctionPrinter::AdditionalParam::
1239-
Role::GenericRequirement,
1240-
FD->getASTContext().getOpaquePointerType(),
1241-
/*isIndirect=*/false, param.getGenericRequirement()});
1242-
break;
1243-
case Role::GenericTypeMetadataSource:
1244-
params.push_back({DeclAndTypeClangFunctionPrinter::AdditionalParam::
1245-
Role::GenericTypeMetadata,
1246-
param.getMetadataSourceType(), /*isIndirect=*/false,
1247-
None});
1248-
break;
12491237
case Role::Self:
12501238
params.push_back(
12511239
{DeclAndTypeClangFunctionPrinter::AdditionalParam::Role::Self,

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,18 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
691691
else
692692
os << "void * _Nonnull";
693693
printParamName(param.getParamDecl());
694+
},
695+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
696+
GenericRequirementParameter &genericRequirementParam) {
697+
emitNewParam();
698+
os << "void * _Nonnull ";
699+
if (auto *proto = genericRequirementParam.getRequirement().Protocol)
700+
ClangSyntaxPrinter(os).printBaseName(proto);
701+
},
702+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
703+
MetadataSourceParameter &metadataSrcParam) {
704+
emitNewParam();
705+
os << "void * _Nonnull ";
694706
});
695707
} else {
696708

@@ -745,13 +757,6 @@ ClangRepresentation DeclAndTypeClangFunctionPrinter::printFunctionSignature(
745757
} else if (param.role == AdditionalParam::Role::Error) {
746758
os << "SWIFT_ERROR_RESULT ";
747759
os << "void * _Nullable * _Nullable _error";
748-
} else if (param.role == AdditionalParam::Role::GenericRequirement) {
749-
os << "void * _Nonnull ";
750-
if (param.genericRequirement->Protocol)
751-
ClangSyntaxPrinter(os).printBaseName(
752-
param.genericRequirement->Protocol);
753-
} else if (param.role == AdditionalParam::Role::GenericTypeMetadata) {
754-
os << "void * _Nonnull ";
755760
}
756761
});
757762
}
@@ -883,14 +888,11 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
883888
IndirectParameter &param) {
884889
printParamUse(param.getParamDecl(), /*isIndirect=*/true,
885890
/*directTypeEncoding=*/"");
886-
});
887-
888-
if (additionalParams.size()) {
889-
if (needsComma)
890-
os << ", ";
891-
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
892-
if (param.role == AdditionalParam::Role::GenericRequirement) {
893-
auto genericRequirement = *param.genericRequirement;
891+
},
892+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
893+
GenericRequirementParameter &genericRequirementParam) {
894+
emitNewParam();
895+
auto genericRequirement = genericRequirementParam.getRequirement();
894896
// FIXME: Add protocol requirement support.
895897
assert(!genericRequirement.Protocol);
896898
if (auto *gtpt = genericRequirement.TypeParameter
@@ -901,20 +903,26 @@ void DeclAndTypeClangFunctionPrinter::printCxxThunkBody(
901903
return;
902904
}
903905
os << "ERROR";
904-
return;
905-
}
906-
if (param.role == AdditionalParam::Role::GenericTypeMetadata) {
906+
},
907+
[&](const IRABIDetailsProvider::LoweredFunctionSignature::
908+
MetadataSourceParameter &metadataSrcParam) {
909+
emitNewParam();
907910
os << "swift::TypeMetadataTrait<";
908911
CFunctionSignatureTypePrinterModifierDelegate delegate;
909912
CFunctionSignatureTypePrinter typePrinter(
910913
os, cPrologueOS, typeMapping, OutputLanguageMode::Cxx,
911914
interopContext, delegate, moduleContext, declPrinter,
912915
FunctionSignatureTypeUse::TypeReference);
913-
auto result = typePrinter.visit(param.type, None, /*isInOut=*/false);
916+
auto result = typePrinter.visit(metadataSrcParam.getType(), None,
917+
/*isInOut=*/false);
914918
assert(!result.isUnsupported());
915919
os << ">::getTypeMetadata()";
916-
return;
917-
}
920+
});
921+
922+
if (additionalParams.size()) {
923+
if (needsComma)
924+
os << ", ";
925+
interleaveComma(additionalParams, os, [&](const AdditionalParam &param) {
918926
if (param.role == AdditionalParam::Role::Self && !hasThrows) {
919927
// FIXME: this is wonky.
920928
needsComma = false;

lib/PrintAsClang/PrintClangFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class DeclAndTypeClangFunctionPrinter {
7979

8080
/// Information about any additional parameters.
8181
struct AdditionalParam {
82-
enum class Role { GenericRequirement, GenericTypeMetadata, Self, Error };
82+
enum class Role { Self, Error };
8383

8484
Role role;
8585
Type type;

0 commit comments

Comments
 (0)