diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-07-06 21:36:04 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-07-06 21:36:04 +0000 |
commit | ba02bc5226546d4883ae43d96a593313742302e5 (patch) | |
tree | 3e641fadb31a452514f9cafc5823640cfff15c4d | |
parent | f5d8b841cef28e1d21bcf6f2757143b94875981b (diff) | |
download | bcm5719-llvm-ba02bc5226546d4883ae43d96a593313742302e5.tar.gz bcm5719-llvm-ba02bc5226546d4883ae43d96a593313742302e5.zip |
[ASTMatchers] A matcher for Objective-C @autoreleasepool
Differential Revision: https://reviews.llvm.org/D48910
llvm-svn: 336468
-rw-r--r-- | clang/docs/LibASTMatchersReference.html | 74 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 13 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 2 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
-rw-r--r-- | clang/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 6c67fd5b60e..3f0ded22709 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -662,6 +662,18 @@ Example matches __atomic_load_n(ptr, 1) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('autoreleasePoolStmt0')"><a name="autoreleasePoolStmt0Anchor">autoreleasePoolStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCAutoreleasePoolStmt.html">ObjCAutoreleasePoolStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="autoreleasePoolStmt0"><pre>Matches an Objective-C autorelease pool statement. + +Given + @autoreleasepool { + int x = 0; + } +autoreleasePoolStmt(stmt()) matches the declaration of "x" +inside the autorelease pool. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('binaryConditionalOperator0')"><a name="binaryConditionalOperator0Anchor">binaryConditionalOperator</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryConditionalOperator.html">BinaryConditionalOperator</a>>...</td></tr> <tr><td colspan="4" class="doc" id="binaryConditionalOperator0"><pre>Matches binary conditional operator expressions (GNU extension). @@ -5222,8 +5234,8 @@ actual casts "explicit" casts.) </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('hasType4')"><a name="hasType4Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType4"><pre>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<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> </pre></td></tr> @@ -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; }; </pre></td></tr> @@ -5396,6 +5412,42 @@ matches 'int x = 0' in </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FriendDecl.html">FriendDecl</a>></td><td class="name" onclick="toggle('hasType5')"><a name="hasType5Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType5"><pre>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<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FriendDecl.html">FriendDecl</a>></td><td class="name" onclick="toggle('hasType1')"><a name="hasType1Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType1"><pre>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; }; +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyParameter0')"><a name="hasAnyParameter0Anchor">hasAnyParameter</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function or an ObjC method declaration or a block. @@ -6432,16 +6484,18 @@ Usable as: Any Matcher </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>></td><td class="name" onclick="toggle('hasType1')"><a name="hasType1Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasType1"><pre>Matches if the expression's or declaration's type matches a type +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>></td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType2"><pre>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; }; </pre></td></tr> @@ -6564,8 +6618,8 @@ usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) matches using X::b but not using X::a </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType4')"><a name="hasType4Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasType4"><pre>Overloaded to match the declaration of the expression's or value +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType6')"><a name="hasType6Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType6"><pre>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<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasType2"><pre>Matches if the expression's or declaration's type matches a type +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType3"><pre>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; }; </pre></td></tr> diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 87a971082b3..1c8d1da37f0 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<Stmt, + ObjCAutoreleasePoolStmt> 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 92b680fd179..d8af47d7505 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<Stmt, ObjCAutoreleasePoolStmt> + autoreleasePoolStmt; const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl> translationUnitDecl; const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 84e6e450f2a..384dd8d4e34 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 8947ccde7a4..fc1a57c4885 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 |