Casting.h revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===// 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The LLVM Compiler Infrastructure 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// License. See LICENSE.TXT for details. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// and dyn_cast_or_null<X>() templates. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef LLVM_SUPPORT_CASTING_H 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define LLVM_SUPPORT_CASTING_H 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Support/Compiler.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "llvm/Support/type_traits.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <cassert> 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 22a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)namespace llvm { 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 24a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)//===----------------------------------------------------------------------===// 25a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// isa<x> Support Templates 26a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)//===----------------------------------------------------------------------===// 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// Define a template that can be specialized by smart pointers to reflect the 29a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// fact that they are automatically dereferenced, and are not involved with the 30a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)// template selection process... the default implementation is a noop. 31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename From> struct simplify_type { 33a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) typedef From SimpleType; // The real type this represents... 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) // An accessor to get the real value... 36a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) static SimpleType &getSimplifiedValue(From &Val) { return Val; } 37a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}; 38a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename From> struct simplify_type<const From> { 40a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) typedef typename simplify_type<From>::SimpleType NonConstSimpleType; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef typename add_const_past_pointer<NonConstSimpleType>::type 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SimpleType; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RetType; 45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch static RetType getSimplifiedValue(const From& Val) { 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}; 495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// The core of the implementation of isa<X> is here; To and From should be 515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// the names of classes. This template can be specialized to customize the 5293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// implementation of isa<> without rewriting it from scratch. 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename To, typename From, typename Enabler = void> 5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)struct isa_impl { 5507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch static inline bool doit(const From &Val) { 5607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return To::classof(&Val); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 58}; 59 60/// \brief Always allow upcasts, and perform no dynamic check for them. 61template <typename To, typename From> 62struct isa_impl< 63 To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { 64 static inline bool doit(const From &) { return true; } 65}; 66 67template <typename To, typename From> struct isa_impl_cl { 68 static inline bool doit(const From &Val) { 69 return isa_impl<To, From>::doit(Val); 70 } 71}; 72 73template <typename To, typename From> struct isa_impl_cl<To, const From> { 74 static inline bool doit(const From &Val) { 75 return isa_impl<To, From>::doit(Val); 76 } 77}; 78 79template <typename To, typename From> struct isa_impl_cl<To, From*> { 80 static inline bool doit(const From *Val) { 81 assert(Val && "isa<> used on a null pointer"); 82 return isa_impl<To, From>::doit(*Val); 83 } 84}; 85 86template <typename To, typename From> struct isa_impl_cl<To, From*const> { 87 static inline bool doit(const From *Val) { 88 assert(Val && "isa<> used on a null pointer"); 89 return isa_impl<To, From>::doit(*Val); 90 } 91}; 92 93template <typename To, typename From> struct isa_impl_cl<To, const From*> { 94 static inline bool doit(const From *Val) { 95 assert(Val && "isa<> used on a null pointer"); 96 return isa_impl<To, From>::doit(*Val); 97 } 98}; 99 100template <typename To, typename From> struct isa_impl_cl<To, const From*const> { 101 static inline bool doit(const From *Val) { 102 assert(Val && "isa<> used on a null pointer"); 103 return isa_impl<To, From>::doit(*Val); 104 } 105}; 106 107template<typename To, typename From, typename SimpleFrom> 108struct isa_impl_wrap { 109 // When From != SimplifiedType, we can simplify the type some more by using 110 // the simplify_type template. 111 static bool doit(const From &Val) { 112 return isa_impl_wrap<To, SimpleFrom, 113 typename simplify_type<SimpleFrom>::SimpleType>::doit( 114 simplify_type<const From>::getSimplifiedValue(Val)); 115 } 116}; 117 118template<typename To, typename FromTy> 119struct isa_impl_wrap<To, FromTy, FromTy> { 120 // When From == SimpleType, we are as simple as we are going to get. 121 static bool doit(const FromTy &Val) { 122 return isa_impl_cl<To,FromTy>::doit(Val); 123 } 124}; 125 126// isa<X> - Return true if the parameter to the template is an instance of the 127// template type argument. Used like this: 128// 129// if (isa<Type>(myVal)) { ... } 130// 131template <class X, class Y> 132LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) { 133 return isa_impl_wrap<X, const Y, 134 typename simplify_type<const Y>::SimpleType>::doit(Val); 135} 136 137//===----------------------------------------------------------------------===// 138// cast<x> Support Templates 139//===----------------------------------------------------------------------===// 140 141template<class To, class From> struct cast_retty; 142 143 144// Calculate what type the 'cast' function should return, based on a requested 145// type of To and a source type of From. 146template<class To, class From> struct cast_retty_impl { 147 typedef To& ret_type; // Normal case, return Ty& 148}; 149template<class To, class From> struct cast_retty_impl<To, const From> { 150 typedef const To &ret_type; // Normal case, return Ty& 151}; 152 153template<class To, class From> struct cast_retty_impl<To, From*> { 154 typedef To* ret_type; // Pointer arg case, return Ty* 155}; 156 157template<class To, class From> struct cast_retty_impl<To, const From*> { 158 typedef const To* ret_type; // Constant pointer arg case, return const Ty* 159}; 160 161template<class To, class From> struct cast_retty_impl<To, const From*const> { 162 typedef const To* ret_type; // Constant pointer arg case, return const Ty* 163}; 164 165 166template<class To, class From, class SimpleFrom> 167struct cast_retty_wrap { 168 // When the simplified type and the from type are not the same, use the type 169 // simplifier to reduce the type, then reuse cast_retty_impl to get the 170 // resultant type. 171 typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type; 172}; 173 174template<class To, class FromTy> 175struct cast_retty_wrap<To, FromTy, FromTy> { 176 // When the simplified type is equal to the from type, use it directly. 177 typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type; 178}; 179 180template<class To, class From> 181struct cast_retty { 182 typedef typename cast_retty_wrap<To, From, 183 typename simplify_type<From>::SimpleType>::ret_type ret_type; 184}; 185 186// Ensure the non-simple values are converted using the simplify_type template 187// that may be specialized by smart pointers... 188// 189template<class To, class From, class SimpleFrom> struct cast_convert_val { 190 // This is not a simple type, use the template to simplify it... 191 static typename cast_retty<To, From>::ret_type doit(From &Val) { 192 return cast_convert_val<To, SimpleFrom, 193 typename simplify_type<SimpleFrom>::SimpleType>::doit( 194 simplify_type<From>::getSimplifiedValue(Val)); 195 } 196}; 197 198template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { 199 // This _is_ a simple type, just cast it. 200 static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { 201 typename cast_retty<To, FromTy>::ret_type Res2 202 = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); 203 return Res2; 204 } 205}; 206 207template <class X> struct is_simple_type { 208 static const bool value = 209 std::is_same<X, typename simplify_type<X>::SimpleType>::value; 210}; 211 212// cast<X> - Return the argument parameter cast to the specified type. This 213// casting operator asserts that the type is correct, so it does not return null 214// on failure. It does not allow a null argument (use cast_or_null for that). 215// It is typically used like this: 216// 217// cast<Instruction>(myVal)->getParent() 218// 219template <class X, class Y> 220inline typename std::enable_if<!is_simple_type<Y>::value, 221 typename cast_retty<X, const Y>::ret_type>::type 222cast(const Y &Val) { 223 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 224 return cast_convert_val< 225 X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); 226} 227 228template <class X, class Y> 229inline typename cast_retty<X, Y>::ret_type cast(Y &Val) { 230 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 231 return cast_convert_val<X, Y, 232 typename simplify_type<Y>::SimpleType>::doit(Val); 233} 234 235template <class X, class Y> 236inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { 237 assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 238 return cast_convert_val<X, Y*, 239 typename simplify_type<Y*>::SimpleType>::doit(Val); 240} 241 242// cast_or_null<X> - Functionally identical to cast, except that a null value is 243// accepted. 244// 245template <class X, class Y> 246LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 247cast_or_null(Y *Val) { 248 if (Val == 0) return 0; 249 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 250 return cast<X>(Val); 251} 252 253 254// dyn_cast<X> - Return the argument parameter cast to the specified type. This 255// casting operator returns null if the argument is of the wrong type, so it can 256// be used to test for a type as well as cast if successful. This should be 257// used in the context of an if statement like this: 258// 259// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } 260// 261 262template <class X, class Y> 263LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< 264 !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type 265dyn_cast(const Y &Val) { 266 return isa<X>(Val) ? cast<X>(Val) : 0; 267} 268 269template <class X, class Y> 270LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type 271dyn_cast(Y &Val) { 272 return isa<X>(Val) ? cast<X>(Val) : 0; 273} 274 275template <class X, class Y> 276LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 277dyn_cast(Y *Val) { 278 return isa<X>(Val) ? cast<X>(Val) : 0; 279} 280 281// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null 282// value is accepted. 283// 284template <class X, class Y> 285LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 286dyn_cast_or_null(Y *Val) { 287 return (Val && isa<X>(Val)) ? cast<X>(Val) : 0; 288} 289 290} // End llvm namespace 291 292#endif 293