Author: szepet
Date: Tue Mar 27 05:11:46 2018
New Revision: 328618

URL: http://llvm.org/viewvc/llvm-project?rev=328618&view=rev
Log:
[ASTMatchers] Add isAssignmentOperator matcher

Adding a matcher for BinaryOperator and cxxOperatorCallExpr to be able to
decide whether it is any kind of assignment operator or not. This would be
useful since allows us to easily detect assignments via matchers for static
analysis (Tidy, SA) purposes.

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


Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
    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=328618&r1=328617&r2=328618&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Tue Mar 27 05:11:46 2018
@@ -1926,6 +1926,19 @@ Example matches a || b (matcher = binary
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a 
href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html";>BinaryOperator</a>&gt;</td><td
 class="name" onclick="toggle('isAssignmentOperator0')"><a 
name="isAssignmentOperator0Anchor">isAssignmentOperator</a></td></tr>
+<tr><td colspan="4" class="doc" id="isAssignmentOperator0"><pre>Matches all 
kinds of assignment operators.
+
+Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 = s2 (matcher = 
cxxOperatorCallExpr(isAssignmentOperator()))
+  struct S { S& operator=(const S&); };
+  void x() { S s1, s2; s1 = s2; })
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html";>CXXBoolLiteralExpr</a>&gt;</td><td
 class="name" onclick="toggle('equals5')"><a 
name="equals5Anchor">equals</a></td><td>bool Value</td></tr>
 <tr><td colspan="4" class="doc" id="equals5"><pre></pre></td></tr>
 
@@ -2306,6 +2319,19 @@ Usable as: Matcher&lt;<a href="http://cl
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;<a 
href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html";>CXXOperatorCallExpr</a>&gt;</td><td
 class="name" onclick="toggle('isAssignmentOperator1')"><a 
name="isAssignmentOperator1Anchor">isAssignmentOperator</a></td></tr>
+<tr><td colspan="4" class="doc" id="isAssignmentOperator1"><pre>Matches all 
kinds of assignment operators.
+
+Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
+  if (a == b)
+    a += b;
+
+Example 2: matches s1 = s2 (matcher = 
cxxOperatorCallExpr(isAssignmentOperator()))
+  struct S { S& operator=(const S&); };
+  void x() { S s1, s2; s1 = s2; })
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;<a 
href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html";>CXXRecordDecl</a>&gt;</td><td
 class="name" onclick="toggle('hasDefinition0')"><a 
name="hasDefinition0Anchor">hasDefinition</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="hasDefinition0"><pre>Matches a class 
declaration that is defined.
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=328618&r1=328617&r2=328618&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Tue Mar 27 05:11:46 2018
@@ -4003,6 +4003,26 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorNam
   return Name == Node.getOpcodeStr(Node.getOpcode());
 }
 
+/// \brief Matches on all kinds of assignment operators.
+///
+/// Example 1: matches a += b (matcher = 
binaryOperator(isAssignmentOperator()))
+/// \code
+///   if (a == b)
+///     a += b;
+/// \endcode
+///
+/// Example 2: matches s1 = s2
+///            (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
+/// \code
+///   struct S { S& operator=(const S&); };
+///   void x() { S s1, s2; s1 = s2; })
+/// \endcode
+AST_POLYMORPHIC_MATCHER(isAssignmentOperator,
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
+                                                        CXXOperatorCallExpr)) {
+  return Node.isAssignmentOp();
+}
+
 /// \brief Matches the left hand side of binary operator expressions.
 ///
 /// Example matches a (matcher = binaryOperator(hasLHS()))

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=328618&r1=328617&r2=328618&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Tue Mar 27 05:11:46 2018
@@ -322,6 +322,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(isAnyPointer);
   REGISTER_MATCHER(isArray);
   REGISTER_MATCHER(isArrow);
+  REGISTER_MATCHER(isAssignmentOperator);
   REGISTER_MATCHER(isBaseInitializer);
   REGISTER_MATCHER(isBitField);
   REGISTER_MATCHER(isCatchAll);

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=328618&r1=328617&r2=328618&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Tue Mar 27 
05:11:46 2018
@@ -2139,5 +2139,20 @@ TEST(HasTrailingReturn, MatchesLambdaTra
           functionDecl(hasTrailingReturn())));
 }
 
+TEST(IsAssignmentOperator, Basic) {
+  StatementMatcher BinAsgmtOperator = binaryOperator(isAssignmentOperator());
+  StatementMatcher CXXAsgmtOperator =
+      cxxOperatorCallExpr(isAssignmentOperator());
+
+  EXPECT_TRUE(matches("void x() { int a; a += 1; }", BinAsgmtOperator));
+  EXPECT_TRUE(matches("void x() { int a; a = 2; }", BinAsgmtOperator));
+  EXPECT_TRUE(matches("void x() { int a; a &= 3; }", BinAsgmtOperator));
+  EXPECT_TRUE(matches("struct S { S& operator=(const S&); };"
+                      "void x() { S s1, s2; s1 = s2; }",
+                      CXXAsgmtOperator));
+  EXPECT_TRUE(
+      notMatches("void x() { int a; if(a == 0) return; }", BinAsgmtOperator));
+}
+
 } // namespace ast_matchers
 } // namespace clang


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

Reply via email to