Casting.h revision 3a3134ab12f3aa65f9791f702a73f6d0b2af423f
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
8b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//===----------------------------------------------------------------------===//
9589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
10589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
11589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// and dyn_cast_or_null<X>() templates.
12589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
13589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//===----------------------------------------------------------------------===//
14589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
15551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#ifndef LLVM_SUPPORT_CASTING_H
16551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#define LLVM_SUPPORT_CASTING_H
17589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
18c7365a9ec96ff434d93d0d8052812283b33e537dReid Spencer#include <cassert>
19c7365a9ec96ff434d93d0d8052812283b33e537dReid Spencer
20d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
21d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
22589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//===----------------------------------------------------------------------===//
237e70829632f82de15db187845666aaca6e04b792Chris Lattner//                          isa<x> Support Templates
24589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//===----------------------------------------------------------------------===//
25589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
267e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl> struct isa_impl_cl;
277e70829632f82de15db187845666aaca6e04b792Chris Lattner
287e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define a template that can be specialized by smart pointers to reflect the
297e70829632f82de15db187845666aaca6e04b792Chris Lattner// fact that they are automatically dereferenced, and are not involved with the
307e70829632f82de15db187845666aaca6e04b792Chris Lattner// template selection process...  the default implementation is a noop.
317e70829632f82de15db187845666aaca6e04b792Chris Lattner//
327e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename From> struct simplify_type {
337e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef       From SimpleType;        // The real type this represents...
347e70829632f82de15db187845666aaca6e04b792Chris Lattner
357e70829632f82de15db187845666aaca6e04b792Chris Lattner  // An accessor to get the real value...
367e70829632f82de15db187845666aaca6e04b792Chris Lattner  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
377e70829632f82de15db187845666aaca6e04b792Chris Lattner};
387e70829632f82de15db187845666aaca6e04b792Chris Lattner
397e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename From> struct simplify_type<const From> {
407e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const From SimpleType;
417e70829632f82de15db187845666aaca6e04b792Chris Lattner  static SimpleType &getSimplifiedValue(const From &Val) {
428b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
437e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
447e70829632f82de15db187845666aaca6e04b792Chris Lattner};
457e70829632f82de15db187845666aaca6e04b792Chris Lattner
467e70829632f82de15db187845666aaca6e04b792Chris Lattner
47589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// isa<X> - Return true if the parameter to the template is an instance of the
48589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// template type argument.  Used like this:
49589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
507e70829632f82de15db187845666aaca6e04b792Chris Lattner//  if (isa<Type*>(myVal)) { ... }
517e70829632f82de15db187845666aaca6e04b792Chris Lattner//
527e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate <typename To, typename From>
5363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmaninline bool isa_impl(const From &Val) {
547e70829632f82de15db187845666aaca6e04b792Chris Lattner  return To::classof(&Val);
557e70829632f82de15db187845666aaca6e04b792Chris Lattner}
567e70829632f82de15db187845666aaca6e04b792Chris Lattner
577e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename To, typename From, typename SimpleType>
587e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_wrap {
597e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When From != SimplifiedType, we can simplify the type some more by using
607e70829632f82de15db187845666aaca6e04b792Chris Lattner  // the simplify_type template.
617e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool doit(const From &Val) {
6263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return isa_impl_cl<const SimpleType>::template
637e70829632f82de15db187845666aaca6e04b792Chris Lattner                    isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
647e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
657e70829632f82de15db187845666aaca6e04b792Chris Lattner};
667e70829632f82de15db187845666aaca6e04b792Chris Lattner
677e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename To, typename FromTy>
687e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_wrap<To, const FromTy, const FromTy> {
697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When From == SimpleType, we are as simple as we are going to get.
707e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool doit(const FromTy &Val) {
717e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl<To,FromTy>(Val);
727e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
737e70829632f82de15db187845666aaca6e04b792Chris Lattner};
747e70829632f82de15db187845666aaca6e04b792Chris Lattner
757e70829632f82de15db187845666aaca6e04b792Chris Lattner// isa_impl_cl - Use class partial specialization to transform types to a single
76776f776838d6e2f83d899bc99452dc83779c341bChris Lattner// canonical form for isa_impl.
77589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
787e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl>
797e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl {
807e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
817e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(const FromCl &Val) {
827e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_wrap<ToCl,const FromCl,
835a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                   typename simplify_type<const FromCl>::SimpleType>::doit(Val);
847e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
857e70829632f82de15db187845666aaca6e04b792Chris Lattner};
867e70829632f82de15db187845666aaca6e04b792Chris Lattner
877e70829632f82de15db187845666aaca6e04b792Chris Lattner// Specialization used to strip const qualifiers off of the FromCl type...
887e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl>
897e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<const FromCl> {
907e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
917e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(const FromCl &Val) {
927e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
937e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
947e70829632f82de15db187845666aaca6e04b792Chris Lattner};
957e70829632f82de15db187845666aaca6e04b792Chris Lattner
967e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define pointer traits in terms of base traits...
977e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class FromCl>
987e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<FromCl*> {
997e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
1007e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(FromCl *Val) {
1012cd91804ec4d631cc432dac2828d8ee0b1a3390fScott Michel    return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
1027e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1037e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1047e70829632f82de15db187845666aaca6e04b792Chris Lattner
1057e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define reference traits in terms of base traits...
1067e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class FromCl>
1077e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<FromCl&> {
1087e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
1097e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(FromCl &Val) {
1107e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
1117e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1127e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1137e70829632f82de15db187845666aaca6e04b792Chris Lattner
114589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
1157e70829632f82de15db187845666aaca6e04b792Chris Lattnerinline bool isa(const Y &Val) {
1167e70829632f82de15db187845666aaca6e04b792Chris Lattner  return isa_impl_cl<Y>::template isa<X>(Val);
117589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
118589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
1197e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1207e70829632f82de15db187845666aaca6e04b792Chris Lattner//                          cast<x> Support Templates
1217e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1227e70829632f82de15db187845666aaca6e04b792Chris Lattner
1237e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty;
1247e70829632f82de15db187845666aaca6e04b792Chris Lattner
1257e70829632f82de15db187845666aaca6e04b792Chris Lattner
1267e70829632f82de15db187845666aaca6e04b792Chris Lattner// Calculate what type the 'cast' function should return, based on a requested
1277e70829632f82de15db187845666aaca6e04b792Chris Lattner// type of To and a source type of From.
1287e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl {
1297e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef To& ret_type;         // Normal case, return Ty&
1307e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1317e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From> {
1327e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To &ret_type;   // Normal case, return Ty&
1337e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1347e70829632f82de15db187845666aaca6e04b792Chris Lattner
1357e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, From*> {
1367e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef To* ret_type;         // Pointer arg case, return Ty*
1377e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1387e70829632f82de15db187845666aaca6e04b792Chris Lattner
1397e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From*> {
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1417e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1427e70829632f82de15db187845666aaca6e04b792Chris Lattner
1437e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From*const> {
1447e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1457e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1467e70829632f82de15db187845666aaca6e04b792Chris Lattner
1477e70829632f82de15db187845666aaca6e04b792Chris Lattner
1487e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From, class SimpleFrom>
1497e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty_wrap {
1507e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When the simplified type and the from type are not the same, use the type
1517e70829632f82de15db187845666aaca6e04b792Chris Lattner  // simplifier to reduce the type, then reuse cast_retty_impl to get the
1527e70829632f82de15db187845666aaca6e04b792Chris Lattner  // resultant type.
1537e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
1547e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1557e70829632f82de15db187845666aaca6e04b792Chris Lattner
1567e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class FromTy>
1577e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty_wrap<To, FromTy, FromTy> {
1587e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When the simplified type is equal to the from type, use it directly.
1597e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
1607e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1617e70829632f82de15db187845666aaca6e04b792Chris Lattner
1627e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From>
1637e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty {
16463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  typedef typename cast_retty_wrap<To, From,
1655a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
1667e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1677e70829632f82de15db187845666aaca6e04b792Chris Lattner
1687e70829632f82de15db187845666aaca6e04b792Chris Lattner// Ensure the non-simple values are converted using the simplify_type template
1697e70829632f82de15db187845666aaca6e04b792Chris Lattner// that may be specialized by smart pointers...
1707e70829632f82de15db187845666aaca6e04b792Chris Lattner//
1717e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From, class SimpleFrom> struct cast_convert_val {
1727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is not a simple type, use the template to simplify it...
1735a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  static typename cast_retty<To, From>::ret_type doit(const From &Val) {
1747e70829632f82de15db187845666aaca6e04b792Chris Lattner    return cast_convert_val<To, SimpleFrom,
1755a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner      typename simplify_type<SimpleFrom>::SimpleType>::doit(
1767e70829632f82de15db187845666aaca6e04b792Chris Lattner                          simplify_type<From>::getSimplifiedValue(Val));
1777e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1787e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1797e70829632f82de15db187845666aaca6e04b792Chris Lattner
1807e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
1817e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This _is_ a simple type, just cast it.
1825a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
1833a3134ab12f3aa65f9791f702a73f6d0b2af423fChris Lattner    typename cast_retty<To, FromTy>::ret_type Res2
1843a3134ab12f3aa65f9791f702a73f6d0b2af423fChris Lattner     = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
1853a3134ab12f3aa65f9791f702a73f6d0b2af423fChris Lattner    return Res2;
1867e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1877e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1887e70829632f82de15db187845666aaca6e04b792Chris Lattner
1897e70829632f82de15db187845666aaca6e04b792Chris Lattner
190589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
191589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast<X> - Return the argument parameter cast to the specified type.  This
192589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator asserts that the type is correct, so it does not return null
193589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// on failure.  But it will correctly return NULL when the input is NULL.
194589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// Used Like this:
195589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
1967e70829632f82de15db187845666aaca6e04b792Chris Lattner//  cast<Instruction>(myVal)->getParent()
197589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
198589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
1995a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattnerinline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
20088d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
2015a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  return cast_convert_val<X, Y,
2025a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                          typename simplify_type<Y>::SimpleType>::doit(Val);
203589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
204589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
205589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast_or_null<X> - Functionally identical to cast, except that a null value is
206589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// accepted.
207589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
208589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
2099a0b165cb58cb5cf49cb3a143c302029f389acb2Argyrios Kyrtzidisinline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
2109a0b165cb58cb5cf49cb3a143c302029f389acb2Argyrios Kyrtzidis  if (Val == 0) return 0;
21188d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
2127e70829632f82de15db187845666aaca6e04b792Chris Lattner  return cast<X>(Val);
213589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
214589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
215589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
216589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
217589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator returns null if the argument is of the wrong type, so it can
218589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// be used to test for a type as well as cast if successful.  This should be
219589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// used in the context of an if statement like this:
220589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
2211ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
222589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
223589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
224589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
225917365bef1cfb8493558b76f8e6ceb1e76eba2c5Gabor Greifinline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
2269a0b165cb58cb5cf49cb3a143c302029f389acb2Argyrios Kyrtzidis  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
227589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
228589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
229589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
230589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// value is accepted.
231589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
232589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
233917365bef1cfb8493558b76f8e6ceb1e76eba2c5Gabor Greifinline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(const Y &Val) {
2349a0b165cb58cb5cf49cb3a143c302029f389acb2Argyrios Kyrtzidis  return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
2357e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2367e70829632f82de15db187845666aaca6e04b792Chris Lattner
2377e70829632f82de15db187845666aaca6e04b792Chris Lattner
2387e70829632f82de15db187845666aaca6e04b792Chris Lattner#ifdef DEBUG_CAST_OPERATORS
239103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner#include "llvm/Support/raw_ostream.h"
2407e70829632f82de15db187845666aaca6e04b792Chris Lattner
2417e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct bar {
2427e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar() {}
2437e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
2447e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar(const bar &);
2457e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2467e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct foo {
2477e70829632f82de15db187845666aaca6e04b792Chris Lattner  void ext() const;
2487e70829632f82de15db187845666aaca6e04b792Chris Lattner  /*  static bool classof(const bar *X) {
249e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling    cerr << "Classof: " << X << "\n";
2507e70829632f82de15db187845666aaca6e04b792Chris Lattner    return true;
2517e70829632f82de15db187845666aaca6e04b792Chris Lattner    }*/
2527e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2537e70829632f82de15db187845666aaca6e04b792Chris Lattner
25463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmantemplate <> inline bool isa_impl<foo,bar>(const bar &Val) {
2550ff129f061233b724abe22fe048f06bcb06cd308David Greene  dbgs() << "Classof: " << &Val << "\n";
2567e70829632f82de15db187845666aaca6e04b792Chris Lattner  return true;
2577e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2587e70829632f82de15db187845666aaca6e04b792Chris Lattner
2597e70829632f82de15db187845666aaca6e04b792Chris Lattner
2607e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub();
2617e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid test(bar &B1, const bar *B2) {
2627e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test various configurations of const
2637e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar &B3 = B1;
2647e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar *const B4 = B2;
2657e70829632f82de15db187845666aaca6e04b792Chris Lattner
2667e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test isa
2677e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B1)) return;
2687e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B2)) return;
2697e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B3)) return;
2707e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B4)) return;
2717e70829632f82de15db187845666aaca6e04b792Chris Lattner
2727e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast
2737e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo &F1 = cast<foo>(B1);
2747e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F3 = cast<foo>(B2);
2757e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F4 = cast<foo>(B2);
2767e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo &F8 = cast<foo>(B3);
2777e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F9 = cast<foo>(B4);
2787e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo *F10 = cast<foo>(fub());
2797e70829632f82de15db187845666aaca6e04b792Chris Lattner
2807e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast_or_null
2817e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F11 = cast_or_null<foo>(B2);
2827e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F12 = cast_or_null<foo>(B2);
2837e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F13 = cast_or_null<foo>(B4);
2847e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
28563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
2867e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These lines are errors...
2877e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F20 = cast<foo>(B2);  // Yields const foo*
2887e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F21 = cast<foo>(B3);  // Yields const foo&
2897e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F22 = cast<foo>(B4);  // Yields const foo*
2907e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F23 = cast_or_null<foo>(B1);
2917e70829632f82de15db187845666aaca6e04b792Chris Lattner  //const foo &F24 = cast_or_null<foo>(B3);
2927e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2937e70829632f82de15db187845666aaca6e04b792Chris Lattner
2947e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub() { return 0; }
2957e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid main() {
2967e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar B;
2977e70829632f82de15db187845666aaca6e04b792Chris Lattner  test(B, &B);
298589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
299589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
300589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#endif
3017e70829632f82de15db187845666aaca6e04b792Chris Lattner
302d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
303d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
3047e70829632f82de15db187845666aaca6e04b792Chris Lattner#endif
305