air20 updated this revision to Diff 236510. air20 added a comment. Fixed Registry.cpp and documentation as per comments.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72233/new/ https://reviews.llvm.org/D72233 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -278,8 +278,8 @@ REGISTER_MATCHER(hasIncrement); REGISTER_MATCHER(hasIndex); REGISTER_MATCHER(hasInit); - REGISTER_MATCHER(hasInitializer); REGISTER_MATCHER(hasInitStatement); + REGISTER_MATCHER(hasInitializer); REGISTER_MATCHER(hasKeywordSelector); REGISTER_MATCHER(hasLHS); REGISTER_MATCHER(hasLocalQualifiers); @@ -455,6 +455,7 @@ REGISTER_MATCHER(on); REGISTER_MATCHER(onImplicitObjectArgument); REGISTER_MATCHER(opaqueValueExpr); + REGISTER_MATCHER(optionally); REGISTER_MATCHER(parameterCountIs); REGISTER_MATCHER(parenExpr); REGISTER_MATCHER(parenListExpr); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2532,7 +2532,27 @@ /// Matches any node regardless of the submatchers. /// /// However, \c optionally will generate a result binding for each matching -/// submatchers. +/// submatcher. +/// +/// Useful when additional information which may or may not present about a +/// main matching node is desired. +/// +/// For example, in: +/// \code +/// class Foo { +/// int bar; +/// } +/// \endcode +/// The matcher: +/// \code +/// cxxRecordDecl( +/// optionally(has( +/// fieldDecl(hasName("bar")).bind("var") +/// ))).bind("record") +/// \endcode +/// will produce a result binding for both "record" and "var". +/// The matcher will produce a "record" binding for even if there is no data +/// member named "bar" in that class. /// /// Usable as: Any Matcher extern const internal::VariadicOperatorMatcherFunc< Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -4689,6 +4689,32 @@ </pre></td></tr> +<tr><td>Matcher<*></td><td class="name" onclick="toggle('optionally0')"><a name="optionally0Anchor">optionally</a></td><td>Matcher<*>, ..., Matcher<*></td></tr> +<tr><td colspan="4" class="doc" id="optionally0"><pre>Matches any node regardless of the submatchers. + +However, optionally will generate a result binding for each matching +submatcher. + +Useful when additional information which may or may not present about a +main matching node is desired. + +For example, in: + class Foo { + int bar; + } +The matcher: + cxxRecordDecl( + optionally(has( + fieldDecl(hasName("bar")).bind("var") + ))).bind("record") +will produce a result binding for both "record" and "var". +The matcher will produce a "record" binding for even if there is no data +member named "bar" in that class. + +Usable as: Any Matcher +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AbstractConditionalOperator.html">AbstractConditionalOperator</a>></td><td class="name" onclick="toggle('hasCondition5')"><a name="hasCondition5Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasCondition5"><pre>Matches the condition expression of an if statement, for loop, switch statement or conditional operator. @@ -5098,15 +5124,15 @@ <tr><td colspan="4" class="doc" id="hasInitStatement2"><pre>Matches selection statements with initializer. Given: - void foo() { + void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} - for (auto& a = get_range(); auto& x : a) {} + for (auto& a = get_range(); auto& x : a) {} } - void bar() { + void bar() { if (foobar() > 0) {} switch (foobar()) {} - for (auto& x : get_range()) {} + for (auto& x : get_range()) {} } ifStmt(hasInitStatement(anything())) matches the if statement in foo but not in bar. @@ -6245,15 +6271,15 @@ <tr><td colspan="4" class="doc" id="hasInitStatement0"><pre>Matches selection statements with initializer. Given: - void foo() { + void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} - for (auto& a = get_range(); auto& x : a) {} + for (auto& a = get_range(); auto& x : a) {} } - void bar() { + void bar() { if (foobar() > 0) {} switch (foobar()) {} - for (auto& x : get_range()) {} + for (auto& x : get_range()) {} } ifStmt(hasInitStatement(anything())) matches the if statement in foo but not in bar. @@ -7005,15 +7031,15 @@ <tr><td colspan="4" class="doc" id="hasInitStatement1"><pre>Matches selection statements with initializer. Given: - void foo() { + void foo() { if (int i = foobar(); i > 0) {} switch (int i = foobar(); i) {} - for (auto& a = get_range(); auto& x : a) {} + for (auto& a = get_range(); auto& x : a) {} } - void bar() { + void bar() { if (foobar() > 0) {} switch (foobar()) {} - for (auto& x : get_range()) {} + for (auto& x : get_range()) {} } ifStmt(hasInitStatement(anything())) matches the if statement in foo but not in bar.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits