clang-query.rst (5180B)
1 .. _using_clang_query: 2 3 Using clang-query 4 ================= 5 6 clang-query is a tool that allows you to quickly iterate and develop the difficult part of a matcher. 7 Once the design of the matcher is completed, it can be transferred to a C++ clang-tidy plugin, `similar 8 to the ones in mozilla-central <https://searchfox.org/mozilla-central/source/build/clang-plugin>`_. 9 10 Recommended Boilerplate 11 ----------------------- 12 13 :: 14 15 set traversal IgnoreUnlessSpelledInSource 16 set bind-root true 17 # ^ true unless you use any .bind("foo") commands 18 set print-matcher true 19 enable output dump 20 21 22 clang-query Options 23 ------------------- 24 25 set traversal 26 ~~~~~~~~~~~~~ 27 28 `Traversal mode <https://clang.llvm.org/docs/LibASTMatchersReference.html#traverse-mode>`_ specifies how the AST Matcher will traverse the nodes in the Abstract Syntax Tree. There are two values: 29 30 AsIs 31 This mode notes all the nodes in the AST, even if they are not explicitly spelled out in the source. This will include nodes you have never seen and probably don't immediately understand, for example ``ExprWithCleanups`` and ``MaterializeTemporaryExpr``. In this mode, it is necessary to write matchers that expliticly match or otherwise traverse these potentially unexpected nodes. 32 33 IgnoreUnlessSpelledInSource 34 This mode skips over 'implicit' nodes that are created as a result of implicit casts or other usually-low-level language details. This is typically much more user-friendly. **Typically you would want to use** ``set traversal IgnoreUnlessSpelledInSource``. 35 36 More examples are available `in the documentation <https://clang.llvm.org/docs/LibASTMatchersReference.html#traverse-mode>`_, but here is a simple example: 37 38 :: 39 40 B func1() { 41 return 42; 42 } 43 44 /* 45 AST Dump in 'Asis' mode for C++17/C++20 dialect: 46 47 FunctionDecl 48 `-CompoundStmt 49 `-ReturnStmt 50 `-ImplicitCastExpr 51 `-CXXConstructExpr 52 `-IntegerLiteral 'int' 42 53 54 AST Dump in 'IgnoreUnlessSpelledInSource' mode for all dialects: 55 56 FunctionDecl 57 `-CompoundStmt 58 `-ReturnStmt 59 `-IntegerLiteral 'int' 42 60 */ 61 62 63 set bind-root 64 ~~~~~~~~~~~~~ 65 66 If you are matching objects and assigning them names for later use, this option may be relevant. If you are debugging a single matcher and not using any ``.bind()``, it is irrelevant. 67 68 Consider the output of ``match functionDecl().bind("x")``: 69 70 :: 71 72 clang-query> match functionDecl().bind("x") 73 74 Match #1: 75 76 testfile.cpp:1:1: note: "root" binds here 77 int addTwo(int num) 78 ^~~~~~~~~~~~~~~~~~~ 79 testfile.cpp:1:1: note: "x" binds here 80 int addTwo(int num) 81 ^~~~~~~~~~~~~~~~~~~ 82 83 Match #2: 84 85 testfile.cpp:6:1: note: "root" binds here 86 int main(int, char**) 87 ^~~~~~~~~~~~~~~~~~~~~ 88 testfile.cpp:6:1: note: "x" binds here 89 int main(int, char**) 90 ^~~~~~~~~~~~~~~~~~~~~ 91 2 matches. 92 93 94 clang-query automatically binds ``root`` to the match, but we also bound the name ``x`` to that match. The ``root`` is redundant. If you ``set bind-root false`` then the output is less noisy: 95 96 :: 97 98 clang-query> set bind-root false 99 clang-query> m functionDecl().bind("x") 100 101 Match #1: 102 103 testfile.cpp:1:1: note: "x" binds here 104 int addtwo(int num) 105 ^~~~~~~~~~~~~~~~~~~ 106 107 Match #2: 108 109 testfile.cpp:6:1: note: "x" binds here 110 int main(int, char**) 111 ^~~~~~~~~~~~~~~~~~~~~ 112 2 matches. 113 114 115 set print-matcher 116 ~~~~~~~~~~~~~~~~~ 117 118 ``set print-matcher true`` will print a header line of the form 'Matcher: <foo>' where foo is the matcher you have written. It is helpful when debugging multiple matchers at the same time, and no inconvience otherwise. 119 120 enable/disable/set output <foo> 121 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 123 These commands will control the type of output you get from clang-query. The options are: 124 125 ``print`` 126 Shows you the C++ form of the node you are matching. This is typically not useful. 127 128 ``diag`` 129 Shows you the individual node you are matching. 130 131 ``dump`` (alias: ``detailed-ast``) 132 Shows you the node you are matching and the entire subtree for the node 133 134 By default, you get ``diag`` output. You can change the output by choosing ``set output``. You can *add* output by using ``enable output``. You can *disable* output using ``disable output`` but this is typically not needed. 135 136 So if you want to get all three output formats you can do: 137 138 :: 139 140 # diag output happens automatically because you did not override with 'set' 141 enable output print 142 enable output dump 143 144 145 Patches 146 ------- 147 148 This section tracks some patches; they are currently not used, but we may want them in the future. 149 150 - Functionality: 151 152 - `traverse() operator available to clang-query <https://reviews.llvm.org/D80654>`_ 153 - `srclog output <https://reviews.llvm.org/D93325>`_ 154 - `allow anyOf() to be empty <https://reviews.llvm.org/D94126>`_ 155 - breakpoints 156 - debug 157 - profile 158 159 - Matcher Changes: 160 161 - `binaryOperation() matcher <https://reviews.llvm.org/D94129>`_ 162 163 - Plumbing: 164 165 - `mapAnyOf() <https://reviews.llvm.org/D94127>`_ (`Example of usage <https://reviews.llvm.org/D94131>`_) 166 - `Make cxxOperatorCallExpr matchers API-compatible with n-ary operators <https://reviews.llvm.org/D94128>`_ 167 - `CXXRewrittenBinaryOperator <https://reviews.llvm.org/D94130>`_