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 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