9 #include "core/value.h"
10 #include "core/global.h"
11 #include "core/expr.h"
12 #include "core/constant.h"
13 #include "core/inst.h"
23 template <
typename T,
typename U>
25 using type =
typename std::conditional
26 < std::is_const<T>::value
27 ,
typename std::add_const<U>::type
45 using TT =
typename std::remove_const<T>::type;
53 template <
typename T,
typename U>
55 using TT =
typename std::remove_const<T>::type;
57 static constexpr
bool value =
58 std::is_base_of<Value, TT>::value &&
59 std::is_base_of<U, TT>::value &&
60 !std::is_same<U, TT>::value;
69 typename std::enable_if<detail::is_value<T>::value, T *>::type
70 cast_or_null(
typename detail::copy_const<T, Value>::type *v)
75 if (v->Is(T::kValueKind)) {
76 return static_cast<T *
>(v);
91 return static_cast<Inst *
>(v);
100 inline const Inst *cast_or_null<const Inst>(
const Value *v)
106 return static_cast<const Inst *
>(v);
114 template <
typename T>
115 typename std::enable_if<detail::is_class<T, Inst>::value, T *>::type
116 cast_or_null(
typename detail::copy_const<T, Value>::type *value)
118 if (value ==
nullptr) {
121 if (!value->Is(Value::Kind::INST)) {
124 auto *inst =
static_cast<typename detail::copy_const<T, Inst>::type *
>(value);
125 if (!inst->Is(T::kInstKind)) {
128 return static_cast<T *
>(value);
134 template <
typename T>
135 typename std::enable_if<detail::is_class<T, Global>::value, T *>::type
136 cast_or_null(
typename detail::copy_const<T, Value>::type *value)
138 if (value ==
nullptr) {
141 if (!value->Is(Value::Kind::GLOBAL)) {
144 if (!
static_cast<const Global *
>(value)->Is(T::kGlobalKind)) {
147 return static_cast<T *
>(value);
153 template <
typename T>
154 typename std::enable_if<detail::is_class<T, Constant>::value, T *>::type
155 cast_or_null(
typename detail::copy_const<T, Value>::type *value)
157 if (value ==
nullptr) {
160 if (!value->Is(Value::Kind::CONST)) {
163 if (!
static_cast<const Constant *
>(value)->Is(T::kConstKind)) {
166 return static_cast<T *
>(value);
172 template <
typename T>
173 typename std::enable_if<detail::is_class<T, Expr>::value, T *>::type
174 cast_or_null(
typename detail::copy_const<T, Value>::type *value)
176 if (value ==
nullptr) {
179 if (!value->Is(Value::Kind::EXPR)) {
182 if (!
static_cast<const Expr *
>(value)->Is(T::kExprKind)) {
185 return static_cast<T *
>(value);
192 template <
typename T,
typename U>
195 if (T *t = ::cast_or_null<T>(from)) {
198 llvm_unreachable(
"invalid dynamic type");
204 template <
typename T,
typename U>
207 return Ref(::cast_or_null<T>(from.Get()), from.Index());
213 template <
typename T,
typename U>
216 return ConstRef(::cast_or_null<const T>(from.Get()), from.Index());
222 template <
typename T,
typename U>
225 return Ref(::cast<T>(from.Get()), from.Index());
231 template <
typename T,
typename U>
234 return ConstRef(::cast<const T>(from.Get()), from.Index());
240 template <
typename T,
typename U>
243 return ::cast_or_null<const T>(from);