https://github.com/Gitspike updated https://github.com/llvm/llvm-project/pull/102152
>From 2d09f0bdc3881f7030d9054045c7839dcc956d22 Mon Sep 17 00:00:00 2001 From: hehouhua <hehou...@feysh.com> Date: Wed, 7 Aug 2024 11:55:30 +0800 Subject: [PATCH 1/3] [clang][ASTMatcher] Add matches for StringLiteral which matches literals on given RegExp Add Matcher matchesString. --- clang/docs/LibASTMatchersReference.html | 14 +++++++++++ clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/ASTMatchers/ASTMatchers.h | 24 +++++++++++++++++++ clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 8 +++++++ 5 files changed, 49 insertions(+) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index a16b9c44ef0eab..77b789b1ec4b94 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -5582,6 +5582,20 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2> </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>></td><td class="name" onclick="toggle('matchesString0')"><a name="matchesString0A">matchesString</a></td><td>StringRef RegExp, Regex::RegexFlags Flags = NoFlags</td></tr> +<tr><td colspan="4" class="doc" id="matchesString0"><pre>Matches string literals that contain a substring matched by the given RegExp + +Example matches "foo" and "foobar" but not "bar" + (matcher = stringLiteral(matchesString("foo.*"))) + const char* a = "foo"; + const char* b = "foobar"; + const char* c = "bar"; + +Usable as: Matcher<StringLiteral> +</pre></td></tr> + + + <tr><td>Matcher<<a href="https://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. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ffdb5f8f5af3ed..826ec64e1baca6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -296,6 +296,8 @@ AST Matchers - Fixed an issue with the `hasName` and `hasAnyName` matcher when matching inline namespaces with an enclosing namespace of the same name. +Add `matchesString` for `StringLiteral` which matches literals on given `RegExp`. + clang-format ------------ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index ca44c3ee085654..bff415294c4561 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3116,6 +3116,30 @@ AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) { return RegExp->match(FullNameString); } +/// Matches string literals that contain a substring matched by the given RegExp. +/// +/// Example matches "foo" and "foobar" but not "bar" +/// (matcher = stringLiteral(matchesString("foo.*"))) +/// \code +/// const char* a = "foo"; +/// const char* b = "foobar"; +/// const char* c = "bar"; +/// \endcode +/// +/// Usable as: Matcher<StringLiteral> +AST_MATCHER_REGEX(StringLiteral, matchesString, RegExp) { + constexpr unsigned StringLength = 64; + SmallString<StringLength> Str; + llvm::raw_svector_ostream OS(Str); + Node.outputString(OS); + StringRef OSRef = OS.str(); + if (OSRef.size() < 2U) { + return false; + } + OSRef = OSRef.substr(1, OSRef.size() - 2); + return RegExp->match(OSRef); +} + /// Matches overloaded operator names. /// /// Matches overloaded operator names specified in strings without the diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 2c75e6beb74301..a3a2515d86be70 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -125,6 +125,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER_OVERLOAD(equals); REGISTER_REGEX_MATCHER(isExpansionInFileMatching); + REGISTER_REGEX_MATCHER(matchesString); REGISTER_REGEX_MATCHER(matchesName); REGISTER_REGEX_MATCHER(matchesSelector); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 611e1f9ba5327c..77b6c4be26f06b 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2503,6 +2503,14 @@ TEST_P(ASTMatchersTest, IsDelegatingConstructor) { cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); } +TEST_P(ASTMatchersTest, MatchesString) { + StatementMatcher Literal = stringLiteral(matchesString("foo.*")); + EXPECT_TRUE(matches("const char* a = \"foo\";", Literal)); + EXPECT_TRUE(matches("const char* b = \"foobar\";", Literal)); + EXPECT_TRUE(matches("const char* b = \"fo\"\"obar\";", Literal)); + EXPECT_TRUE(notMatches("const char* c = \"bar\";", Literal)); +} + TEST_P(ASTMatchersTest, HasSize) { StatementMatcher Literal = stringLiteral(hasSize(4)); EXPECT_TRUE(matches("const char *s = \"abcd\";", Literal)); >From 6a2049761beef1e622b04fbaaa8da6997e2d0b52 Mon Sep 17 00:00:00 2001 From: hehouhua <hehou...@feysh.com> Date: Thu, 8 Aug 2024 10:19:47 +0800 Subject: [PATCH 2/3] add testcases for prefix and embed nulls --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 77b6c4be26f06b..c4a4a43e86b970 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2509,6 +2509,14 @@ TEST_P(ASTMatchersTest, MatchesString) { EXPECT_TRUE(matches("const char* b = \"foobar\";", Literal)); EXPECT_TRUE(matches("const char* b = \"fo\"\"obar\";", Literal)); EXPECT_TRUE(notMatches("const char* c = \"bar\";", Literal)); + // test prefix + EXPECT_TRUE(matches("const wchar_t* a = L\"foo\";", Literal)); + EXPECT_TRUE(matches("const char16_t* a = u\"foo\";", Literal)); + EXPECT_TRUE(matches("const char32_t* a = U\"foo\";", Literal)); + // test embedded nulls + Literal = stringLiteral(matchesString("bar")); + EXPECT_TRUE(matches("const char* b = \"foo\0bar\";", Literal)); + EXPECT_TRUE(notMatches("const char* b = \"foo\0b\0ar\";", Literal)); } TEST_P(ASTMatchersTest, HasSize) { >From a7b9c08f1653f135647fab1c1b4e6d6c2f65c554 Mon Sep 17 00:00:00 2001 From: hehouhua <hehou...@feysh.com> Date: Thu, 8 Aug 2024 11:59:39 +0800 Subject: [PATCH 3/3] test --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index c4a4a43e86b970..d79f8b03a519c1 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2514,9 +2514,9 @@ TEST_P(ASTMatchersTest, MatchesString) { EXPECT_TRUE(matches("const char16_t* a = u\"foo\";", Literal)); EXPECT_TRUE(matches("const char32_t* a = U\"foo\";", Literal)); // test embedded nulls - Literal = stringLiteral(matchesString("bar")); - EXPECT_TRUE(matches("const char* b = \"foo\0bar\";", Literal)); - EXPECT_TRUE(notMatches("const char* b = \"foo\0b\0ar\";", Literal)); + StatementMatcher Literal2 = stringLiteral(matchesString("bar")); + EXPECT_TRUE(matches("const char* b = \"foo\0bar\";", Literal2)); + EXPECT_TRUE(notMatches("const char* b = \"foo\0b\0ar\";", Literal2)); } TEST_P(ASTMatchersTest, HasSize) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits