[clang] [clang][ASTMatcher] Add matchers for isExplicitObjectMemberFunction() (PR #84446)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 8 00:37:48 PST 2024
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/84446
Note that this patch will be necessary to fix `forEachArgumentWithParam()` and `forEachArgumentWithParamType()` matchers for deducing "this"; which is my true motivation.
>From 9ffc1b9ec60a9638c5b07cb25574ddb2420b77a2 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 7 Mar 2024 19:23:48 +0100
Subject: [PATCH] [clang][ASTMatcher] Add matchers for
isExplicitObjectMemberFunction()
---
clang/docs/LibASTMatchersReference.html | 15 +++++++++++++++
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/ASTMatchers/ASTMatchers.h | 19 +++++++++++++++++++
clang/include/clang/Testing/CommandLineArgs.h | 1 +
clang/include/clang/Testing/TestClangConfig.h | 16 +++++++++++-----
clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 +
clang/lib/Testing/CommandLineArgs.cpp | 7 +++++++
.../ASTMatchers/ASTMatchersNarrowingTest.cpp | 14 ++++++++++++++
.../ASTMatchers/ASTMatchersNodeTest.cpp | 2 +-
clang/unittests/ASTMatchers/ASTMatchersTest.h | 14 ++++++++++----
10 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 8a06084955aa6b..bb1b68f6671b1a 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -3546,6 +3546,21 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
</pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isExplicitObjectMemberFunction0')"><a name="isExplicitObjectMemberFunction0Anchor">isExplicitObjectMemberFunction</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicitObjectMemberFunction0"><pre>Matches if the given method declaration declares a member function with an explicit object parameter.
+
+Given
+struct A {
+ int operator-(this A, int);
+ void fun(this A &&self);
+ static int operator()(int);
+ int operator+(int);
+};
+
+cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two methods but not the last two.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isCopyAssignmentOperator0')"><a name="isCopyAssignmentOperator0Anchor">isCopyAssignmentOperator</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isCopyAssignmentOperator0"><pre>Matches if the given method declaration declares a copy assignment
operator.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 942820a5268576..898380f94b7956 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -415,6 +415,7 @@ AST Matchers
------------
- ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
+- Add ``isExplicitObjectMemberFunction``.
clang-format
------------
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index ced89ff127ab3e..96dbcdc344e131 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -6366,6 +6366,25 @@ AST_MATCHER(CXXMethodDecl, isConst) {
return Node.isConst();
}
+/// Matches if the given method declaration declares a member function with an
+/// explicit object parameter.
+///
+/// Given
+/// \code
+/// struct A {
+/// int operator-(this A, int);
+/// void fun(this A &&self);
+/// static int operator()(int);
+/// int operator+(int);
+/// };
+/// \endcode
+///
+/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
+/// methods but not the last two.
+AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
+ return Node.isExplicitObjectMemberFunction();
+}
+
/// Matches if the given method declaration declares a copy assignment
/// operator.
///
diff --git a/clang/include/clang/Testing/CommandLineArgs.h b/clang/include/clang/Testing/CommandLineArgs.h
index 4dd28718dfa67c..e71907e8bbd0c6 100644
--- a/clang/include/clang/Testing/CommandLineArgs.h
+++ b/clang/include/clang/Testing/CommandLineArgs.h
@@ -28,6 +28,7 @@ enum TestLanguage {
Lang_CXX14,
Lang_CXX17,
Lang_CXX20,
+ Lang_CXX23,
Lang_OpenCL,
Lang_OBJC,
Lang_OBJCXX
diff --git a/clang/include/clang/Testing/TestClangConfig.h b/clang/include/clang/Testing/TestClangConfig.h
index 92d5cc3cff994f..1b4efca80e9d47 100644
--- a/clang/include/clang/Testing/TestClangConfig.h
+++ b/clang/include/clang/Testing/TestClangConfig.h
@@ -34,24 +34,30 @@ struct TestClangConfig {
bool isCXX() const {
return Language == Lang_CXX03 || Language == Lang_CXX11 ||
Language == Lang_CXX14 || Language == Lang_CXX17 ||
- Language == Lang_CXX20;
+ Language == Lang_CXX20 || Language == Lang_CXX23;
}
bool isCXX11OrLater() const {
return Language == Lang_CXX11 || Language == Lang_CXX14 ||
- Language == Lang_CXX17 || Language == Lang_CXX20;
+ Language == Lang_CXX17 || Language == Lang_CXX20 ||
+ Language == Lang_CXX23;
}
bool isCXX14OrLater() const {
return Language == Lang_CXX14 || Language == Lang_CXX17 ||
- Language == Lang_CXX20;
+ Language == Lang_CXX20 || Language == Lang_CXX23;
}
bool isCXX17OrLater() const {
- return Language == Lang_CXX17 || Language == Lang_CXX20;
+ return Language == Lang_CXX17 || Language == Lang_CXX20 ||
+ Language == Lang_CXX23;
}
- bool isCXX20OrLater() const { return Language == Lang_CXX20; }
+ bool isCXX20OrLater() const {
+ return Language == Lang_CXX20 || Language == Lang_CXX23;
+ }
+
+ bool isCXX23OrLater() const { return Language == Lang_CXX23; }
bool supportsCXXDynamicExceptionSpecification() const {
return Language == Lang_CXX03 || Language == Lang_CXX11 ||
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 15dad022df5fe0..2c75e6beb74301 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -432,6 +432,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isExpansionInMainFile);
REGISTER_MATCHER(isExpansionInSystemHeader);
REGISTER_MATCHER(isExplicit);
+ REGISTER_MATCHER(isExplicitObjectMemberFunction);
REGISTER_MATCHER(isExplicitTemplateSpecialization);
REGISTER_MATCHER(isExpr);
REGISTER_MATCHER(isExternC);
diff --git a/clang/lib/Testing/CommandLineArgs.cpp b/clang/lib/Testing/CommandLineArgs.cpp
index 0da087c33e3f4e..3abc689b93e8d0 100644
--- a/clang/lib/Testing/CommandLineArgs.cpp
+++ b/clang/lib/Testing/CommandLineArgs.cpp
@@ -37,6 +37,9 @@ std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang) {
case Lang_CXX20:
Args = {"-std=c++20", "-frtti"};
break;
+ case Lang_CXX23:
+ Args = {"-std=c++23", "-frtti"};
+ break;
case Lang_OBJC:
Args = {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"};
break;
@@ -73,6 +76,9 @@ std::vector<std::string> getCC1ArgsForTesting(TestLanguage Lang) {
case Lang_CXX20:
Args = {"-std=c++20"};
break;
+ case Lang_CXX23:
+ Args = {"-std=c++23"};
+ break;
case Lang_OBJC:
Args = {"-xobjective-c"};
break;
@@ -96,6 +102,7 @@ StringRef getFilenameForTesting(TestLanguage Lang) {
case Lang_CXX14:
case Lang_CXX17:
case Lang_CXX20:
+ case Lang_CXX23:
return "input.cc";
case Lang_OpenCL:
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index b75da7bc1ed069..87774b00956a5a 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2107,6 +2107,20 @@ TEST_P(ASTMatchersTest, IsPure) {
EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
}
+TEST_P(ASTMatchersTest, IsExplicitObjectMemberFunction) {
+ if (!GetParam().isCXX23OrLater()) {
+ return;
+ }
+
+ auto ExpObjParamFn = cxxMethodDecl(isExplicitObjectMemberFunction());
+ EXPECT_TRUE(
+ notMatches("struct A { static int operator()(int); };", ExpObjParamFn));
+ EXPECT_TRUE(notMatches("struct A { int operator+(int); };", ExpObjParamFn));
+ EXPECT_TRUE(
+ matches("struct A { int operator-(this A, int); };", ExpObjParamFn));
+ EXPECT_TRUE(matches("struct A { void fun(this A &&self); };", ExpObjParamFn));
+}
+
TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {
if (!GetParam().isCXX()) {
return;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index ae30c03126d768..0edc65162fbe3f 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2754,7 +2754,7 @@ TEST(MatchFinderAPI, MatchesDynamic) {
static std::vector<TestClangConfig> allTestClangConfigs() {
std::vector<TestClangConfig> all_configs;
for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11,
- Lang_CXX14, Lang_CXX17, Lang_CXX20}) {
+ Lang_CXX14, Lang_CXX17, Lang_CXX20, Lang_CXX23}) {
TestClangConfig config;
config.Language = lang;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.h b/clang/unittests/ASTMatchers/ASTMatchersTest.h
index 79c6186054839c..1ed1b5958a8b3a 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.h
@@ -62,22 +62,28 @@ class VerifyMatch : public MatchFinder::MatchCallback {
inline ArrayRef<TestLanguage> langCxx11OrLater() {
static const TestLanguage Result[] = {Lang_CXX11, Lang_CXX14, Lang_CXX17,
- Lang_CXX20};
+ Lang_CXX20, Lang_CXX23};
return ArrayRef<TestLanguage>(Result);
}
inline ArrayRef<TestLanguage> langCxx14OrLater() {
- static const TestLanguage Result[] = {Lang_CXX14, Lang_CXX17, Lang_CXX20};
+ static const TestLanguage Result[] = {Lang_CXX14, Lang_CXX17, Lang_CXX20,
+ Lang_CXX23};
return ArrayRef<TestLanguage>(Result);
}
inline ArrayRef<TestLanguage> langCxx17OrLater() {
- static const TestLanguage Result[] = {Lang_CXX17, Lang_CXX20};
+ static const TestLanguage Result[] = {Lang_CXX17, Lang_CXX20, Lang_CXX23};
return ArrayRef<TestLanguage>(Result);
}
inline ArrayRef<TestLanguage> langCxx20OrLater() {
- static const TestLanguage Result[] = {Lang_CXX20};
+ static const TestLanguage Result[] = {Lang_CXX20, Lang_CXX23};
+ return ArrayRef<TestLanguage>(Result);
+}
+
+inline ArrayRef<TestLanguage> langCxx23OrLater() {
+ static const TestLanguage Result[] = {Lang_CXX23};
return ArrayRef<TestLanguage>(Result);
}
More information about the cfe-commits
mailing list