/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Enum Utility Declarations                                                  *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|* From: FIRAttr.td                                                           *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace fir {
// allowed 32-bit signless integer cases: 0, 1
enum class BoxFieldAttr : uint32_t {
  base_addr = 0,
  derived_type = 1,
};

::std::optional<BoxFieldAttr> symbolizeBoxFieldAttr(uint32_t);
::llvm::StringRef stringifyBoxFieldAttr(BoxFieldAttr);
::std::optional<BoxFieldAttr> symbolizeBoxFieldAttr(::llvm::StringRef);
inline constexpr unsigned getMaxEnumValForBoxFieldAttr() {
  return 1;
}


inline ::llvm::StringRef stringifyEnum(BoxFieldAttr enumValue) {
  return stringifyBoxFieldAttr(enumValue);
}

template <typename EnumType>
::std::optional<EnumType> symbolizeEnum(::llvm::StringRef);

template <>
inline ::std::optional<BoxFieldAttr> symbolizeEnum<BoxFieldAttr>(::llvm::StringRef str) {
  return symbolizeBoxFieldAttr(str);
}

class BoxFieldAttrAttr : public ::mlir::IntegerAttr {
public:
  using ValueType = BoxFieldAttr;
  using ::mlir::IntegerAttr::IntegerAttr;
  static bool classof(::mlir::Attribute attr);
  static BoxFieldAttrAttr get(::mlir::MLIRContext *context, BoxFieldAttr val);
  BoxFieldAttr getValue() const;
};
} // namespace fir

namespace mlir {
template <typename T, typename>
struct FieldParser;

template<>
struct FieldParser<fir::BoxFieldAttr, fir::BoxFieldAttr> {
  template <typename ParserT>
  static FailureOr<fir::BoxFieldAttr> parse(ParserT &parser) {
    // Parse the keyword/string containing the enum.
    std::string enumKeyword;
    auto loc = parser.getCurrentLocation();
    if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
      return parser.emitError(loc, "expected keyword for allowed 32-bit signless integer cases: 0, 1");

    // Symbolize the keyword.
    if (::std::optional<fir::BoxFieldAttr> attr = fir::symbolizeEnum<fir::BoxFieldAttr>(enumKeyword))
      return *attr;
    return parser.emitError(loc, "invalid allowed 32-bit signless integer cases: 0, 1 specification: ") << enumKeyword;
  }
};
} // namespace mlir

namespace llvm {
inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, fir::BoxFieldAttr value) {
  auto valueStr = stringifyEnum(value);
  return p << valueStr;
}
} // namespace llvm

namespace llvm {
template<> struct DenseMapInfo<fir::BoxFieldAttr> {
  using StorageInfo = ::llvm::DenseMapInfo<uint32_t>;

  static inline fir::BoxFieldAttr getEmptyKey() {
    return static_cast<fir::BoxFieldAttr>(StorageInfo::getEmptyKey());
  }

  static inline fir::BoxFieldAttr getTombstoneKey() {
    return static_cast<fir::BoxFieldAttr>(StorageInfo::getTombstoneKey());
  }

  static unsigned getHashValue(const fir::BoxFieldAttr &val) {
    return StorageInfo::getHashValue(static_cast<uint32_t>(val));
  }

  static bool isEqual(const fir::BoxFieldAttr &lhs, const fir::BoxFieldAttr &rhs) {
    return lhs == rhs;
  }
};
}

