@@ -705,6 +705,41 @@ static CanType getArgumentLoweringType(CanType type,
705
705
}
706
706
}
707
707
708
+ static bool isABIIgnoredParameterWithoutStorage (IRGenModule &IGM,
709
+ IRGenFunction &IGF,
710
+ CanSILFunctionType substType,
711
+ unsigned paramIdx) {
712
+ auto param = substType->getParameters ()[paramIdx];
713
+ SILType argType = IGM.silConv .getSILType (param);
714
+ auto argLoweringTy =
715
+ getArgumentLoweringType (argType.getSwiftRValueType (), param);
716
+ auto &ti = IGF.getTypeInfoForLowered (argLoweringTy);
717
+ // Empty values don't matter.
718
+ return ti.getSchema ().size () == 0 && !param.isFormalIndirect ();
719
+ }
720
+
721
+ // / Find the parameter index for the one (assuming there was only one) partially
722
+ // / applied argument ignoring empty types that are not passed as part of the
723
+ // / ABI.
724
+ static unsigned findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes (
725
+ IRGenFunction &IGF, CanSILFunctionType substType,
726
+ CanSILFunctionType outType) {
727
+ auto substParameters = substType->getParameters ();
728
+ auto outParamters = outType->getParameters ();
729
+ unsigned firstNonEmpty = -1U ;
730
+ for (unsigned paramIdx = outParamters.size () ; paramIdx != substParameters.size (); ++paramIdx) {
731
+ bool isEmpty =
732
+ isABIIgnoredParameterWithoutStorage (IGF.IGM , IGF, substType, paramIdx);
733
+ assert ((isEmpty || firstNonEmpty == -1U ) && " Expect at most one partially "
734
+ " applied that is passed as an "
735
+ " ABI argument" );
736
+ if (!isEmpty)
737
+ firstNonEmpty = paramIdx;
738
+ }
739
+ assert (firstNonEmpty != -1U );
740
+ return firstNonEmpty;
741
+ }
742
+
708
743
// / Emit the forwarding stub function for a partial application.
709
744
// /
710
745
// / If 'layout' is null, there is a single captured value of
@@ -924,11 +959,9 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
924
959
// care for the former for the purpose of reconstructing polymorphic
925
960
// parameters from regular arguments.
926
961
if (!calleeHasContext) {
927
- unsigned paramI = substType->getParameters ().size () - 1 ;
928
- assert (substType->getParameters ().size () -
929
- outType->getParameters ().size () ==
930
- 1 &&
931
- " Expect one partially applied argument" );
962
+ unsigned paramI =
963
+ findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes (
964
+ subIGF, substType, outType);
932
965
auto paramInfo = substType->getParameters ()[paramI];
933
966
auto &ti = IGM.getTypeInfoForLowered (paramInfo.getType ());
934
967
Explosion param;
@@ -1097,13 +1130,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
1097
1130
1098
1131
// Skip empty parameters.
1099
1132
while (origParamI < origType->getParameters ().size ()) {
1100
- auto param = substType->getParameters ()[origParamI];
1101
- SILType argType = IGM.silConv .getSILType (param);
1102
- auto argLoweringTy =
1103
- getArgumentLoweringType (argType.getSwiftRValueType (), param);
1104
- auto &ti = subIGF.getTypeInfoForLowered (argLoweringTy);
1105
- // Empty values don't matter.
1106
- if (ti.getSchema ().size () != 0 || param.isFormalIndirect ())
1133
+ if (!isABIIgnoredParameterWithoutStorage (IGM, subIGF, substType,
1134
+ origParamI))
1107
1135
break ;
1108
1136
origParamI++;
1109
1137
}
0 commit comments