aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2012-10-23 15:46:39 +0000
committerDaniel Jasper <djasper@google.com>2012-10-23 15:46:39 +0000
commitc711af2ddbbb1d46223cc9379d32a203fb5bc7f4 (patch)
tree9381fb8f504206785b39d1c6413d22a5a0b1ab94
parentac2153e5187fa46b37bc2db582926e05fdb28262 (diff)
Make hasDeclaration() matcher work inside the memberExpr() matcher.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166479 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h3
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h28
-rw-r--r--unittests/ASTMatchers/ASTMatchersTest.cpp9
3 files changed, 30 insertions, 10 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index b26bc62c99..259be8680a 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1470,7 +1470,8 @@ unless(const M &InnerMatcher) {
/// \brief Matches a type if the declaration of the type matches the given
/// matcher.
///
-/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>
+/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
+/// Matcher<MemberExpr>
inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
internal::Matcher<Decl> >
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index c675a3bcca..49867f1342 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -380,18 +380,14 @@ private:
/// FIXME: Add other ways to convert...
if (Node.isNull())
return false;
- CXXRecordDecl *NodeAsRecordDecl = Node->getAsCXXRecordDecl();
- return NodeAsRecordDecl != NULL &&
- InnerMatcher.matches(*NodeAsRecordDecl, Finder, Builder);
+ return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder);
}
/// \brief Extracts the Decl of the callee of a CallExpr and returns whether
/// the inner matcher matches on it.
bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- const Decl *NodeAsDecl = Node.getCalleeDecl();
- return NodeAsDecl != NULL &&
- InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
+ return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
}
/// \brief Extracts the Decl of the constructor call and returns whether the
@@ -399,9 +395,23 @@ private:
bool matchesSpecialized(const CXXConstructExpr &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
- const Decl *NodeAsDecl = Node.getConstructor();
- return NodeAsDecl != NULL &&
- InnerMatcher.matches(*NodeAsDecl, Finder, Builder);
+ return matchesDecl(Node.getConstructor(), Finder, Builder);
+ }
+
+ /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns
+ /// whether the inner matcher matches on it.
+ bool matchesSpecialized(const MemberExpr &Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return matchesDecl(Node.getMemberDecl(), Finder, Builder);
+ }
+
+ /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node
+ /// is \c NULL.
+ bool matchesDecl(const Decl *Node,
+ ASTMatchFinder *Finder,
+ BoundNodesTreeBuilder *Builder) const {
+ return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder);
}
const Matcher<Decl> InnerMatcher;
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index a97e90d74c..5060e807c6 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -2139,6 +2139,15 @@ TEST(Member, MatchesInMemberFunctionCall) {
memberExpr(member(hasName("first")))));
}
+TEST(Member, MatchesMember) {
+ EXPECT_TRUE(matches(
+ "struct A { int i; }; void f() { A a; a.i = 2; }",
+ memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
+ EXPECT_TRUE(notMatches(
+ "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
+ memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
+}
+
TEST(Member, MatchesMemberAllocationFunction) {
// Fails in C++11 mode
EXPECT_TRUE(matchesConditionally(