Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -4689,6 +4689,32 @@ +Matcher<*>optionallyMatcher<*>, ..., Matcher<*> +
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
+
+ + Matcher<AbstractConditionalOperator>hasConditionMatcher<Expr> InnerMatcher
Matches the condition expression of an if statement, for loop,
 switch statement or conditional operator.
@@ -5098,15 +5124,15 @@
 
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 @@
 
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 @@
 
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.
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/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);