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