summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorPeter Szecsi <szepet95@gmail.com>2018-03-27 12:11:46 +0000
committerPeter Szecsi <szepet95@gmail.com>2018-03-27 12:11:46 +0000
commitfff11dbc4829bd1752bf5ee824317f38e2ae05b6 (patch)
tree2378f1c318de067c19d7af9faccc20616ad5ae35 /clang
parent06cf6a6490bbb466f340307c111b63a979a5b17e (diff)
downloadbcm5719-llvm-fff11dbc4829bd1752bf5ee824317f38e2ae05b6.tar.gz
bcm5719-llvm-fff11dbc4829bd1752bf5ee824317f38e2ae05b6.zip
[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 llvm-svn: 328618
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/LibASTMatchersReference.html26
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h20
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp1
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp15
4 files changed, 62 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 8775314afc9..9c55e8214d9 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1926,6 +1926,19 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
</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://clang.llvm.org/doxygen/classclang_1_1CXXOp
</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.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 31620de85fd..65f1524223a 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4003,6 +4003,26 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
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()))
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 79aa4e667b3..fd373bca561 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -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);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 3e27948db78..ad90f75409c 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2139,5 +2139,20 @@ TEST(HasTrailingReturn, MatchesLambdaTrailingReturn) {
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
OpenPOWER on IntegriCloud