Skip to content

Commit 7457e2c

Browse files
authored
[clang][ASTMatcher] Add matchers for isExplicitObjectMemberFunction() (llvm#84446)
Note that this patch will be necessary to fix `forEachArgumentWithParam()` and `forEachArgumentWithParamType()` matchers for deducing "this"; which is my true motivation. There the bug is that with explicit obj params, one should not adjust the number of arguments in presence of `CXXMethodDecls`, and this causes a mismatch there mapping the argument to the wrong param. But, I'll come back there once we have this matcher.
1 parent 4d1d127 commit 7457e2c

File tree

10 files changed

+80
-10
lines changed

10 files changed

+80
-10
lines changed

clang/docs/LibASTMatchersReference.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3546,6 +3546,21 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
35463546
</pre></td></tr>
35473547

35483548

3549+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicitObjectMemberFunction0')"><a name="isExplicitObjectMemberFunction0Anchor">isExplicitObjectMemberFunction</a></td><td></td></tr>
3550+
<tr><td colspan="4" class="doc" id="isExplicitObjectMemberFunction0"><pre>Matches if the given method declaration declares a member function with an explicit object parameter.
3551+
3552+
Given
3553+
struct A {
3554+
int operator-(this A, int);
3555+
void fun(this A &&self);
3556+
static int operator()(int);
3557+
int operator+(int);
3558+
};
3559+
3560+
cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two methods but not the last two.
3561+
</pre></td></tr>
3562+
3563+
35493564
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isCopyAssignmentOperator0')"><a name="isCopyAssignmentOperator0Anchor">isCopyAssignmentOperator</a></td><td></td></tr>
35503565
<tr><td colspan="4" class="doc" id="isCopyAssignmentOperator0"><pre>Matches if the given method declaration declares a copy assignment
35513566
operator.

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ AST Matchers
433433
------------
434434

435435
- ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
436+
- Add ``isExplicitObjectMemberFunction``.
436437

437438
clang-format
438439
------------

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6366,6 +6366,25 @@ AST_MATCHER(CXXMethodDecl, isConst) {
63666366
return Node.isConst();
63676367
}
63686368

6369+
/// Matches if the given method declaration declares a member function with an
6370+
/// explicit object parameter.
6371+
///
6372+
/// Given
6373+
/// \code
6374+
/// struct A {
6375+
/// int operator-(this A, int);
6376+
/// void fun(this A &&self);
6377+
/// static int operator()(int);
6378+
/// int operator+(int);
6379+
/// };
6380+
/// \endcode
6381+
///
6382+
/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
6383+
/// methods but not the last two.
6384+
AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
6385+
return Node.isExplicitObjectMemberFunction();
6386+
}
6387+
63696388
/// Matches if the given method declaration declares a copy assignment
63706389
/// operator.
63716390
///

