diff options
author | Sean Silva <silvas@purdue.edu> | 2012-10-11 23:30:40 +0000 |
---|---|---|
committer | Sean Silva <silvas@purdue.edu> | 2012-10-11 23:30:40 +0000 |
commit | 8b8fa7b2f403ae2f342413239c4151e075022c97 (patch) | |
tree | 70dca59e93c6b45c7a55b1e328c89fe332e36d77 /include | |
parent | 8ac1995456d6938b68f232995f49c86369dd121d (diff) | |
download | llvm-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.h | 13 |
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); |