tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>`_