|
39 | 39 | // See ASTMatchFinder.h for how to use the generated matchers to run over
|
40 | 40 | // an AST.
|
41 | 41 | //
|
| 42 | +// The doxygen comments on matchers are used to: |
| 43 | +// - create the doxygen documentation |
| 44 | +// - get information in the editor via signature help and goto definition |
| 45 | +// - generate the AST matcher reference html file |
| 46 | +// - test the documentation using a special syntax |
| 47 | +// |
| 48 | +// TLDR: |
| 49 | +// |
| 50 | +// The automatic testing uses doxygen commands (aliases) to extract the |
| 51 | +// relevant information about an example of using a matcher from the |
| 52 | +// documentation. |
| 53 | +// |
| 54 | +// \header{a.h} |
| 55 | +// \endheader <- zero or more header |
| 56 | +// |
| 57 | +// \code |
| 58 | +// int a = 42; |
| 59 | +// \endcode |
| 60 | +// \compile_args{-std=c++,c23-or-later} <- optional, the std flag supports |
| 61 | +// std ranges and |
| 62 | +// whole languages |
| 63 | +// |
| 64 | +// \matcher{expr()} <- one or more matchers in succession |
| 65 | +// \matcher{integerLiteral()} <- one or more matchers in succession |
| 66 | +// both matcher will have to match the |
| 67 | +// following matches |
| 68 | +// \match{42} <- one or more matches in succession |
| 69 | +// |
| 70 | +// \matcher{varDecl()} <- new matcher resets the context, the above |
| 71 | +// \match will not count for this new |
| 72 | +// matcher(-group) |
| 73 | +// \match{int a = 42} <- only applies to the previous matcher (not to the |
| 74 | +// previous case) |
| 75 | +// |
| 76 | +// |
| 77 | +// The above block can be repeated inside a doxygen command for multiple code |
| 78 | +// examples for a single matcher. The test generation script will only look for |
| 79 | +// these annotations and ignore anything else like `\c` or the sentences where |
| 80 | +// these annotations are embedded into: `The matcher \matcher{expr()} matches |
| 81 | +// the number \match{42}.`. |
| 82 | +// |
| 83 | +// Language Grammar: |
| 84 | +// |
| 85 | +// [] denotes an optional, and <> denotes user-input |
| 86 | +// |
| 87 | +// compile_args j:= \compile_args{[<compile_arg>;]<compile_arg>} |
| 88 | +// matcher_tag_key ::= type |
| 89 | +// match_tag_key ::= type || std || count || sub |
| 90 | +// matcher_tags ::= [matcher_tag_key=<value>;]matcher_tag_key=<value> |
| 91 | +// match_tags ::= [match_tag_key=<value>;]match_tag_key=<value> |
| 92 | +// matcher ::= \matcher{[matcher_tags$]<matcher>} |
| 93 | +// matchers ::= [matcher] matcher |
| 94 | +// match ::= \match{[match_tags$]<match>} |
| 95 | +// matches ::= [match] match |
| 96 | +// case ::= matchers matches |
| 97 | +// cases ::= [case] case |
| 98 | +// header-block ::= \header{<name>} <code> \endheader |
| 99 | +// code-block ::= \code <code> \endcode |
| 100 | +// testcase ::= code-block [compile_args] cases |
| 101 | +// |
| 102 | +// Language Standard Versions: |
| 103 | +// |
| 104 | +// The 'std' tag and '\compile_args' support specifying a specific language |
| 105 | +// version, a whole language and all of its versions, and thresholds (implies |
| 106 | +// ranges). Multiple arguments are passed with a ',' separator. For a language |
| 107 | +// and version to execute a tested matcher, it has to match the specified |
| 108 | +// '\compile_args' for the code, and the 'std' tag for the matcher. Predicates |
| 109 | +// for the 'std' compiler flag are used with disjunction between languages |
| 110 | +// (e.g. 'c || c++') and conjunction for all predicates specific to each |
| 111 | +// language (e.g. 'c++11-or-later && c++23-or-earlier'). |
| 112 | +// |
| 113 | +// Examples: |
| 114 | +// - `c` all available versions of C |
| 115 | +// - `c++11` only C++11 |
| 116 | +// - `c++11-or-later` C++11 or later |
| 117 | +// - `c++11-or-earlier` C++11 or earlier |
| 118 | +// - `c++11-or-later,c++23-or-earlier,c` all of C and C++ between 11 and |
| 119 | +// 23 (inclusive) |
| 120 | +// - `c++11-23,c` same as above |
| 121 | +// |
| 122 | +// Tags |
| 123 | +// |
| 124 | +// `type`: |
| 125 | +// **Match types** are used to select where the string that is used to check if |
| 126 | +// a node matches comes from. Available: `code`, `name`, `typestr`, |
| 127 | +// `typeofstr`. The default is `code`. |
| 128 | +// |
| 129 | +// - `code`: Forwards to `tooling::fixit::getText(...)` and should be the |
| 130 | +// preferred way to show what matches. |
| 131 | +// - `name`: Casts the match to a `NamedDecl` and returns the result of |
| 132 | +// `getNameAsString`. Useful when the matched AST node is not easy to spell |
| 133 | +// out (`code` type), e.g., namespaces or classes with many members. |
| 134 | +// - `typestr`: Returns the result of `QualType::getAsString` for the type |
| 135 | +// derived from `Type` (otherwise, if it is derived from `Decl`, recurses with |
| 136 | +// `Node->getTypeForDecl()`) |
| 137 | +// |
| 138 | +// **Matcher types** are used to mark matchers as sub-matcher with 'sub' or as |
| 139 | +// deactivated using 'none'. Testing sub-matcher is not implemented. |
| 140 | +// |
| 141 | +// `count`: |
| 142 | +// Specifying a 'count=n' on a match will result in a test that requires that |
| 143 | +// the specified match will be matched n times. Default is 1. |
| 144 | +// |
| 145 | +// `std`: |
| 146 | +// A match allows specifying if it matches only in specific language versions. |
| 147 | +// This may be needed when the AST differs between language versions. |
| 148 | +// |
| 149 | +// `sub`: |
| 150 | +// The `sub` tag on a `\match` will indicate that the match is for a node of a |
| 151 | +// bound sub-matcher. E.g., `\matcher{expr(expr().bind("inner"))}` has a |
| 152 | +// sub-matcher that binds to `inner`, which is the value for the `sub` tag of |
| 153 | +// the expected match for the sub-matcher `\match{sub=inner$...}`. Currently, |
| 154 | +// sub-matchers are not tested in any way. |
| 155 | +// |
| 156 | +// |
| 157 | +// What if ...? |
| 158 | +// |
| 159 | +// ... I want to add a matcher? |
| 160 | +// |
| 161 | +// Add a doxygen comment to the matcher with a code example, corresponding |
| 162 | +// matchers and matches, that shows what the matcher is supposed to do. Specify |
| 163 | +// the compile arguments/supported languages if required, and run `ninja |
| 164 | +// check-clang-unit` to test the documentation. |
| 165 | +// |
| 166 | +// ... the example I wrote is wrong? |
| 167 | +// |
| 168 | +// The test-generation script will try to compile your example code before it |
| 169 | +// continues. This makes finding issues with your example code easier because |
| 170 | +// the test-failures are much more verbose. |
| 171 | +// |
| 172 | +// The test-failure output of the generated test file will provide information |
| 173 | +// about |
| 174 | +// - where the generated test file is located |
| 175 | +// - which line in `ASTMatcher.h` the example is from |
| 176 | +// - which matches were: found, not-(yet)-found, expected |
| 177 | +// - in case of an unexpected match: what the node looks like using the |
| 178 | +// different `type`s |
| 179 | +// - the language version and if the test ran with a windows `-target` flag |
| 180 | +// (also in failure summary) |
| 181 | +// |
| 182 | +// ... I don't adhere to the required order of the syntax? |
| 183 | +// |
| 184 | +// The script will diagnose any found issues, such as `matcher is missing an |
| 185 | +// example` with a `file:line:` prefix, which should provide enough information |
| 186 | +// about the issue. |
| 187 | +// |
| 188 | +// ... the script diagnoses a false-positive issue with a doxygen comment? |
| 189 | +// |
| 190 | +// It hopefully shouldn't, but if you, e.g., added some non-matcher code and |
| 191 | +// documented it with doxygen, then the script will consider that as a matcher |
| 192 | +// documentation. As a result, the script will print that it detected a |
| 193 | +// mismatch between the actual and the expected number of failures. If the |
| 194 | +// diagnostic truly is a false-positive, change the |
| 195 | +// `expected_failure_statistics` at the top of the |
| 196 | +// `generate_ast_matcher_doc_tests.py` file. |
| 197 | +// |
42 | 198 | //===----------------------------------------------------------------------===//
|
43 | 199 |
|
44 | 200 | #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
|
|
0 commit comments