LLVM API Documentation
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