//===- StorageUniquerSupport.h - MLIR Storage Uniquer Utilities -*- 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 // //===----------------------------------------------------------------------===// // // This file defines utility classes for interfacing with StorageUniquer. // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_STORAGEUNIQUERSUPPORT_H #define MLIR_IR_STORAGEUNIQUERSUPPORT_H #include "mlir/IR/AttrTypeSubElements.h" #include "mlir/IR/DialectRegistry.h" #include "mlir/Support/InterfaceSupport.h" #include "mlir/Support/StorageUniquer.h" #include "mlir/Support/TypeID.h" #include "llvm/ADT/FunctionExtras.h" namespace mlir { class InFlightDiagnostic; class Location; class MLIRContext; namespace detail { /// Utility method to generate a callback that can be used to generate a /// diagnostic when checking the construction invariants of a storage object. /// This is defined out-of-line to avoid the need to include Location.h. llvm::unique_function<InFlightDiagnostic()> getDefaultDiagnosticEmitFn(MLIRContext *ctx); llvm::unique_function<InFlightDiagnostic()> getDefaultDiagnosticEmitFn(const Location &loc); //===----------------------------------------------------------------------===// // StorageUserTraitBase //===----------------------------------------------------------------------===// /// Helper class for implementing traits for storage classes. Clients are not /// expected to interact with this directly, so its members are all protected. template <typename ConcreteType, template <typename> class TraitType> class StorageUserTraitBase { … }; namespace StorageUserTrait { /// This trait is used to determine if a storage user, like Type, is mutable /// or not. A storage user is mutable if ImplType of the derived class defines /// a `mutate` function with a proper signature. Note that this trait is not /// supposed to be used publicly. Users should use alias names like /// `TypeTrait::IsMutable` instead. template <typename ConcreteType> struct IsMutable : public StorageUserTraitBase<ConcreteType, IsMutable> { … }; } // namespace StorageUserTrait //===----------------------------------------------------------------------===// // StorageUserBase //===----------------------------------------------------------------------===// namespace storage_user_base_impl { /// Returns true if this given Trait ID matches the IDs of any of the provided /// trait types `Traits`. template <template <typename T> class... Traits> bool hasTrait(TypeID traitID) { … } // We specialize for the empty case to not define an empty array. template <> inline bool hasTrait(TypeID traitID) { … } } // namespace storage_user_base_impl /// Utility class for implementing users of storage classes uniqued by a /// StorageUniquer. Clients are not expected to interact with this class /// directly. template <typename ConcreteT, typename BaseT, typename StorageT, typename UniquerT, template <typename T> class... Traits> class StorageUserBase : public BaseT, public Traits<ConcreteT>... { … }; } // namespace detail } // namespace mlir #endif