Author: shuaiwang
Date: Thu Aug 23 10:16:06 2018
New Revision: 340547

URL: http://llvm.org/viewvc/llvm-project?rev=340547&view=rev
Log:
[ASTMatchers] Let hasObjectExpression also support UnresolvedMemberExpr, 
CXXDependentScopeMemberExpr

Reviewers: aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D50617

Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=340547&r1=340546&r2=340547&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Thu Aug 23 10:16:06 2018
@@ -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 = hasUnary
 </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.

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=340547&r1=340546&r2=340547&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Aug 23 10:16:06 2018
@@ -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);
 }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=340547&r1=340546&r2=340547&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Thu Aug 23 
10:16:06 2018
@@ -1517,6 +1517,26 @@ TEST(HasObjectExpression, MatchesBaseOfV
     "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,


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to