LLVM API Documentation

Casting.h
Go to the documentation of this file.
00001 //===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
00011 // and dyn_cast_or_null<X>() templates.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_SUPPORT_CASTING_H
00016 #define LLVM_SUPPORT_CASTING_H
00017 
00018 #include "llvm/Support/type_traits.h"
00019 #include <cassert>
00020 
00021 namespace llvm {
00022 
00023 //===----------------------------------------------------------------------===//
00024 //                          isa<x> Support Templates
00025 //===----------------------------------------------------------------------===//
00026 
00027 // Define a template that can be specialized by smart pointers to reflect the
00028 // fact that they are automatically dereferenced, and are not involved with the
00029 // template selection process...  the default implementation is a noop.
00030 //
00031 template<typename From> struct simplify_type {
00032   typedef       From SimpleType;        // The real type this represents...
00033 
00034   // An accessor to get the real value...
00035   static SimpleType &getSimplifiedValue(From &Val) { return Val; }
00036 };
00037 
00038 template<typename From> struct simplify_type<const From> {
00039   typedef typename simplify_type<From>::SimpleType NonConstSimpleType;
00040   typedef typename add_const_past_pointer<NonConstSimpleType>::type
00041     SimpleType;
00042   typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type
00043     RetType;
00044   static RetType getSimplifiedValue(const From& Val) {
00045     return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val));
00046   }
00047 };
00048 
00049 // The core of the implementation of isa<X> is here; To and From should be
00050 // the names of classes.  This template can be specialized to customize the
00051 // implementation of isa<> without rewriting it from scratch.
00052 template <typename To, typename From, typename Enabler = void>
00053 struct isa_impl {
00054   static inline bool doit(const From &Val) {
00055     return To::classof(&Val);
00056   }
00057 };
00058 
00059 /// \brief Always allow upcasts, and perform no dynamic check for them.
00060 template <typename To, typename From>
00061 struct isa_impl<To, From,
00062                 typename enable_if<
00063                   llvm::is_base_of<To, From>
00064                 >::type
00065                > {
00066   static inline bool doit(const From &) { return true; }
00067 };
00068 
00069 template <typename To, typename From> struct isa_impl_cl {
00070   static inline bool doit(const From &Val) {
00071     return isa_impl<To, From>::doit(Val);
00072   }
00073 };
00074 
00075 template <typename To, typename From> struct isa_impl_cl<To, const From> {
00076   static inline bool doit(const From &Val) {
00077     return isa_impl<To, From>::doit(Val);
00078   }
00079 };
00080 
00081 template <typename To, typename From> struct isa_impl_cl<To, From*> {
00082   static inline bool doit(const From *Val) {
00083     assert(Val && "isa<> used on a null pointer");
00084     return isa_impl<To, From>::doit(*Val);
00085   }
00086 };
00087 
00088 template <typename To, typename From> struct isa_impl_cl<To, From*const> {
00089   static inline bool doit(const From *Val) {
00090     assert(Val && "isa<> used on a null pointer");
00091     return isa_impl<To, From>::doit(*Val);
00092   }
00093 };
00094 
00095 template <typename To, typename From> struct isa_impl_cl<To, const From*> {
00096   static inline bool doit(const From *Val) {
00097     assert(Val && "isa<> used on a null pointer");
00098     return isa_impl<To, From>::doit(*Val);
00099   }
00100 };
00101 
00102 template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
00103   static inline bool doit(const From *Val) {
00104     assert(Val && "isa<> used on a null pointer");
00105     return isa_impl<To, From>::doit(*Val);
00106   }
00107 };
00108 
00109 template<typename To, typename From, typename SimpleFrom>
00110 struct isa_impl_wrap {
00111   // When From != SimplifiedType, we can simplify the type some more by using
00112   // the simplify_type template.
00113   static bool doit(const From &Val) {
00114     return isa_impl_wrap<To, SimpleFrom,
00115       typename simplify_type<SimpleFrom>::SimpleType>::doit(
00116                           simplify_type<const From>::getSimplifiedValue(Val));
00117   }
00118 };
00119 
00120 template<typename To, typename FromTy>
00121 struct isa_impl_wrap<To, FromTy, FromTy> {
00122   // When From == SimpleType, we are as simple as we are going to get.
00123   static bool doit(const FromTy &Val) {
00124     return isa_impl_cl<To,FromTy>::doit(Val);
00125   }
00126 };
00127 
00128 // isa<X> - Return true if the parameter to the template is an instance of the
00129 // template type argument.  Used like this:
00130 //
00131 //  if (isa<Type>(myVal)) { ... }
00132 //
00133 template <class X, class Y>
00134 inline bool isa(const Y &Val) {
00135   return isa_impl_wrap<X, const Y,
00136                        typename simplify_type<const Y>::SimpleType>::doit(Val);
00137 }
00138 
00139 //===----------------------------------------------------------------------===//
00140 //                          cast<x> Support Templates
00141 //===----------------------------------------------------------------------===//
00142 
00143 template<class To, class From> struct cast_retty;
00144 
00145 
00146 // Calculate what type the 'cast' function should return, based on a requested
00147 // type of To and a source type of From.
00148 template<class To, class From> struct cast_retty_impl {
00149   typedef To& ret_type;         // Normal case, return Ty&
00150 };
00151 template<class To, class From> struct cast_retty_impl<To, const From> {
00152   typedef const To &ret_type;   // Normal case, return Ty&
00153 };
00154 
00155 template<class To, class From> struct cast_retty_impl<To, From*> {
00156   typedef To* ret_type;         // Pointer arg case, return Ty*
00157 };
00158 
00159 template<class To, class From> struct cast_retty_impl<To, const From*> {
00160   typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
00161 };
00162 
00163 template<class To, class From> struct cast_retty_impl<To, const From*const> {
00164   typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
00165 };
00166 
00167 
00168 template<class To, class From, class SimpleFrom>
00169 struct cast_retty_wrap {
00170   // When the simplified type and the from type are not the same, use the type
00171   // simplifier to reduce the type, then reuse cast_retty_impl to get the
00172   // resultant type.
00173   typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
00174 };
00175 
00176 template<class To, class FromTy>
00177 struct cast_retty_wrap<To, FromTy, FromTy> {
00178   // When the simplified type is equal to the from type, use it directly.
00179   typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
00180 };
00181 
00182 template<class To, class From>
00183 struct cast_retty {
00184   typedef typename cast_retty_wrap<To, From,
00185                    typename simplify_type<From>::SimpleType>::ret_type ret_type;
00186 };
00187 
00188 // Ensure the non-simple values are converted using the simplify_type template
00189 // that may be specialized by smart pointers...
00190 //
00191 template<class To, class From, class SimpleFrom> struct cast_convert_val {
00192   // This is not a simple type, use the template to simplify it...
00193   static typename cast_retty<To, From>::ret_type doit(From &Val) {
00194     return cast_convert_val<To, SimpleFrom,
00195       typename simplify_type<SimpleFrom>::SimpleType>::doit(
00196                           simplify_type<From>::getSimplifiedValue(Val));
00197   }
00198 };
00199 
00200 template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
00201   // This _is_ a simple type, just cast it.
00202   static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
00203     typename cast_retty<To, FromTy>::ret_type Res2
00204      = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
00205     return Res2;
00206   }
00207 };
00208 
00209 
00210 
00211 // cast<X> - Return the argument parameter cast to the specified type.  This
00212 // casting operator asserts that the type is correct, so it does not return null
00213 // on failure.  It does not allow a null argument (use cast_or_null for that).
00214 // It is typically used like this:
00215 //
00216 //  cast<Instruction>(myVal)->getParent()
00217 //
00218 template <class X, class Y>
00219 inline typename cast_retty<X, const Y>::ret_type cast(const Y &Val) {
00220   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
00221   return cast_convert_val<X, const Y,
00222                         typename simplify_type<const Y>::SimpleType>::doit(Val);
00223 }
00224 
00225 template <class X, class Y>
00226 inline typename cast_retty<X, Y>::ret_type cast(Y &Val) {
00227   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
00228   return cast_convert_val<X, Y,
00229                           typename simplify_type<Y>::SimpleType>::doit(Val);
00230 }
00231 
00232 template <class X, class Y>
00233 inline typename enable_if<
00234   is_same<Y, typename simplify_type<Y>::SimpleType>,
00235   typename cast_retty<X, Y*>::ret_type
00236 >::type cast(Y *Val) {
00237   assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
00238   return cast_convert_val<X, Y*,
00239                           typename simplify_type<Y*>::SimpleType>::doit(Val);
00240 }
00241 
00242 // cast_or_null<X> - Functionally identical to cast, except that a null value is
00243 // accepted.
00244 //
00245 template <class X, class Y>
00246 inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
00247   if (Val == 0) return 0;
00248   assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
00249   return cast<X>(Val);
00250 }
00251 
00252 
00253 // dyn_cast<X> - Return the argument parameter cast to the specified type.  This
00254 // casting operator returns null if the argument is of the wrong type, so it can
00255 // be used to test for a type as well as cast if successful.  This should be
00256 // used in the context of an if statement like this:
00257 //
00258 //  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
00259 //
00260 
00261 template <class X, class Y>
00262 inline typename cast_retty<X, const Y>::ret_type dyn_cast(const Y &Val) {
00263   return isa<X>(Val) ? cast<X>(Val) : 0;
00264 }
00265 
00266 template <class X, class Y>
00267 inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
00268   return isa<X>(Val) ? cast<X>(Val) : 0;
00269 }
00270 
00271 template <class X, class Y>
00272 inline typename enable_if<
00273   is_same<Y, typename simplify_type<Y>::SimpleType>,
00274   typename cast_retty<X, Y*>::ret_type
00275 >::type dyn_cast(Y *Val) {
00276   return isa<X>(Val) ? cast<X>(Val) : 0;
00277 }
00278 
00279 // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
00280 // value is accepted.
00281 //
00282 template <class X, class Y>
00283 inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
00284   return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
00285 }
00286 
00287 } // End llvm namespace
00288 
00289 #endif