/*
 * Copyright 2020 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// match.h - Provides an easily extensible layered API for matching expression
// patterns and extracting their components. The low-level API provides modular
// building blocks for creating matchers for any data type and the high-level
// API provides a succinct and flexible interface for matching expressions and
// extracting useful information from them.

#ifndef wasm_ir_match_h
#define wasm_ir_match_h

#include "ir/abstract.h"
#include "wasm.h"

namespace wasm::Match {

// The available matchers are:
//
//  i32, i64, f32, f64
//
//    Match constants of the corresponding type. Takes zero or one argument. The
//    argument can be a specific value to match or it can be a pointer to a
//    value, Literal, or Const* at which to store the matched entity.
//
//  bval, ival, fval
//
//    Match any boolean, any integer or any floating point constant. Takes
//    neither, either, or both of two possible arguments: first, a pointer to a
//    value, Literal, or Const* at which to store the matched entity and second,
//    a specific value to match.
//
//  constant
//
//    Matches any numeric Const expression. Takes neither, either, or both of
//    two possible arguments: first, a pointer to either Literal or Const* at
//    which to store the matched entity and second, a specific value (given as
//    an int32_t) to match..
//
//  any
//
//    Matches any Expression. Optionally takes as an argument a pointer to
//    Expression* at which to store the matched Expression*.
//
//  unary
//
//    Matches Unary expressions. Takes an optional pointer to Unary* at which to
//    store the matched Unary*, followed by either a UnaryOp or an Abstract::Op
//    describing which unary expressions to match, followed by a matcher to
//    apply to the unary expression's operand.
//
//  binary
//
//    Matches Binary expressions. Takes an optional pointer to Binary* at which
//    to store the matched Binary*, followed by either a BinaryOp or an
//    Abstract::Op describing which binary expressions to match, followed by
//    matchers to apply to the binary expression's left and right operands.
//
//  select
//
//    Matches Select expressions. Takes an optional pointer to Select* at which
//    to store the matched Select*, followed by matchers to apply to the ifTrue,
//    ifFalse, and condition operands.
//
//
// How to create new matchers:
//
//  Lets add a matcher for an expression type that is declared in wasm.h:
//
//    class Frozzle : public SpecificExpression<Expression::FrozzleId> {
//    public:
//      Expression* foo;
//      Expression* bar;
//      Expression* baz;
//    };
//
//  This expression is very simple; in order to match it, all we need to do is
//  apply other matchers to its subexpressions. The matcher infrastructure will
//  handle this automatically once we tell it how to access the subexpressions.
//  To tell the matcher infrastructure how many subexpressions there are we need
//  to specialize `NumComponents`.
//
//    template<> struct NumComponents<Frozzle*> {
//      static constexpr size_t value = 3;
//    };
//
//  And to tell the matcher infrastructure how to access those three
//  subexpressions, we need to specialize `GetComponent` three times.
//
//    template<> struct GetComponent<Frozzle*, 0> {
//      Expression* operator()(Frozzle* curr) { return curr->foo; }
//    };
//    template<> struct GetComponent<Frozzle*, 1> {
//      Expression* operator()(Frozzle* curr) { return curr->bar; }
//    };
//    template<> struct GetComponent<Frozzle*, 2> {
//      Expression* operator()(Frozzle* curr) { return curr->baz; }
//    };
//
//  For simple expressions, that's all we need to do to get a fully functional
//  matcher that we can construct and use like this, where S1, S2, and S3 are
//  the types of the submatchers to use and s1, s2, and s3 are instances of
//  those types:
//
//    Frozzle* extracted;
//    auto matcher = Matcher<Frozzle*, S1, S2, S3>(&extracted, {}, s1, s2, s3);
//    if (matches(expr, matcher)) {
//      // `extracted` set to `expr` here
//    }
//
//  It's annoying to have to write out the types S1, S2, and S3 and we don't get
//  class template argument deduction (CTAD) until C++17, so it's useful to
//  create a wrapper function so can take advantage of function template
//  argument deduction. We can also take this opportunity to make the interface
//  more compact.
//
//    template<class S1, class S2, class S3>
//    inline decltype(auto) frozzle(Frozzle** binder,
//                                  S1&& s1, S2&& s2, S3&& s3) {
//      return Matcher<Frozzle*, S1, S2, S3>(binder, {}, s1, s2, s3);
//    }
//    template<class S1, class S2, class S3>
//    inline decltype(auto) frozzle(S1&& s1, S2&& s2, S3&& s3) {
//      return Matcher<Frozzle*, S1, S2, S3>(nullptr, {}, s1, s2, s3);
//    }
//
//  Notice that we make the interface more compact by providing overloads with
//  and without the binder. Here is the final matcher usage:
//
//    Frozzle* extracted;
//    if (matches(expr, frozzle(&extracted, s1, s2, s3))) {
//      // `extracted` set to `expr` here
//    }
//
//  Some matchers are more complicated, though, because they need to do
//  something besides just applying submatchers to the components of an
//  expression. These matchers require slightly more work.
//
//
// Complex matchers:
//
//  Lets add a matcher that will match calls to functions whose names start with
//  certain prefixes. Since this is not a normal matcher for Call expressions,
//  we can't identify it by the Call* type. Instead, we have to create a new
//  identifier type, called a "Kind" for it.
//
//    struct PrefixCallKind {};
//
//  Next, since we're not in the common case of using a specific expression
//  pointer as our kind, we have to tell the matcher infrastructure what type of
//  thing this matcher matches. Since we want this matcher to be able to match
//  any given prefix, we also need the matcher to contain the given prefix as
//  state, and we need to tell the matcher infrastructure what type that state
//  is as well. To specify these types, we need to specialize
//  `KindTypeRegistry` for `PrefixCallKind`.
//
//    template<> struct KindTypeRegistry<PrefixCallKind> {
//      using matched_t = Call*;
//      using data_t = Name;
//    };
//
//  Note that because `matched_t` is set to a specific expression pointer, this
//  matcher will automatically be able to be applied to any `Expression*`, not
//  just `Call*`. If `matched_t` were not a specific expression pointer, this
//  matcher would only be able to be applied to types compatible with
//  `matched_t`. Also note that if a matcher does not need to store any state,
//  its `data_t` should be set to `unused_t`.
//
//  Now we need to tell the matcher infrastructure what custom logic to apply
//  for this matcher. We do this by specializing `MatchSelf`.
//
//    template<> struct MatchSelf<PrefixCallKind> {
//      bool operator()(Call* curr, Name prefix) {
//        return curr->name.startsWith(prefix);
//      }
//    };
//
//  Note that the first parameter to `MatchSelf<Kind>::operator()` will be that
//  kind's `matched_t` and the second parameter will be that kind's `data_t`,
//  which may be `unused_t`. (TODO: detect if `data_t` is `unused_t` and don't
//  expose it in the Matcher interface if so.)
//
//  After this, everything is the same as in the simple matcher case. This
//  particular matcher doesn't need to recurse into any subcomponents, so we can
//  skip straight to creating the wrapper function.
//
//    decltype(auto) prefixCall(Call** binder, Name prefix) {
//      return Matcher<PrefixCallKind>(binder, prefix);
//    }
//
//  Now we can use the new matcher:
//
//    Call* call;
//    if (matches(expr, prefixCall(&call, "__foo"))) {
//      // `call` set to `expr` here
//    }
//

// The main entrypoint for matching. If the match succeeds, all variables bound
// in the matcher will be set to their corresponding matched values. Otherwise,
// the value of the bound variables is unspecified and may have changed.
template<class Matcher> inline bool matches(Expression* expr, Matcher matcher) {
  return matcher.matches(expr);
}

namespace Internal {

struct unused_t {};

// Each matcher has a `Kind`, which controls how candidate values are
// destructured and inspected. For most matchers, `Kind` is a pointer to the
// matched subtype of Expression, but when there are multiple matchers for the
// same kind of expression, they are disambiguated by having different `Kind`s.
// In this case, or if the matcher matches something besides a pointer to a
// subtype of Expression, or if the matcher requires additional state, the
// matched type and the type of additional state must be associated with the
// `Kind` via a specialization of `KindTypeRegistry`.
template<class Kind> struct KindTypeRegistry {
  // The matched type
  using matched_t = void;
  // The type of additional state needed to perform a match. Can be set to
  // `unused_t` if it's not needed.
  using data_t = unused_t;
};

// Given a `Kind`, produce the type `matched_t` that is matched by that Kind and
// the type `candidate_t` that is the type of the parameter of the `matches`
// method. These types are only different if `matched_t` is a pointer to a
// subtype of Expression, in which case `candidate_t` is Expression*.
template<class Kind> struct MatchTypes {
  using matched_t = typename std::conditional_t<
    std::is_base_of<Expression, std::remove_pointer_t<Kind>>::value,
    Kind,
    typename KindTypeRegistry<Kind>::matched_t>;

  static constexpr bool isExpr =
    std::is_base_of<Expression, std::remove_pointer_t<matched_t>>::value;

  using candidate_t =
    typename std::conditional_t<isExpr, Expression*, matched_t>;
};

template<class Kind> using matched_t = typename MatchTypes<Kind>::matched_t;
template<class Kind> using candidate_t = typename MatchTypes<Kind>::candidate_t;
template<class Kind> using data_t = typename KindTypeRegistry<Kind>::data_t;

// Defined if the matched type is a specific expression pointer, so can be
// `dynCast`ed to from Expression*.
template<class Kind>
using enable_if_castable_t = typename std::enable_if<
  std::is_base_of<Expression, std::remove_pointer_t<matched_t<Kind>>>::value &&
    !std::is_same<Expression*, matched_t<Kind>>::value,
  int>::type;

// Opposite of above
template<class Kind>
using enable_if_not_castable_t = typename std::enable_if<
  !std::is_base_of<Expression, std::remove_pointer_t<matched_t<Kind>>>::value ||
    std::is_same<Expression*, matched_t<Kind>>::value,
  int>::type;

// Do a normal dynCast from Expression* to the subtype, storing the result in
// `out` and returning `true` iff the cast succeeded.
template<class Kind, enable_if_castable_t<Kind> = 0>
inline bool dynCastCandidate(candidate_t<Kind> candidate,
                             matched_t<Kind>& out) {
  out = candidate->template dynCast<std::remove_pointer_t<matched_t<Kind>>>();
  return out != nullptr;
}

// Otherwise we are not matching an Expression, so this is infallible.
template<class Kind, enable_if_not_castable_t<Kind> = 0>
inline bool dynCastCandidate(candidate_t<Kind> candidate,
                             matched_t<Kind>& out) {
  out = candidate;
  return true;
}

// Matchers can optionally specialize this to perform custom matching logic
// before recursing into submatchers, potentially short-circuiting the match.
// Uses a struct because partial specialization of functions is not allowed.
template<class Kind> struct MatchSelf {
  bool operator()(matched_t<Kind>, data_t<Kind>) { return true; }
};

// Used to statically ensure that each matcher has the correct number of
// submatchers. This needs to be specialized for each kind of matcher that has
// submatchers.
template<class Kind> struct NumComponents {
  static constexpr size_t value = 0;
};

// Every kind of matcher needs to partially specialize this for each of its
// components. Each specialization should define
//
//   T operator()(matched_t<Kind>)
//
// where T is the component's type. Components will be matched from first to
// last. Uses a struct instead of a function because partial specialization of
// functions is not allowed.
template<class Kind, int pos> struct GetComponent;

// A type-level linked list to hold an arbitrary number of matchers.
template<class...> struct SubMatchers {};
template<class CurrMatcher, class... NextMatchers>
struct SubMatchers<CurrMatcher, NextMatchers...> {
  CurrMatcher curr;
  SubMatchers<NextMatchers...> next;
  SubMatchers(CurrMatcher curr, NextMatchers... next)
    : curr(curr), next(next...) {};
};

// Iterates through the components of the candidate, applying a submatcher to
// each component. Uses a struct instead of a function because partial
// specialization of functions is not allowed.
template<class Kind, int pos, class CurrMatcher = void, class... NextMatchers>
struct Components {
  static inline bool
  match(matched_t<Kind> candidate,
        SubMatchers<CurrMatcher, NextMatchers...>& matchers) {
    return matchers.curr.matches(GetComponent<Kind, pos>{}(candidate)) &&
           Components<Kind, pos + 1, NextMatchers...>::match(candidate,
                                                             matchers.next);
  }
};
template<class Kind, int pos> struct Components<Kind, pos> {
  static_assert(pos == NumComponents<Kind>::value,
                "Unexpected number of submatchers");
  static inline bool match(matched_t<Kind>, SubMatchers<>) {
    // Base case when there are no components left; trivially true.
    return true;
  }
};

template<class Kind, class... Matchers> struct Matcher {
  matched_t<Kind>* binder;
  data_t<Kind> data;
  SubMatchers<Matchers...> submatchers;

  Matcher(matched_t<Kind>* binder, data_t<Kind> data, Matchers... submatchers)
    : binder(binder), data(data), submatchers(submatchers...) {}

  inline bool matches(candidate_t<Kind> candidate) {
    matched_t<Kind> casted;
    if (dynCastCandidate<Kind>(candidate, casted)) {
      if (binder != nullptr) {
        *binder = casted;
      }
      return MatchSelf<Kind>{}(casted, data) &&
             Components<Kind, 0, Matchers...>::match(casted, submatchers);
    }
    return false;
  }
};

// Concrete low-level matcher implementations. Not intended for direct external
// use.

// Any<T>: matches any value of the expected type
template<class T> struct AnyKind {};
template<class T> struct KindTypeRegistry<AnyKind<T>> {
  using matched_t = T;
  using data_t = unused_t;
};
template<class T> inline decltype(auto) Any(T* binder) {
  return Matcher<AnyKind<T>>(binder, {});
}

// Exact<T>: matches exact values of the expected type
template<class T> struct ExactKind {};
template<class T> struct KindTypeRegistry<ExactKind<T>> {
  using matched_t = T;
  using data_t = T;
};
template<class T> struct MatchSelf<ExactKind<T>> {
  bool operator()(T self, T expected) { return self == expected; }
};
template<class T> inline decltype(auto) Exact(T* binder, T data) {
  return Matcher<ExactKind<T>>(binder, data);
}

// {Bool,I32,I64,Int,F32,F64,Float,Number}Lit:
// match `Literal` of the expected `Type`
struct BoolLK {
  static bool matchType(Literal lit) {
    return lit.type == Type::i32 && (uint32_t)lit.geti32() <= 1U;
  }
  static int32_t getVal(Literal lit) { return lit.geti32(); }
};
struct I32LK {
  static bool matchType(Literal lit) { return lit.type == Type::i32; }
  static int32_t getVal(Literal lit) { return lit.geti32(); }
};
struct I64LK {
  static bool matchType(Literal lit) { return lit.type == Type::i64; }
  static int64_t getVal(Literal lit) { return lit.geti64(); }
};
struct IntLK {
  static bool matchType(Literal lit) { return lit.type.isInteger(); }
  static int64_t getVal(Literal lit) { return lit.getInteger(); }
};
struct F32LK {
  static bool matchType(Literal lit) { return lit.type == Type::f32; }
  static float getVal(Literal lit) { return lit.getf32(); }
};
struct F64LK {
  static bool matchType(Literal lit) { return lit.type == Type::f64; }
  static double getVal(Literal lit) { return lit.getf64(); }
};
struct FloatLK {
  static bool matchType(Literal lit) { return lit.type.isFloat(); }
  static double getVal(Literal lit) { return lit.getFloat(); }
};
template<class T> struct LitKind {};
template<class T> struct KindTypeRegistry<LitKind<T>> {
  using matched_t = Literal;
  using data_t = unused_t;
};
template<class T> struct MatchSelf<LitKind<T>> {
  bool operator()(Literal lit, unused_t) { return T::matchType(lit); }
};
template<class T> struct NumComponents<LitKind<T>> {
  static constexpr size_t value = 1;
};
template<class T> struct GetComponent<LitKind<T>, 0> {
  decltype(auto) operator()(Literal lit) { return T::getVal(lit); }
};
template<class S> inline decltype(auto) BoolLit(Literal* binder, S&& s) {
  return Matcher<LitKind<BoolLK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) I32Lit(Literal* binder, S&& s) {
  return Matcher<LitKind<I32LK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) I64Lit(Literal* binder, S&& s) {
  return Matcher<LitKind<I64LK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) IntLit(Literal* binder, S&& s) {
  return Matcher<LitKind<IntLK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) F32Lit(Literal* binder, S&& s) {
  return Matcher<LitKind<F32LK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) F64Lit(Literal* binder, S&& s) {
  return Matcher<LitKind<F64LK>, S>(binder, {}, s);
}
template<class S> inline decltype(auto) FloatLit(Literal* binder, S&& s) {
  return Matcher<LitKind<FloatLK>, S>(binder, {}, s);
}
struct NumberLitKind {};
template<> struct KindTypeRegistry<NumberLitKind> {
  using matched_t = Literal;
  using data_t = int32_t;
};
template<> struct MatchSelf<NumberLitKind> {
  bool operator()(Literal lit, int32_t expected) {
    return lit.type.isNumber() &&
           Literal::makeFromInt32(expected, lit.type) == lit;
  }
};
inline decltype(auto) NumberLit(Literal* binder, int32_t expected) {
  return Matcher<NumberLitKind>(binder, expected);
}

// Const
template<> struct NumComponents<Const*> {
  static constexpr size_t value = 1;
};
template<> struct GetComponent<Const*, 0> {
  Literal operator()(Const* c) { return c->value; }
};
template<class S> inline decltype(auto) ConstMatcher(Const** binder, S&& s) {
  return Matcher<Const*, S>(binder, {}, s);
}

// Unary, UnaryOp and AbstractUnaryOp
template<> struct NumComponents<Unary*> {
  static constexpr size_t value = 2;
};
template<> struct GetComponent<Unary*, 0> {
  UnaryOp operator()(Unary* curr) { return curr->op; }
};
template<> struct GetComponent<Unary*, 1> {
  Expression* operator()(Unary* curr) { return curr->value; }
};
struct UnaryOpK {
  using Op = UnaryOp;
  static UnaryOp getOp(Type, Op op) { return op; }
};
struct AbstractUnaryOpK {
  using Op = Abstract::Op;
  static UnaryOp getOp(Type type, Abstract::Op op) {
    return Abstract::getUnary(type, op);
  }
};
template<class T> struct UnaryOpKind {};
template<class T> struct KindTypeRegistry<UnaryOpKind<T>> {
  using matched_t = Unary*;
  using data_t = typename T::Op;
};
template<class T> struct MatchSelf<UnaryOpKind<T>> {
  bool operator()(Unary* curr, typename T::Op op) {
    return curr->op == T::getOp(curr->value->type, op);
  }
};
template<class T> struct NumComponents<UnaryOpKind<T>> {
  static constexpr size_t value = 1;
};
template<class T> struct GetComponent<UnaryOpKind<T>, 0> {
  Expression* operator()(Unary* curr) { return curr->value; }
};
template<class S1, class S2>
inline decltype(auto) UnaryMatcher(Unary** binder, S1&& s1, S2&& s2) {
  return Matcher<Unary*, S1, S2>(binder, {}, s1, s2);
}
template<class S>
inline decltype(auto) UnaryOpMatcher(Unary** binder, UnaryOp op, S&& s) {
  return Matcher<UnaryOpKind<UnaryOpK>, S>(binder, op, s);
}
template<class S>
inline decltype(auto)
AbstractUnaryOpMatcher(Unary** binder, Abstract::Op op, S&& s) {
  return Matcher<UnaryOpKind<AbstractUnaryOpK>, S>(binder, op, s);
}

// Binary, BinaryOp and AbstractBinaryOp
template<> struct NumComponents<Binary*> {
  static constexpr size_t value = 3;
};
template<> struct GetComponent<Binary*, 0> {
  BinaryOp operator()(Binary* curr) { return curr->op; }
};
template<> struct GetComponent<Binary*, 1> {
  Expression* operator()(Binary* curr) { return curr->left; }
};
template<> struct GetComponent<Binary*, 2> {
  Expression* operator()(Binary* curr) { return curr->right; }
};
struct BinaryOpK {
  using Op = BinaryOp;
  static BinaryOp getOp(Type, Op op) { return op; }
};
struct AbstractBinaryOpK {
  using Op = Abstract::Op;
  static BinaryOp getOp(Type type, Abstract::Op op) {
    return Abstract::getBinary(type, op);
  }
};
template<class T> struct BinaryOpKind {};
template<class T> struct KindTypeRegistry<BinaryOpKind<T>> {
  using matched_t = Binary*;
  using data_t = typename T::Op;
};
template<class T> struct MatchSelf<BinaryOpKind<T>> {
  bool operator()(Binary* curr, typename T::Op op) {
    return curr->op == T::getOp(curr->left->type, op);
  }
};
template<class T> struct NumComponents<BinaryOpKind<T>> {
  static constexpr size_t value = 2;
};
template<class T> struct GetComponent<BinaryOpKind<T>, 0> {
  Expression* operator()(Binary* curr) { return curr->left; }
};
template<class T> struct GetComponent<BinaryOpKind<T>, 1> {
  Expression* operator()(Binary* curr) { return curr->right; }
};
template<class S1, class S2, class S3>
inline decltype(auto)
BinaryMatcher(Binary** binder, S1&& s1, S2&& s2, S3&& s3) {
  return Matcher<Binary*, S1, S2, S3>(binder, {}, s1, s2, s3);
}
template<class S1, class S2>
inline decltype(auto)
BinaryOpMatcher(Binary** binder, BinaryOp op, S1&& s1, S2&& s2) {
  return Matcher<BinaryOpKind<BinaryOpK>, S1, S2>(binder, op, s1, s2);
}
template<class S1, class S2>
inline decltype(auto)
AbstractBinaryOpMatcher(Binary** binder, Abstract::Op op, S1&& s1, S2&& s2) {
  return Matcher<BinaryOpKind<AbstractBinaryOpK>, S1, S2>(binder, op, s1, s2);
}

// Select
template<> struct NumComponents<Select*> {
  static constexpr size_t value = 3;
};
template<> struct GetComponent<Select*, 0> {
  Expression* operator()(Select* curr) { return curr->ifTrue; }
};
template<> struct GetComponent<Select*, 1> {
  Expression* operator()(Select* curr) { return curr->ifFalse; }
};
template<> struct GetComponent<Select*, 2> {
  Expression* operator()(Select* curr) { return curr->condition; }
};
template<class S1, class S2, class S3>
inline decltype(auto)
SelectMatcher(Select** binder, S1&& s1, S2&& s2, S3&& s3) {
  return Matcher<Select*, S1, S2, S3>(binder, {}, s1, s2, s3);
}

// LocalGet
template<> struct NumComponents<LocalGet*> {
  static constexpr size_t value = 1;
};
template<> struct GetComponent<LocalGet*, 0> {
  Index operator()(LocalGet* curr) { return curr->index; }
};
template<class S>
inline decltype(auto) LocalGetMatcher(LocalGet** binder, S&& s) {
  return Matcher<LocalGet*, S>(binder, {}, s);
}

} // namespace Internal

// Public matching API

inline decltype(auto) bval() {
  return Internal::ConstMatcher(
    nullptr, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr)));
}
inline decltype(auto) bval(bool x) {
  return Internal::ConstMatcher(
    nullptr, Internal::BoolLit(nullptr, Internal::Exact<bool>(nullptr, x)));
}
inline decltype(auto) bval(bool* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::BoolLit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) bval(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::BoolLit(binder, Internal::Any<bool>(nullptr)));
}
inline decltype(auto) bval(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::BoolLit(nullptr, Internal::Any<bool>(nullptr)));
}

inline decltype(auto) i32() {
  return Internal::ConstMatcher(
    nullptr, Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr)));
}
// Use int rather than int32_t to disambiguate literal 0, which otherwise could
// be resolved to either the int32_t overload or any of the pointer overloads.
inline decltype(auto) i32(int x) {
  return Internal::ConstMatcher(
    nullptr, Internal::I32Lit(nullptr, Internal::Exact<int32_t>(nullptr, x)));
}
inline decltype(auto) i32(int32_t* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::I32Lit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) i32(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::I32Lit(binder, Internal::Any<int32_t>(nullptr)));
}
inline decltype(auto) i32(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::I32Lit(nullptr, Internal::Any<int32_t>(nullptr)));
}

inline decltype(auto) i64() {
  return Internal::ConstMatcher(
    nullptr, Internal::I64Lit(nullptr, Internal::Any<int64_t>(nullptr)));
}
inline decltype(auto) i64(int64_t x) {
  return Internal::ConstMatcher(
    nullptr, Internal::I64Lit(nullptr, Internal::Exact<int64_t>(nullptr, x)));
}
// Disambiguate literal 0, which could otherwise be interpreted as a pointer
inline decltype(auto) i64(int x) { return i64(int64_t(x)); }
inline decltype(auto) i64(int64_t* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::I64Lit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) i64(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::I64Lit(binder, Internal::Any<int64_t>(nullptr)));
}
inline decltype(auto) i64(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::I64Lit(nullptr, Internal::Any<int64_t>(nullptr)));
}

inline decltype(auto) f32() {
  return Internal::ConstMatcher(
    nullptr, Internal::F32Lit(nullptr, Internal::Any<float>(nullptr)));
}
inline decltype(auto) f32(float x) {
  return Internal::ConstMatcher(
    nullptr, Internal::F32Lit(nullptr, Internal::Exact<float>(nullptr, x)));
}
// Disambiguate literal 0, which could otherwise be interpreted as a pointer
inline decltype(auto) f32(int x) { return f32(float(x)); }
inline decltype(auto) f32(float* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::F32Lit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) f32(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::F32Lit(binder, Internal::Any<float>(nullptr)));
}
inline decltype(auto) f32(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::F32Lit(nullptr, Internal::Any<float>(nullptr)));
}

inline decltype(auto) f64() {
  return Internal::ConstMatcher(
    nullptr, Internal::F64Lit(nullptr, Internal::Any<double>(nullptr)));
}
inline decltype(auto) f64(double x) {
  return Internal::ConstMatcher(
    nullptr, Internal::F64Lit(nullptr, Internal::Exact<double>(nullptr, x)));
}
// Disambiguate literal 0, which could otherwise be interpreted as a pointer
inline decltype(auto) f64(int x) { return f64(double(x)); }
inline decltype(auto) f64(double* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::F64Lit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) f64(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::F64Lit(binder, Internal::Any<double>(nullptr)));
}
inline decltype(auto) f64(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::F64Lit(nullptr, Internal::Any<double>(nullptr)));
}

inline decltype(auto) ival() {
  return Internal::ConstMatcher(
    nullptr, Internal::IntLit(nullptr, Internal::Any<int64_t>(nullptr)));
}
inline decltype(auto) ival(int64_t x) {
  return Internal::ConstMatcher(
    nullptr, Internal::IntLit(nullptr, Internal::Exact<int64_t>(nullptr, x)));
}
// Disambiguate literal 0, which could otherwise be interpreted as a pointer
inline decltype(auto) ival(int x) { return ival(int64_t(x)); }
inline decltype(auto) ival(int64_t* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::IntLit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) ival(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::IntLit(binder, Internal::Any<int64_t>(nullptr)));
}
inline decltype(auto) ival(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::IntLit(nullptr, Internal::Any<int64_t>(nullptr)));
}
inline decltype(auto) ival(Literal* binder, int64_t x) {
  return Internal::ConstMatcher(
    nullptr, Internal::IntLit(binder, Internal::Exact<int64_t>(nullptr, x)));
}
inline decltype(auto) ival(Const** binder, int64_t x) {
  return Internal::ConstMatcher(
    binder, Internal::IntLit(nullptr, Internal::Exact<int64_t>(nullptr, x)));
}

inline decltype(auto) fval() {
  return Internal::ConstMatcher(
    nullptr, Internal::FloatLit(nullptr, Internal::Any<double>(nullptr)));
}
inline decltype(auto) fval(double x) {
  return Internal::ConstMatcher(
    nullptr, Internal::FloatLit(nullptr, Internal::Exact<double>(nullptr, x)));
}
// Disambiguate literal 0, which could otherwise be interpreted as a pointer
inline decltype(auto) fval(int x) { return fval(double(x)); }
inline decltype(auto) fval(double* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::FloatLit(nullptr, Internal::Any(binder)));
}
inline decltype(auto) fval(Literal* binder) {
  return Internal::ConstMatcher(
    nullptr, Internal::FloatLit(binder, Internal::Any<double>(nullptr)));
}
inline decltype(auto) fval(Const** binder) {
  return Internal::ConstMatcher(
    binder, Internal::FloatLit(nullptr, Internal::Any<double>(nullptr)));
}
inline decltype(auto) fval(Literal* binder, double x) {
  return Internal::ConstMatcher(
    nullptr, Internal::FloatLit(binder, Internal::Exact<double>(nullptr, x)));
}
inline decltype(auto) fval(Const** binder, double x) {
  return Internal::ConstMatcher(
    binder, Internal::FloatLit(nullptr, Internal::Exact<double>(nullptr, x)));
}

inline decltype(auto) constant() {
  return Internal::ConstMatcher(nullptr, Internal::Any<Literal>(nullptr));
}
inline decltype(auto) constant(int x) {
  return Internal::ConstMatcher(nullptr, Internal::NumberLit(nullptr, x));
}
inline decltype(auto) constant(Literal* binder) {
  return Internal::ConstMatcher(nullptr, Internal::Any(binder));
}
inline decltype(auto) constant(Const** binder) {
  return Internal::ConstMatcher(binder, Internal::Any<Literal>(nullptr));
}
inline decltype(auto) constant(Literal* binder, int32_t x) {
  return Internal::ConstMatcher(nullptr, Internal::NumberLit(binder, x));
}
inline decltype(auto) constant(Const** binder, int32_t x) {
  return Internal::ConstMatcher(binder, Internal::NumberLit(nullptr, x));
}

inline decltype(auto) any() { return Internal::Any<Expression*>(nullptr); }
inline decltype(auto) any(Expression** binder) { return Internal::Any(binder); }

template<class S> inline decltype(auto) unary(S&& s) {
  return Internal::UnaryMatcher(nullptr, Internal::Any<UnaryOp>(nullptr), s);
}
template<class S> inline decltype(auto) unary(Unary** binder, S&& s) {
  return Internal::UnaryMatcher(binder, Internal::Any<UnaryOp>(nullptr), s);
}
template<class S> inline decltype(auto) unary(UnaryOp* binder, S&& s) {
  return Internal::UnaryMatcher(nullptr, Internal::Any<UnaryOp>(binder), s);
}
template<class S> inline decltype(auto) unary(UnaryOp op, S&& s) {
  return Internal::UnaryOpMatcher(nullptr, op, s);
}
template<class S> inline decltype(auto) unary(Abstract::Op op, S&& s) {
  return Internal::AbstractUnaryOpMatcher(nullptr, op, s);
}
template<class S>
inline decltype(auto) unary(Unary** binder, UnaryOp op, S&& s) {
  return Internal::UnaryOpMatcher(binder, op, s);
}
template<class S>
inline decltype(auto) unary(Unary** binder, Abstract::Op op, S&& s) {
  return Internal::AbstractUnaryOpMatcher(binder, op, s);
}
template<class S1, class S2> inline decltype(auto) binary(S1&& s1, S2&& s2) {
  return Internal::BinaryMatcher(
    nullptr, Internal::Any<BinaryOp>(nullptr), s1, s2);
}
template<class S1, class S2>
inline decltype(auto) binary(Binary** binder, S1&& s1, S2&& s2) {
  return Internal::BinaryMatcher(
    binder, Internal::Any<BinaryOp>(nullptr), s1, s2);
}
template<class S1, class S2>
inline decltype(auto) binary(BinaryOp* binder, S1&& s1, S2&& s2) {
  return Internal::BinaryMatcher(
    nullptr, Internal::Any<BinaryOp>(binder), s1, s2);
}
template<class S1, class S2>
inline decltype(auto) binary(BinaryOp op, S1&& s1, S2&& s2) {
  return Internal::BinaryOpMatcher(nullptr, op, s1, s2);
}
template<class S1, class S2>
inline decltype(auto) binary(Abstract::Op op, S1&& s1, S2&& s2) {
  return Internal::AbstractBinaryOpMatcher(nullptr, op, s1, s2);
}
template<class S1, class S2>
inline decltype(auto) binary(Binary** binder, BinaryOp op, S1&& s1, S2&& s2) {
  return Internal::BinaryOpMatcher(binder, op, s1, s2);
}
template<class S1, class S2>
inline decltype(auto)
binary(Binary** binder, Abstract::Op op, S1&& s1, S2&& s2) {
  return Internal::AbstractBinaryOpMatcher(binder, op, s1, s2);
}

template<class S1, class S2, class S3>
inline decltype(auto) select(S1&& s1, S2&& s2, S3&& s3) {
  return Internal::SelectMatcher(nullptr, s1, s2, s3);
}
template<class S1, class S2, class S3>
inline decltype(auto) select(Select** binder, S1&& s1, S2&& s2, S3&& s3) {
  return Internal::SelectMatcher(binder, s1, s2, s3);
}

inline decltype(auto) local() {
  return Internal::LocalGetMatcher(nullptr, Internal::Any<Index>(nullptr));
}
inline decltype(auto) local(Index* binder) {
  return Internal::LocalGetMatcher(nullptr, Internal::Any(binder));
}

} // namespace wasm::Match

#endif // wasm_ir_match_h
