This revision was automatically updated to reflect the committed changes.
Closed by commit rGb17baa1db613: [ASTMatchers] Adding a new matcher for callee
declarations of Obj-C (authored by ziqingluo-90).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D129398/new/
https://reviews.llvm.org/D129398
Files:
clang/docs/LibASTMatchersReference.html
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
Index: clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -198,13 +198,32 @@
constructMatcher("hasName", StringRef("x")))))
.getTypedMatcher<Stmt>();
+ Matcher<Stmt> ObjCMsgExpr =
+ constructMatcher(
+ "objcMessageExpr",
+ constructMatcher(
+ "callee",
+ constructMatcher("objcMethodDecl",
+ constructMatcher("hasName", StringRef("x")))))
+ .getTypedMatcher<Stmt>();
+
std::string Code = "class Y { public: void x(); }; void z() { Y y; y.x(); }";
EXPECT_FALSE(matches(Code, CallExpr0));
EXPECT_TRUE(matches(Code, CallExpr1));
+ EXPECT_FALSE(matches(Code, ObjCMsgExpr));
Code = "class Z { public: void z() { this->z(); } };";
EXPECT_TRUE(matches(Code, CallExpr0));
EXPECT_FALSE(matches(Code, CallExpr1));
+ EXPECT_FALSE(matches(Code, ObjCMsgExpr));
+
+ Code = "@interface I "
+ "+ (void)x; "
+ "@end\n"
+ "int main() { [I x]; }";
+ EXPECT_FALSE(matchesObjC(Code, CallExpr0));
+ EXPECT_FALSE(matchesObjC(Code, CallExpr1));
+ EXPECT_TRUE(matchesObjC(Code, ObjCMsgExpr));
Matcher<Decl> DeclDecl = declaratorDecl(hasTypeLoc(
constructMatcher(
Index: clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2307,6 +2307,45 @@
hasName("cc"), hasInitializer(integerLiteral(equals(1))))))))));
}
+TEST(ASTMatchersTestObjC, ObjCMessageCalees) {
+ StatementMatcher MessagingFoo =
+ objcMessageExpr(callee(objcMethodDecl(hasName("foo"))));
+
+ EXPECT_TRUE(matchesObjC("@interface I"
+ "+ (void)foo;"
+ "@end\n"
+ "int main() {"
+ " [I foo];"
+ "}",
+ MessagingFoo));
+ EXPECT_TRUE(notMatchesObjC("@interface I"
+ "+ (void)foo;"
+ "+ (void)bar;"
+ "@end\n"
+ "int main() {"
+ " [I bar];"
+ "}",
+ MessagingFoo));
+ EXPECT_TRUE(matchesObjC("@interface I"
+ "- (void)foo;"
+ "- (void)bar;"
+ "@end\n"
+ "int main() {"
+ " I *i;"
+ " [i foo];"
+ "}",
+ MessagingFoo));
+ EXPECT_TRUE(notMatchesObjC("@interface I"
+ "- (void)foo;"
+ "- (void)bar;"
+ "@end\n"
+ "int main() {"
+ " I *i;"
+ " [i bar];"
+ "}",
+ MessagingFoo));
+}
+
TEST(ASTMatchersTestObjC, ObjCMessageExpr) {
// Don't find ObjCMessageExpr where none are present.
EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -3838,8 +3838,9 @@
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
-/// Matches if the call expression's callee's declaration matches the
-/// given matcher.
+/// Matches 1) if the call expression's callee's declaration matches the
+/// given matcher; or 2) if the Obj-C message expression's callee's method
+/// declaration matches the given matcher.
///
/// Example matches y.x() (matcher = callExpr(callee(
/// cxxMethodDecl(hasName("x")))))
@@ -3847,9 +3848,31 @@
/// class Y { public: void x(); };
/// void z() { Y y; y.x(); }
/// \endcode
-AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
- 1) {
- return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
+///
+/// Example 2. Matches [I foo] with
+/// objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+///
+/// \code
+/// @interface I: NSObject
+/// +(void)foo;
+/// @end
+/// ...
+/// [I foo]
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
+ callee, AST_POLYMORPHIC_SUPPORTED_TYPES(ObjCMessageExpr, CallExpr),
+ internal::Matcher<Decl>, InnerMatcher, 1) {
+ if (const auto *CallNode = dyn_cast<CallExpr>(&Node))
+ return callExpr(hasDeclaration(InnerMatcher))
+ .matches(Node, Finder, Builder);
+ else {
+ // The dynamic cast below is guaranteed to succeed as there are only 2
+ // supported return types.
+ const auto *MsgNode = cast<ObjCMessageExpr>(&Node);
+ const Decl *DeclNode = MsgNode->getMethodDecl();
+ return (DeclNode != nullptr &&
+ InnerMatcher.matches(*DeclNode, Finder, Builder));
+ }
}
/// Matches if the expression's or declaration's type matches a type
Index: clang/docs/LibASTMatchersReference.html
===================================================================
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -7255,14 +7255,24 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('callee1')"><a name="callee1Anchor">callee</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="callee1"><pre>Matches if the call expression's callee's declaration matches the
-given matcher.
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('callee2')"><a name="callee2Anchor">callee</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="callee2"><pre>Matches 1) if the call expression's callee's declaration matches the
+given matcher; or 2) if the Obj-C message expression's callee's method
+declaration matches the given matcher.
Example matches y.x() (matcher = callExpr(callee(
cxxMethodDecl(hasName("x")))))
class Y { public: void x(); };
void z() { Y y; y.x(); }
+
+Example 2. Matches [I foo] with
+objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+
+ @interface I: NSObject
+ +(void)foo;
+ @end
+ ...
+ [I foo]
</pre></td></tr>
@@ -8814,6 +8824,27 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('callee1')"><a name="callee1Anchor">callee</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="callee1"><pre>Matches 1) if the call expression's callee's declaration matches the
+given matcher; or 2) if the Obj-C message expression's callee's method
+declaration matches the given matcher.
+
+Example matches y.x() (matcher = callExpr(callee(
+ cxxMethodDecl(hasName("x")))))
+ class Y { public: void x(); };
+ void z() { Y y; y.x(); }
+
+Example 2. Matches [I foo] with
+objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+
+ @interface I: NSObject
+ +(void)foo;
+ @end
+ ...
+ [I foo]
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument3')"><a name="hasAnyArgument3Anchor">hasAnyArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasAnyArgument3"><pre>Matches any argument of a call expression or a constructor call
expression, or an ObjC-message-send expression.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits