@@ -619,6 +619,35 @@ class InputMatchesTypes<list<string> inputArgs, list<Type> allowedTypes> :
619
619
list<Type> allowedTypeList = allowedTypes;
620
620
}
621
621
622
+ // Checks that inputArgs match one of the allowed type combinations.
623
+ // Each combination in allowedCombinations must have the same number of types
624
+ // as there are inputArgs.
625
+ class InputAddressIsCombinationOf<list<string> inputArgs,
626
+ list<list<Type>> allowedCombinations,
627
+ string description = ""> :
628
+ PredOpTrait<!if(!empty(description),
629
+ "operands {" # !interleave(inputArgs, ", ") # "} match one of the allowed type combinations",
630
+ description),
631
+ Or<!foreach(combination, allowedCombinations,
632
+ !foldl(TruePred, !range(!size(inputArgs)), acc, i,
633
+ And<[acc,
634
+ SubstLeaves<"$_self", "$" # inputArgs[i] # ".getType()",
635
+ combination[i].predicate>
636
+ ]>))>> {
637
+ assert !gt(!size(allowedCombinations), 0),
638
+ "allowedCombinations must not be empty";
639
+
640
+ // Validate that each combination has the same number of types as inputArgs
641
+ defvar inputArgSize = !size(inputArgs);
642
+ defvar validSizes = !foldl(1, allowedCombinations, acc, combination,
643
+ !and(acc, !eq(inputArgSize, !size(combination))));
644
+ assert validSizes,
645
+ "each combination in allowedCombinations must have the same length as inputArgs";
646
+
647
+ list<string> inputArgList = inputArgs;
648
+ list<list<Type>> allowedCombinationList = allowedCombinations;
649
+ }
650
+
622
651
// Type Constraint operand `idx`'s Element type is `type`.
623
652
class TCopVTEtIs<int idx, Type type> : And<[
624
653
CPred<"$_op.getNumOperands() > " # idx>,
0 commit comments