namespace fir {
// Fortran variable attributes
enum class FortranVariableFlagsEnum : uint32_t {
  None = 0,
  allocatable = 1,
  asynchronous = 2,
  bind_c = 4,
  contiguous = 8,
  intent_in = 16,
  intent_inout = 32,
  intent_out = 64,
  optional = 128,
  parameter = 256,
  pointer = 512,
  target = 1024,
  value = 2048,
  fortran_volatile = 4096,
  host_assoc = 8192,
};

::std::optional<FortranVariableFlagsEnum> symbolizeFortranVariableFlagsEnum(uint32_t);
std::string stringifyFortranVariableFlagsEnum(FortranVariableFlagsEnum);
::std::optional<FortranVariableFlagsEnum> symbolizeFortranVariableFlagsEnum(::llvm::StringRef);

inline constexpr FortranVariableFlagsEnum operator|(FortranVariableFlagsEnum a, FortranVariableFlagsEnum b) {
  return static_cast<FortranVariableFlagsEnum>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
}
inline constexpr FortranVariableFlagsEnum operator&(FortranVariableFlagsEnum a, FortranVariableFlagsEnum b) {
  return static_cast<FortranVariableFlagsEnum>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
}
inline constexpr FortranVariableFlagsEnum operator^(FortranVariableFlagsEnum a, FortranVariableFlagsEnum b) {
  return static_cast<FortranVariableFlagsEnum>(static_cast<uint32_t>(a) ^ static_cast<uint32_t>(b));
}
inline constexpr FortranVariableFlagsEnum operator~(FortranVariableFlagsEnum bits) {
  // Ensure only bits that can be present in the enum are set
  return static_cast<FortranVariableFlagsEnum>(~static_cast<uint32_t>(bits) & static_cast<uint32_t>(16383u));
}
inline constexpr bool bitEnumContainsAll(FortranVariableFlagsEnum bits, FortranVariableFlagsEnum bit) {
  return (bits & bit) == bit;
}
inline constexpr bool bitEnumContainsAny(FortranVariableFlagsEnum bits, FortranVariableFlagsEnum bit) {
  return (static_cast<uint32_t>(bits) & static_cast<uint32_t>(bit)) != 0;
}
inline constexpr FortranVariableFlagsEnum bitEnumClear(FortranVariableFlagsEnum bits, FortranVariableFlagsEnum bit) {
  return bits & ~bit;
}
inline constexpr FortranVariableFlagsEnum bitEnumSet(FortranVariableFlagsEnum bits, FortranVariableFlagsEnum bit, /*optional*/bool value=true) {
  return value ? (bits | bit) : bitEnumClear(bits, bit);
}
  
inline std::string stringifyEnum(FortranVariableFlagsEnum enumValue) {
  return stringifyFortranVariableFlagsEnum(enumValue);
}

template <typename EnumType>
::std::optional<EnumType> symbolizeEnum(::llvm::StringRef);

template <>
inline ::std::optional<FortranVariableFlagsEnum> symbolizeEnum<FortranVariableFlagsEnum>(::llvm::StringRef str) {
  return symbolizeFortranVariableFlagsEnum(str);
}

class FortranVariableFlagsEnumAttr : public ::mlir::IntegerAttr {
public:
  using ValueType = FortranVariableFlagsEnum;
  using ::mlir::IntegerAttr::IntegerAttr;
  static bool classof(::mlir::Attribute attr);
  static FortranVariableFlagsEnumAttr get(::mlir::MLIRContext *context, FortranVariableFlagsEnum val);
  FortranVariableFlagsEnum getValue() const;
};
} // namespace fir

namespace mlir {
template <typename T, typename>
struct FieldParser;

template<>
struct FieldParser<::fir::FortranVariableFlagsEnum, ::fir::FortranVariableFlagsEnum> {
  template <typename ParserT>
  static FailureOr<::fir::FortranVariableFlagsEnum> parse(ParserT &parser) {
    // Parse the keyword/string containing the enum.
    std::string enumKeyword;
    auto loc = parser.getCurrentLocation();
    if (failed(parser.parseOptionalKeywordOrString(&enumKeyword)))
      return parser.emitError(loc, "expected keyword for Fortran variable attributes");

    // Symbolize the keyword.
    if (::std::optional<::fir::FortranVariableFlagsEnum> attr = ::fir::symbolizeEnum<::fir::FortranVariableFlagsEnum>(enumKeyword))
      return *attr;
    return parser.emitError(loc, "invalid Fortran variable attributes specification: ") << enumKeyword;
  }
};
} // namespace mlir

namespace llvm {
inline ::llvm::raw_ostream &operator<<(::llvm::raw_ostream &p, ::fir::FortranVariableFlagsEnum value) {
  auto valueStr = stringifyEnum(value);
  auto underlyingValue = static_cast<std::make_unsigned_t<::fir::FortranVariableFlagsEnum>>(value);
  if (underlyingValue && !llvm::has_single_bit(underlyingValue))
    return p << '"' << valueStr << '"';
  return p << valueStr;
}
} // namespace llvm

namespace llvm {
template<> struct DenseMapInfo<::fir::FortranVariableFlagsEnum> {
  using StorageInfo = ::llvm::DenseMapInfo<uint32_t>;

  static inline ::fir::FortranVariableFlagsEnum getEmptyKey() {
    return static_cast<::fir::FortranVariableFlagsEnum>(StorageInfo::getEmptyKey());
  }

  static inline ::fir::FortranVariableFlagsEnum getTombstoneKey() {
    return static_cast<::fir::FortranVariableFlagsEnum>(StorageInfo::getTombstoneKey());
  }

  static unsigned getHashValue(const ::fir::FortranVariableFlagsEnum &val) {
    return StorageInfo::getHashValue(static_cast<uint32_t>(val));
  }

  static bool isEqual(const ::fir::FortranVariableFlagsEnum &lhs, const ::fir::FortranVariableFlagsEnum &rhs) {
    return lhs == rhs;
  }
};
}

