1//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), 11// and dyn_cast_or_null<X>() templates. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_SUPPORT_CASTING_H 16#define LLVM_SUPPORT_CASTING_H 17 18#include "llvm/Support/Compiler.h" 19#include "llvm/Support/type_traits.h" 20#include <cassert> 21 22namespace llvm { 23 24//===----------------------------------------------------------------------===// 25// isa<x> Support Templates 26//===----------------------------------------------------------------------===// 27 28// Define a template that can be specialized by smart pointers to reflect the 29// fact that they are automatically dereferenced, and are not involved with the 30// template selection process... the default implementation is a noop. 31// 32template<typename From> struct simplify_type { 33 typedef From SimpleType; // The real type this represents... 34 35 // An accessor to get the real value... 36 static SimpleType &getSimplifiedValue(From &Val) { return Val; } 37}; 38 39template<typename From> struct simplify_type<const From> { 40 typedef typename simplify_type<From>::SimpleType NonConstSimpleType; 41 typedef typename add_const_past_pointer<NonConstSimpleType>::type 42 SimpleType; 43 typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type 44 RetType; 45 static RetType getSimplifiedValue(const From& Val) { 46 return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); 47 } 48}; 49 50// The core of the implementation of isa<X> is here; To and From should be 51// the names of classes. This template can be specialized to customize the 52// implementation of isa<> without rewriting it from scratch. 53template <typename To, typename From, typename Enabler = void> 54struct isa_impl { 55 static inline bool doit(const From &Val) { 56 return To::classof(&Val); 57 } 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 std::enable_if< 247 !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type 248cast_or_null(const Y &Val) { 249 if (!Val) 250 return nullptr; 251 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 252 return cast<X>(Val); 253} 254 255template <class X, class Y> 256LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< 257 !is_simple_type<Y>::value, typename cast_retty<X, Y>::ret_type>::type 258cast_or_null(Y &Val) { 259 if (!Val) 260 return nullptr; 261 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 262 return cast<X>(Val); 263} 264 265template <class X, class Y> 266LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 267cast_or_null(Y *Val) { 268 if (!Val) return nullptr; 269 assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 270 return cast<X>(Val); 271} 272 273 274// dyn_cast<X> - Return the argument parameter cast to the specified type. This 275// casting operator returns null if the argument is of the wrong type, so it can 276// be used to test for a type as well as cast if successful. This should be 277// used in the context of an if statement like this: 278// 279// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } 280// 281 282template <class X, class Y> 283LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< 284 !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type 285dyn_cast(const Y &Val) { 286 return isa<X>(Val) ? cast<X>(Val) : nullptr; 287} 288 289template <class X, class Y> 290LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type 291dyn_cast(Y &Val) { 292 return isa<X>(Val) ? cast<X>(Val) : nullptr; 293} 294 295template <class X, class Y> 296LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 297dyn_cast(Y *Val) { 298 return isa<X>(Val) ? cast<X>(Val) : nullptr; 299} 300 301// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null 302// value is accepted. 303// 304template <class X, class Y> 305LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< 306 !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type 307dyn_cast_or_null(const Y &Val) { 308 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 309} 310 311template <class X, class Y> 312LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< 313 !is_simple_type<Y>::value, typename cast_retty<X, Y>::ret_type>::type 314dyn_cast_or_null(Y &Val) { 315 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 316} 317 318template <class X, class Y> 319LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type 320dyn_cast_or_null(Y *Val) { 321 return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 322} 323 324} // End llvm namespace 325 326#endif 327