summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorShuai Wang <shuaiwang@google.com>2018-08-23 17:16:06 +0000
committerShuai Wang <shuaiwang@google.com>2018-08-23 17:16:06 +0000
commit92f9d1b8ac6ed54d4bf856ae729cfa1ab6be5b1f (patch)
tree0bc6be1e934b04b5164baf76db579e88e5419049 /clang
parent15f869238140e45f4a9331429bd42f1254e77259 (diff)
downloadbcm5719-llvm-92f9d1b8ac6ed54d4bf856ae729cfa1ab6be5b1f.tar.gz
bcm5719-llvm-92f9d1b8ac6ed54d4bf856ae729cfa1ab6be5b1f.zip
[ASTMatchers] Let hasObjectExpression also support UnresolvedMemberExpr, CXXDependentScopeMemberExpr
Reviewers: aaron.ballman Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D50617 llvm-svn: 340547
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/LibASTMatchersReference.html28
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h13
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp20
3 files changed, 59 insertions, 2 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 5c47e518082..ae446624892 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -4668,6 +4668,20 @@ with withInitializer matching (1)
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html">CXXDependentScopeMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression2')"><a name="hasObjectExpression2Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasObjectExpression2"><pre>Matches a member expression where the object expression is
+matched by a given matcher.
+
+Given
+ struct X { int m; };
+ void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
+ matches "x.m" and "m"
+with hasObjectExpression(...)
+ matching "x" and the implicit object expression of "m" which has type X*.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody3')"><a name="hasBody3Anchor">hasBody</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasBody3"><pre>Matches a 'for', 'while', 'do while' statement or a function
definition that has a given body.
@@ -6692,6 +6706,20 @@ Example matches true (matcher = hasUnaryOperand(
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html">UnresolvedMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression1')"><a name="hasObjectExpression1Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasObjectExpression1"><pre>Matches a member expression where the object expression is
+matched by a given matcher.
+
+Given
+ struct X { int m; };
+ void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
+ matches "x.m" and "m"
+with hasObjectExpression(...)
+ matching "x" and the implicit object expression of "m" which has type X*.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>const Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a node if the declaration associated with that node
matches the given matcher.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index d923daf70f1..25152d9de7d 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4825,8 +4825,17 @@ AST_MATCHER_P(MemberExpr, member,
/// matches "x.m" and "m"
/// with hasObjectExpression(...)
/// matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(MemberExpr, hasObjectExpression,
- internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasObjectExpression,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+ CXXDependentScopeMemberExpr),
+ internal::Matcher<Expr>, InnerMatcher) {
+ if (const auto *E = dyn_cast<UnresolvedMemberExpr>(&Node))
+ if (E->isImplicitAccess())
+ return false;
+ if (const auto *E = dyn_cast<CXXDependentScopeMemberExpr>(&Node))
+ if (E->isImplicitAccess())
+ return false;
return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 1e7b10e99e7..ac73fdfa605 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1517,6 +1517,26 @@ TEST(HasObjectExpression, MatchesBaseOfVariable) {
"struct X { int m; }; void f(X* x) { x->m; }",
memberExpr(hasObjectExpression(
hasType(pointsTo(recordDecl(hasName("X"))))))));
+ EXPECT_TRUE(matches("template <class T> struct X { void f() { T t; t.m; } };",
+ cxxDependentScopeMemberExpr(hasObjectExpression(
+ declRefExpr(to(namedDecl(hasName("t"))))))));
+ EXPECT_TRUE(
+ matches("template <class T> struct X { void f() { T t; t->m; } };",
+ cxxDependentScopeMemberExpr(hasObjectExpression(
+ declRefExpr(to(namedDecl(hasName("t"))))))));
+}
+
+TEST(HasObjectExpression, MatchesBaseOfMemberFunc) {
+ EXPECT_TRUE(matches(
+ "struct X { void f(); }; void g(X x) { x.f(); }",
+ memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
+ EXPECT_TRUE(matches("struct X { template <class T> void f(); };"
+ "template <class T> void g(X x) { x.f<T>(); }",
+ unresolvedMemberExpr(hasObjectExpression(
+ hasType(recordDecl(hasName("X")))))));
+ EXPECT_TRUE(matches("template <class T> void f(T t) { t.g(); }",
+ cxxDependentScopeMemberExpr(hasObjectExpression(
+ declRefExpr(to(namedDecl(hasName("t"))))))));
}
TEST(HasObjectExpression,
OpenPOWER on IntegriCloud