[ASTMatchers] Introduce a matcher for ObjCIvarExpr, support getting it's declaration.

ObjCIvarExpr is *not* a subclass of MemberExpr, and a separate matcher
is required to support it.
Adding a hasDeclaration support as well, as it's not very useful without
it.

Differential Revision: https://reviews.llvm.org/D49701

llvm-svn: 338137
This commit is contained in:
George Karpenkov
2018-07-27 17:26:11 +00:00
parent faea2d3130
commit 079275b4dc
6 changed files with 66 additions and 1 deletions

View File

@@ -1267,6 +1267,20 @@ Example matches @finally
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('objcIvarRefExpr0')"><a name="objcIvarRefExpr0Anchor">objcIvarRefExpr</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCIvarRefExpr.html">ObjCIvarRefExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcIvarRefExpr0"><pre>Matches a reference to an ObjCIvar.
Example: matches "a" in "init" method:
@implementation A {
NSString *a;
}
- (void) init {
a = @"hello";
}
}
</pre></td></tr>
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('objcMessageExpr0')"><a name="objcMessageExpr0Anchor">objcMessageExpr</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="objcMessageExpr0"><pre>Matches ObjectiveC Message invocation expressions.
@@ -4251,6 +4265,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -4547,6 +4562,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -4750,6 +4766,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -4900,6 +4917,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -5061,6 +5079,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -5247,6 +5266,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -5667,6 +5687,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -5700,6 +5721,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -5733,6 +5755,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6093,6 +6116,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6174,6 +6198,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6326,6 +6351,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6448,6 +6474,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6501,6 +6528,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6565,6 +6593,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given
@@ -6629,6 +6658,7 @@ The associated declaration is:
- for MemberExpr, the declaration of the referenced member
- for CXXConstructExpr, the declaration of the constructor
- for CXXNewExpr, the declaration of the operator new
- for ObjCIvarExpr, the declaration of the ivar
For type nodes, hasDeclaration will generally match the declaration of the
sugared type. Given

View File

@@ -1644,6 +1644,21 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
declRefExpr;
/// Matches a reference to an ObjCIvar.
///
/// Example: matches "a" in "init" method:
/// \code
/// @implementation A {
/// NSString *a;
/// }
/// - (void) init {
/// a = @"hello";
/// }
//}
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
objcIvarRefExpr;
/// Matches if statements.
///
/// Example matches 'if (x) {}'
@@ -2655,6 +2670,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
/// - for MemberExpr, the declaration of the referenced member
/// - for CXXConstructExpr, the declaration of the constructor
/// - for CXXNewExpr, the declaration of the operator new
/// - for ObjCIvarExpr, the declaration of the ivar
///
/// For type nodes, hasDeclaration will generally match the declaration of the
/// sugared type. Given

View File

@@ -42,6 +42,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateName.h"
@@ -865,6 +866,12 @@ private:
return matchesDecl(Node.getConstructor(), Finder, Builder);
}
bool matchesSpecialized(const ObjCIvarRefExpr &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return matchesDecl(Node.getDecl(), Finder, Builder);
}
/// Extracts the operator new of the new call and returns whether the
/// inner matcher matches on it.
bool matchesSpecialized(const CXXNewExpr &Node,
@@ -1110,7 +1117,7 @@ using HasDeclarationSupportedTypes =
ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
MemberExpr, QualType, RecordType, TagType,
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType>;
UnresolvedUsingType, ObjCIvarRefExpr>;
/// Converts a \c Matcher<T> to a matcher of desired type \c To by
/// "adapting" a \c To into a \c T.

View File

@@ -679,6 +679,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
cxxOperatorCallExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>

View File

@@ -410,6 +410,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(objcImplementationDecl);
REGISTER_MATCHER(objcInterfaceDecl);
REGISTER_MATCHER(objcIvarDecl);
REGISTER_MATCHER(objcIvarRefExpr);
REGISTER_MATCHER(objcMessageExpr);
REGISTER_MATCHER(objcMethodDecl);
REGISTER_MATCHER(objcObjectPointerType);

View File

@@ -1354,6 +1354,16 @@ TEST(Matcher, HandlesNullQualTypes) {
))))));
}
TEST(ObjCIvarRefExprMatcher, IvarExpr) {
std::string ObjCString =
"@interface A @end "
"@implementation A { A *x; } - (void) func { x = 0; } @end";
EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr()));
EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr(
hasDeclaration(namedDecl(hasName("x"))))));
EXPECT_FALSE(matchesObjC(ObjCString, objcIvarRefExpr(
hasDeclaration(namedDecl(hasName("y"))))));
}
TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
EXPECT_TRUE(matches("void f() { }",