Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -1267,6 +1267,20 @@ +Matcher<Stmt>objcIvarRefExprMatcher<ObjCIvarRefExpr>... +
Matches a reference to an ObjCIvar.
+
+Example: matches "a" in "init" method:
+@implementation A {
+  NSString *a;
+}
+- (void) init {
+  a = @"hello";
+}
+}
+
+ + Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>...
Matches ObjectiveC Message invocation expressions.
 
@@ -3275,9 +3289,9 @@
 matcher = objcMessagaeExpr(isInstanceMessage())
 matches
   NSString *x = @"hello";
-  [x containsString:@"h"]
+  [x containsString:@"h"];
 but not
-  [NSString stringWithFormat:@"format"]
+  [NSString stringWithFormat:@"format"];
 
@@ -5894,7 +5908,7 @@ For example the method call in NSString *x = @"hello"; - [x containsString:@"h"] + [x containsString:@"h"]; is matched by objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x")))))) @@ -6564,7 +6578,7 @@ For example, in: class A {}; using B = A; -The matcher type(hasUnqualifeidDesugaredType(recordType())) matches +The matcher type(hasUnqualifiedDesugaredType(recordType())) matches both B and A. Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1638,6 +1638,21 @@ extern const internal::VariadicDynCastAllOfMatcher 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 + objcIvarRefExpr; + /// Matches if statements. /// /// Example matches 'if (x) {}' Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -41,6 +41,7 @@ #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" @@ -865,6 +866,12 @@ 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 @@ ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr, QualType, RecordType, TagType, TemplateSpecializationType, TemplateTypeParmType, TypedefType, - UnresolvedUsingType>; + UnresolvedUsingType, ObjCIvarRefExpr>; /// Converts a \c Matcher to a matcher of desired type \c To by /// "adapting" a \c To into a \c T. Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp =================================================================== --- clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -679,6 +679,7 @@ cxxOperatorCallExpr; const internal::VariadicDynCastAllOfMatcher expr; const internal::VariadicDynCastAllOfMatcher declRefExpr; +const internal::VariadicDynCastAllOfMatcher objcIvarRefExpr; const internal::VariadicDynCastAllOfMatcher ifStmt; const internal::VariadicDynCastAllOfMatcher forStmt; const internal::VariadicDynCastAllOfMatcher Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -408,6 +408,7 @@ REGISTER_MATCHER(objcImplementationDecl); REGISTER_MATCHER(objcInterfaceDecl); REGISTER_MATCHER(objcIvarDecl); + REGISTER_MATCHER(objcIvarRefExpr); REGISTER_MATCHER(objcMessageExpr); REGISTER_MATCHER(objcMethodDecl); REGISTER_MATCHER(objcObjectPointerType); Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1354,6 +1354,16 @@ )))))); } +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() { }",