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