-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[ASTMatchers] Fix matching CXXOperatorCallExpr
of ->
#139994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Eric Li (tJener) ChangesThe Instead of trying to determine the equivalent unary or binary operator and then deriving the opcode string, we consult For Full diff: https://github.com/llvm/llvm-project/pull/139994.diff 2 Files Affected:
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 71dfc49b7fcca..4a27a5d099e60 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -2161,8 +2161,10 @@ inline const Expr *getSubExpr(const NodeType &Node) {
template <>
inline const Expr *
getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
- if (!internal::equivalentUnaryOperator(Node))
+ if (!internal::equivalentUnaryOperator(Node) &&
+ Node.getOperator() != OO_Arrow) {
return nullptr;
+ }
return Node.getArg(0);
}
@@ -2223,14 +2225,9 @@ inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
return Node.getOpcodeStr();
}
inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
- auto optBinaryOpcode = equivalentBinaryOperator(Node);
- if (!optBinaryOpcode) {
- auto optUnaryOpcode = equivalentUnaryOperator(Node);
- if (!optUnaryOpcode)
- return std::nullopt;
- return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
- }
- return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
+ if (const char *Str = getOperatorSpelling(Node.getOperator()))
+ return Str;
+ return std::nullopt;
}
inline StringRef getOpName(const CXXFoldExpr &Node) {
return BinaryOperator::getOpcodeStr(Node.getOperator());
@@ -2271,14 +2268,9 @@ class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
return Node.getOpcodeStr();
}
static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
- auto optBinaryOpcode = equivalentBinaryOperator(Node);
- if (!optBinaryOpcode) {
- auto optUnaryOpcode = equivalentUnaryOperator(Node);
- if (!optUnaryOpcode)
- return std::nullopt;
- return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
- }
- return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
+ if (const char *Str = getOperatorSpelling(Node.getOperator()))
+ return Str;
+ return std::nullopt;
}
std::vector<std::string> Names;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 8759811092b6f..8ddae4e47004b 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -2025,14 +2025,24 @@ void plusIntOperator()
hasOperatorName("+"), hasUnaryOperand(expr())))));
Code = R"cpp(
-struct HasOpArrow
+struct S {
+ void foo(int);
+};
+struct HasOpStar
{
int& operator*();
};
-void foo()
+struct HasOpArrow
{
- HasOpArrow s1;
- *s1;
+ S* operator->();
+};
+void hasOpStarMem(HasOpStar s)
+{
+ *s;
+}
+void hasOpArrowMem(HasOpArrow a)
+{
+ a->foo(42);
}
)cpp";
@@ -2040,6 +2050,11 @@ void foo()
matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
cxxOperatorCallExpr(hasOperatorName("*"),
hasUnaryOperand(expr())))));
+ EXPECT_TRUE(matches(
+ Code, traverse(TK_IgnoreUnlessSpelledInSource,
+ cxxOperatorCallExpr(hasOperatorName("->"),
+ hasUnaryOperand(declRefExpr(
+ to(varDecl(hasName("a")))))))));
}
TEST(Matcher, UnaryOperatorTypes) {
|
The `->` operator does not have a corresponding `UnaryOperatorKind`, and so was unsupported by the `hasOperatorName` and `hasUnaryOperand` matchers. Instead of trying to determine the equivalent unary or binary operator and then deriving the opcode string, we consult `OperatorKinds.def` directly (through `getOperatorSpelling`). For `hasUnaryOperand` support, we special case the arrow operator specifically.
c081799
to
fdaba64
Compare
->
CXXOperatorCallExpr
of ->
The
->
operator does not have a correspondingUnaryOperatorKind
, and so was unsupported by thehasOperatorName
andhasUnaryOperand
matchers.Instead of trying to determine the equivalent unary or binary operator and then deriving the opcode string, we consult
OperatorKinds.def
directly (throughgetOperatorSpelling
).For
hasUnaryOperand
support, we special case the arrow operator specifically.