bool operator!() const { return impl == nullptr; }
- template <typename U>
- bool isa() const;
- template <typename First, typename Second, typename... Rest>
+ /// Casting utility functions. These are deprecated and will be removed,
+ /// please prefer using the `llvm` namespace variants instead.
+ template <typename... Tys>
bool isa() const;
- template <typename First, typename... Rest>
+ template <typename... Tys>
bool isa_and_nonnull() const;
template <typename U>
U dyn_cast() const;
return impl->getAbstractAttribute();
}
+ /// Return the internal Attribute implementation.
+ ImplType *getImpl() const { return impl; }
+
protected:
ImplType *impl{nullptr};
};
return os;
}
-template <typename U>
-bool Attribute::isa() const {
- assert(impl && "isa<> used on a null attribute.");
- return U::classof(*this);
-}
-
-template <typename First, typename Second, typename... Rest>
+template <typename... Tys>
bool Attribute::isa() const {
- return isa<First>() || isa<Second, Rest...>();
+ return llvm::isa<Tys...>(*this);
}
-template <typename First, typename... Rest>
+template <typename... Tys>
bool Attribute::isa_and_nonnull() const {
- return impl && isa<First, Rest...>();
+ return llvm::isa_and_present<Tys...>(*this);
}
template <typename U>
U Attribute::dyn_cast() const {
- return isa<U>() ? U(impl) : U(nullptr);
+ return llvm::dyn_cast<U>(*this);
}
+
template <typename U>
U Attribute::dyn_cast_or_null() const {
- return (impl && isa<U>()) ? U(impl) : U(nullptr);
+ return llvm::dyn_cast_if_present<U>(*this);
}
+
template <typename U>
U Attribute::cast() const {
- assert(isa<U>());
- return U(impl);
+ return llvm::cast<U>(*this);
}
inline ::llvm::hash_code hash_value(Attribute arg) {
}
};
+/// Add support for llvm style casts. We provide a cast between To and From if
+/// From is mlir::Attribute or derives from it.
+template <typename To, typename From>
+struct 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>>>
+ : NullableValueCastFailed<To>,
+ DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
+ /// Arguments are taken as mlir::Attribute here and not as `From`, because
+ /// when casting from an intermediate type of the hierarchy to one of its
+ /// children, the val.getTypeID() inside T::classof will use the static
+ /// getTypeID of the parent instead of the non-static Type::getTypeID that
+ /// returns the dynamic ID. This means that T::classof would end up comparing
+ /// the static TypeID of the children to the static TypeID of its parent,
+ /// making it impossible to downcast from the parent to the child.
+ static inline bool isPossible(mlir::Attribute ty) {
+ /// Return a constant true instead of a dynamic true when casting to self or
+ /// up the hierarchy.
+ return std::is_same_v<To, std::remove_const_t<From>> ||
+ std::is_base_of_v<To, From> || To::classof(ty);
+ }
+ static inline To doCast(mlir::Attribute attr) { return To(attr.getImpl()); }
+};
+
} // namespace llvm
#endif