135 lines · plain
1======================2Matching the Clang AST3======================4 5This document explains how to use Clang's LibASTMatchers to match interesting6nodes of the AST and execute code that uses the matched nodes. Combined with7:doc:`LibTooling`, LibASTMatchers helps to write code-to-code transformation8tools or query tools.9 10We assume basic knowledge about the Clang AST. See the :doc:`Introduction11to the Clang AST <IntroductionToTheClangAST>` if you want to learn more12about how the AST is structured.13 14.. FIXME: create tutorial and link to the tutorial15 16Introduction17------------18 19LibASTMatchers provides a domain specific language to create predicates on20Clang's AST. This DSL is written in and can be used from C++, allowing users21to write a single program to both match AST nodes and access the node's C++22interface to extract attributes, source locations, or any other information23provided on the AST level.24 25AST matchers are predicates on nodes in the AST. Matchers are created by26calling creator functions that allow building up a tree of matchers, where27inner matchers are used to make the match more specific.28 29For example, to create a matcher that matches all class or union declarations30in the AST of a translation unit, you can call `recordDecl()31<LibASTMatchersReference.html#recordDecl0Anchor>`_. To narrow the match down,32for example to find all class or union declarations with the name "``Foo``",33insert a `hasName <LibASTMatchersReference.html#hasName0Anchor>`_ matcher: the34call ``recordDecl(hasName("Foo"))`` returns a matcher that matches classes or35unions that are named "``Foo``", in any namespace. By default, matchers that36accept multiple inner matchers use an implicit `allOf()37<LibASTMatchersReference.html#allOf0Anchor>`_. This allows further narrowing38down the match, for example to match all classes that are derived from39"``Bar``": ``recordDecl(hasName("Foo"), isDerivedFrom("Bar"))``.40 41How to create a matcher42-----------------------43 44With more than a thousand classes in the Clang AST, one can quickly get lost45when trying to figure out how to create a matcher for a specific pattern. This46section will teach you how to use a rigorous step-by-step pattern to build the47matcher you are interested in. Note that there will always be matchers missing48for some part of the AST. See the section about :ref:`how to write your own49AST matchers <astmatchers-writing>` later in this document.50 51.. FIXME: why is it linking back to the same section?!52 53The precondition to using the matchers is to understand how the AST for what you54want to match looks like. The55:doc:`Introduction to the Clang AST <IntroductionToTheClangAST>` teaches you56how to dump a translation unit's AST into a human readable format.57 58.. FIXME: Introduce link to ASTMatchersTutorial.html59.. FIXME: Introduce link to ASTMatchersCookbook.html60 61In general, the strategy to create the right matchers is:62 63#. Find the outermost class in Clang's AST you want to match.64#. Look at the `AST Matcher Reference <LibASTMatchersReference.html>`_ for65 matchers that either match the node you're interested in or narrow down66 attributes on the node.67#. Create your outer match expression. Verify that it works as expected.68#. Examine the matchers for what the next inner node you want to match is.69#. Repeat until the matcher is finished.70 71.. _astmatchers-bind:72 73Binding nodes in match expressions74----------------------------------75 76Matcher expressions allow you to specify which parts of the AST are interesting77for a certain task. Often you will want to then do something with the nodes78that were matched, like building source code transformations.79 80To that end, matchers that match specific AST nodes (so called node matchers)81are bindable; for example, ``recordDecl(hasName("MyClass")).bind("id")`` will82bind the matched ``recordDecl`` node to the string "``id``", to be later83retrieved in the `match callback84<https://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder_1_1MatchCallback.html>`_.85 86.. FIXME: Introduce link to ASTMatchersTutorial.html87.. FIXME: Introduce link to ASTMatchersCookbook.html88 89Writing your own matchers90-------------------------91 92There are multiple different ways to define a matcher, depending on its type93and flexibility.94 95``VariadicDynCastAllOfMatcher<Base, Derived>``96^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^97 98Those match all nodes of type *Base* if they can be dynamically cast to99*Derived*. The names of those matchers are nouns, which closely resemble100*Derived*. ``VariadicDynCastAllOfMatchers`` are the backbone of the matcher101hierarchy. Most often, your match expression will start with one of them, and102you can :ref:`bind <astmatchers-bind>` the node they represent to ids for later103processing.104 105``VariadicDynCastAllOfMatchers`` are callable classes that model variadic106template functions in C++03. They take an arbitrary number of107``Matcher<Derived>`` and return a ``Matcher<Base>``.108 109``AST_MATCHER_P(Type, Name, ParamType, Param)``110^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^111 112Most matcher definitions use the matcher creation macros. Those define both113the matcher of type ``Matcher<Type>`` itself, and a matcher-creation function114named *Name* that takes a parameter of type *ParamType* and returns the115corresponding matcher.116 117There are multiple matcher definition macros that deal with polymorphic return118values and different parameter counts. See `ASTMatchersMacros.h119<https://clang.llvm.org/doxygen/ASTMatchersMacros_8h.html>`_.120 121.. _astmatchers-writing:122 123Matcher creation functions124^^^^^^^^^^^^^^^^^^^^^^^^^^125 126Matchers are generated by nesting calls to matcher creation functions. Most of127the time those functions are either created by using128``VariadicDynCastAllOfMatcher`` or the matcher creation macros (see below).129The free-standing functions are an indication that this matcher is just a130combination of other matchers, as is for example the case with `callee131<LibASTMatchersReference.html#callee1Anchor>`_.132 133.. FIXME: "... macros (see below)" --- there isn't anything below134 135