llvm/mlir/include/mlir/IR/Attributes.h

//===- Attributes.h - MLIR Attribute Classes --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_IR_ATTRIBUTES_H
#define MLIR_IR_ATTRIBUTES_H

#include "mlir/IR/AttributeSupport.h"
#include "llvm/Support/PointerLikeTypeTraits.h"

namespace mlir {
class AsmState;
class StringAttr;

/// Attributes are known-constant values of operations.
///
/// Instances of the Attribute class are references to immortal key-value pairs
/// with immutable, uniqued keys owned by MLIRContext. As such, an Attribute is
/// a thin wrapper around an underlying storage pointer. Attributes are usually
/// passed by value.
class Attribute {};

inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {}

template <typename... Tys>
bool Attribute::isa() const {}

template <typename... Tys>
bool Attribute::isa_and_nonnull() const {}

template <typename U>
U Attribute::dyn_cast() const {}

template <typename U>
U Attribute::dyn_cast_or_null() const {}

template <typename U>
U Attribute::cast() const {}

inline ::llvm::hash_code hash_value(Attribute arg) {}

//===----------------------------------------------------------------------===//
// NamedAttribute
//===----------------------------------------------------------------------===//

/// NamedAttribute represents a combination of a name and an Attribute value.
class NamedAttribute {};

inline ::llvm::hash_code hash_value(const NamedAttribute &arg) {}

/// Allow walking and replacing the subelements of a NamedAttribute.
template <>
struct AttrTypeSubElementHandler<NamedAttribute> {};

//===----------------------------------------------------------------------===//
// AttributeTraitBase
//===----------------------------------------------------------------------===//

namespace AttributeTrait {
/// This class represents the base of an attribute trait.
TraitBase;
} // namespace AttributeTrait

//===----------------------------------------------------------------------===//
// AttributeInterface
//===----------------------------------------------------------------------===//

/// This class represents the base of an attribute interface. See the definition
/// of `detail::Interface` for requirements on the `Traits` type.
template <typename ConcreteType, typename Traits>
class AttributeInterface
    : public detail::Interface<ConcreteType, Attribute, Traits, Attribute,
                               AttributeTrait::TraitBase> {};

//===----------------------------------------------------------------------===//
// Core AttributeTrait
//===----------------------------------------------------------------------===//

namespace AttributeTrait {
/// This trait is used to determine if an attribute is mutable or not. It is
/// attached on an attribute if the corresponding ConcreteType defines a
/// `mutate` function with proper signature.
IsMutable;

/// This trait is used to determine if an attribute is a location or not. It is
/// attached to an attribute by the user if they intend the attribute to be used
/// as a location.
template <typename ConcreteType>
struct IsLocation : public AttributeTrait::TraitBase<ConcreteType, IsLocation> {};
} // namespace AttributeTrait

} // namespace mlir.

namespace llvm {

// Attribute hash just like pointers.
template <>
struct DenseMapInfo<mlir::Attribute> {};
DenseMapInfo<T, std::enable_if_t<std::is_base_of<mlir::Attribute, T>::value && !mlir::detail::IsInterface<T>::value>>;

/// Allow LLVM to steal the low bits of Attributes.
template <>
struct PointerLikeTypeTraits<mlir::Attribute> {};

template <>
struct DenseMapInfo<mlir::NamedAttribute> {};

/// Add support for llvm style casts. We provide a cast between To and From if
/// From is mlir::Attribute or derives from it.
CastInfo<To, From, std::enable_if_t<std::is_same_v<mlir::Attribute, std::remove_const_t<From>> || std::is_base_of_v<mlir::Attribute, From>>>;

} // namespace llvm

#endif