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

namespace fir {

/// Interface for attributes defining whether creation of a temporary
///     copy of a Fortran array is safe and/or how to produce proper
///     dynamic checks to avoid it, if it is unsafe.
class SafeTempArrayCopyAttrInterface;

} // namespace fir
namespace fir {

/// Interface for attributes defining whether creation of a temporary
///     copy of a Fortran array is safe and/or how to produce proper
///     dynamic checks to avoid it, if it is unsafe.
namespace detail {
struct SafeTempArrayCopyAttrInterfaceInterfaceTraits {
  struct Concept {
    /// The methods defined by the interface.
    bool (*isDynamicallySafe)();
    mlir::Value (*genDynamicCheck)(::mlir::Location, ::fir::FirOpBuilder &, ::mlir::Value);
    void (*registerTempDeallocation)(::mlir::Location, ::fir::FirOpBuilder &, ::mlir::Value, ::mlir::Value);
  };
  template<typename ConcreteAttr>
  class Model : public Concept {
  public:
    using Interface = ::fir::SafeTempArrayCopyAttrInterface;
    Model() : Concept{isDynamicallySafe, genDynamicCheck, registerTempDeallocation} {}

    static inline bool isDynamicallySafe();
    static inline mlir::Value genDynamicCheck(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array);
    static inline void registerTempDeallocation(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array, ::mlir::Value temp);
  };
  template<typename ConcreteAttr>
  class FallbackModel : public Concept {
  public:
    using Interface = ::fir::SafeTempArrayCopyAttrInterface;
    FallbackModel() : Concept{isDynamicallySafe, genDynamicCheck, registerTempDeallocation} {}

    static inline bool isDynamicallySafe();
    static inline mlir::Value genDynamicCheck(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array);
    static inline void registerTempDeallocation(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array, ::mlir::Value temp);
  };
  template<typename ConcreteModel, typename ConcreteAttr>
  class ExternalModel : public FallbackModel<ConcreteModel> {
  public:
    using ConcreteEntity = ConcreteAttr;
  };
};
template <typename ConcreteAttr>
struct SafeTempArrayCopyAttrInterfaceTrait;

} // namespace detail
class SafeTempArrayCopyAttrInterface : public ::mlir::AttributeInterface<SafeTempArrayCopyAttrInterface, detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits> {
public:
  using ::mlir::AttributeInterface<SafeTempArrayCopyAttrInterface, detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits>::AttributeInterface;
  template <typename ConcreteAttr>
  struct Trait : public detail::SafeTempArrayCopyAttrInterfaceTrait<ConcreteAttr> {};

  /// Returns true iff the usage of the temporary array copy
  /// can be made safe applying some dynamic checks.
  bool isDynamicallySafe() const;

  /// Generate FIR that produces an i1 Value indicating
  /// whether the creation of the temporary array copy is safe.
  /// \p array is a definition of the original array.
  /// The implementation may assume that \p array is present
  /// (though, it may be empty).
  mlir::Value genDynamicCheck(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array) const;

  /// This method allows inserting any FIR right before the optional
  /// copy-out (from \p temp to \p array) and the deallocation
  /// of the temporary array (implying that the temporary copy was
  /// actually created).
  void registerTempDeallocation(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array, ::mlir::Value temp) const;
};

} // namespace fir
namespace fir::detail {

  template <typename ConcreteAttr>
  struct SafeTempArrayCopyAttrInterfaceTrait : public ::mlir::AttributeInterface<SafeTempArrayCopyAttrInterface, detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits>::Trait<ConcreteAttr> {
  };

} // namespace fir::detail
namespace fir {

template<typename ConcreteAttr>
bool detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::Model<ConcreteAttr>::isDynamicallySafe() {
  return ConcreteAttr::isDynamicallySafe();
}
template<typename ConcreteAttr>
mlir::Value detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::Model<ConcreteAttr>::genDynamicCheck(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array) {
  return ConcreteAttr::genDynamicCheck(loc, builder, array);
}
template<typename ConcreteAttr>
void detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::Model<ConcreteAttr>::registerTempDeallocation(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array, ::mlir::Value temp) {
  return ConcreteAttr::registerTempDeallocation(loc, builder, array, temp);
}
template<typename ConcreteAttr>
bool detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::FallbackModel<ConcreteAttr>::isDynamicallySafe() {
  return ConcreteAttr::isDynamicallySafe();
}
template<typename ConcreteAttr>
mlir::Value detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::FallbackModel<ConcreteAttr>::genDynamicCheck(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array) {
  return ConcreteAttr::genDynamicCheck(loc, builder, array);
}
template<typename ConcreteAttr>
void detail::SafeTempArrayCopyAttrInterfaceInterfaceTraits::FallbackModel<ConcreteAttr>::registerTempDeallocation(::mlir::Location loc, ::fir::FirOpBuilder & builder, ::mlir::Value array, ::mlir::Value temp) {
  return ConcreteAttr::registerTempDeallocation(loc, builder, array, temp);
}

} // namespace fir
