You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
5.9 KiB
134 lines
5.9 KiB
====================== |
|
Matching the Clang AST |
|
====================== |
|
|
|
This document explains how to use Clang's LibASTMatchers to match interesting |
|
nodes of the AST and execute code that uses the matched nodes. Combined with |
|
:doc:`LibTooling`, LibASTMatchers helps to write code-to-code transformation |
|
tools or query tools. |
|
|
|
We assume basic knowledge about the Clang AST. See the :doc:`Introduction |
|
to the Clang AST <IntroductionToTheClangAST>` if you want to learn more |
|
about how the AST is structured. |
|
|
|
.. FIXME: create tutorial and link to the tutorial |
|
|
|
Introduction |
|
------------ |
|
|
|
LibASTMatchers provides a domain specific language to create predicates on |
|
Clang's AST. This DSL is written in and can be used from C++, allowing users |
|
to write a single program to both match AST nodes and access the node's C++ |
|
interface to extract attributes, source locations, or any other information |
|
provided on the AST level. |
|
|
|
AST matchers are predicates on nodes in the AST. Matchers are created by |
|
calling creator functions that allow building up a tree of matchers, where |
|
inner matchers are used to make the match more specific. |
|
|
|
For example, to create a matcher that matches all class or union declarations |
|
in the AST of a translation unit, you can call `recordDecl() |
|
<LibASTMatchersReference.html#recordDecl0Anchor>`_. To narrow the match down, |
|
for example to find all class or union declarations with the name "``Foo``", |
|
insert a `hasName <LibASTMatchersReference.html#hasName0Anchor>`_ matcher: the |
|
call ``recordDecl(hasName("Foo"))`` returns a matcher that matches classes or |
|
unions that are named "``Foo``", in any namespace. By default, matchers that |
|
accept multiple inner matchers use an implicit `allOf() |
|
<LibASTMatchersReference.html#allOf0Anchor>`_. This allows further narrowing |
|
down the match, for example to match all classes that are derived from |
|
"``Bar``": ``recordDecl(hasName("Foo"), isDerivedFrom("Bar"))``. |
|
|
|
How to create a matcher |
|
----------------------- |
|
|
|
With more than a thousand classes in the Clang AST, one can quickly get lost |
|
when trying to figure out how to create a matcher for a specific pattern. This |
|
section will teach you how to use a rigorous step-by-step pattern to build the |
|
matcher you are interested in. Note that there will always be matchers missing |
|
for some part of the AST. See the section about :ref:`how to write your own |
|
AST matchers <astmatchers-writing>` later in this document. |
|
|
|
.. FIXME: why is it linking back to the same section?! |
|
|
|
The precondition to using the matchers is to understand how the AST for what you |
|
want to match looks like. The |
|
:doc:`Introduction to the Clang AST <IntroductionToTheClangAST>` teaches you |
|
how to dump a translation unit's AST into a human readable format. |
|
|
|
.. FIXME: Introduce link to ASTMatchersTutorial.html |
|
.. FIXME: Introduce link to ASTMatchersCookbook.html |
|
|
|
In general, the strategy to create the right matchers is: |
|
|
|
#. Find the outermost class in Clang's AST you want to match. |
|
#. Look at the `AST Matcher Reference <LibASTMatchersReference.html>`_ for |
|
matchers that either match the node you're interested in or narrow down |
|
attributes on the node. |
|
#. Create your outer match expression. Verify that it works as expected. |
|
#. Examine the matchers for what the next inner node you want to match is. |
|
#. Repeat until the matcher is finished. |
|
|
|
.. _astmatchers-bind: |
|
|
|
Binding nodes in match expressions |
|
---------------------------------- |
|
|
|
Matcher expressions allow you to specify which parts of the AST are interesting |
|
for a certain task. Often you will want to then do something with the nodes |
|
that were matched, like building source code transformations. |
|
|
|
To that end, matchers that match specific AST nodes (so called node matchers) |
|
are bindable; for example, ``recordDecl(hasName("MyClass")).bind("id")`` will |
|
bind the matched ``recordDecl`` node to the string "``id``", to be later |
|
retrieved in the `match callback |
|
<http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder_1_1MatchCallback.html>`_. |
|
|
|
.. FIXME: Introduce link to ASTMatchersTutorial.html |
|
.. FIXME: Introduce link to ASTMatchersCookbook.html |
|
|
|
Writing your own matchers |
|
------------------------- |
|
|
|
There are multiple different ways to define a matcher, depending on its type |
|
and flexibility. |
|
|
|
``VariadicDynCastAllOfMatcher<Base, Derived>`` |
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
|
|
Those match all nodes of type *Base* if they can be dynamically casted to |
|
*Derived*. The names of those matchers are nouns, which closely resemble |
|
*Derived*. ``VariadicDynCastAllOfMatchers`` are the backbone of the matcher |
|
hierarchy. Most often, your match expression will start with one of them, and |
|
you can :ref:`bind <astmatchers-bind>` the node they represent to ids for later |
|
processing. |
|
|
|
``VariadicDynCastAllOfMatchers`` are callable classes that model variadic |
|
template functions in C++03. They take an aribtrary number of |
|
``Matcher<Derived>`` and return a ``Matcher<Base>``. |
|
|
|
``AST_MATCHER_P(Type, Name, ParamType, Param)`` |
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
|
|
Most matcher definitions use the matcher creation macros. Those define both |
|
the matcher of type ``Matcher<Type>`` itself, and a matcher-creation function |
|
named *Name* that takes a parameter of type *ParamType* and returns the |
|
corresponding matcher. |
|
|
|
There are multiple matcher definition macros that deal with polymorphic return |
|
values and different parameter counts. See `ASTMatchersMacros.h |
|
<http://clang.llvm.org/doxygen/ASTMatchersMacros_8h.html>`_. |
|
|
|
.. _astmatchers-writing: |
|
|
|
Matcher creation functions |
|
^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
|
|
Matchers are generated by nesting calls to matcher creation functions. Most of |
|
the time those functions are either created by using |
|
``VariadicDynCastAllOfMatcher`` or the matcher creation macros (see below). |
|
The free-standing functions are an indication that this matcher is just a |
|
combination of other matchers, as is for example the case with `callee |
|
<LibASTMatchersReference.html#callee1Anchor>`_. |
|
|
|
.. FIXME: "... macros (see below)" --- there isn't anything below |
|
|
|
|