17ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===// 27ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 37ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// The LLVM Compiler Infrastructure 47ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 57ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file is distributed under the University of Illinois Open Source 67ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// License. See LICENSE.TXT for details. 77ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 87ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 97ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(), 117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// and dyn_cast_or_null<X>() templates. 127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#ifndef LLVM_SUPPORT_CASTING_H 167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#define LLVM_SUPPORT_CASTING_H 177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/Support/Compiler.h" 197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/Support/type_traits.h" 207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <cassert> 217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnamespace llvm { 237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// isa<x> Support Templates 267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Define a template that can be specialized by smart pointers to reflect the 297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// fact that they are automatically dereferenced, and are not involved with the 307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// template selection process... the default implementation is a noop. 317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<typename From> struct simplify_type { 337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef From SimpleType; // The real type this represents... 347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // An accessor to get the real value... 367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static SimpleType &getSimplifiedValue(From &Val) { return Val; } 377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<typename From> struct simplify_type<const From> { 407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename simplify_type<From>::SimpleType NonConstSimpleType; 417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename add_const_past_pointer<NonConstSimpleType>::type 427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens SimpleType; 437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename add_lvalue_reference_if_not_pointer<SimpleType>::type 447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens RetType; 457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static RetType getSimplifiedValue(const From& Val) { 467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return simplify_type<From>::getSimplifiedValue(const_cast<From&>(Val)); 477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// The core of the implementation of isa<X> is here; To and From should be 517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// the names of classes. This template can be specialized to customize the 527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// implementation of isa<> without rewriting it from scratch. 537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From, typename Enabler = void> 547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct isa_impl { 557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From &Val) { 567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return To::classof(&Val); 577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// \brief Always allow upcasts, and perform no dynamic check for them. 617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> 627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct isa_impl< 637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { 647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From &) { return true; } 657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl { 687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From &Val) { 697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(Val); 707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl<To, const From> { 747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From &Val) { 757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(Val); 767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl<To, From*> { 807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From *Val) { 817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Val && "isa<> used on a null pointer"); 827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(*Val); 837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl<To, From*const> { 877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From *Val) { 887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Val && "isa<> used on a null pointer"); 897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(*Val); 907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl<To, const From*> { 947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From *Val) { 957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Val && "isa<> used on a null pointer"); 967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(*Val); 977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename To, typename From> struct isa_impl_cl<To, const From*const> { 1017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static inline bool doit(const From *Val) { 1027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Val && "isa<> used on a null pointer"); 1037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl<To, From>::doit(*Val); 1047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<typename To, typename From, typename SimpleFrom> 1087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct isa_impl_wrap { 1097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // When From != SimplifiedType, we can simplify the type some more by using 1107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // the simplify_type template. 1117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool doit(const From &Val) { 1127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl_wrap<To, SimpleFrom, 1137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<SimpleFrom>::SimpleType>::doit( 1147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens simplify_type<const From>::getSimplifiedValue(Val)); 1157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<typename To, typename FromTy> 1197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct isa_impl_wrap<To, FromTy, FromTy> { 1207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // When From == SimpleType, we are as simple as we are going to get. 1217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool doit(const FromTy &Val) { 1227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl_cl<To,FromTy>::doit(Val); 1237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// isa<X> - Return true if the parameter to the template is an instance of the 1277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// template type argument. Used like this: 1287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 1297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// if (isa<Type>(myVal)) { ... } 1307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 1312df178997d17474042e8c3704cc93ab2db6619bfNicolas Capenstemplate <class X, class Y> LLVM_NODISCARD inline bool isa(const Y &Val) { 1327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa_impl_wrap<X, const Y, 1337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<const Y>::SimpleType>::doit(Val); 1347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 1357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 1377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// cast<x> Support Templates 1387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 1397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty; 1417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Calculate what type the 'cast' function should return, based on a requested 1447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// type of To and a source type of From. 1457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty_impl { 1467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef To& ret_type; // Normal case, return Ty& 1477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty_impl<To, const From> { 1497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const To &ret_type; // Normal case, return Ty& 1507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty_impl<To, From*> { 1537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef To* ret_type; // Pointer arg case, return Ty* 1547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty_impl<To, const From*> { 1577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const To* ret_type; // Constant pointer arg case, return const Ty* 1587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> struct cast_retty_impl<To, const From*const> { 1617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const To* ret_type; // Constant pointer arg case, return const Ty* 1627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From, class SimpleFrom> 1667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct cast_retty_wrap { 1677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // When the simplified type and the from type are not the same, use the type 1687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // simplifier to reduce the type, then reuse cast_retty_impl to get the 1697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // resultant type. 1707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type; 1717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class FromTy> 1747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct cast_retty_wrap<To, FromTy, FromTy> { 1757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // When the simplified type is equal to the from type, use it directly. 1767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type; 1777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From> 1807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstruct cast_retty { 1817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename cast_retty_wrap<To, From, 1827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<From>::SimpleType>::ret_type ret_type; 1837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Ensure the non-simple values are converted using the simplify_type template 1867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// that may be specialized by smart pointers... 1877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 1887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class From, class SimpleFrom> struct cast_convert_val { 1897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // This is not a simple type, use the template to simplify it... 1907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static typename cast_retty<To, From>::ret_type doit(From &Val) { 1917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast_convert_val<To, SimpleFrom, 1927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<SimpleFrom>::SimpleType>::doit( 1937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens simplify_type<From>::getSimplifiedValue(Val)); 1947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { 1987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // This _is_ a simple type, just cast it. 1997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { 2007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename cast_retty<To, FromTy>::ret_type Res2 2017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val); 2027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Res2; 2037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 2057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X> struct is_simple_type { 2077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static const bool value = 2087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::is_same<X, typename simplify_type<X>::SimpleType>::value; 2097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 2107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// cast<X> - Return the argument parameter cast to the specified type. This 2127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// casting operator asserts that the type is correct, so it does not return null 2137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// on failure. It does not allow a null argument (use cast_or_null for that). 2147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// It is typically used like this: 2157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 2167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// cast<Instruction>(myVal)->getParent() 2177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 2187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline typename std::enable_if<!is_simple_type<Y>::value, 2207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename cast_retty<X, const Y>::ret_type>::type 2217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenscast(const Y &Val) { 2227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 2237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast_convert_val< 2247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); 2257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline typename cast_retty<X, Y>::ret_type cast(Y &Val) { 2297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 2307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast_convert_val<X, Y, 2317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<Y>::SimpleType>::doit(Val); 2327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { 2367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); 2377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast_convert_val<X, Y*, 2387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename simplify_type<Y*>::SimpleType>::doit(Val); 2397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// cast_or_null<X> - Functionally identical to cast, except that a null value is 2427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// accepted. 2437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 2447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2452df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline 2462df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<!is_simple_type<Y>::value, 2472df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename cast_retty<X, const Y>::ret_type>::type 2482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens cast_or_null(const Y &Val) { 2497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!Val) 2507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return nullptr; 2517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 2527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast<X>(Val); 2537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2562df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline 2572df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<!is_simple_type<Y>::value, 2582df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename cast_retty<X, Y>::ret_type>::type 2592df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens cast_or_null(Y &Val) { 2607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!Val) 2617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return nullptr; 2627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 2637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast<X>(Val); 2647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2672df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type 2687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenscast_or_null(Y *Val) { 2697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!Val) return nullptr; 2707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); 2717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return cast<X>(Val); 2727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// dyn_cast<X> - Return the argument parameter cast to the specified type. This 2767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// casting operator returns null if the argument is of the wrong type, so it can 2777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// be used to test for a type as well as cast if successful. This should be 2787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// used in the context of an if statement like this: 2797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 2807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } 2817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 2827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2842df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline 2852df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<!is_simple_type<Y>::value, 2862df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename cast_retty<X, const Y>::ret_type>::type 2872df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens dyn_cast(const Y &Val) { 2887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa<X>(Val) ? cast<X>(Val) : nullptr; 2897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2922df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { 2937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa<X>(Val) ? cast<X>(Val) : nullptr; 2947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 2957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 2972df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { 2987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isa<X>(Val) ? cast<X>(Val) : nullptr; 2997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null 3027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// value is accepted. 3037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 3047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 3052df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline 3062df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<!is_simple_type<Y>::value, 3072df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename cast_retty<X, const Y>::ret_type>::type 3082df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens dyn_cast_or_null(const Y &Val) { 3097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 3107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 3132df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline 3142df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename std::enable_if<!is_simple_type<Y>::value, 3152df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens typename cast_retty<X, Y>::ret_type>::type 3162df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens dyn_cast_or_null(Y &Val) { 3177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 3187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class X, class Y> 3212df178997d17474042e8c3704cc93ab2db6619bfNicolas CapensLLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type 3227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensdyn_cast_or_null(Y *Val) { 3237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr; 3247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} // End llvm namespace 3277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 329