Line data Source code
1 : //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
11 : // and dyn_cast_or_null<X>() templates.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_SUPPORT_CASTING_H
16 : #define LLVM_SUPPORT_CASTING_H
17 :
18 : #include "llvm/Support/Compiler.h"
19 : #include "llvm/Support/type_traits.h"
20 : #include <cassert>
21 : #include <memory>
22 : #include <type_traits>
23 :
24 : namespace llvm {
25 :
26 : //===----------------------------------------------------------------------===//
27 : // isa<x> Support Templates
28 : //===----------------------------------------------------------------------===//
29 :
30 : // Define a template that can be specialized by smart pointers to reflect the
31 : // fact that they are automatically dereferenced, and are not involved with the
32 : // template selection process... the default implementation is a noop.
33 : //
34 : template<typename From> struct simplify_type {
35 : using SimpleType = From; // The real type this represents...
36 :
37 : // An accessor to get the real value...
38 : static SimpleType &getSimplifiedValue(From &Val) { return Val; }
39 : };
40 :
41 : template<typename From> struct simplify_type<const From> {
42 : using NonConstSimpleType = typename simplify_type<From>::SimpleType;
43 : using SimpleType =
44 : typename add_const_past_pointer<NonConstSimpleType>::type;
45 : using RetType =
46 : typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
47 :
48 0 : static RetType getSimplifiedValue(const From& Val) {
49 0 : return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
50 : }
51 0 : };
52 0 :
53 : // The core of the implementation of isa<X> is here; To and From should be
54 0 : // the names of classes. This template can be specialized to customize the
55 0 : // implementation of isa<> without rewriting it from scratch.
56 : template <typename To, typename From, typename Enabler = void>
57 0 : struct isa_impl {
58 0 : static inline bool doit(const From &Val) {
59 72754 : return To::classof(&Val);
60 0 : }
61 0 : };
62 :
63 0 : /// Always allow upcasts, and perform no dynamic check for them.
64 0 : template <typename To, typename From>
65 1354738 : struct isa_impl<
66 0 : To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
67 0 : static inline bool doit(const From &) { return true; }
68 10415930 : };
69 0 :
70 0 : template <typename To, typename From> struct isa_impl_cl {
71 6821616 : static inline bool doit(const From &Val) {
72 0 : return isa_impl<To, From>::doit(Val);
73 0 : }
74 6470631 : };
75 0 :
76 0 : template <typename To, typename From> struct isa_impl_cl<To, const From> {
77 2004703 : static inline bool doit(const From &Val) {
78 0 : return isa_impl<To, From>::doit(Val);
79 0 : }
80 208633 : };
81 0 :
82 0 : template <typename To, typename From>
83 70992516 : struct isa_impl_cl<To, const std::unique_ptr<From>> {
84 0 : static inline bool doit(const std::unique_ptr<From> &Val) {
85 0 : assert(Val && "isa<> used on a null pointer");
86 1825906 : return isa_impl_cl<To, From>::doit(*Val);
87 0 : }
88 0 : };
89 1368340 :
90 0 : template <typename To, typename From> struct isa_impl_cl<To, From*> {
91 0 : static inline bool doit(const From *Val) {
92 5476 : assert(Val && "isa<> used on a null pointer");
93 0 : return isa_impl<To, From>::doit(*Val);
94 0 : }
95 4810 : };
96 0 :
97 0 : template <typename To, typename From> struct isa_impl_cl<To, From*const> {
98 281 : static inline bool doit(const From *Val) {
99 0 : assert(Val && "isa<> used on a null pointer");
100 0 : return isa_impl<To, From>::doit(*Val);
101 7945503 : }
102 0 : };
103 0 :
104 2170 : template <typename To, typename From> struct isa_impl_cl<To, const From*> {
105 0 : static inline bool doit(const From *Val) {
106 0 : assert(Val && "isa<> used on a null pointer");
107 0 : return isa_impl<To, From>::doit(*Val);
108 2 : }
109 0 : };
110 497 :
111 0 : template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
112 0 : static inline bool doit(const From *Val) {
113 56 : assert(Val && "isa<> used on a null pointer");
114 0 : return isa_impl<To, From>::doit(*Val);
115 0 : }
116 8664315 : };
117 0 :
118 0 : template<typename To, typename From, typename SimpleFrom>
119 18019147 : struct isa_impl_wrap {
120 0 : // When From != SimplifiedType, we can simplify the type some more by using
121 0 : // the simplify_type template.
122 1465 : static bool doit(const From &Val) {
123 0 : return isa_impl_wrap<To, SimpleFrom,
124 0 : typename simplify_type<SimpleFrom>::SimpleType>::doit(
125 4424788 : simplify_type<const From>::getSimplifiedValue(Val));
126 0 : }
127 0 : };
128 0 :
129 0 : template<typename To, typename FromTy>
130 0 : struct isa_impl_wrap<To, FromTy, FromTy> {
131 297805 : // When From == SimpleType, we are as simple as we are going to get.
132 0 : static bool doit(const FromTy &Val) {
133 0 : return isa_impl_cl<To,FromTy>::doit(Val);
134 297815 : }
135 0 : };
136 4 :
137 122235 : // isa<X> - Return true if the parameter to the template is an instance of the
138 0 : // template type argument. Used like this:
139 4 : //
140 122225 : // if (isa<Type>(myVal)) { ... }
141 0 : //
142 3138 : template <class X, class Y> LLVM_NODISCARD inline bool isa(const Y &Val) {
143 1960251 : return isa_impl_wrap<X, const Y,
144 0 : typename simplify_type<const Y>::SimpleType>::doit(Val);
145 3138 : }
146 21159395 :
147 0 : //===----------------------------------------------------------------------===//
148 0 : // cast<x> Support Templates
149 19480319 : //===----------------------------------------------------------------------===//
150 0 :
151 29175 : template<class To, class From> struct cast_retty;
152 69924 :
153 0 : // Calculate what type the 'cast' function should return, based on a requested
154 1946426 : // type of To and a source type of From.
155 30416 : template<class To, class From> struct cast_retty_impl {
156 0 : using ret_type = To &; // Normal case, return Ty&
157 1919072 : };
158 0 : template<class To, class From> struct cast_retty_impl<To, const From> {
159 0 : using ret_type = const To &; // Normal case, return Ty&
160 1821 : };
161 10 :
162 20440886 : template<class To, class From> struct cast_retty_impl<To, From*> {
163 0 : using ret_type = To *; // Pointer arg case, return Ty*
164 0 : };
165 20440886 :
166 0 : template<class To, class From> struct cast_retty_impl<To, const From*> {
167 0 : using ret_type = const To *; // Constant pointer arg case, return const Ty*
168 19967 : };
169 2 :
170 0 : template<class To, class From> struct cast_retty_impl<To, const From*const> {
171 19967 : using ret_type = const To *; // Constant pointer arg case, return const Ty*
172 101039 : };
173 0 :
174 0 : template <class To, class From>
175 101037 : struct cast_retty_impl<To, std::unique_ptr<From>> {
176 0 : private:
177 0 : using PointerType = typename cast_retty_impl<To, From *>::ret_type;
178 26018 : using ResultType = typename std::remove_pointer<PointerType>::type;
179 149387 :
180 0 : public:
181 26018 : using ret_type = std::unique_ptr<ResultType>;
182 149387 : };
183 1672599 :
184 0 : template<class To, class From, class SimpleFrom>
185 1050 : struct cast_retty_wrap {
186 1672599 : // When the simplified type and the from type are not the same, use the type
187 0 : // simplifier to reduce the type, then reuse cast_retty_impl to get the
188 1050 : // resultant type.
189 0 : using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
190 0 : };
191 29175 :
192 0 : template<class To, class FromTy>
193 0 : struct cast_retty_wrap<To, FromTy, FromTy> {
194 29175 : // When the simplified type is equal to the from type, use it directly.
195 0 : using ret_type = typename cast_retty_impl<To,FromTy>::ret_type;
196 19133463 : };
197 0 :
198 0 : template<class To, class From>
199 19133463 : struct cast_retty {
200 0 : using ret_type = typename cast_retty_wrap<
201 0 : To, From, typename simplify_type<From>::SimpleType>::ret_type;
202 20428546 : };
203 0 :
204 0 : // Ensure the non-simple values are converted using the simplify_type template
205 20428546 : // that may be specialized by smart pointers...
206 0 : //
207 301690 : template<class To, class From, class SimpleFrom> struct cast_convert_val {
208 0 : // This is not a simple type, use the template to simplify it...
209 0 : static typename cast_retty<To, From>::ret_type doit(From &Val) {
210 3889 : return cast_convert_val<To, SimpleFrom,
211 0 : typename simplify_type<SimpleFrom>::SimpleType>::doit(
212 0 : simplify_type<From>::getSimplifiedValue(Val));
213 0 : }
214 39508 : };
215 0 :
216 0 : template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
217 39508 : // This _is_ a simple type, just cast it.
218 0 : static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
219 118912 : typename cast_retty<To, FromTy>::ret_type Res2
220 0 : = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
221 0 : return Res2;
222 0 : }
223 0 : };
224 0 :
225 0 : template <class X> struct is_simple_type {
226 0 : static const bool value =
227 0 : std::is_same<X, typename simplify_type<X>::SimpleType>::value;
228 0 : };
229 0 :
230 0 : // cast<X> - Return the argument parameter cast to the specified type. This
231 0 : // casting operator asserts that the type is correct, so it does not return null
232 0 : // on failure. It does not allow a null argument (use cast_or_null for that).
233 0 : // It is typically used like this:
234 0 : //
235 0 : // cast<Instruction>(myVal)->getParent()
236 0 : //
237 0 : template <class X, class Y>
238 0 : inline typename std::enable_if<!is_simple_type<Y>::value,
239 0 : typename cast_retty<X, const Y>::ret_type>::type
240 0 : cast(const Y &Val) {
241 0 : assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
242 0 : return cast_convert_val<
243 8 : X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val);
244 0 : }
245 0 :
246 0 : template <class X, class Y>
247 0 : inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
248 0 : assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
249 0 : return cast_convert_val<X, Y,
250 2 : typename simplify_type<Y>::SimpleType>::doit(Val);
251 0 : }
252 0 :
253 0 : template <class X, class Y>
254 0 : inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
255 164614 : assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
256 0 : return cast_convert_val<X, Y*,
257 0 : typename simplify_type<Y*>::SimpleType>::doit(Val);
258 0 : }
259 0 :
260 0 : template <class X, class Y>
261 15 : inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
262 2184 : cast(std::unique_ptr<Y> &&Val) {
263 0 : assert(isa<X>(Val.get()) && "cast<Ty>() argument of incompatible type!");
264 0 : using ret_type = typename cast_retty<X, std::unique_ptr<Y>>::ret_type;
265 0 : return ret_type(
266 14161 : cast_convert_val<X, Y *, typename simplify_type<Y *>::SimpleType>::doit(
267 199 : Val.release()));
268 0 : }
269 0 :
270 0 : // cast_or_null<X> - Functionally identical to cast, except that a null value is
271 0 : // accepted.
272 0 : //
273 0 : template <class X, class Y>
274 0 : LLVM_NODISCARD inline
275 0 : typename std::enable_if<!is_simple_type<Y>::value,
276 0 : typename cast_retty<X, const Y>::ret_type>::type
277 26018 : cast_or_null(const Y &Val) {
278 3 : if (!Val)
279 375 : return nullptr;
280 0 : assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
281 0 : return cast<X>(Val);
282 0 : }
283 0 :
284 0 : template <class X, class Y>
285 0 : LLVM_NODISCARD inline
286 0 : typename std::enable_if<!is_simple_type<Y>::value,
287 2725 : typename cast_retty<X, Y>::ret_type>::type
288 0 : cast_or_null(Y &Val) {
289 156 : if (!Val)
290 0 : return nullptr;
291 0 : assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
292 0 : return cast<X>(Val);
293 4 : }
294 0 :
295 0 : template <class X, class Y>
296 0 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type
297 182 : cast_or_null(Y *Val) {
298 655332 : if (!Val) return nullptr;
299 6019 : assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
300 0 : return cast<X>(Val);
301 182 : }
302 13252 :
303 443 : template <class X, class Y>
304 0 : inline typename cast_retty<X, std::unique_ptr<Y>>::ret_type
305 5138 : cast_or_null(std::unique_ptr<Y> &&Val) {
306 0 : if (!Val)
307 0 : return nullptr;
308 147226 : return cast<X>(std::move(Val));
309 0 : }
310 0 :
311 5476 : // dyn_cast<X> - Return the argument parameter cast to the specified type. This
312 0 : // casting operator returns null if the argument is of the wrong type, so it can
313 448182 : // be used to test for a type as well as cast if successful. This should be
314 150628 : // used in the context of an if statement like this:
315 0 : //
316 9547 : // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
317 519 : //
318 2162588 :
319 9547 : template <class X, class Y>
320 70983 : LLVM_NODISCARD inline
321 0 : typename std::enable_if<!is_simple_type<Y>::value,
322 0 : typename cast_retty<X, const Y>::ret_type>::type
323 113049 : dyn_cast(const Y &Val) {
324 136090 : return isa<X>(Val) ? cast<X>(Val) : nullptr;
325 4 : }
326 1257 :
327 165 : template <class X, class Y>
328 33018341 : LLVM_NODISCARD inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
329 320764 : return isa<X>(Val) ? cast<X>(Val) : nullptr;
330 4 : }
331 0 :
332 220 : template <class X, class Y>
333 1317 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
334 6393086 : return isa<X>(Val) ? cast<X>(Val) : nullptr;
335 0 : }
336 0 :
337 140 : // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
338 0 : // value is accepted.
339 447246 : //
340 535 : template <class X, class Y>
341 39 : LLVM_NODISCARD inline
342 5222869 : typename std::enable_if<!is_simple_type<Y>::value,
343 3901 : typename cast_retty<X, const Y>::ret_type>::type
344 140112 : dyn_cast_or_null(const Y &Val) {
345 4897488 : return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
346 788 : }
347 0 :
348 99 : template <class X, class Y>
349 9940536 : LLVM_NODISCARD inline
350 23750 : typename std::enable_if<!is_simple_type<Y>::value,
351 0 : typename cast_retty<X, Y>::ret_type>::type
352 0 : dyn_cast_or_null(Y &Val) {
353 18 : return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
354 76221540 : }
355 81843 :
356 0 : template <class X, class Y>
357 127 : LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type
358 8683 : dyn_cast_or_null(Y *Val) {
359 393667 : return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
360 131 : }
361 0 :
362 1901 : // unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
363 2000 : // taking ownership of the input pointer iff isa<X>(Val) is true. If the
364 1496 : // cast is successful, From refers to nullptr on exit and the casted value
365 47 : // is returned. If the cast is unsuccessful, the function returns nullptr
366 7965 : // and From is unchanged.
367 3512 : template <class X, class Y>
368 1709404 : LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
369 5160715 : -> decltype(cast<X>(Val)) {
370 190 : if (!isa<X>(Val))
371 4185831 : return nullptr;
372 821683 : return cast<X>(std::move(Val));
373 68204 : }
374 2402 :
375 30180 : template <class X, class Y>
376 311 : LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
377 1266 : -> decltype(cast<X>(Val)) {
378 35968228 : return unique_dyn_cast<X, Y>(Val);
379 235 : }
380 152291 :
381 4185984 : // dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, except that
382 90 : // a null value is accepted.
383 120445351 : template <class X, class Y>
384 933785 : LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
385 154576490 : -> decltype(cast<X>(Val)) {
386 42875 : if (!Val)
387 291 : return nullptr;
388 190 : return unique_dyn_cast<X, Y>(Val);
389 29299 : }
390 3671306 :
391 4835 : template <class X, class Y>
392 13999 : LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val)
393 3501 : -> decltype(cast<X>(Val)) {
394 3186255 : return unique_dyn_cast_or_null<X, Y>(Val);
395 11901175 : }
396 275611 :
397 724253 : } // end namespace llvm
398 51904276 :
399 3074805 : #endif // LLVM_SUPPORT_CASTING_H
|