Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -644,7 +644,8 @@ though. Example matches 'a', L'a' - char ch = 'a'; wchar_t chw = L'a'; + char ch = 'a'; + wchar_t chw = L'a'; @@ -652,7 +653,8 @@
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);
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";
Matches ConstantArrayType nodes that have the specified size. +@@ -2955,6 +2963,23 @@ 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"
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" +
Matches if a declaration has a body attached. Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -1560,7 +1560,8 @@ /// /// 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 @@ /// /// 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 @@ /// /// 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 @@ /// 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::hasSize(Node, N); } /// \brief Matches C++ arrays whose size is a value-dependent expression. Index: include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- include/clang/ASTMatchers/ASTMatchersInternal.h +++ include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1651,6 +1651,19 @@ } template +struct HasSizeMatcher { + static bool hasSize(const Ty &Node, unsigned int N) { + return Node.getSize() == N; + } +}; + +template <> +inline bool HasSizeMatcher ::hasSize( + const StringLiteral &Node, unsigned int N) { + return Node.getLength() == N; +} + +template struct GetSourceExpressionMatcher { static const Expr *get(const Ty &Node) { return Node.getSubExpr(); Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -51,7 +51,6 @@ // 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 @@ 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));