13#ifndef MLIR_IR_STORAGEUNIQUERSUPPORT_H
14#define MLIR_IR_STORAGEUNIQUERSUPPORT_H
21#include "llvm/ADT/FunctionExtras.h"
32llvm::unique_function<InFlightDiagnostic()>
34llvm::unique_function<InFlightDiagnostic()>
43template <
typename ConcreteType,
template <
typename>
class TraitType>
52 auto *trait =
static_cast<const TraitType<ConcreteType> *
>(
this);
53 return *
static_cast<const ConcreteType *
>(trait);
63template <
typename ConcreteType>
74template <
template <
typename T>
class... Traits>
77 for (
unsigned i = 0, e =
sizeof...(Traits); i != e; ++i)
78 if (traitIDs[i] == traitID)
93template <
typename ConcreteT,
typename BaseT,
typename StorageT,
94 typename UniquerT,
template <
typename T>
class... Traits>
109 template <
typename T>
111 static_assert(std::is_convertible<ConcreteT, T>::value,
112 "casting from a non-convertible type");
136 llvm::cast<ConcreteT>(instance), walkAttrsFn, walkTypesFn);
145 return ::mlir::detail::replaceImmediateSubElementsImpl(
146 llvm::cast<ConcreteT>(instance), replAttrs, replTypes);
154 template <
typename... IfaceModels>
156 typename ConcreteT::AbstractTy *abstract =
160 llvm::report_fatal_error(
"Registering an interface for an attribute/type "
161 "that is not itself registered.");
165 abstract->getDialect(), abstract->getTypeID(),
166 IfaceModels::Interface::getInterfaceID()),
169 (checkInterfaceTarget<IfaceModels>(), ...);
170 abstract->interfaceMap.template insertModels<IfaceModels...>();
176 template <
typename... Args>
181 return UniquerT::template
get<ConcreteT>(ctx, std::forward<Args>(args)...);
188 template <
typename... Args>
191 std::forward<Args>(args)...);
202 template <
typename Arg1,
typename... Args,
203 typename = std::enable_if_t<std::is_convertible_v<
206 Arg1 &&ctx, Args... args) {
208 if (failed(ConcreteT::verifyInvariants(emitErrorFn, args...)))
210 return UniquerT::template
get<ConcreteT>(ctx, std::forward<Args>(args)...);
215 return ConcreteT((
const typename BaseT::ImplType *)
ptr);
224 template <
typename... Args>
226 static_assert(std::is_base_of<StorageUserTrait::IsMutable<ConcreteT>,
228 "The `mutate` function expects mutable trait "
229 "(e.g. TypeTrait::IsMutable) to be attached on parent.");
231 std::forward<Args>(args)...);
235 template <
typename... Args>
242 template <
typename T>
243 using has_concrete_entity_t =
typename T::ConcreteEntity;
249 template <
typename T,
250 bool = llvm::is_detected<has_concrete_entity_t, T>::value>
251 struct IfaceTargetOrConcreteT {
252 using type =
typename T::ConcreteEntity;
254 template <
typename T>
255 struct IfaceTargetOrConcreteT<T,
false> {
256 using type = ConcreteT;
262 template <
typename T>
263 static void checkInterfaceTarget() {
264 static_assert(std::is_base_of<typename IfaceTargetOrConcreteT<T>::type,
266 "attaching an interface to the wrong attribute/type kind");
false
Parses a map_entries map type from a string format back into its numeric value.
Attributes are known-constant values of operations.
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
This class provides an efficient unique identifier for a specific C++ type.
static TypeID get()
Construct a type info object for the given type T.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides an efficient mapping between a given Interface type, and a particular implementat...
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
static LogicalResult verifyInvariants(Args... args)
Default implementation that just returns success.
static void attachInterface(MLIRContext &context)
Attach the given models as implementations of the corresponding interfaces for the concrete storage u...
static bool classof(T val)
Provide an implementation of 'classof' that compares the type id of the provided value with that of t...
static ConcreteType get(MLIRContext *ctx, Args &&...args)
LogicalResult mutate(Args &&...args)
Mutate the current storage instance.
static TypeID getTypeID()
Return a unique identifier for the concrete type.
static ConcreteT getFromOpaquePointer(const void *ptr)
Get an instance of the concrete type from a void pointer.
StorageUserBase< ConcreteType, BaseType, StorageType, detail::AttributeUniquer, Traits... > Base
static HasTraitFn getHasTraitFn()
Returns the function that returns true if the given Trait ID matches the IDs of any of the traits def...
bool(*)(TypeID) HasTraitFn
static ConcreteT getChecked(function_ref< InFlightDiagnostic()> emitErrorFn, Arg1 &&ctx, Args... args)
Get or create a new ConcreteT instance within the ctx.
static ConcreteT getChecked(const Location &loc, Args &&...args)
Get or create a new ConcreteT instance within the ctx, defined at the given, potentially unknown,...
ImplType * getImpl() const
Utility for easy access to the storage instance.
static auto getWalkImmediateSubElementsFn()
Returns a function that walks immediate sub elements of a given instance of the storage user.
static detail::InterfaceMap getInterfaceMap()
Returns an interface map for the interfaces registered to this storage user.
static auto getReplaceImmediateSubElementsFn()
Returns a function that replaces immediate sub elements of a given instance of the storage user.
Helper class for implementing traits for storage classes.
ConcreteType getInstance() const
Return the derived instance.
bool hasTrait(TypeID traitID)
Returns true if this given Trait ID matches the IDs of any of the provided trait types Traits.
void walkImmediateSubElementsImpl(T derived, function_ref< void(Attribute)> walkAttrsFn, function_ref< void(Type)> walkTypesFn)
This function provides the underlying implementation for the SubElementInterface walk method,...
llvm::unique_function< InFlightDiagnostic()> getDefaultDiagnosticEmitFn(MLIRContext *ctx)
Utility method to generate a callback that can be used to generate a diagnostic when checking the con...
void handleAdditionOfUndefinedPromisedInterface(Dialect &dialect, TypeID interfaceRequestorID, TypeID interfaceID)
Checks if the given interface, which is attempting to be attached, is a promised interface of this di...
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref
This trait is used to determine if a storage user, like Type, is mutable or not.