/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Interface Declarations                                                     *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace fir {

/// Provides methods to control movement of operations during transformations.
/// For example, some LoopLikeOpInterface operations may disallow
/// hoisting speculatable operations (e.g. even Pure ones) under some
/// conditions. Operations may control when the hoisting
/// (or rather a general movement) is allowed by implementing this interface.
class OperationMoveOpInterface;

} // namespace fir
namespace fir {

/// Provides methods to control movement of operations during transformations.
/// For example, some LoopLikeOpInterface operations may disallow
/// hoisting speculatable operations (e.g. even Pure ones) under some
/// conditions. Operations may control when the hoisting
/// (or rather a general movement) is allowed by implementing this interface.
namespace detail {
struct OperationMoveOpInterfaceInterfaceTraits {
  struct Concept {
    /// The methods defined by the interface.
    bool (*canMoveFromDescendant)(const Concept *impl, ::mlir::Operation *, ::mlir::Operation *, ::mlir::Operation *);
    bool (*canMoveOutOf)(const Concept *impl, ::mlir::Operation *, ::mlir::Operation *);
  };
  template<typename ConcreteOp>
  class Model : public Concept {
  public:
    using Interface = ::fir::OperationMoveOpInterface;
    Model() : Concept{canMoveFromDescendant, canMoveOutOf} {}

    static inline bool canMoveFromDescendant(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * descendant, ::mlir::Operation * candidate);
    static inline bool canMoveOutOf(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * candidate);
  };
  template<typename ConcreteOp>
  class FallbackModel : public Concept {
  public:
    using Interface = ::fir::OperationMoveOpInterface;
    FallbackModel() : Concept{canMoveFromDescendant, canMoveOutOf} {}

    static inline bool canMoveFromDescendant(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * descendant, ::mlir::Operation * candidate);
    static inline bool canMoveOutOf(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * candidate);
  };
  template<typename ConcreteModel, typename ConcreteOp>
  class ExternalModel : public FallbackModel<ConcreteModel> {
  public:
    using ConcreteEntity = ConcreteOp;
  };
};
template <typename ConcreteOp>
struct OperationMoveOpInterfaceTrait;

} // namespace detail
class OperationMoveOpInterface : public ::mlir::OpInterface<OperationMoveOpInterface, detail::OperationMoveOpInterfaceInterfaceTraits> {
public:
  using ::mlir::OpInterface<OperationMoveOpInterface, detail::OperationMoveOpInterfaceInterfaceTraits>::OpInterface;
  template <typename ConcreteOp>
  struct Trait : public detail::OperationMoveOpInterfaceTrait<ConcreteOp> {};

  /// Returns true if it is allowed to move the given 'candidate'
  /// operation from the 'descendant' operation into this operation.
  /// If 'candidate' is nullptr, then the caller is querying whether
  /// any operation from any descendant can be moved into this operation.
  bool canMoveFromDescendant(::mlir::Operation * descendant, ::mlir::Operation * candidate);

  /// Returns true if it is allowed to move the given 'candidate'
  /// operation out of this operation. If 'candidate' is nullptr,
  /// then the caller is querying whether any operation can be moved
  /// out of this operation.
  bool canMoveOutOf(::mlir::Operation * candidate);
};

} // namespace fir
namespace fir::detail {

  template <typename ConcreteOp>
  struct OperationMoveOpInterfaceTrait : public ::mlir::OpInterface<OperationMoveOpInterface, detail::OperationMoveOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
    static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
      return detail::verifyOperationMoveOpInterface(op);
    }
  };

} // namespace fir::detail
namespace fir {

template<typename ConcreteOp>
bool detail::OperationMoveOpInterfaceInterfaceTraits::Model<ConcreteOp>::canMoveFromDescendant(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * descendant, ::mlir::Operation * candidate) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).canMoveFromDescendant(descendant, candidate);
}
template<typename ConcreteOp>
bool detail::OperationMoveOpInterfaceInterfaceTraits::Model<ConcreteOp>::canMoveOutOf(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * candidate) {
  return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).canMoveOutOf(candidate);
}
template<typename ConcreteOp>
bool detail::OperationMoveOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::canMoveFromDescendant(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * descendant, ::mlir::Operation * candidate) {
  return static_cast<const ConcreteOp *>(impl)->canMoveFromDescendant(tablegen_opaque_val, descendant, candidate);
}
template<typename ConcreteOp>
bool detail::OperationMoveOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::canMoveOutOf(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Operation * candidate) {
  return static_cast<const ConcreteOp *>(impl)->canMoveOutOf(tablegen_opaque_val, candidate);
}

} // namespace fir
