X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FCasting.h;h=d35febbe6d80b979bcb119c2a0d993a83687d2f8;hb=2fa8af224ea026f9432e833fd6f42a216423a010;hp=e0d50fe5d552c327d19a505ab69d160d9868b91a;hpb=5a6d63ae29512d654c8c697f42f32f97b9dc010b;p=oota-llvm.git diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index e0d50fe5d55..d35febbe6d8 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -1,21 +1,28 @@ -//===-- Support/Casting.h - Allow flexible, checked, casts -------*- C++ -*--=// +//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines the isa(), cast(), dyn_cast(), cast_or_null(), // and dyn_cast_or_null() templates. // //===----------------------------------------------------------------------===// -#ifndef SUPPORT_CASTING_H -#define SUPPORT_CASTING_H +#ifndef LLVM_SUPPORT_CASTING_H +#define LLVM_SUPPORT_CASTING_H -#include +#include + +namespace llvm { //===----------------------------------------------------------------------===// // isa Support Templates //===----------------------------------------------------------------------===// -template struct isa_impl_cl; - // Define a template that can be specialized by smart pointers to reflect the // fact that they are automatically dereferenced, and are not involved with the // template selection process... the default implementation is a noop. @@ -30,81 +37,80 @@ template struct simplify_type { template struct simplify_type { typedef const From SimpleType; static SimpleType &getSimplifiedValue(const From &Val) { - return simplify_type::getSimplifiedValue((From&)Val); + return simplify_type::getSimplifiedValue(static_cast(Val)); } }; - -// isa - Return true if the parameter to the template is an instance of the -// template type argument. Used like this: -// -// if (isa(myVal)) { ... } -// +// The core of the implementation of isa is here; To and From should be +// the names of classes. This template can be specialized to customize the +// implementation of isa<> without rewriting it from scratch. template -inline bool isa_impl(const From &Val) { - return To::classof(&Val); -} +struct isa_impl { + static inline bool doit(const From &Val) { + return To::classof(&Val); + } +}; -template -struct isa_impl_wrap { - // When From != SimplifiedType, we can simplify the type some more by using - // the simplify_type template. - static bool doit(const From &Val) { - return isa_impl_cl::template - isa(simplify_type::getSimplifiedValue(Val)); +template struct isa_impl_cl { + static inline bool doit(const From &Val) { + return isa_impl::doit(Val); } }; -template -struct isa_impl_wrap { - // When From == SimpleType, we are as simple as we are going to get. - static bool doit(const FromTy &Val) { - return isa_impl(Val); +template struct isa_impl_cl { + static inline bool doit(const From &Val) { + return isa_impl::doit(Val); } }; -// isa_impl_cl - Use class partial specialization to transform types to a single -// cannonical form for isa_impl. -// -template -struct isa_impl_cl { - template - static bool isa(const FromCl &Val) { - return isa_impl_wrap::SimpleType>::doit(Val); +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); } }; -// Specialization used to strip const qualifiers off of the FromCl type... -template -struct isa_impl_cl { - template - static bool isa(const FromCl &Val) { - return isa_impl_cl::template isa(Val); +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); } }; -// Define pointer traits in terms of base traits... -template -struct isa_impl_cl { - template - static bool isa(FromCl *Val) { - return isa_impl_cl::template isa(*Val); +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); } }; -// Define reference traits in terms of base traits... -template -struct isa_impl_cl { - template - static bool isa(FromCl &Val) { - return isa_impl_cl::template isa(&Val); +template +struct isa_impl_wrap { + // When From != SimplifiedType, we can simplify the type some more by using + // the simplify_type template. + static bool doit(const From &Val) { + return isa_impl_wrap::SimpleType>::doit( + simplify_type::getSimplifiedValue(Val)); } }; +template +struct isa_impl_wrap { + // When From == SimpleType, we are as simple as we are going to get. + static bool doit(const FromTy &Val) { + return isa_impl_cl::doit(Val); + } +}; + +// isa - Return true if the parameter to the template is an instance of the +// template type argument. Used like this: +// +// if (isa(myVal)) { ... } +// template inline bool isa(const Y &Val) { - return isa_impl_cl::template isa(Val); + return isa_impl_wrap::SimpleType>::doit(Val); } //===----------------------------------------------------------------------===// @@ -152,7 +158,7 @@ struct cast_retty_wrap { template struct cast_retty { - typedef typename cast_retty_wrap::SimpleType>::ret_type ret_type; }; @@ -171,7 +177,9 @@ template struct cast_convert_val { template struct cast_convert_val { // This _is_ a simple type, just cast it. static typename cast_retty::ret_type doit(const FromTy &Val) { - return (typename cast_retty::ret_type)Val; + typename cast_retty::ret_type Res2 + = (typename cast_retty::ret_type)const_cast(Val); + return Res2; } }; @@ -179,14 +187,14 @@ template struct cast_convert_val { // cast - Return the argument parameter cast to the specified type. This // casting operator asserts that the type is correct, so it does not return null -// on failure. But it will correctly return NULL when the input is NULL. -// Used Like this: +// on failure. It does not allow a null argument (use cast_or_null for that). +// It is typically used like this: // // cast(myVal)->getParent() // template inline typename cast_retty::ret_type cast(const Y &Val) { - assert(isa(Val) && "cast() argument of uncompatible type!"); + assert(isa(Val) && "cast() argument of incompatible type!"); return cast_convert_val::SimpleType>::doit(Val); } @@ -197,7 +205,7 @@ inline typename cast_retty::ret_type cast(const Y &Val) { template inline typename cast_retty::ret_type cast_or_null(Y *Val) { if (Val == 0) return 0; - assert(isa(Val) && "cast_or_null() argument of uncompatible type!"); + assert(isa(Val) && "cast_or_null() argument of incompatible type!"); return cast(Val); } @@ -207,12 +215,12 @@ inline typename cast_retty::ret_type cast_or_null(Y *Val) { // be used to test for a type as well as cast if successful. This should be // used in the context of an if statement like this: // -// if (const Instruction *I = dyn_cast(myVal)) { ... } +// if (const Instruction *I = dyn_cast(myVal)) { ... } // template -inline typename cast_retty::ret_type dyn_cast(Y *Val) { - return isa(Val) ? cast(Val) : 0; +inline typename cast_retty::ret_type dyn_cast(const Y &Val) { + return isa(Val) ? cast(Val) : 0; } // dyn_cast_or_null - Functionally identical to dyn_cast, except that a null @@ -220,72 +228,9 @@ inline typename cast_retty::ret_type dyn_cast(Y *Val) { // template inline typename cast_retty::ret_type dyn_cast_or_null(Y *Val) { - return (Val && isa(Val)) ? cast(Val) : 0; + return (Val && isa(Val)) ? cast(Val) : 0; } - -#ifdef DEBUG_CAST_OPERATORS -#include - -struct bar { - bar() {} -private: - bar(const bar &); -}; -struct foo { - void ext() const; - /* static bool classof(const bar *X) { - cerr << "Classof: " << X << "\n"; - return true; - }*/ -}; - -template <> inline bool isa_impl(const bar &Val) { - cerr << "Classof: " << &Val << "\n"; - return true; -} - - -bar *fub(); -void test(bar &B1, const bar *B2) { - // test various configurations of const - const bar &B3 = B1; - const bar *const B4 = B2; - - // test isa - if (!isa(B1)) return; - if (!isa(B2)) return; - if (!isa(B3)) return; - if (!isa(B4)) return; - - // test cast - foo &F1 = cast(B1); - const foo *F3 = cast(B2); - const foo *F4 = cast(B2); - const foo &F8 = cast(B3); - const foo *F9 = cast(B4); - foo *F10 = cast(fub()); - - // test cast_or_null - const foo *F11 = cast_or_null(B2); - const foo *F12 = cast_or_null(B2); - const foo *F13 = cast_or_null(B4); - const foo *F14 = cast_or_null(fub()); // Shouldn't print. - - // These lines are errors... - //foo *F20 = cast(B2); // Yields const foo* - //foo &F21 = cast(B3); // Yields const foo& - //foo *F22 = cast(B4); // Yields const foo* - //foo &F23 = cast_or_null(B1); - //const foo &F24 = cast_or_null(B3); -} - -bar *fub() { return 0; } -void main() { - bar B; - test(B, &B); -} - -#endif +} // End llvm namespace #endif