@@ -47,11 +47,11 @@ class Attribute {
4747
4848 bool operator !() const { return impl == nullptr ; }
4949
50- template < typename U>
51- bool isa () const ;
52- template <typename First, typename Second, typename ... Rest >
50+ // / Casting utility functions. These are deprecated and will be removed,
51+ // / please prefer using the `llvm` namespace variants instead.
52+ template <typename ... Tys >
5353 bool isa () const ;
54- template <typename First, typename ... Rest >
54+ template <typename ... Tys >
5555 bool isa_and_nonnull () const ;
5656 template <typename U>
5757 U dyn_cast () const ;
@@ -100,6 +100,9 @@ class Attribute {
100100 return impl->getAbstractAttribute ();
101101 }
102102
103+ // / Return the internal Attribute implementation.
104+ ImplType *getImpl () const { return impl; }
105+
103106protected:
104107 ImplType *impl{nullptr };
105108};
@@ -109,34 +112,29 @@ inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
109112 return os;
110113}
111114
112- template <typename U>
113- bool Attribute::isa () const {
114- assert (impl && " isa<> used on a null attribute." );
115- return U::classof (*this );
116- }
117-
118- template <typename First, typename Second, typename ... Rest>
115+ template <typename ... Tys>
119116bool Attribute::isa () const {
120- return isa<First>() || isa<Second, Rest ...>();
117+ return llvm:: isa<Tys ...>(* this );
121118}
122119
123- template <typename First, typename ... Rest >
120+ template <typename ... Tys >
124121bool Attribute::isa_and_nonnull () const {
125- return impl && isa<First, Rest ...>();
122+ return llvm::isa_and_present<Tys ...>(* this );
126123}
127124
128125template <typename U>
129126U Attribute::dyn_cast () const {
130- return isa <U>() ? U (impl) : U ( nullptr );
127+ return llvm::dyn_cast <U>(* this );
131128}
129+
132130template <typename U>
133131U Attribute::dyn_cast_or_null () const {
134- return (impl && isa <U>()) ? U (impl) : U ( nullptr );
132+ return llvm::dyn_cast_if_present <U>(* this );
135133}
134+
136135template <typename U>
137136U Attribute::cast () const {
138- assert (isa<U>());
139- return U (impl);
137+ return llvm::cast<U>(*this );
140138}
141139
142140inline ::llvm::hash_code hash_value (Attribute arg) {
@@ -318,6 +316,31 @@ struct DenseMapInfo<mlir::NamedAttribute> {
318316 }
319317};
320318
319+ // / Add support for llvm style casts. We provide a cast between To and From if
320+ // / From is mlir::Attribute or derives from it.
321+ template <typename To, typename From>
322+ struct CastInfo <To, From,
323+ std::enable_if_t <std::is_same_v<mlir::Attribute,
324+ std::remove_const_t <From>> ||
325+ std::is_base_of_v<mlir::Attribute, From>>>
326+ : NullableValueCastFailed<To>,
327+ DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
328+ // / Arguments are taken as mlir::Attribute here and not as `From`, because
329+ // / when casting from an intermediate type of the hierarchy to one of its
330+ // / children, the val.getTypeID() inside T::classof will use the static
331+ // / getTypeID of the parent instead of the non-static Type::getTypeID that
332+ // / returns the dynamic ID. This means that T::classof would end up comparing
333+ // / the static TypeID of the children to the static TypeID of its parent,
334+ // / making it impossible to downcast from the parent to the child.
335+ static inline bool isPossible (mlir::Attribute ty) {
336+ // / Return a constant true instead of a dynamic true when casting to self or
337+ // / up the hierarchy.
338+ return std::is_same_v<To, std::remove_const_t <From>> ||
339+ std::is_base_of_v<To, From> || To::classof (ty);
340+ }
341+ static inline To doCast (mlir::Attribute attr) { return To (attr.getImpl ()); }
342+ };
343+
321344} // namespace llvm
322345
323346#endif
0 commit comments