r269274 - Add an AST matcher for string-literal length
Etienne Bergeron via cfe-commits
cfe-commits at lists.llvm.org
Wed May 11 21:20:05 PDT 2016
Author: etienneb
Date: Wed May 11 23:20:04 2016
New Revision: 269274
URL: http://llvm.org/viewvc/llvm-project?rev=269274&view=rev
Log:
Add an AST matcher for string-literal length
Summary:
This patch is adding support for a matcher to check string literal length.
This matcher is used in clang-tidy checkers and is part of this refactoring:
see: http://reviews.llvm.org/D19841
Reviewers: sbenza, klimek, aaron.ballman
Subscribers: alexfh, klimek, cfe-commits
Differential Revision: http://reviews.llvm.org/D19876
Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=269274&r1=269273&r2=269274&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Wed May 11 23:20:04 2016
@@ -644,7 +644,8 @@ Not matching Hex-encoded chars (e.g. 0x1
though.
Example matches 'a', L'a'
- char ch = 'a'; wchar_t chw = L'a';
+ char ch = 'a';
+ wchar_t chw = L'a';
</pre></td></tr>
@@ -652,7 +653,8 @@ Example matches 'a', L'a'
<tr><td colspan="4" class="doc" id="compoundLiteralExpr0"><pre>Matches compound (i.e. non-scalar) literals
Example match: {1}, (1, 2)
- int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+ int array[4] = {1};
+ vector int myvec = (vector int)(1, 2);
</pre></td></tr>
@@ -1217,7 +1219,8 @@ Example match: ({ int X = 4; X; })
<tr><td colspan="4" class="doc" id="stringLiteral0"><pre>Matches string literals (also matches wide string literals).
Example matches "abcd", L"abcd"
- char *s = "abcd"; wchar_t *ws = L"abcd"
+ char *s = "abcd";
+ wchar_t *ws = L"abcd";
</pre></td></tr>
@@ -2191,14 +2194,19 @@ compoundStmt(statementCountIs(0)))
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConstantArrayType.html">ConstantArrayType</a>></td><td class="name" onclick="toggle('hasSize0')"><a name="hasSize0Anchor">hasSize</a></td><td>unsigned N</td></tr>
-<tr><td colspan="4" class="doc" id="hasSize0"><pre>Matches ConstantArrayType nodes that have the specified size.
+<tr><td colspan="4" class="doc" id="hasSize0"><pre>Matches nodes that have the specified size.
Given
int a[42];
int b[2 * 21];
int c[41], d[43];
+ char *s = "abcd";
+ wchar_t *ws = L"abcd";
+ char *w = "a";
constantArrayType(hasSize(42))
matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+ matches "abcd", L"abcd"
</pre></td></tr>
@@ -2955,6 +2963,23 @@ Usable as: Matcher<<a href="http://cl
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>></td><td class="name" onclick="toggle('hasSize1')"><a name="hasSize1Anchor">hasSize</a></td><td>unsigned N</td></tr>
+<tr><td colspan="4" class="doc" id="hasSize1"><pre>Matches nodes that have the specified size.
+
+Given
+ int a[42];
+ int b[2 * 21];
+ int c[41], d[43];
+ char *s = "abcd";
+ wchar_t *ws = L"abcd";
+ char *w = "a";
+constantArrayType(hasSize(42))
+ matches "int a[42]" and "int b[2 * 21]"
+stringLiteral(hasSize(4))
+ matches "abcd", L"abcd"
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>></td><td class="name" onclick="toggle('isDefinition0')"><a name="isDefinition0Anchor">isDefinition</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached.
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=269274&r1=269273&r2=269274&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed May 11 23:20:04 2016
@@ -1560,7 +1560,8 @@ const internal::VariadicDynCastAllOfMatc
///
/// Example matches "abcd", L"abcd"
/// \code
-/// char *s = "abcd"; wchar_t *ws = L"abcd"
+/// char *s = "abcd";
+/// wchar_t *ws = L"abcd";
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
@@ -1573,7 +1574,8 @@ const internal::VariadicDynCastAllOfMatc
///
/// Example matches 'a', L'a'
/// \code
-/// char ch = 'a'; wchar_t chw = L'a';
+/// char ch = 'a';
+/// wchar_t chw = L'a';
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
@@ -1609,7 +1611,8 @@ const internal::VariadicDynCastAllOfMatc
///
/// Example match: {1}, (1, 2)
/// \code
-/// int array[4] = {1}; vector int myvec = (vector int)(1, 2);
+/// int array[4] = {1};
+/// vector int myvec = (vector int)(1, 2);
/// \endcode
const internal::VariadicDynCastAllOfMatcher<
Stmt,
@@ -4228,18 +4231,26 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasElementT
/// matches "int a[2]"
AST_TYPE_MATCHER(ConstantArrayType, constantArrayType);
-/// \brief Matches \c ConstantArrayType nodes that have the specified size.
+/// \brief Matches nodes that have the specified size.
///
/// Given
/// \code
/// int a[42];
/// int b[2 * 21];
/// int c[41], d[43];
+/// char *s = "abcd";
+/// wchar_t *ws = L"abcd";
+/// char *w = "a";
/// \endcode
/// constantArrayType(hasSize(42))
/// matches "int a[42]" and "int b[2 * 21]"
-AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) {
- return Node.getSize() == N;
+/// stringLiteral(hasSize(4))
+/// matches "abcd", L"abcd"
+AST_POLYMORPHIC_MATCHER_P(hasSize,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,
+ StringLiteral),
+ unsigned, N) {
+ return internal::HasSizeMatcher<NodeType>::hasSize(Node, N);
}
/// \brief Matches C++ arrays whose size is a value-dependent expression.
Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=269274&r1=269273&r2=269274&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Wed May 11 23:20:04 2016
@@ -1651,6 +1651,19 @@ inline const Stmt *GetBodyMatcher<Functi
}
template <typename Ty>
+struct HasSizeMatcher {
+ static bool hasSize(const Ty &Node, unsigned int N) {
+ return Node.getSize() == N;
+ }
+};
+
+template <>
+inline bool HasSizeMatcher<StringLiteral>::hasSize(
+ const StringLiteral &Node, unsigned int N) {
+ return Node.getLength() == N;
+}
+
+template <typename Ty>
struct GetSourceExpressionMatcher {
static const Expr *get(const Ty &Node) {
return Node.getSubExpr();
Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=269274&r1=269273&r2=269274&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Wed May 11 23:20:04 2016
@@ -51,7 +51,6 @@ TEST(Finder, DynamicOnlyAcceptsSomeMatch
// Do not accept non-toplevel matchers.
EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
- EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
}
@@ -2536,6 +2535,17 @@ TEST(Matcher, StringLiterals) {
EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
}
+TEST(StringLiteral, HasSize) {
+ StatementMatcher Literal = stringLiteral(hasSize(4));
+ EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal));
+ // wide string
+ EXPECT_TRUE(matches("const wchar_t *s = L\"abcd\";", Literal));
+ // with escaped characters
+ EXPECT_TRUE(matches("const char *s = \"\x05\x06\x07\x08\";", Literal));
+ // no matching, too small
+ EXPECT_TRUE(notMatches("const char *s = \"ab\";", Literal));
+}
+
TEST(Matcher, CharacterLiterals) {
StatementMatcher CharLiteral = characterLiteral();
EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
More information about the cfe-commits
mailing list