X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FCasting.h;h=6ba5efa4755498195c6a056314887d6b4e9e5d12;hb=HEAD;hp=d35febbe6d80b979bcb119c2a0d993a83687d2f8;hpb=f5091b476c46333ecfcf095cd2e422e9748e9546;p=oota-llvm.git diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index d35febbe6d8..6ba5efa4755 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -15,6 +15,8 @@ #ifndef LLVM_SUPPORT_CASTING_H #define LLVM_SUPPORT_CASTING_H +#include "llvm/Support/Compiler.h" +#include "llvm/Support/type_traits.h" #include namespace llvm { @@ -35,22 +37,33 @@ template struct simplify_type { }; template struct simplify_type { - typedef const From SimpleType; - static SimpleType &getSimplifiedValue(const From &Val) { - return simplify_type::getSimplifiedValue(static_cast(Val)); + typedef typename simplify_type::SimpleType NonConstSimpleType; + typedef typename add_const_past_pointer::type + SimpleType; + typedef typename add_lvalue_reference_if_not_pointer::type + RetType; + static RetType getSimplifiedValue(const From& Val) { + return simplify_type::getSimplifiedValue(const_cast(Val)); } }; // 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 +template struct isa_impl { static inline bool doit(const From &Val) { return To::classof(&Val); } }; +/// \brief Always allow upcasts, and perform no dynamic check for them. +template +struct isa_impl< + To, From, typename std::enable_if::value>::type> { + static inline bool doit(const From &) { return true; } +}; + template struct isa_impl_cl { static inline bool doit(const From &Val) { return isa_impl::doit(Val); @@ -70,6 +83,13 @@ template struct isa_impl_cl { } }; +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); + } +}; + template struct isa_impl_cl { static inline bool doit(const From *Val) { assert(Val && "isa<> used on a null pointer"); @@ -91,7 +111,7 @@ struct isa_impl_wrap { static bool doit(const From &Val) { return isa_impl_wrap::SimpleType>::doit( - simplify_type::getSimplifiedValue(Val)); + simplify_type::getSimplifiedValue(Val)); } }; @@ -109,8 +129,9 @@ struct isa_impl_wrap { // if (isa(myVal)) { ... } // template -inline bool isa(const Y &Val) { - return isa_impl_wrap::SimpleType>::doit(Val); +LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) { + return isa_impl_wrap::SimpleType>::doit(Val); } //===----------------------------------------------------------------------===// @@ -167,7 +188,7 @@ struct cast_retty { // template struct cast_convert_val { // This is not a simple type, use the template to simplify it... - static typename cast_retty::ret_type doit(const From &Val) { + static typename cast_retty::ret_type doit(From &Val) { return cast_convert_val::SimpleType>::doit( simplify_type::getSimplifiedValue(Val)); @@ -183,7 +204,10 @@ template struct cast_convert_val { } }; - +template struct is_simple_type { + static const bool value = + std::is_same::SimpleType>::value; +}; // 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 @@ -193,18 +217,55 @@ template struct cast_convert_val { // cast(myVal)->getParent() // template -inline typename cast_retty::ret_type cast(const Y &Val) { +inline typename std::enable_if::value, + typename cast_retty::ret_type>::type +cast(const Y &Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return cast_convert_val< + X, const Y, typename simplify_type::SimpleType>::doit(Val); +} + +template +inline typename cast_retty::ret_type cast(Y &Val) { assert(isa(Val) && "cast() argument of incompatible type!"); return cast_convert_val::SimpleType>::doit(Val); } +template +inline typename cast_retty::ret_type cast(Y *Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return cast_convert_val::SimpleType>::doit(Val); +} + // cast_or_null - Functionally identical to cast, except that a null value is // accepted. // template -inline typename cast_retty::ret_type cast_or_null(Y *Val) { - if (Val == 0) return 0; +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type::value, typename cast_retty::ret_type>::type +cast_or_null(const Y &Val) { + if (!Val) + return nullptr; + assert(isa(Val) && "cast_or_null() argument of incompatible type!"); + return cast(Val); +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type::value, typename cast_retty::ret_type>::type +cast_or_null(Y &Val) { + if (!Val) + return nullptr; + assert(isa(Val) && "cast_or_null() argument of incompatible type!"); + return cast(Val); +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type +cast_or_null(Y *Val) { + if (!Val) return nullptr; assert(isa(Val) && "cast_or_null() argument of incompatible type!"); return cast(Val); } @@ -219,16 +280,45 @@ inline typename cast_retty::ret_type cast_or_null(Y *Val) { // template -inline typename cast_retty::ret_type dyn_cast(const Y &Val) { - return isa(Val) ? cast(Val) : 0; +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type::value, typename cast_retty::ret_type>::type +dyn_cast(const Y &Val) { + return isa(Val) ? cast(Val) : nullptr; +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type +dyn_cast(Y &Val) { + return isa(Val) ? cast(Val) : nullptr; +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type +dyn_cast(Y *Val) { + return isa(Val) ? cast(Val) : nullptr; } // dyn_cast_or_null - Functionally identical to dyn_cast, except that a null // value is accepted. // template -inline typename cast_retty::ret_type dyn_cast_or_null(Y *Val) { - return (Val && isa(Val)) ? cast(Val) : 0; +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type::value, typename cast_retty::ret_type>::type +dyn_cast_or_null(const Y &Val) { + return (Val && isa(Val)) ? cast(Val) : nullptr; +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type::value, typename cast_retty::ret_type>::type +dyn_cast_or_null(Y &Val) { + return (Val && isa(Val)) ? cast(Val) : nullptr; +} + +template +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type +dyn_cast_or_null(Y *Val) { + return (Val && isa(Val)) ? cast(Val) : nullptr; } } // End llvm namespace