diff options
Diffstat (limited to 'docs/LibASTMatchers.rst')
-rw-r--r-- | docs/LibASTMatchers.rst | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/docs/LibASTMatchers.rst b/docs/LibASTMatchers.rst new file mode 100644 index 0000000..738de79 --- /dev/null +++ b/docs/LibASTMatchers.rst @@ -0,0 +1,134 @@ +====================== +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 + |