[llvm-commits] [PATCH] Rewrite isa<> impl to match the cast<> impl (PR7952)
Eli Friedman
eli.friedman at gmail.com
Sat Apr 16 00:18:21 PDT 2011
Attached rewrites isa<> so it uses the same logic as cast<> to figure
out the underlying type of the argument; in particular, this means
that it won't automatically dereference multi-level pointers. My
knowledge of C++ templates is relatively weak, but this patch seems
correct.
The change to include/clang/AST/DeclBase.h in clang is necessary
because it specialized a template whose meaning has changed.
The rest of the changes are just making sure not to use isa<> on
multi-level pointers.
-Eli
-------------- next part --------------
Index: include/clang/AST/DeclBase.h
===================================================================
--- include/clang/AST/DeclBase.h (revision 129634)
+++ include/clang/AST/DeclBase.h (working copy)
@@ -1333,17 +1333,12 @@
namespace llvm {
/// isa<T>(DeclContext*)
-template<class ToTy>
-struct isa_impl_wrap<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {
+template <typename To>
+struct isa_impl<To, ::clang::DeclContext> {
static bool doit(const ::clang::DeclContext &Val) {
- return ToTy::classofKind(Val.getDeclKind());
+ return To::classofKind(Val.getDeclKind());
}
};
-template<class ToTy>
-struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
- : public isa_impl_wrap<ToTy,
- const ::clang::DeclContext,const ::clang::DeclContext> {};
/// cast<T>(DeclContext*)
template<class ToTy>
Index: lib/Frontend/CreateInvocationFromCommandLine.cpp
===================================================================
--- lib/Frontend/CreateInvocationFromCommandLine.cpp (revision 129634)
+++ lib/Frontend/CreateInvocationFromCommandLine.cpp (working copy)
@@ -65,7 +65,7 @@
// We expect to get back exactly one command job, if we didn't something
// failed.
const driver::JobList &Jobs = C->getJobs();
- if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
+ if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
llvm::SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
C->PrintJob(OS, C->getJobs(), "; ", true);
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp (revision 129634)
+++ lib/CodeGen/CGStmt.cpp (working copy)
@@ -978,7 +978,7 @@
// If we're looking for the case, just see if we can skip each of the
// substatements.
for (; Case && I != E; ++I) {
- HadSkippedDecl |= isa<DeclStmt>(I);
+ HadSkippedDecl |= isa<DeclStmt>(*I);
switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) {
case CSFC_Failure: return CSFC_Failure;
-------------- next part --------------
Index: lib/Transforms/Scalar/SCCP.cpp
===================================================================
--- lib/Transforms/Scalar/SCCP.cpp (revision 129634)
+++ lib/Transforms/Scalar/SCCP.cpp (working copy)
@@ -655,7 +655,7 @@
// Just mark all destinations executable!
// TODO: This could be improved if the operand is a [cast of a] BlockAddress.
- if (isa<IndirectBrInst>(&TI))
+ if (isa<IndirectBrInst>(TI))
return true;
#ifndef NDEBUG
Index: include/llvm/Support/Casting.h
===================================================================
--- include/llvm/Support/Casting.h (revision 129634)
+++ include/llvm/Support/Casting.h (working copy)
@@ -23,8 +23,6 @@
// isa<x> Support Templates
//===----------------------------------------------------------------------===//
-template<typename FromCl> 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.
@@ -43,12 +41,9 @@
}
};
-
-// isa<X> - Return true if the parameter to the template is an instance of the
-// template type argument. Used like this:
-//
-// if (isa<Type*>(myVal)) { ... }
-//
+// 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>
struct isa_impl {
static inline bool doit(const From &Val) {
@@ -56,66 +51,63 @@
}
};
-template<typename To, typename From, typename SimpleType>
-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<const SimpleType>::template
- isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
+template <typename To, typename From> struct isa_impl_cl {
+ static inline bool doit(const From &Val) {
+ return isa_impl<To, From>::doit(Val);
}
};
-template<typename To, typename FromTy>
-struct isa_impl_wrap<To, const FromTy, const FromTy> {
- // When From == SimpleType, we are as simple as we are going to get.
- static bool doit(const FromTy &Val) {
- return isa_impl<To,FromTy>::doit(Val);
+template <typename To, typename From> struct isa_impl_cl<To, const From> {
+ static inline bool doit(const From &Val) {
+ return isa_impl<To, From>::doit(Val);
}
};
-// isa_impl_cl - Use class partial specialization to transform types to a single
-// canonical form for isa_impl.
-//
-template<typename FromCl>
-struct isa_impl_cl {
- template<class ToCl>
- static bool isa(const FromCl &Val) {
- return isa_impl_wrap<ToCl,const FromCl,
- typename simplify_type<const FromCl>::SimpleType>::doit(Val);
+template <typename To, typename From> struct isa_impl_cl<To, From*> {
+ static inline bool doit(const From *Val) {
+ return isa_impl<To, From>::doit(*Val);
}
};
-// Specialization used to strip const qualifiers off of the FromCl type...
-template<typename FromCl>
-struct isa_impl_cl<const FromCl> {
- template<class ToCl>
- static bool isa(const FromCl &Val) {
- return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
+template <typename To, typename From> struct isa_impl_cl<To, const From*> {
+ static inline bool doit(const From *Val) {
+ return isa_impl<To, From>::doit(*Val);
}
};
-// Define pointer traits in terms of base traits...
-template<class FromCl>
-struct isa_impl_cl<FromCl*> {
- template<class ToCl>
- static bool isa(FromCl *Val) {
- return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
+template <typename To, typename From> struct isa_impl_cl<To, const From*const> {
+ static inline bool doit(const From *Val) {
+ return isa_impl<To, From>::doit(*Val);
}
};
-// Define reference traits in terms of base traits...
-template<class FromCl>
-struct isa_impl_cl<FromCl&> {
- template<class ToCl>
- static bool isa(FromCl &Val) {
- return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
+template<typename To, typename From, typename SimpleFrom>
+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<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
}
};
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, FromTy, FromTy> {
+ // When From == SimpleType, we are as simple as we are going to get.
+ static bool doit(const FromTy &Val) {
+ return isa_impl_cl<To,FromTy>::doit(Val);
+ }
+};
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument. Used like this:
+//
+// if (isa<Type>(myVal)) { ... }
+//
template <class X, class Y>
inline bool isa(const Y &Val) {
- return isa_impl_cl<Y>::template isa<X>(Val);
+ return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
}
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list