summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSean Silva <silvas@purdue.edu>2012-10-11 23:30:40 +0000
committerSean Silva <silvas@purdue.edu>2012-10-11 23:30:40 +0000
commit8b8fa7b2f403ae2f342413239c4151e075022c97 (patch)
tree70dca59e93c6b45c7a55b1e328c89fe332e36d77 /include
parent8ac1995456d6938b68f232995f49c86369dd121d (diff)
downloadllvm-8b8fa7b2f403ae2f342413239c4151e075022c97.tar.gz
llvm-8b8fa7b2f403ae2f342413239c4151e075022c97.tar.bz2
llvm-8b8fa7b2f403ae2f342413239c4151e075022c97.tar.xz
Casting.h: Automatically handle isa<Base>(Derived).
Additionally, all such cases are handled with no dynamic check. All `classof()` of the form class Foo { [...] static bool classof(const Bar *) { return true; } [...] } where Foo is an ancestor of Bar are no longer necessary. Don't write them! Note: The exact test is `is_base_of<Foo, Bar>`, which is non-strict, so that Foo is considered an ancestor of itself. This leads to the following rule of thumb for LLVM-style RTTI: The argument type of `classof()` should be a strict ancestor. For more information about implementing LLVM-style RTTI, see docs/HowToSetUpLLVMStyleRTTI.rst git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165765 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Support/Casting.h13
1 files changed, 12 insertions, 1 deletions
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index d35febbe6d..0c71882a77 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_CASTING_H
#define LLVM_SUPPORT_CASTING_H
+#include "llvm/Support/type_traits.h"
#include <cassert>
namespace llvm {
@@ -44,13 +45,23 @@ template<typename From> struct simplify_type<const From> {
// The core of the implementation of isa<X> 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 <typename To, typename From>
+template <typename To, typename From, typename Enabler = void>
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 <typename To, typename From>
+struct isa_impl<To, From,
+ typename llvm::enable_if_c<
+ llvm::is_base_of<To, From>::value
+ >::type
+ > {
+ static inline bool doit(const From &) { return true; }
+};
+
template <typename To, typename From> struct isa_impl_cl {
static inline bool doit(const From &Val) {
return isa_impl<To, From>::doit(Val);