123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- ======================
- Matching the Clang AST
- ======================
- NOTE: this document applies to the original Clang project, not the DirectX
- Compiler. It's made available for informational purposes only.
- 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
|