clang/include/clang/Testing/CommandLineArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum TestLanguage {
2828
Lang_CXX14,
2929
Lang_CXX17,
3030
Lang_CXX20,
31+
Lang_CXX23,
3132
Lang_OpenCL,
3233
Lang_OBJC,
3334
Lang_OBJCXX

clang/include/clang/Testing/TestClangConfig.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,30 @@ struct TestClangConfig {
3434
bool isCXX() const {
3535
return Language == Lang_CXX03 || Language == Lang_CXX11 ||
3636
Language == Lang_CXX14 || Language == Lang_CXX17 ||
37-
Language == Lang_CXX20;
37+
Language == Lang_CXX20 || Language == Lang_CXX23;
3838
}
3939

4040
bool isCXX11OrLater() const {
4141
return Language == Lang_CXX11 || Language == Lang_CXX14 ||
42-
Language == Lang_CXX17 || Language == Lang_CXX20;
42+
Language == Lang_CXX17 || Language == Lang_CXX20 ||
43+
Language == Lang_CXX23;
4344
}
4445

4546
bool isCXX14OrLater() const {
4647
return Language == Lang_CXX14 || Language == Lang_CXX17 ||
47-
Language == Lang_CXX20;
48+
Language == Lang_CXX20 || Language == Lang_CXX23;
4849
}
4950

5051
bool isCXX17OrLater() const {
51-
return Language == Lang_CXX17 || Language == Lang_CXX20;
52+
return Language == Lang_CXX17 || Language == Lang_CXX20 ||
53+
Language == Lang_CXX23;
5254
}
5355

54-
bool isCXX20OrLater() const { return Language == Lang_CXX20; }
56+
bool isCXX20OrLater() const {
57+
return Language == Lang_CXX20 || Language == Lang_CXX23;
58+
}
59+
60+
bool isCXX23OrLater() const { return Language == Lang_CXX23; }
5561

5662
bool supportsCXXDynamicExceptionSpecification() const {
5763
return Language == Lang_CXX03 || Language == Lang_CXX11 ||

clang/lib/ASTMatchers/Dynamic/Registry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ RegistryMaps::RegistryMaps() {
432432
REGISTER_MATCHER(isExpansionInMainFile);
433433
REGISTER_MATCHER(isExpansionInSystemHeader);
434434
REGISTER_MATCHER(isExplicit);
435+
REGISTER_MATCHER(isExplicitObjectMemberFunction);
435436
REGISTER_MATCHER(isExplicitTemplateSpecialization);
436437
REGISTER_MATCHER(isExpr);
437438
REGISTER_MATCHER(isExternC);

clang/lib/Testing/CommandLineArgs.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang) {
3737
case Lang_CXX20:
3838
Args = {"-std=c++20", "-frtti"};
3939
break;
40+
case Lang_CXX23:
41+
Args = {"-std=c++23", "-frtti"};
42+
break;
4043
case Lang_OBJC:
4144
Args = {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"};
4245
break;
@@ -73,6 +76,9 @@ std::vector<std::string> getCC1ArgsForTesting(TestLanguage Lang) {
7376
case Lang_CXX20:
7477
Args = {"-std=c++20"};
7578
break;
79+
case Lang_CXX23:
80+
Args = {"-std=c++23"};
81+
break;
7682
case Lang_OBJC:
7783
Args = {"-xobjective-c"};
7884
break;
@@ -96,6 +102,7 @@ StringRef getFilenameForTesting(TestLanguage Lang) {
96102
case Lang_CXX14:
97103
case Lang_CXX17:
98104
case Lang_CXX20:
105+
case Lang_CXX23:
99106
return "input.cc";
100107

101108
case Lang_OpenCL:

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,20 @@ TEST_P(ASTMatchersTest, IsPure) {
21072107
EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
21082108
}
21092109

2110+
TEST_P(ASTMatchersTest, IsExplicitObjectMemberFunction) {
2111+
if (!GetParam().isCXX23OrLater()) {
2112+
return;
2113+
}
2114+
2115+
auto ExpObjParamFn = cxxMethodDecl(isExplicitObjectMemberFunction());
2116+
EXPECT_TRUE(
2117+
notMatches("struct A { static int operator()(int); };", ExpObjParamFn));
2118+
EXPECT_TRUE(notMatches("struct A { int operator+(int); };", ExpObjParamFn));
2119+
EXPECT_TRUE(
2120+
matches("struct A { int operator-(this A, int); };", ExpObjParamFn));
2121+
EXPECT_TRUE(matches("struct A { void fun(this A &&self); };", ExpObjParamFn));
2122+
}
2123+
21102124
TEST_P(ASTMatchersTest, IsCopyAssignmentOperator) {
21112125
if (!GetParam().isCXX()) {
21122126
return;

clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2754,7 +2754,7 @@ TEST(MatchFinderAPI, MatchesDynamic) {
27542754
static std::vector<TestClangConfig> allTestClangConfigs() {
27552755
std::vector<TestClangConfig> all_configs;
27562756
for (TestLanguage lang : {Lang_C89, Lang_C99, Lang_CXX03, Lang_CXX11,
2757-
Lang_CXX14, Lang_CXX17, Lang_CXX20}) {
2757+
Lang_CXX14, Lang_CXX17, Lang_CXX20, Lang_CXX23}) {
27582758
TestClangConfig config;
27592759
config.Language = lang;
27602760

clang/unittests/ASTMatchers/ASTMatchersTest.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,28 @@ class VerifyMatch : public MatchFinder::MatchCallback {
6262

6363
inline ArrayRef<TestLanguage> langCxx11OrLater() {
6464
static const TestLanguage Result[] = {Lang_CXX11, Lang_CXX14, Lang_CXX17,
65-
Lang_CXX20};
65+
Lang_CXX20, Lang_CXX23};
6666
return ArrayRef<TestLanguage>(Result);
6767
}
6868

6969
inline ArrayRef<TestLanguage> langCxx14OrLater() {
70-
static const TestLanguage Result[] = {Lang_CXX14, Lang_CXX17, Lang_CXX20};
70+
static const TestLanguage Result[] = {Lang_CXX14, Lang_CXX17, Lang_CXX20,
71+
Lang_CXX23};
7172
return ArrayRef<TestLanguage>(Result);
7273
}
7374

7475
inline ArrayRef<TestLanguage> langCxx17OrLater() {
75-
static const TestLanguage Result[] = {Lang_CXX17, Lang_CXX20};
76+
static const TestLanguage Result[] = {Lang_CXX17, Lang_CXX20, Lang_CXX23};
7677
return ArrayRef<TestLanguage>(Result);
7778
}
7879

7980
inline ArrayRef<TestLanguage> langCxx20OrLater() {
80-
static const TestLanguage Result[] = {Lang_CXX20};
81+
static const TestLanguage Result[] = {Lang_CXX20, Lang_CXX23};
82+
return ArrayRef<TestLanguage>(Result);
83+
}
84+
85+
inline ArrayRef<TestLanguage> langCxx23OrLater() {
86+
static const TestLanguage Result[] = {Lang_CXX23};
8187
return ArrayRef<TestLanguage>(Result);
8288
}
8389

0 commit comments

Comments
 (0)