Casting.h revision d0fde30ce850b78371fd1386338350591f9ff494
148486893f46d2e12e926682a3ecb908716bc66c4Chris Lattner//===-- Support/Casting.h - Allow flexible, checked, casts ------*- C++ -*-===//
2b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
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.
7b2109ce97881269a610fa4afbcbca350e975174dJohn Criswell//
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
15589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#ifndef SUPPORT_CASTING_H
16589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#define 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) {
407e70829632f82de15db187845666aaca6e04b792Chris Lattner    return simplify_type<From>::getSimplifiedValue((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>
517e70829632f82de15db187845666aaca6e04b792Chris Lattnerinline 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) {
607e70829632f82de15db187845666aaca6e04b792Chris Lattner    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 {
1627e70829632f82de15db187845666aaca6e04b792Chris Lattner  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) {
1815a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner    return (typename cast_retty<To, FromTy>::ret_type)Val;
1827e70829632f82de15db187845666aaca6e04b792Chris Lattner  }
1837e70829632f82de15db187845666aaca6e04b792Chris Lattner};
1847e70829632f82de15db187845666aaca6e04b792Chris Lattner
1857e70829632f82de15db187845666aaca6e04b792Chris Lattner
186589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
187589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast<X> - Return the argument parameter cast to the specified type.  This
188589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator asserts that the type is correct, so it does not return null
189589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// on failure.  But it will correctly return NULL when the input is NULL.
190589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// Used Like this:
191589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
1927e70829632f82de15db187845666aaca6e04b792Chris Lattner//  cast<Instruction>(myVal)->getParent()
193589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
194589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
1955a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattnerinline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
19688d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
1975a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner  return cast_convert_val<X, Y,
1985a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattner                          typename simplify_type<Y>::SimpleType>::doit(Val);
199589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
200589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
201589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// cast_or_null<X> - Functionally identical to cast, except that a null value is
202589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// accepted.
203589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
204589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
2055a6d63ae29512d654c8c697f42f32f97b9dc010bChris Lattnerinline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
2067e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (Val == 0) return 0;
20788d942d8983aadecae477fee523c23312d194515Misha Brukman  assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
2087e70829632f82de15db187845666aaca6e04b792Chris Lattner  return cast<X>(Val);
209589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
210589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
211589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
212589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast<X> - Return the argument parameter cast to the specified type.  This
213589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// casting operator returns null if the argument is of the wrong type, so it can
214589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// be used to test for a type as well as cast if successful.  This should be
215589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// used in the context of an if statement like this:
216589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
2171ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner//  if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
218589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
219589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
220589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
221ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattnerinline typename cast_retty<X, Y>::ret_type dyn_cast(Y Val) {
222ea0f49e52436272c65b52fe1e83f5009aa191a21Chris Lattner  return isa<X>(Val) ? cast<X, Y>(Val) : 0;
223589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
224589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
225589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
226589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner// value is accepted.
227589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner//
228589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattnertemplate <class X, class Y>
2291ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattnerinline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(Y Val) {
2301ff1da7ac9bff43ba24445ff30ba2fd79bd95cd7Chris Lattner  return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
2317e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2327e70829632f82de15db187845666aaca6e04b792Chris Lattner
2337e70829632f82de15db187845666aaca6e04b792Chris Lattner
2347e70829632f82de15db187845666aaca6e04b792Chris Lattner#ifdef DEBUG_CAST_OPERATORS
2357e70829632f82de15db187845666aaca6e04b792Chris Lattner#include <iostream>
2367e70829632f82de15db187845666aaca6e04b792Chris Lattner
2377e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct bar {
2387e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar() {}
2397e70829632f82de15db187845666aaca6e04b792Chris Lattnerprivate:
2407e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar(const bar &);
2417e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2427e70829632f82de15db187845666aaca6e04b792Chris Lattnerstruct foo {
2437e70829632f82de15db187845666aaca6e04b792Chris Lattner  void ext() const;
2447e70829632f82de15db187845666aaca6e04b792Chris Lattner  /*  static bool classof(const bar *X) {
2457e70829632f82de15db187845666aaca6e04b792Chris Lattner    cerr << "Classof: " << X << "\n";
2467e70829632f82de15db187845666aaca6e04b792Chris Lattner    return true;
2477e70829632f82de15db187845666aaca6e04b792Chris Lattner    }*/
2487e70829632f82de15db187845666aaca6e04b792Chris Lattner};
2497e70829632f82de15db187845666aaca6e04b792Chris Lattner
2507e70829632f82de15db187845666aaca6e04b792Chris Lattnertemplate <> inline bool isa_impl<foo,bar>(const bar &Val) {
2517e70829632f82de15db187845666aaca6e04b792Chris Lattner  cerr << "Classof: " << &Val << "\n";
2527e70829632f82de15db187845666aaca6e04b792Chris Lattner  return true;
2537e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2547e70829632f82de15db187845666aaca6e04b792Chris Lattner
2557e70829632f82de15db187845666aaca6e04b792Chris Lattner
2567e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub();
2577e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid test(bar &B1, const bar *B2) {
2587e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test various configurations of const
2597e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar &B3 = B1;
2607e70829632f82de15db187845666aaca6e04b792Chris Lattner  const bar *const B4 = B2;
2617e70829632f82de15db187845666aaca6e04b792Chris Lattner
2627e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test isa
2637e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B1)) return;
2647e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B2)) return;
2657e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B3)) return;
2667e70829632f82de15db187845666aaca6e04b792Chris Lattner  if (!isa<foo>(B4)) return;
2677e70829632f82de15db187845666aaca6e04b792Chris Lattner
2687e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast
2697e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo &F1 = cast<foo>(B1);
2707e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F3 = cast<foo>(B2);
2717e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F4 = cast<foo>(B2);
2727e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo &F8 = cast<foo>(B3);
2737e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F9 = cast<foo>(B4);
2747e70829632f82de15db187845666aaca6e04b792Chris Lattner  foo *F10 = cast<foo>(fub());
2757e70829632f82de15db187845666aaca6e04b792Chris Lattner
2767e70829632f82de15db187845666aaca6e04b792Chris Lattner  // test cast_or_null
2777e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F11 = cast_or_null<foo>(B2);
2787e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F12 = cast_or_null<foo>(B2);
2797e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F13 = cast_or_null<foo>(B4);
2807e70829632f82de15db187845666aaca6e04b792Chris Lattner  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
2817e70829632f82de15db187845666aaca6e04b792Chris Lattner
2827e70829632f82de15db187845666aaca6e04b792Chris Lattner  // These lines are errors...
2837e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F20 = cast<foo>(B2);  // Yields const foo*
2847e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F21 = cast<foo>(B3);  // Yields const foo&
2857e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo *F22 = cast<foo>(B4);  // Yields const foo*
2867e70829632f82de15db187845666aaca6e04b792Chris Lattner  //foo &F23 = cast_or_null<foo>(B1);
2877e70829632f82de15db187845666aaca6e04b792Chris Lattner  //const foo &F24 = cast_or_null<foo>(B3);
2887e70829632f82de15db187845666aaca6e04b792Chris Lattner}
2897e70829632f82de15db187845666aaca6e04b792Chris Lattner
2907e70829632f82de15db187845666aaca6e04b792Chris Lattnerbar *fub() { return 0; }
2917e70829632f82de15db187845666aaca6e04b792Chris Lattnervoid main() {
2927e70829632f82de15db187845666aaca6e04b792Chris Lattner  bar B;
2937e70829632f82de15db187845666aaca6e04b792Chris Lattner  test(B, &B);
294589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner}
295589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner
296589df88ba03a81b2b3dc9d084c191a3a74724ecdChris Lattner#endif
2977e70829632f82de15db187845666aaca6e04b792Chris Lattner
298d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
299d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
3007e70829632f82de15db187845666aaca6e04b792Chris Lattner#endif
301