aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-02-19 17:14:34 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-02-19 17:14:34 +0000
commit523806028d812a7f29636c59a8bc0e7e3d3fd9ae (patch)
tree7edb63f1490da1e00927ecd3bc73cd0640f8cc6e /include
parent3b41a100a65e05309dbfdad65e2f79439fdaf4c0 (diff)
Support in hasDeclaration for types with getDecl()
Using a new metafunction for detecting the presence of the member 'getDecl' in a type T, added support to hasDeclaration for any such type T. This allows hasDecl() to be replaced and enables several other subclasses of clang::Type to use hasDeclaration. Updated unittests and LibASTMatchersReference.html. Reviewers: klimek git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175532 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h13
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h21
2 files changed, 26 insertions, 8 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index fe2c14f58b..de9919aaf0 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1561,8 +1561,12 @@ unless(const M &InnerMatcher) {
/// \brief Matches a type if the declaration of the type matches the given
/// matcher.
///
+/// In addition to being usable as Matcher<TypedefType>, also usable as
+/// Matcher<T> for any T supporting the getDecl() member function. e.g. various
+/// subtypes of clang::Type.
+///
/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-/// Matcher<MemberExpr>
+/// Matcher<MemberExpr>, Matcher<TypedefType>
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
internal::Matcher<Decl> >
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
@@ -2846,13 +2850,6 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee);
/// matches "typedef int X"
AST_TYPE_MATCHER(TypedefType, typedefType);
-/// \brief Matches \c TypedefTypes referring to a specific
-/// \c TypedefNameDecl.
-AST_MATCHER_P(TypedefType, hasDecl,
- internal::Matcher<TypedefNameDecl>, InnerMatcher) {
- return InnerMatcher.matches(*Node.getDecl(), Finder, Builder);
-}
-
/// \brief Matches nested name specifiers.
///
/// Given
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index b41a74ce83..cc4edacf42 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -353,6 +353,18 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
return Matcher<T>(Implementation);
}
+/// \brief Metafunction to determine if type T has a member called getDecl.
+template <typename T> struct has_getDecl {
+ typedef char yes[1];
+ typedef char no[2];
+
+ template <typename TestType>
+ static yes &test(char[sizeof(&TestType::getDecl)]);
+ template <typename> static no &test(...);
+
+ static bool const value = sizeof(test<T>(0)) == sizeof(yes);
+};
+
/// \brief Matches declarations for QualType and CallExpr.
///
/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but
@@ -373,6 +385,15 @@ public:
}
private:
+ /// \brief If getDecl exists as a member of U, returns whether the inner
+ /// matcher matches Node.getDecl().
+ template <typename U>
+ bool matchesSpecialized(
+ const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+ typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+ return matchesDecl(Node.getDecl(), Finder, Builder);
+ }
+
/// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns
/// whether the inner matcher matches on it.
bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,