LLVM API Documentation
00001 //===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source 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 <cassert> 00019 00020 namespace llvm { 00021 00022 //===----------------------------------------------------------------------===// 00023 // isa<x> Support Templates 00024 //===----------------------------------------------------------------------===// 00025 00026 template<typename FromCl> struct isa_impl_cl; 00027 00028 // Define a template that can be specialized by smart pointers to reflect the 00029 // fact that they are automatically dereferenced, and are not involved with the 00030 // template selection process... the default implementation is a noop. 00031 // 00032 template<typename From> struct simplify_type { 00033 typedef From SimpleType; // The real type this represents... 00034 00035 // An accessor to get the real value... 00036 static SimpleType &getSimplifiedValue(From &Val) { return Val; } 00037 }; 00038 00039 template<typename From> struct simplify_type<const From> { 00040 typedef const From SimpleType; 00041 static SimpleType &getSimplifiedValue(const From &Val) { 00042 return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val)); 00043 } 00044 }; 00045 00046 00047 // isa<X> - Return true if the parameter to the template is an instance of the 00048 // template type argument. Used like this: 00049 // 00050 // if (isa<Type*>(myVal)) { ... } 00051 // 00052 template <typename To, typename From> 00053 inline bool isa_impl(const From &Val) { 00054 return To::classof(&Val); 00055 } 00056 00057 template<typename To, typename From, typename SimpleType> 00058 struct isa_impl_wrap { 00059 // When From != SimplifiedType, we can simplify the type some more by using 00060 // the simplify_type template. 00061 static bool doit(const From &Val) { 00062 return isa_impl_cl<const SimpleType>::template 00063 isa<To>(simplify_type<const From>::getSimplifiedValue(Val)); 00064 } 00065 }; 00066 00067 template<typename To, typename FromTy> 00068 struct isa_impl_wrap<To, const FromTy, const FromTy> { 00069 // When From == SimpleType, we are as simple as we are going to get. 00070 static bool doit(const FromTy &Val) { 00071 return isa_impl<To,FromTy>(Val); 00072 } 00073 }; 00074 00075 // isa_impl_cl - Use class partial specialization to transform types to a single 00076 // canonical form for isa_impl. 00077 // 00078 template<typename FromCl> 00079 struct isa_impl_cl { 00080 template<class ToCl> 00081 static bool isa(const FromCl &Val) { 00082 return isa_impl_wrap<ToCl,const FromCl, 00083 typename simplify_type<const FromCl>::SimpleType>::doit(Val); 00084 } 00085 }; 00086 00087 // Specialization used to strip const qualifiers off of the FromCl type... 00088 template<typename FromCl> 00089 struct isa_impl_cl<const FromCl> { 00090 template<class ToCl> 00091 static bool isa(const FromCl &Val) { 00092 return isa_impl_cl<FromCl>::template isa<ToCl>(Val); 00093 } 00094 }; 00095 00096 // Define pointer traits in terms of base traits... 00097 template<class FromCl> 00098 struct isa_impl_cl<FromCl*> { 00099 template<class ToCl> 00100 static bool isa(FromCl *Val) { 00101 return isa_impl_cl<FromCl>::template isa<ToCl>(*Val); 00102 } 00103 }; 00104 00105 // Define reference traits in terms of base traits... 00106 template<class FromCl> 00107 struct isa_impl_cl<FromCl&> { 00108 template<class ToCl> 00109 static bool isa(FromCl &Val) { 00110 return isa_impl_cl<FromCl>::template isa<ToCl>(&Val); 00111 } 00112 }; 00113 00114 template <class X, class Y> 00115 inline bool isa(const Y &Val) { 00116 return isa_impl_cl<Y>::template isa<X>(Val); 00117 } 00118 00119 //===----------------------------------------------------------------------===// 00120 // cast<x> Support Templates 00121 //===----------------------------------------------------------------------===// 00122 00123 template<class To, class From> struct cast_retty; 00124 00125 00126 // Calculate what type the 'cast' function should return, based on a requested 00127 // type of To and a source type of From. 00128 template<class To, class From> struct cast_retty_impl { 00129 typedef To& ret_type; // Normal case, return Ty& 00130 }; 00131 template<class To, class From> struct cast_retty_impl<To, const From> { 00132 typedef const To &ret_type; // Normal case, return Ty& 00133 }; 00134 00135 template<class To, class From> struct cast_retty_impl<To, From*> { 00136 typedef To* ret_type; // Pointer arg case, return Ty* 00137 }; 00138 00139 template<class To, class From> struct cast_retty_impl<To, const From*> { 00140 typedef const To* ret_type; // Constant pointer arg case, return const Ty* 00141 }; 00142 00143 template<class To, class From> struct cast_retty_impl<To, const From*const> { 00144 typedef const To* ret_type; // Constant pointer arg case, return const Ty* 00145 }; 00146 00147 00148 template<class To, class From, class SimpleFrom> 00149 struct cast_retty_wrap { 00150 // When the simplified type and the from type are not the same, use the type 00151 // simplifier to reduce the type, then reuse cast_retty_impl to get the 00152 // resultant type. 00153 typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type; 00154 }; 00155 00156 template<class To, class FromTy> 00157 struct cast_retty_wrap<To, FromTy, FromTy> { 00158 // When the simplified type is equal to the from type, use it directly. 00159 typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type; 00160 }; 00161 00162 template<class To, class From> 00163 struct cast_retty { 00164 typedef typename cast_retty_wrap<To, From, 00165 typename simplify_type<From>::SimpleType>::ret_type ret_type; 00166 }; 00167 00168 // Ensure the non-simple values are converted using the simplify_type template 00169 // that may be specialized by smart pointers... 00170 // 00171 template<class To, class From, class SimpleFrom> struct cast_convert_val { 00172 // This is not a simple type, use the template to simplify it... 00173 static typename cast_retty<To, From>::ret_type doit(const From &Val) { 00174 return cast_convert_val<To, SimpleFrom, 00175 typename simplify_type<SimpleFrom>::SimpleType>::doit( 00176 simplify_type<From>::getSimplifiedValue(Val)); 00177 } 00178 }; 00179 00180 template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { 00181 // This _is_ a simple type, just cast it. 00182 static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { 00183 return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>( 00184 const_cast<FromTy&>(Val)); 00185 } 00186 }; 00187 00188 00189 00190 // cast<X> - Return the argument parameter cast to the specified type. This 00191 // casting operator asserts that the type is correct, so it does not return null 00192 // on failure. But it will correctly return NULL when the input is NULL. 00193 // Used Like this: 00194 // 00195 // cast<Instruction>(myVal)->getParent() 00196 // 00197 template <class X, class Y> 00198 inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) { 00199 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 00200 return cast_convert_val<X, Y, 00201 typename simplify_type<Y>::SimpleType>::doit(Val); 00202 } 00203 00204 // cast_or_null<X> - Functionally identical to cast, except that a null value is 00205 // accepted. 00206 // 00207 template <class X, class Y> 00208 inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { 00209 if (Val == 0) return 0; 00210 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 00211 return cast<X>(Val); 00212 } 00213 00214 00215 // dyn_cast<X> - Return the argument parameter cast to the specified type. This 00216 // casting operator returns null if the argument is of the wrong type, so it can 00217 // be used to test for a type as well as cast if successful. This should be 00218 // used in the context of an if statement like this: 00219 // 00220 // if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } 00221 // 00222 00223 template <class X, class Y> 00224 inline typename cast_retty<X, Y>::ret_type dyn_cast(Y Val) { 00225 return isa<X>(Val) ? cast<X, Y>(Val) : 0; 00226 } 00227 00228 // dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null 00229 // value is accepted. 00230 // 00231 template <class X, class Y> 00232 inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(Y Val) { 00233 return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0; 00234 } 00235 00236 00237 #ifdef DEBUG_CAST_OPERATORS 00238 #include <iostream> 00239 00240 struct bar { 00241 bar() {} 00242 private: 00243 bar(const bar &); 00244 }; 00245 struct foo { 00246 void ext() const; 00247 /* static bool classof(const bar *X) { 00248 cerr << "Classof: " << X << "\n"; 00249 return true; 00250 }*/ 00251 }; 00252 00253 template <> inline bool isa_impl<foo,bar>(const bar &Val) { 00254 cerr << "Classof: " << &Val << "\n"; 00255 return true; 00256 } 00257 00258 00259 bar *fub(); 00260 void test(bar &B1, const bar *B2) { 00261 // test various configurations of const 00262 const bar &B3 = B1; 00263 const bar *const B4 = B2; 00264 00265 // test isa 00266 if (!isa<foo>(B1)) return; 00267 if (!isa<foo>(B2)) return; 00268 if (!isa<foo>(B3)) return; 00269 if (!isa<foo>(B4)) return; 00270 00271 // test cast 00272 foo &F1 = cast<foo>(B1); 00273 const foo *F3 = cast<foo>(B2); 00274 const foo *F4 = cast<foo>(B2); 00275 const foo &F8 = cast<foo>(B3); 00276 const foo *F9 = cast<foo>(B4); 00277 foo *F10 = cast<foo>(fub()); 00278 00279 // test cast_or_null 00280 const foo *F11 = cast_or_null<foo>(B2); 00281 const foo *F12 = cast_or_null<foo>(B2); 00282 const foo *F13 = cast_or_null<foo>(B4); 00283 const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print. 00284 00285 // These lines are errors... 00286 //foo *F20 = cast<foo>(B2); // Yields const foo* 00287 //foo &F21 = cast<foo>(B3); // Yields const foo& 00288 //foo *F22 = cast<foo>(B4); // Yields const foo* 00289 //foo &F23 = cast_or_null<foo>(B1); 00290 //const foo &F24 = cast_or_null<foo>(B3); 00291 } 00292 00293 bar *fub() { return 0; } 00294 void main() { 00295 bar B; 00296 test(B, &B); 00297 } 00298 00299 #endif 00300 00301 } // End llvm namespace 00302 00303 #endif