Casting.h revision 63b3afa98460ce38a1c48d3c44ef6edfdaf37b77
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
3b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//                     The LLVM Compiler Infrastructure
4b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
5b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// This file was developed by the LLVM research group and is distributed under
6b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell// the University of Illinois Open Source 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
18d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
19d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
20589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//===----------------------------------------------------------------------===//
217e70829632f82de15db187845666aaca6e04b792Chris Lattner//                          isa<x> Support Templates
22589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//===----------------------------------------------------------------------===//
23589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
247e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl> struct isa_impl_cl;
257e70829632f82de15db187845666aaca6e04b792Chris Lattner
267e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define a template that can be specialized by smart pointers to reflect the
277e70829632f82de15db187845666aaca6e04b792Chris Lattner// fact that they are automatically dereferenced, and are not involved with the
287e70829632f82de15db187845666aaca6e04b792Chris Lattner// template selection process...  the default implementation is a noop.
297e70829632f82de15db187845666aaca6e04b792Chris Lattner//
307e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename From> struct simplify_type {
317e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef       From SimpleType;        // The real type this represents...
327e70829632f82de15db187845666aaca6e04b792Chris Lattner
337e70829632f82de15db187845666aaca6e04b792Chris Lattner  // An accessor to get the real value...
347e70829632f82de15db187845666aaca6e04b792Chris Lattner  static SimpleType &getSimplifiedValue(From &Val) { return Val; }
357e70829632f82de15db187845666aaca6e04b792Chris Lattner};
367e70829632f82de15db187845666aaca6e04b792Chris Lattner
377e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename From> struct simplify_type<const From> {
387e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const From SimpleType;
397e70829632f82de15db187845666aaca6e04b792Chris Lattner  static SimpleType &getSimplifiedValue(const From &Val) {
408b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
417e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
427e70829632f82de15db187845666aaca6e04b792Chris Lattner};
437e70829632f82de15db187845666aaca6e04b792Chris Lattner
447e70829632f82de15db187845666aaca6e04b792Chris Lattner
45589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// isa<X> - Return true if the parameter to the template is an instance of the
46589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// template type argument.  Used like this:
47589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
487e70829632f82de15db187845666aaca6e04b792Chris Lattner//  if (isa<Type*>(myVal)) { ... }
497e70829632f82de15db187845666aaca6e04b792Chris Lattner//
507e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate <typename To, typename From>
5163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmaninline bool isa_impl(const From &Val) {
527e70829632f82de15db187845666aaca6e04b792Chris Lattner  return To::classof(&Val);
537e70829632f82de15db187845666aaca6e04b792Chris Lattner}
547e70829632f82de15db187845666aaca6e04b792Chris Lattner
557e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename To, typename From, typename SimpleType>
567e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_wrap {
577e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When From != SimplifiedType, we can simplify the type some more by using
587e70829632f82de15db187845666aaca6e04b792Chris Lattner  // the simplify_type template.
597e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool doit(const From &Val) {
6063b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    return isa_impl_cl<const SimpleType>::template
617e70829632f82de15db187845666aaca6e04b792Chris Lattner                    isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
627e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
637e70829632f82de15db187845666aaca6e04b792Chris Lattner};
647e70829632f82de15db187845666aaca6e04b792Chris Lattner
657e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename To, typename FromTy>
667e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_wrap<To, const FromTy, const FromTy> {
677e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When From == SimpleType, we are as simple as we are going to get.
687e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool doit(const FromTy &Val) {
697e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl<To,FromTy>(Val);
707e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
717e70829632f82de15db187845666aaca6e04b792Chris Lattner};
727e70829632f82de15db187845666aaca6e04b792Chris Lattner
737e70829632f82de15db187845666aaca6e04b792Chris Lattner// isa_impl_cl - Use class partial specialization to transform types to a single
74776f776838d6e2f83d899bc99452dc83779c341bChris Lattner// canonical form for isa_impl.
75589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
767e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl>
777e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl {
787e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
797e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(const FromCl &Val) {
807e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_wrap<ToCl,const FromCl,
815a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                   typename simplify_type<const FromCl>::SimpleType>::doit(Val);
827e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
837e70829632f82de15db187845666aaca6e04b792Chris Lattner};
847e70829632f82de15db187845666aaca6e04b792Chris Lattner
857e70829632f82de15db187845666aaca6e04b792Chris Lattner// Specialization used to strip const qualifiers off of the FromCl type...
867e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<typename FromCl>
877e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<const FromCl> {
887e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
897e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(const FromCl &Val) {
907e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
917e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
927e70829632f82de15db187845666aaca6e04b792Chris Lattner};
937e70829632f82de15db187845666aaca6e04b792Chris Lattner
947e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define pointer traits in terms of base traits...
957e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class FromCl>
967e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<FromCl*> {
977e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
987e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(FromCl *Val) {
997e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
1007e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1017e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1027e70829632f82de15db187845666aaca6e04b792Chris Lattner
1037e70829632f82de15db187845666aaca6e04b792Chris Lattner// Define reference traits in terms of base traits...
1047e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class FromCl>
1057e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct isa_impl_cl<FromCl&> {
1067e70829632f82de15db187845666aaca6e04b792Chris Lattner  template<class ToCl>
1077e70829632f82de15db187845666aaca6e04b792Chris Lattner  static bool isa(FromCl &Val) {
1087e70829632f82de15db187845666aaca6e04b792Chris Lattner    return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
1097e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1107e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1117e70829632f82de15db187845666aaca6e04b792Chris Lattner
112589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
1137e70829632f82de15db187845666aaca6e04b792Chris Lattnerinline bool isa(const Y &Val) {
1147e70829632f82de15db187845666aaca6e04b792Chris Lattner  return isa_impl_cl<Y>::template isa<X>(Val);
115589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
116589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
1177e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1187e70829632f82de15db187845666aaca6e04b792Chris Lattner//                          cast<x> Support Templates
1197e70829632f82de15db187845666aaca6e04b792Chris Lattner//===----------------------------------------------------------------------===//
1207e70829632f82de15db187845666aaca6e04b792Chris Lattner
1217e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty;
1227e70829632f82de15db187845666aaca6e04b792Chris Lattner
1237e70829632f82de15db187845666aaca6e04b792Chris Lattner
1247e70829632f82de15db187845666aaca6e04b792Chris Lattner// Calculate what type the 'cast' function should return, based on a requested
1257e70829632f82de15db187845666aaca6e04b792Chris Lattner// type of To and a source type of From.
1267e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl {
1277e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef To& ret_type;         // Normal case, return Ty&
1287e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1297e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From> {
1307e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To &ret_type;   // Normal case, return Ty&
1317e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1327e70829632f82de15db187845666aaca6e04b792Chris Lattner
1337e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, From*> {
1347e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef To* ret_type;         // Pointer arg case, return Ty*
1357e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1367e70829632f82de15db187845666aaca6e04b792Chris Lattner
1377e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From*> {
1387e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1397e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1407e70829632f82de15db187845666aaca6e04b792Chris Lattner
1417e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From> struct cast_retty_impl<To, const From*const> {
1427e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef const To* ret_type;   // Constant pointer arg case, return const Ty*
1437e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1447e70829632f82de15db187845666aaca6e04b792Chris Lattner
1457e70829632f82de15db187845666aaca6e04b792Chris Lattner
1467e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From, class SimpleFrom>
1477e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty_wrap {
1487e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When the simplified type and the from type are not the same, use the type
1497e70829632f82de15db187845666aaca6e04b792Chris Lattner  // simplifier to reduce the type, then reuse cast_retty_impl to get the
1507e70829632f82de15db187845666aaca6e04b792Chris Lattner  // resultant type.
1517e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
1527e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1537e70829632f82de15db187845666aaca6e04b792Chris Lattner
1547e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class FromTy>
1557e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty_wrap<To, FromTy, FromTy> {
1567e70829632f82de15db187845666aaca6e04b792Chris Lattner  // When the simplified type is equal to the from type, use it directly.
1577e70829632f82de15db187845666aaca6e04b792Chris Lattner  typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
1587e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1597e70829632f82de15db187845666aaca6e04b792Chris Lattner
1607e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From>
1617e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct cast_retty {
16263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman  typedef typename cast_retty_wrap<To, From,
1635a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                   typename simplify_type<From>::SimpleType>::ret_type ret_type;
1647e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1657e70829632f82de15db187845666aaca6e04b792Chris Lattner
1667e70829632f82de15db187845666aaca6e04b792Chris Lattner// Ensure the non-simple values are converted using the simplify_type template
1677e70829632f82de15db187845666aaca6e04b792Chris Lattner// that may be specialized by smart pointers...
1687e70829632f82de15db187845666aaca6e04b792Chris Lattner//
1697e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class From, class SimpleFrom> struct cast_convert_val {
1707e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This is not a simple type, use the template to simplify it...
1715a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  static typename cast_retty<To, From>::ret_type doit(const From &Val) {
1727e70829632f82de15db187845666aaca6e04b792Chris Lattner    return cast_convert_val<To, SimpleFrom,
1735a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner      typename simplify_type<SimpleFrom>::SimpleType>::doit(
1747e70829632f82de15db187845666aaca6e04b792Chris Lattner                          simplify_type<From>::getSimplifiedValue(Val));
1757e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1767e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1777e70829632f82de15db187845666aaca6e04b792Chris Lattner
1787e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
1797e70829632f82de15db187845666aaca6e04b792Chris Lattner  // This _is_ a simple type, just cast it.
1805a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
1818b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner    return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>(
1828b70b78ba489b090d9866e6a4084ab1e8613b527Chris Lattner                         const_cast<FromTy&>(Val));
1837e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1847e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1857e70829632f82de15db187845666aaca6e04b792Chris Lattner
1867e70829632f82de15db187845666aaca6e04b792Chris Lattner
187589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
188589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast<X> - Return the argument parameter cast to the specified type.  This
189589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator asserts that the type is correct, so it does not return null
190589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// on failure.  But it will correctly return NULL when the input is NULL.
191589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// Used Like this:
192589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
1937e70829632f82de15db187845666aaca6e04b792Chris Lattner//  cast<Instruction>(myVal)->getParent()
194589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
195589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
1965a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattnerinline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
19788d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
1985a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  return cast_convert_val<X, Y,
1995a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                          typename simplify_type<Y>::SimpleType>::doit(Val);
200589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
201589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
202589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast_or_null<X> - Functionally identical to cast, except that a null value is
203589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// accepted.
204589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
205589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
2065a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattnerinline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
2077e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (Val == 0) return 0;
20888d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
2097e70829632f82de15db187845666aaca6e04b792Chris Lattner  return cast<X>(Val);
210589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
211589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
212589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
213589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
214589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator returns null if the argument is of the wrong type, so it can
215589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// be used to test for a type as well as cast if successful.  This should be
216589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// used in the context of an if statement like this:
217589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
2181ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
219589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
220589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
221589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
222ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattnerinline typename cast_retty<X, Y>::ret_type dyn_cast(Y Val) {
223ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattner  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
224589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
225589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
226589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
227589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// value is accepted.
228589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
229589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
2301ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattnerinline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(Y Val) {
2311ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner  return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
2327e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2337e70829632f82de15db187845666aaca6e04b792Chris Lattner
2347e70829632f82de15db187845666aaca6e04b792Chris Lattner
2357e70829632f82de15db187845666aaca6e04b792Chris Lattner#ifdef DEBUG_CAST_OPERATORS
2367e70829632f82de15db187845666aaca6e04b792Chris Lattner#include <iostream>
2377e70829632f82de15db187845666aaca6e04b792Chris Lattner
2387e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct bar {
2397e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar() {}
2407e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
2417e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar(const bar &);
2427e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2437e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct foo {
2447e70829632f82de15db187845666aaca6e04b792Chris Lattner  void ext() const;
2457e70829632f82de15db187845666aaca6e04b792Chris Lattner  /*  static bool classof(const bar *X) {
2467e70829632f82de15db187845666aaca6e04b792Chris Lattner    cerr << "Classof: " << X << "\n";
2477e70829632f82de15db187845666aaca6e04b792Chris Lattner    return true;
2487e70829632f82de15db187845666aaca6e04b792Chris Lattner    }*/
2497e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2507e70829632f82de15db187845666aaca6e04b792Chris Lattner
25163b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukmantemplate <> inline bool isa_impl<foo,bar>(const bar &Val) {
2527e70829632f82de15db187845666aaca6e04b792Chris Lattner  cerr << "Classof: " << &Val << "\n";
2537e70829632f82de15db187845666aaca6e04b792Chris Lattner  return true;
2547e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2557e70829632f82de15db187845666aaca6e04b792Chris Lattner
2567e70829632f82de15db187845666aaca6e04b792Chris Lattner
2577e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub();
2587e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid test(bar &B1, const bar *B2) {
2597e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test various configurations of const
2607e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar &B3 = B1;
2617e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar *const B4 = B2;
2627e70829632f82de15db187845666aaca6e04b792Chris Lattner
2637e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test isa
2647e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B1)) return;
2657e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B2)) return;
2667e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B3)) return;
2677e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B4)) return;
2687e70829632f82de15db187845666aaca6e04b792Chris Lattner
2697e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast
2707e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo &F1 = cast<foo>(B1);
2717e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F3 = cast<foo>(B2);
2727e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F4 = cast<foo>(B2);
2737e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo &F8 = cast<foo>(B3);
2747e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F9 = cast<foo>(B4);
2757e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo *F10 = cast<foo>(fub());
2767e70829632f82de15db187845666aaca6e04b792Chris Lattner
2777e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast_or_null
2787e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F11 = cast_or_null<foo>(B2);
2797e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F12 = cast_or_null<foo>(B2);
2807e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F13 = cast_or_null<foo>(B4);
2817e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
28263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
2837e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These lines are errors...
2847e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F20 = cast<foo>(B2);  // Yields const foo*
2857e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F21 = cast<foo>(B3);  // Yields const foo&
2867e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F22 = cast<foo>(B4);  // Yields const foo*
2877e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F23 = cast_or_null<foo>(B1);
2887e70829632f82de15db187845666aaca6e04b792Chris Lattner  //const foo &F24 = cast_or_null<foo>(B3);
2897e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2907e70829632f82de15db187845666aaca6e04b792Chris Lattner
2917e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub() { return 0; }
2927e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid main() {
2937e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar B;
2947e70829632f82de15db187845666aaca6e04b792Chris Lattner  test(B, &B);
295589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
296589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
297589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#endif
2987e70829632f82de15db187845666aaca6e04b792Chris Lattner
299d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
300d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
3017e70829632f82de15db187845666aaca6e04b792Chris Lattner#endif
302