From ba02bc5226546d4883ae43d96a593313742302e5 Mon Sep 17 00:00:00 2001 From: George Karpenkov Date: Fri, 6 Jul 2018 21:36:04 +0000 Subject: [PATCH] [ASTMatchers] A matcher for Objective-C @autoreleasepool Differential Revision: https://reviews.llvm.org/D48910 llvm-svn: 336468 --- clang/docs/LibASTMatchersReference.html | 74 +++++++++++++++++++--- clang/include/clang/ASTMatchers/ASTMatchers.h | 13 ++++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 2 + clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + .../unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 12 ++++ 5 files changed, 94 insertions(+), 8 deletions(-) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 6c67fd5..3f0ded2 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -662,6 +662,18 @@ Example matches __atomic_load_n(ptr, 1) +Matcher<Stmt>autoreleasePoolStmtMatcher<ObjCAutoreleasePoolStmt>... +
Matches an Objective-C autorelease pool statement.
+
+Given
+  @autoreleasepool {
+    int x = 0;
+  }
+autoreleasePoolStmt(stmt()) matches the declaration of "x"
+inside the autorelease pool.
+
+ + Matcher<Stmt>binaryConditionalOperatorMatcher<BinaryConditionalOperator>...
Matches binary conditional operator expressions (GNU extension).
 
@@ -5222,8 +5234,8 @@ actual casts "explicit" casts.)
 
-Matcher<Expr>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<Expr>hasTypeMatcher<Decl> InnerMatcher
+
Overloaded to match the declaration of the expression's or value
 declaration's type.
 
 In case of a value declaration (for example a variable declaration),
@@ -5234,8 +5246,10 @@ declaration of x.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
+ class Y { friend class X; };
 
 Usable as: Matcher<Expr>, Matcher<ValueDecl>
 
@@ -5248,9 +5262,11 @@ matcher. Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) and U (matcher = typedefDecl(hasType(asString("int"))) + and friend class X (matcher = friendDecl(hasType("X")) class X {}; void y(X &x) { x; X z; } typedef int U; + class Y { friend class X; };
@@ -5396,6 +5412,42 @@ matches 'int x = 0' in +Matcher<FriendDecl>hasTypeMatcher<Decl> InnerMatcher +
Overloaded to match the declaration of the expression's or value
+declaration's type.
+
+In case of a value declaration (for example a variable declaration),
+this resolves one layer of indirection. For example, in the value
+declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
+X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
+declaration of x.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
+ class X {};
+ void y(X &x) { x; X z; }
+ class Y { friend class X; };
+
+Usable as: Matcher<Expr>, Matcher<ValueDecl>
+
+ + +Matcher<FriendDecl>hasTypeMatcher<QualType> InnerMatcher +
Matches if the expression's or declaration's type matches a type
+matcher.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
+ class X {};
+ void y(X &x) { x; X z; }
+ typedef int U;
+ class Y { friend class X; };
+
+ + Matcher<FunctionDecl>hasAnyParameterMatcher<ParmVarDecl> InnerMatcher
Matches any parameter of a function or an ObjC method declaration or a
 block.
@@ -6432,16 +6484,18 @@ Usable as: Any Matcher
 
-Matcher<TypedefNameDecl>hasTypeMatcher<QualType> InnerMatcher -
Matches if the expression's or declaration's type matches a type
+Matcher<TypedefNameDecl>hasTypeMatcher<QualType> InnerMatcher
+
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
             and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
  typedef int U;
+ class Y { friend class X; };
 
@@ -6564,8 +6618,8 @@ usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) matches using X::b but not using X::a
-Matcher<ValueDecl>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<ValueDecl>hasTypeMatcher<Decl> InnerMatcher
+
Overloaded to match the declaration of the expression's or value
 declaration's type.
 
 In case of a value declaration (for example a variable declaration),
@@ -6576,23 +6630,27 @@ declaration of x.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
+ class Y { friend class X; };
 
 Usable as: Matcher<Expr>, Matcher<ValueDecl>
 
-Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher -
Matches if the expression's or declaration's type matches a type
+Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher
+
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
             and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
  typedef int U;
+ class Y { friend class X; };
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 87a9710..1c8d1da 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -966,6 +966,19 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue, return Node.getAsIntegral().toString(10) == Value; } +/// Matches an Objective-C autorelease pool statement. +/// +/// Given +/// \code +/// @autoreleasepool { +/// int x = 0; +/// } +/// \endcode +/// autoreleasePoolStmt(stmt()) matches the declaration of "x" +/// inside the autorelease pool. +extern const internal::VariadicDynCastAllOfMatcher autoreleasePoolStmt; + /// Matches any value declaration. /// /// Example matches A, B, C and F diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 92b680f..d8af47d 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -548,6 +548,8 @@ bool HasNameMatcher::matchesNode(const NamedDecl &Node) const { } // end namespace internal +const internal::VariadicDynCastAllOfMatcher + autoreleasePoolStmt; const internal::VariadicDynCastAllOfMatcher translationUnitDecl; const internal::VariadicDynCastAllOfMatcher typedefDecl; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 84e6e45..384dd8d 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -134,6 +134,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(atomicExpr); REGISTER_MATCHER(atomicType); REGISTER_MATCHER(autoType); + REGISTER_MATCHER(autoreleasePoolStmt) REGISTER_MATCHER(binaryOperator); REGISTER_MATCHER(binaryConditionalOperator); REGISTER_MATCHER(blockDecl); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index 8947ccd..fc1a57c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1687,5 +1687,17 @@ TEST(ObjCStmtMatcher, ExceptionStmts) { objcFinallyStmt())); } +TEST(ObjCAutoreleaseMatcher, AutoreleasePool) { + std::string ObjCString = + "void f() {" + "@autoreleasepool {" + " int x = 1;" + "}" + "}"; + EXPECT_TRUE(matchesObjC(ObjCString, autoreleasePoolStmt())); + std::string ObjCStringNoPool = "void f() { int x = 1; }"; + EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt())); +} + } // namespace ast_matchers } // namespace clang -- 2.7.4