Casting.h revision f5091b476c46333ecfcf095cd2e422e9748e9546
18a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
28a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
38a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//                     The LLVM Compiler Infrastructure
48a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
58a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// This file is distributed under the University of Illinois Open Source
68a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// License. See LICENSE.TXT for details.
78a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
88a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
98a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// and dyn_cast_or_null<X>() templates.
128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#ifndef LLVM_SUPPORT_CASTING_H
168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#define LLVM_SUPPORT_CASTING_H
178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#include <cassert>
198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chennamespace llvm {
218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//                          isa<x> Support Templates
248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// Define a template that can be specialized by smart pointers to reflect the
278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// fact that they are automatically dereferenced, and are not involved with the
288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// template selection process...  the default implementation is a noop.
298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<typename From> struct simplify_type {
318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef       From SimpleType;        // The real type this represents...
328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // An accessor to get the real value...
348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<typename From> struct simplify_type<const From> {
388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef const From SimpleType;
398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static SimpleType &getSimplifiedValue(const From &Val) {
408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// The core of the implementation of isa<X> is here; To and From should be
458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// the names of classes.  This template can be specialized to customize the
468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// implementation of isa<> without rewriting it from scratch.
478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From>
488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct isa_impl {
498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From &Val) {
508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return To::classof(&Val);
518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From> struct isa_impl_cl {
558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From &Val) {
568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl<To, From>::doit(Val);
578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From> struct isa_impl_cl<To, const From> {
618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From &Val) {
628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl<To, From>::doit(Val);
638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From> struct isa_impl_cl<To, From*> {
678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From *Val) {
688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    assert(Val && "isa<> used on a null pointer");
698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl<To, From>::doit(*Val);
708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From> struct isa_impl_cl<To, const From*> {
748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From *Val) {
758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    assert(Val && "isa<> used on a null pointer");
768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl<To, From>::doit(*Val);
778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <typename To, typename From> struct isa_impl_cl<To, const From*const> {
818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static inline bool doit(const From *Val) {
828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    assert(Val && "isa<> used on a null pointer");
838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl<To, From>::doit(*Val);
848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<typename To, typename From, typename SimpleFrom>
888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct isa_impl_wrap {
898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // When From != SimplifiedType, we can simplify the type some more by using
908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // the simplify_type template.
918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static bool doit(const From &Val) {
928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl_wrap<To, SimpleFrom,
938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen      typename simplify_type<SimpleFrom>::SimpleType>::doit(
948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                          simplify_type<From>::getSimplifiedValue(Val));
958a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
968a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
978a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
988a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<typename To, typename FromTy>
998a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct isa_impl_wrap<To, FromTy, FromTy> {
1008a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // When From == SimpleType, we are as simple as we are going to get.
1018a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static bool doit(const FromTy &Val) {
1028a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return isa_impl_cl<To,FromTy>::doit(Val);
1038a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
1048a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1058a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1068a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// isa<X> - Return true if the parameter to the template is an instance of the
1078a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// template type argument.  Used like this:
1088a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
1098a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//  if (isa<Type>(myVal)) { ... }
1108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
1118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <class X, class Y>
1128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheninline bool isa(const Y &Val) {
1138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
1148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen}
1158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
1178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//                          cast<x> Support Templates
1188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//===----------------------------------------------------------------------===//
1198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty;
1218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// Calculate what type the 'cast' function should return, based on a requested
1248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// type of To and a source type of From.
1258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty_impl {
1268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef To& ret_type;         // Normal case, return Ty&
1278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty_impl<To, const From> {
1298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef const To &ret_type;   // Normal case, return Ty&
1308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty_impl<To, From*> {
1338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef To* ret_type;         // Pointer arg case, return Ty*
1348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty_impl<To, const From*> {
1378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1388a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1398a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1408a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From> struct cast_retty_impl<To, const From*const> {
1418a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1428a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1438a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1448a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1458a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From, class SimpleFrom>
1468a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct cast_retty_wrap {
1478a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // When the simplified type and the from type are not the same, use the type
1488a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // simplifier to reduce the type, then reuse cast_retty_impl to get the
1498a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // resultant type.
1508a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
1518a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1528a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1538a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class FromTy>
1548a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct cast_retty_wrap<To, FromTy, FromTy> {
1558a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // When the simplified type is equal to the from type, use it directly.
1568a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
1578a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1588a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1598a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From>
1608a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chenstruct cast_retty {
1618a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  typedef typename cast_retty_wrap<To, From,
1628a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
1638a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1648a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1658a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// Ensure the non-simple values are converted using the simplify_type template
1668a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// that may be specialized by smart pointers...
1678a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
1688a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class From, class SimpleFrom> struct cast_convert_val {
1698a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // This is not a simple type, use the template to simplify it...
1708a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static typename cast_retty<To, From>::ret_type doit(const From &Val) {
1718a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return cast_convert_val<To, SimpleFrom,
1728a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen      typename simplify_type<SimpleFrom>::SimpleType>::doit(
1738a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                          simplify_type<From>::getSimplifiedValue(Val));
1748a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
1758a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1768a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1778a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
1788a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  // This _is_ a simple type, just cast it.
1798a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
1808a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    typename cast_retty<To, FromTy>::ret_type Res2
1818a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
1828a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen    return Res2;
1838a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  }
1848a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen};
1858a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1868a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1878a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
1888a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// cast<X> - Return the argument parameter cast to the specified type.  This
1898a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// casting operator asserts that the type is correct, so it does not return null
1908a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// on failure.  It does not allow a null argument (use cast_or_null for that).
1918a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// It is typically used like this:
1928a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
1938a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//  cast<Instruction>(myVal)->getParent()
1948a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
1958a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <class X, class Y>
1968a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheninline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
1978a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
1988a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  return cast_convert_val<X, Y,
1998a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen                          typename simplify_type<Y>::SimpleType>::doit(Val);
2008a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen}
2018a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2028a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// cast_or_null<X> - Functionally identical to cast, except that a null value is
2038a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// accepted.
2048a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
2058a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <class X, class Y>
2068a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheninline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
2078a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  if (Val == 0) return 0;
2088a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
2098a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  return cast<X>(Val);
2108a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen}
2118a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2128a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2138a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
2148a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// casting operator returns null if the argument is of the wrong type, so it can
2158a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// be used to test for a type as well as cast if successful.  This should be
2168a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// used in the context of an if statement like this:
2178a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
2188a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
2198a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
2208a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2218a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <class X, class Y>
2228a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheninline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
2238a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
2248a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen}
2258a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2268a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
2278a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen// value is accepted.
2288a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen//
2298a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chentemplate <class X, class Y>
2308a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Cheninline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
2318a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen  return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
2328a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen}
2338a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2348a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen} // End llvm namespace
2358a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen
2368a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen#endif
2378a3c0430323c28c1fbe8ceecd2cd8e58b64a9295Johnny Chen