/TypeID.h Secret
Created
February 12, 2025 17:49
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MLIR_USE_FALLBACK_TYPE_IDS | |
#define MLIR_USE_FALLBACK_TYPE_IDS false | |
#endif | |
template <typename T> | |
struct is_fully_resolved_t { | |
/// Trait to check if `U` is fully resolved. We use this to verify that `T` is | |
/// fully resolved when trying to resolve a TypeID. We don't technically need | |
/// to have the full definition of `T` for the fallback, but it does help | |
/// prevent situations where a forward declared type uses this fallback even | |
/// though there is a strong definition for the TypeID in the location where | |
/// `T` is defined. | |
template <typename U> | |
using is_fully_resolved_trait = decltype(sizeof(U)); | |
template <typename U> | |
using is_fully_resolved = llvm::is_detected<is_fully_resolved_trait, U>; | |
using value = is_fully_resolved<T>; | |
}; | |
template <typename T> | |
static bool is_fully_resolved() { | |
return is_fully_resolved_t<T>::value; | |
} | |
/// This class provides a resolver for getting the ID for a given class T. This | |
/// allows for the derived type to specialize its resolution behavior. The | |
/// default implementation uses the string name of the type to resolve the ID. | |
/// This provides a strong definition, but at the cost of performance (we need | |
/// to do an initial lookup) and is not usable by classes defined in anonymous | |
/// contexts. | |
/// | |
/// TODO: The use of the type name is only necessary when building in the | |
/// presence of shared libraries. We could add a build flag that guarantees | |
/// "static"-like environments and switch this to a more optimal implementation | |
/// when that is enabled. | |
template <typename T, typename Enable = void> | |
class TypeIDResolver : public FallbackTypeIDResolver { | |
public: | |
static TypeID resolveTypeID() { | |
static_assert(is_fully_resolved<T>(), | |
"TypeID::get<> requires the complete definition of `T`"); | |
static TypeID id = registerImplicitTypeID(llvm::getTypeName<T>()); | |
return id; | |
} | |
}; | |
/// This class provides a resolver for getting the ID for a given class T, when | |
/// the class provides a `static TypeID resolveTypeID()` method. This allows for | |
/// simplifying situations when the class can resolve the ID itself. | |
template <typename T> | |
class TypeIDResolver< | |
T, std::enable_if_t<InlineTypeIDResolver::has_resolve_typeid<T>::value>> { | |
public: | |
static TypeID resolveTypeID() { | |
return InlineTypeIDResolver::resolveTypeID<T>(); | |
} | |
}; | |
/// If MLIR_USE_FALLBACK_TYPE_IDS is enabled, use fallback string TypeIDs | |
/// for any types without inline type IDs defined. | |
template <typename T> | |
class TypeIDResolver< | |
T, std::enable_if_t< | |
MLIR_USE_FALLBACK_TYPE_IDS && | |
!detail::InlineTypeIDResolver::has_resolve_typeid<T>::value>> | |
: public FallbackTypeIDResolver { | |
public: | |
static TypeID resolveTypeID() { | |
static_assert(is_fully_resolved<T>(), | |
"TypeID::get<> requires the complete definition of `T`"); | |
static TypeID id = registerImplicitTypeID(llvm::getTypeName<T>()); | |
return id; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment