/*
 * 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);
}

} // 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);
}

} // namespace wasm::Match

#endif // wasm_ir_match_h
