//===- 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 { public: /// Utility class for implementing attributes. template class... Traits> using AttrBase = detail::StorageUserBase; using ImplType = AttributeStorage; using ValueType = void; using AbstractTy = AbstractAttribute; constexpr Attribute() = default; /* implicit */ Attribute(const ImplType *impl) : impl(const_cast(impl)) {} Attribute(const Attribute &other) = default; Attribute &operator=(const Attribute &other) = default; bool operator==(Attribute other) const { return impl == other.impl; } bool operator!=(Attribute other) const { return !(*this == other); } explicit operator bool() const { return impl; } bool operator!() const { return impl == nullptr; } /// Return a unique identifier for the concrete attribute type. This is used /// to support dynamic type casting. TypeID getTypeID() { return impl->getAbstractAttribute().getTypeID(); } /// Return the context this attribute belongs to. MLIRContext *getContext() const; /// Get the dialect this attribute is registered to. Dialect &getDialect() const { return impl->getAbstractAttribute().getDialect(); } /// Print the attribute. If `elideType` is set, the attribute is printed /// without a trailing colon type if it has one. void print(raw_ostream &os, bool elideType = false) const; void print(raw_ostream &os, AsmState &state, bool elideType = false) const; void dump() const; /// Print the attribute without dialect wrapping. void printStripped(raw_ostream &os) const; void printStripped(raw_ostream &os, AsmState &state) const; /// Get an opaque pointer to the attribute. const void *getAsOpaquePointer() const { return impl; } /// Construct an attribute from the opaque pointer representation. static Attribute getFromOpaquePointer(const void *ptr) { return Attribute(reinterpret_cast(ptr)); } friend ::llvm::hash_code hash_value(Attribute arg); /// Returns true if `InterfaceT` has been promised by the dialect or /// implemented. template bool hasPromiseOrImplementsInterface() { return dialect_extension_detail::hasPromisedInterface( getDialect(), getTypeID(), InterfaceT::getInterfaceID()) || mlir::isa(*this); } /// Returns true if the type was registered with a particular trait. template