@@ -47,11 +47,11 @@ class Attribute {
47
47
48
48
bool operator !() const { return impl == nullptr ; }
49
49
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 >
53
53
bool isa () const ;
54
- template <typename First, typename ... Rest >
54
+ template <typename ... Tys >
55
55
bool isa_and_nonnull () const ;
56
56
template <typename U>
57
57
U dyn_cast () const ;
@@ -100,6 +100,9 @@ class Attribute {
100
100
return impl->getAbstractAttribute ();
101
101
}
102
102
103
+ // / Return the internal Attribute implementation.
104
+ ImplType *getImpl () const { return impl; }
105
+
103
106
protected:
104
107
ImplType *impl{nullptr };
105
108
};
@@ -109,34 +112,29 @@ inline raw_ostream &operator<<(raw_ostream &os, Attribute attr) {
109
112
return os;
110
113
}
111
114
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>
119
116
bool Attribute::isa () const {
120
- return isa<First>() || isa<Second, Rest ...>();
117
+ return llvm:: isa<Tys ...>(* this );
121
118
}
122
119
123
- template <typename First, typename ... Rest >
120
+ template <typename ... Tys >
124
121
bool Attribute::isa_and_nonnull () const {
125
- return impl && isa<First, Rest ...>();
122
+ return llvm::isa_and_present<Tys ...>(* this );
126
123
}
127
124
128
125
template <typename U>
129
126
U Attribute::dyn_cast () const {
130
- return isa <U>() ? U (impl) : U ( nullptr );
127
+ return llvm::dyn_cast <U>(* this );
131
128
}
129
+
132
130
template <typename U>
133
131
U Attribute::dyn_cast_or_null () const {
134
- return (impl && isa <U>()) ? U (impl) : U ( nullptr );
132
+ return llvm::dyn_cast_if_present <U>(* this );
135
133
}
134
+
136
135
template <typename U>
137
136
U Attribute::cast () const {
138
- assert (isa<U>());
139
- return U (impl);
137
+ return llvm::cast<U>(*this );
140
138
}
141
139
142
140
inline ::llvm::hash_code hash_value (Attribute arg) {
@@ -318,6 +316,31 @@ struct DenseMapInfo<mlir::NamedAttribute> {
318
316
}
319
317
};
320
318
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
+
321
344
} // namespace llvm
322
345
323
346
#endif
0 commit comments