forked from OSchip/llvm-project
[ASTMatchers] Let isArrow also support UnresolvedMemberExpr, CXXDependentScopeMemberExpr
Reviewers: aaron.ballman Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D52157 llvm-svn: 342407
This commit is contained in:
parent
534c87df82
commit
e0248aecbe
|
@ -2235,6 +2235,32 @@ cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html">CXXDependentScopeMemberExpr</a>></td><td class="name" onclick="toggle('isArrow2')"><a name="isArrow2Anchor">isArrow</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isArrow2"><pre>Matches member expressions that are called with '->' as opposed
|
||||
to '.'.
|
||||
|
||||
Member calls on the implicit this pointer match as called with '->'.
|
||||
|
||||
Given
|
||||
class Y {
|
||||
void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
|
||||
template <class T> void f() { this->f<T>(); f<T>(); }
|
||||
int a;
|
||||
static int b;
|
||||
};
|
||||
template <class T>
|
||||
class Z {
|
||||
void x() { this->m; }
|
||||
};
|
||||
memberExpr(isArrow())
|
||||
matches this->x, x, y.x, a, this->b
|
||||
cxxDependentScopeMemberExpr(isArrow())
|
||||
matches this->m
|
||||
unresolvedMemberExpr(isArrow())
|
||||
matches this->f<T>, f<T>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isConst0')"><a name="isConst0Anchor">isConst</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isConst0"><pre>Matches if the given method declaration is const.
|
||||
|
||||
|
@ -3228,11 +3254,20 @@ Member calls on the implicit this pointer match as called with '->'.
|
|||
Given
|
||||
class Y {
|
||||
void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
|
||||
template <class T> void f() { this->f<T>(); f<T>(); }
|
||||
int a;
|
||||
static int b;
|
||||
};
|
||||
template <class T>
|
||||
class Z {
|
||||
void x() { this->m; }
|
||||
};
|
||||
memberExpr(isArrow())
|
||||
matches this->x, x, y.x, a, this->b
|
||||
cxxDependentScopeMemberExpr(isArrow())
|
||||
matches this->m
|
||||
unresolvedMemberExpr(isArrow())
|
||||
matches this->f<T>, f<T>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
|
@ -3886,6 +3921,32 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html">UnresolvedMemberExpr</a>></td><td class="name" onclick="toggle('isArrow1')"><a name="isArrow1Anchor">isArrow</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isArrow1"><pre>Matches member expressions that are called with '->' as opposed
|
||||
to '.'.
|
||||
|
||||
Member calls on the implicit this pointer match as called with '->'.
|
||||
|
||||
Given
|
||||
class Y {
|
||||
void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
|
||||
template <class T> void f() { this->f<T>(); f<T>(); }
|
||||
int a;
|
||||
static int b;
|
||||
};
|
||||
template <class T>
|
||||
class Z {
|
||||
void x() { this->m; }
|
||||
};
|
||||
memberExpr(isArrow())
|
||||
matches this->x, x, y.x, a, this->b
|
||||
cxxDependentScopeMemberExpr(isArrow())
|
||||
matches this->m
|
||||
unresolvedMemberExpr(isArrow())
|
||||
matches this->f<T>, f<T>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasAutomaticStorageDuration0')"><a name="hasAutomaticStorageDuration0Anchor">hasAutomaticStorageDuration</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAutomaticStorageDuration0"><pre>Matches a variable declaration that has automatic storage duration.
|
||||
|
||||
|
|
|
@ -4697,13 +4697,24 @@ AST_MATCHER(CXXMethodDecl, isUserProvided) {
|
|||
/// \code
|
||||
/// class Y {
|
||||
/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
|
||||
/// template <class T> void f() { this->f<T>(); f<T>(); }
|
||||
/// int a;
|
||||
/// static int b;
|
||||
/// };
|
||||
/// template <class T>
|
||||
/// class Z {
|
||||
/// void x() { this->m; }
|
||||
/// };
|
||||
/// \endcode
|
||||
/// memberExpr(isArrow())
|
||||
/// matches this->x, x, y.x, a, this->b
|
||||
AST_MATCHER(MemberExpr, isArrow) {
|
||||
/// cxxDependentScopeMemberExpr(isArrow())
|
||||
/// matches this->m
|
||||
/// unresolvedMemberExpr(isArrow())
|
||||
/// matches this->f<T>, f<T>
|
||||
AST_POLYMORPHIC_MATCHER(
|
||||
isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
|
||||
CXXDependentScopeMemberExpr)) {
|
||||
return Node.isArrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -765,6 +765,11 @@ TEST(IsArrow, MatchesMemberVariablesViaArrow) {
|
|||
memberExpr(isArrow())));
|
||||
EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
|
||||
memberExpr(isArrow())));
|
||||
EXPECT_TRUE(matches("template <class T> class Y { void x() { this->m; } };",
|
||||
cxxDependentScopeMemberExpr(isArrow())));
|
||||
EXPECT_TRUE(
|
||||
notMatches("template <class T> class Y { void x() { (*this).m; } };",
|
||||
cxxDependentScopeMemberExpr(isArrow())));
|
||||
}
|
||||
|
||||
TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
|
||||
|
@ -783,6 +788,14 @@ TEST(IsArrow, MatchesMemberCallsViaArrow) {
|
|||
memberExpr(isArrow())));
|
||||
EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
|
||||
memberExpr(isArrow())));
|
||||
EXPECT_TRUE(
|
||||
matches("class Y { template <class T> void x() { this->x<T>(); } };",
|
||||
unresolvedMemberExpr(isArrow())));
|
||||
EXPECT_TRUE(matches("class Y { template <class T> void x() { x<T>(); } };",
|
||||
unresolvedMemberExpr(isArrow())));
|
||||
EXPECT_TRUE(
|
||||
notMatches("class Y { template <class T> void x() { (*this).x<T>(); } };",
|
||||
unresolvedMemberExpr(isArrow())));
|
||||
}
|
||||
|
||||
TEST(ConversionDeclaration, IsExplicit) {
|
||||
|
|
|
@ -27,7 +27,7 @@ TEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
|
|||
nullptr));
|
||||
|
||||
// Do not accept non-toplevel matchers.
|
||||
EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
|
||||
EXPECT_FALSE(Finder.addDynamicMatcher(isMain(), nullptr));
|
||||
EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
|
||||
}
|
||||
|
||||
|
|
|
@ -440,7 +440,8 @@ TEST_F(RegistryTest, Errors) {
|
|||
Error.get()).isNull());
|
||||
EXPECT_EQ("Incorrect type for arg 1. "
|
||||
"(Expected = Matcher<CXXRecordDecl>) != "
|
||||
"(Actual = Matcher<CXXRecordDecl>&Matcher<MemberExpr>)",
|
||||
"(Actual = Matcher<CXXRecordDecl>&Matcher"
|
||||
"<MemberExpr|UnresolvedMemberExpr|CXXDependentScopeMemberExpr>)",
|
||||
Error->toString());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue