diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -4669,6 +4669,22 @@ +
Matches if the node or any descendant matches. + +Generates results for each match. + +For example, in: + class A { class B {}; class C {}; }; +The matcher: + cxxRecordDecl(hasName("::A"), + findAll(cxxRecordDecl(isDefinition()).bind("m"))) +will generate results for A, B and C. + +Usable as: Any Matcher +
Matches AST nodes that have descendant AST nodes that match the provided matcher. @@ -4803,6 +4819,22 @@
Causes all nested matchers to be matched with the specified traversal kind. + +Given + void foo() + { + int i = 3.0; + } +The matcher + traverse(TK_IgnoreImplicitCastsAndParentheses, + varDecl(hasInitializer(floatLiteral().bind("init"))) + ) +matches the variable declaration with "init" bound to the "3.0". +
Matches the condition expression of an if statement, for loop, switch statement or conditional operator. @@ -4833,7 +4865,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -4950,7 +4982,7 @@
Matches if either the left hand side or the right hand side of a binary operator matches.
Matches a node if the declaration associated with that node matches the given matcher. @@ -5376,7 +5408,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -5584,7 +5616,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -5731,7 +5763,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -5918,7 +5950,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -6430,7 +6462,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -6464,7 +6496,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -6525,7 +6557,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -6949,7 +6981,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -7031,7 +7063,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -7106,7 +7138,7 @@
Same as unaryExprOrTypeTraitExpr, but only matching alignof.
Same as unaryExprOrTypeTraitExpr, but only matching sizeof.
Matches a node if the declaration associated with that node matches the given matcher. @@ -7314,7 +7346,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -7368,7 +7400,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -7402,42 +7434,6 @@
Matches if the node or any descendant matches. - -Generates results for each match. - -For example, in: - class A { class B {}; class C {}; }; -The matcher: - cxxRecordDecl(hasName("::A"), - findAll(cxxRecordDecl(isDefinition()).bind("m"))) -will generate results for A, B and C. - -Usable as: Any Matcher -
Causes all nested matchers to be matched with the specified traversal kind. - -Given - void foo() - { - int i = 3.0; - } -The matcher - traverse(TK_IgnoreImplicitCastsAndParentheses, - varDecl(hasInitializer(floatLiteral().bind("init"))) - ) -matches the variable declaration with "init" bound to the "3.0". -
Matches TypeLocs for which the given inner QualType-matcher matches. @@ -7459,7 +7455,7 @@
Matches a node if the declaration associated with that node matches the given matcher. @@ -7542,7 +7538,7 @@
Matches a node if the declaration associated with that node matches the given matcher. diff --git a/clang/docs/tools/dump_ast_matchers.py b/clang/docs/tools/dump_ast_matchers.py --- a/clang/docs/tools/dump_ast_matchers.py +++ b/clang/docs/tools/dump_ast_matchers.py @@ -101,6 +101,8 @@ args = re.sub(r'extern const\s+(.*)&', r'\1 ', args) args = re.sub(r'&', r' ', args) args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args) + args = re.sub(r'BindableMatcher', r'Matcher', args) + args = re.sub(r'const Matcher', r'Matcher', args) return args def unify_type(result_type): @@ -125,7 +127,8 @@ 'id': matcher_id, } if is_dyncast: - node_matchers[result_type + name] = matcher_html + dict = node_matchers + lookup = result_type + name # Use a heuristic to figure out whether a matcher is a narrowing or # traversal matcher. By default, matchers that take other matchers as # arguments (and are not node matchers) do traversal. We specifically @@ -133,9 +136,14 @@ # arguments. elif ('Matcher<' not in args or name in ['allOf', 'anyOf', 'anything', 'unless']): - narrowing_matchers[result_type + name + esc(args)] = matcher_html + dict = narrowing_matchers + lookup = result_type + name + esc(args) else: - traversal_matchers[result_type + name + esc(args)] = matcher_html + dict = traversal_matchers + lookup = result_type + name + esc(args) + + if dict.get(lookup) is None or len(dict.get(lookup)) < len(matcher_html): + dict[lookup] = matcher_html def act_on_decl(declaration, comment, allowed_types): """Parse the matcher out of the given declaration and comment. @@ -145,6 +153,9 @@ definition. """ if declaration.strip(): + + if re.match(r'^\s?(#|namespace|using)', declaration): return + # Node matchers are defined by writing: # VariadicDynCastAllOfMatchername; m = re.match(r""".*Variadic(?:DynCast)?AllOfMatcher\s*< @@ -317,16 +328,27 @@ # Parse free standing matcher functions, like: # Matcher Name(Matcher InnerMatcher) { - m = re.match(r"""^\s*(.*)\s+ + m = re.match(r"""^\s*(?:template\s+<\s*(?:class|typename)\s+(.+)\s*>\s+)? + (.*)\s+ ([^\s\(]+)\s*\( (.*) \)\s*{""", declaration, re.X) if m: - result, name, args = m.groups() + template_name, result, name, args = m.groups() + if template_name: + matcherTemplateArgs = re.findall(r'Matcher<\s*(%s)\s*>' % template_name, args) + templateArgs = re.findall(r'(?:^|[\s,<])(%s)(?:$|[\s,>])' % template_name, args) + if len(matcherTemplateArgs) < len(templateArgs): + # The template name is used naked, so don't replace with `*`` later on + template_name = None + else : + args = re.sub(r'(^|[\s,<])%s($|[\s,>])' % template_name, r'\1*\2', args) args = ', '.join(p.strip() for p in args.split(',')) - m = re.match(r'.*\s+internal::(Bindable)?Matcher<([^>]+)>$', result) + m = re.match(r'(?:^|.*\s+)internal::(?:Bindable)?Matcher<([^>]+)>$', result) if m: - result_types = [m.group(2)] + result_types = [m.group(1)] + if template_name and len(result_types) is 1 and result_types[0] == template_name: + result_types = ['*'] else: result_types = extract_result_types(comment) if not result_types: