1193323Sed//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
11193323Sed// and dyn_cast_or_null<X>() templates.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#ifndef LLVM_SUPPORT_CASTING_H
16193323Sed#define LLVM_SUPPORT_CASTING_H
17193323Sed
18243830Sdim#include "llvm/Support/type_traits.h"
19193323Sed#include <cassert>
20193323Sed
21193323Sednamespace llvm {
22193323Sed
23193323Sed//===----------------------------------------------------------------------===//
24193323Sed//                          isa<x> Support Templates
25193323Sed//===----------------------------------------------------------------------===//
26193323Sed
27193323Sed// Define a template that can be specialized by smart pointers to reflect the
28193323Sed// fact that they are automatically dereferenced, and are not involved with the
29193323Sed// template selection process...  the default implementation is a noop.
30193323Sed//
31193323Sedtemplate<typename From> struct simplify_type {
32193323Sed  typedef       From SimpleType;        // The real type this represents...
33193323Sed
34193323Sed  // An accessor to get the real value...
35193323Sed  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
36193323Sed};
37193323Sed
38193323Sedtemplate<typename From> struct simplify_type<const From> {
39249423Sdim  typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
40249423Sdim  typedef typename add_const_past_pointer<NonConstSimpleType>::type
41249423Sdim    SimpleType;
42249423Sdim  typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
43249423Sdim    RetType;
44249423Sdim  static RetType getSimplifiedValue(const From& Val) {
45249423Sdim    return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
46193323Sed  }
47193323Sed};
48193323Sed
49223017Sdim// The core of the implementation of isa<X> is here; To and From should be
50223017Sdim// the names of classes.  This template can be specialized to customize the
51223017Sdim// implementation of isa<> without rewriting it from scratch.
52243830Sdimtemplate <typename To, typename From, typename Enabler = void>
53206083Srdivackystruct isa_impl {
54206083Srdivacky  static inline bool doit(const From &Val) {
55206083Srdivacky    return To::classof(&Val);
56206083Srdivacky  }
57206083Srdivacky};
58193323Sed
59243830Sdim/// \brief Always allow upcasts, and perform no dynamic check for them.
60243830Sdimtemplate <typename To, typename From>
61243830Sdimstruct isa_impl<To, From,
62249423Sdim                typename enable_if<
63249423Sdim                  llvm::is_base_of<To, From>
64243830Sdim                >::type
65243830Sdim               > {
66243830Sdim  static inline bool doit(const From &) { return true; }
67243830Sdim};
68243830Sdim
69223017Sdimtemplate <typename To, typename From> struct isa_impl_cl {
70223017Sdim  static inline bool doit(const From &Val) {
71223017Sdim    return isa_impl<To, From>::doit(Val);
72193323Sed  }
73193323Sed};
74193323Sed
75223017Sdimtemplate <typename To, typename From> struct isa_impl_cl<To, const From> {
76223017Sdim  static inline bool doit(const From &Val) {
77223017Sdim    return isa_impl<To, From>::doit(Val);
78193323Sed  }
79193323Sed};
80193323Sed
81223017Sdimtemplate <typename To, typename From> struct isa_impl_cl<To, From*> {
82223017Sdim  static inline bool doit(const From *Val) {
83243830Sdim    assert(Val && "isa<> used on a null pointer");
84223017Sdim    return isa_impl<To, From>::doit(*Val);
85193323Sed  }
86193323Sed};
87193323Sed
88249423Sdimtemplate <typename To, typename From> struct isa_impl_cl<To, From*const> {
89249423Sdim  static inline bool doit(const From *Val) {
90249423Sdim    assert(Val && "isa<> used on a null pointer");
91249423Sdim    return isa_impl<To, From>::doit(*Val);
92249423Sdim  }
93249423Sdim};
94249423Sdim
95223017Sdimtemplate <typename To, typename From> struct isa_impl_cl<To, const From*> {
96223017Sdim  static inline bool doit(const From *Val) {
97243830Sdim    assert(Val && "isa<> used on a null pointer");
98223017Sdim    return isa_impl<To, From>::doit(*Val);
99193323Sed  }
100193323Sed};
101193323Sed
102223017Sdimtemplate <typename To, typename From> struct isa_impl_cl<To, const From*const> {
103223017Sdim  static inline bool doit(const From *Val) {
104243830Sdim    assert(Val && "isa<> used on a null pointer");
105223017Sdim    return isa_impl<To, From>::doit(*Val);
106193323Sed  }
107193323Sed};
108193323Sed
109223017Sdimtemplate<typename To, typename From, typename SimpleFrom>
110223017Sdimstruct isa_impl_wrap {
111223017Sdim  // When From != SimplifiedType, we can simplify the type some more by using
112223017Sdim  // the simplify_type template.
113223017Sdim  static bool doit(const From &Val) {
114223017Sdim    return isa_impl_wrap<To, SimpleFrom,
115223017Sdim      typename simplify_type<SimpleFrom>::SimpleType>::doit(
116249423Sdim                          simplify_type<const From>::getSimplifiedValue(Val));
117193323Sed  }
118193323Sed};
119193323Sed
120223017Sdimtemplate<typename To, typename FromTy>
121223017Sdimstruct isa_impl_wrap<To, FromTy, FromTy> {
122223017Sdim  // When From == SimpleType, we are as simple as we are going to get.
123223017Sdim  static bool doit(const FromTy &Val) {
124223017Sdim    return isa_impl_cl<To,FromTy>::doit(Val);
125223017Sdim  }
126223017Sdim};
127223017Sdim
128223017Sdim// isa<X> - Return true if the parameter to the template is an instance of the
129223017Sdim// template type argument.  Used like this:
130223017Sdim//
131223017Sdim//  if (isa<Type>(myVal)) { ... }
132223017Sdim//
133193323Sedtemplate <class X, class Y>
134193323Sedinline bool isa(const Y &Val) {
135249423Sdim  return isa_impl_wrap<X, const Y,
136249423Sdim                       typename simplify_type<const Y>::SimpleType>::doit(Val);
137193323Sed}
138193323Sed
139193323Sed//===----------------------------------------------------------------------===//
140193323Sed//                          cast<x> Support Templates
141193323Sed//===----------------------------------------------------------------------===//
142193323Sed
143193323Sedtemplate<class To, class From> struct cast_retty;
144193323Sed
145193323Sed
146193323Sed// Calculate what type the 'cast' function should return, based on a requested
147193323Sed// type of To and a source type of From.
148193323Sedtemplate<class To, class From> struct cast_retty_impl {
149193323Sed  typedef To& ret_type;         // Normal case, return Ty&
150193323Sed};
151193323Sedtemplate<class To, class From> struct cast_retty_impl<To, const From> {
152193323Sed  typedef const To &ret_type;   // Normal case, return Ty&
153193323Sed};
154193323Sed
155193323Sedtemplate<class To, class From> struct cast_retty_impl<To, From*> {
156193323Sed  typedef To* ret_type;         // Pointer arg case, return Ty*
157193323Sed};
158193323Sed
159193323Sedtemplate<class To, class From> struct cast_retty_impl<To, const From*> {
160193323Sed  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
161193323Sed};
162193323Sed
163193323Sedtemplate<class To, class From> struct cast_retty_impl<To, const From*const> {
164193323Sed  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
165193323Sed};
166193323Sed
167193323Sed
168193323Sedtemplate<class To, class From, class SimpleFrom>
169193323Sedstruct cast_retty_wrap {
170193323Sed  // When the simplified type and the from type are not the same, use the type
171193323Sed  // simplifier to reduce the type, then reuse cast_retty_impl to get the
172193323Sed  // resultant type.
173193323Sed  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
174193323Sed};
175193323Sed
176193323Sedtemplate<class To, class FromTy>
177193323Sedstruct cast_retty_wrap<To, FromTy, FromTy> {
178193323Sed  // When the simplified type is equal to the from type, use it directly.
179193323Sed  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
180193323Sed};
181193323Sed
182193323Sedtemplate<class To, class From>
183193323Sedstruct cast_retty {
184193323Sed  typedef typename cast_retty_wrap<To, From,
185193323Sed                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
186193323Sed};
187193323Sed
188193323Sed// Ensure the non-simple values are converted using the simplify_type template
189193323Sed// that may be specialized by smart pointers...
190193323Sed//
191193323Sedtemplate<class To, class From, class SimpleFrom> struct cast_convert_val {
192193323Sed  // This is not a simple type, use the template to simplify it...
193249423Sdim  static typename cast_retty<To, From>::ret_type doit(From &Val) {
194193323Sed    return cast_convert_val<To, SimpleFrom,
195193323Sed      typename simplify_type<SimpleFrom>::SimpleType>::doit(
196193323Sed                          simplify_type<From>::getSimplifiedValue(Val));
197193323Sed  }
198193323Sed};
199193323Sed
200193323Sedtemplate<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
201193323Sed  // This _is_ a simple type, just cast it.
202193323Sed  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
203203954Srdivacky    typename cast_retty<To, FromTy>::ret_type Res2
204203954Srdivacky     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
205203954Srdivacky    return Res2;
206193323Sed  }
207193323Sed};
208193323Sed
209193323Sed
210193323Sed
211193323Sed// cast<X> - Return the argument parameter cast to the specified type.  This
212193323Sed// casting operator asserts that the type is correct, so it does not return null
213221345Sdim// on failure.  It does not allow a null argument (use cast_or_null for that).
214221345Sdim// It is typically used like this:
215193323Sed//
216193323Sed//  cast<Instruction>(myVal)->getParent()
217193323Sed//
218193323Sedtemplate <class X, class Y>
219249423Sdiminline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
220193323Sed  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
221249423Sdim  return cast_convert_val<X, const Y,
222249423Sdim                        typename simplify_type<const Y>::SimpleType>::doit(Val);
223249423Sdim}
224249423Sdim
225249423Sdimtemplate <class X, class Y>
226249423Sdiminline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
227249423Sdim  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
228193323Sed  return cast_convert_val<X, Y,
229193323Sed                          typename simplify_type<Y>::SimpleType>::doit(Val);
230193323Sed}
231193323Sed
232249423Sdimtemplate <class X, class Y>
233249423Sdiminline typename enable_if<
234249423Sdim  is_same<Y, typename simplify_type<Y>::SimpleType>,
235249423Sdim  typename cast_retty<X, Y*>::ret_type
236249423Sdim>::type cast(Y *Val) {
237249423Sdim  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
238249423Sdim  return cast_convert_val<X, Y*,
239249423Sdim                          typename simplify_type<Y*>::SimpleType>::doit(Val);
240249423Sdim}
241249423Sdim
242193323Sed// cast_or_null<X> - Functionally identical to cast, except that a null value is
243193323Sed// accepted.
244193323Sed//
245193323Sedtemplate <class X, class Y>
246193323Sedinline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
247193323Sed  if (Val == 0) return 0;
248193323Sed  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
249193323Sed  return cast<X>(Val);
250193323Sed}
251193323Sed
252193323Sed
253193323Sed// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
254193323Sed// casting operator returns null if the argument is of the wrong type, so it can
255193323Sed// be used to test for a type as well as cast if successful.  This should be
256193323Sed// used in the context of an if statement like this:
257193323Sed//
258193323Sed//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
259193323Sed//
260193323Sed
261193323Sedtemplate <class X, class Y>
262249423Sdiminline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
263249423Sdim  return isa<X>(Val) ? cast<X>(Val) : 0;
264193323Sed}
265193323Sed
266249423Sdimtemplate <class X, class Y>
267249423Sdiminline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
268249423Sdim  return isa<X>(Val) ? cast<X>(Val) : 0;
269249423Sdim}
270249423Sdim
271249423Sdimtemplate <class X, class Y>
272249423Sdiminline typename enable_if<
273249423Sdim  is_same<Y, typename simplify_type<Y>::SimpleType>,
274249423Sdim  typename cast_retty<X, Y*>::ret_type
275249423Sdim>::type dyn_cast(Y *Val) {
276249423Sdim  return isa<X>(Val) ? cast<X>(Val) : 0;
277249423Sdim}
278249423Sdim
279193323Sed// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
280193323Sed// value is accepted.
281193323Sed//
282193323Sedtemplate <class X, class Y>
283218893Sdiminline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
284218893Sdim  return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
285193323Sed}
286193323Sed
287193323Sed} // End llvm namespace
288193323Sed
289193323Sed#endif
290