зеркало из https://github.com/microsoft/clang-1.git
131 строка
6.9 KiB
HTML
131 строка
6.9 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
|
"http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Matching the Clang AST</title>
|
|
<link type="text/css" rel="stylesheet" href="../menu.css" />
|
|
<link type="text/css" rel="stylesheet" href="../content.css" />
|
|
</head>
|
|
<body>
|
|
|
|
<!--#include virtual="../menu.html.incl"-->
|
|
|
|
<div id="content">
|
|
|
|
<h1>Matching the Clang AST</h1>
|
|
<p>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
|
|
<a href="LibTooling.html">LibTooling</a>, LibASTMatchers helps to write
|
|
code-to-code transformation tools or query tools.</p>
|
|
|
|
<p>We assume basic knowledge about the Clang AST. See the
|
|
<a href="IntroductionToTheClangAST.html">Introduction to the Clang AST</a> if
|
|
you want to learn more about how the AST is structured.</p>
|
|
|
|
<!-- FIXME: create tutorial and link to the tutorial -->
|
|
|
|
<!-- ======================================================================= -->
|
|
<h2 id="intro">Introduction</h2>
|
|
<!-- ======================================================================= -->
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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.</p>
|
|
|
|
</p>For example, to create a matcher that matches all class or union declarations
|
|
in the AST of a translation unit, you can call
|
|
<a href="LibASTMatchersReference.html#recordDecl0Anchor">recordDecl()</a>.
|
|
To narrow the match down, for example to find all class or union declarations with the name "Foo",
|
|
insert a <a href="LibASTMatchersReference.html#hasName0Anchor">hasName</a>
|
|
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 <a href="LibASTMatchersReference.html#allOf0Anchor">allOf()</a>.
|
|
This allows further narrowing down the match, for example to match all classes
|
|
that are derived from "Bar": recordDecl(hasName("Foo"), isDerivedFrom("Bar")).</p>
|
|
|
|
<!-- ======================================================================= -->
|
|
<h2 id="writing">How to create a matcher</h2>
|
|
<!-- ======================================================================= -->
|
|
|
|
<p>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 <a href="#writing">how to write
|
|
your own AST matchers</a> later in this document.</p>
|
|
|
|
<p>The precondition to using the matchers is to understand how the AST
|
|
for what you want to match looks like. The <a href="IntroductionToTheClangAST.html">Introduction to the Clang AST</a>
|
|
teaches you how to dump a translation unit's AST into a human readable format.</p>
|
|
|
|
<!-- FIXME: Introduce link to ASTMatchersTutorial.html -->
|
|
<!-- FIXME: Introduce link to ASTMatchersCookbook.html -->
|
|
|
|
<p>In general, the strategy to create the right matchers is:</p>
|
|
<ol>
|
|
<li>Find the outermost class in Clang's AST you want to match.</li>
|
|
<li>Look at the <a href="LibASTMatchersReference.html">AST Matcher Reference</a> for matchers that either match the
|
|
node you're interested in or narrow down attributes on the node.</li>
|
|
<li>Create your outer match expression. Verify that it works as expected.</li>
|
|
<li>Examine the matchers for what the next inner node you want to match is.</li>
|
|
<li>Repeat until the matcher is finished.</li>
|
|
</ol>
|
|
|
|
<!-- ======================================================================= -->
|
|
<h2 id="binding">Binding nodes in match expressions</h2>
|
|
<!-- ======================================================================= -->
|
|
|
|
<p>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.</p>
|
|
|
|
<p>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
|
|
<a href="http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder_1_1MatchCallback.html">match callback</a>.</p>
|
|
|
|
<!-- FIXME: Introduce link to ASTMatchersTutorial.html -->
|
|
<!-- FIXME: Introduce link to ASTMatchersCookbook.html -->
|
|
|
|
<!-- ======================================================================= -->
|
|
<h2 id="writing">Writing your own matchers</h2>
|
|
<!-- ======================================================================= -->
|
|
|
|
<p>There are multiple different ways to define a matcher, depending on its
|
|
type and flexibility.</p>
|
|
<ul>
|
|
<li><b>VariadicDynCastAllOfMatcher<Base, Derived></b><p>Those match all nodes
|
|
of type <i>Base</i> if they can be dynamically casted to <i>Derived</i>. The
|
|
names of those matchers are nouns, which closely resemble <i>Derived</i>.
|
|
VariadicDynCastAllOfMatchers are the backbone of the matcher hierarchy. Most
|
|
often, your match expression will start with one of them, and you can
|
|
<a href="#binding">bind</a> the node they represent to ids for later processing.</p>
|
|
<p>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>.</p></li>
|
|
<li><b>AST_MATCHER_P(Type, Name, ParamType, Param)</b><p> Most matcher definitions
|
|
use the matcher creation macros. Those define both the matcher of type Matcher<Type>
|
|
itself, and a matcher-creation function named <i>Name</i> that takes a parameter
|
|
of type <i>ParamType</i> and returns the corresponding matcher.</p>
|
|
<p>There are multiple matcher definition macros that deal with polymorphic return
|
|
values and different parameter counts. See <a href="http://clang.llvm.org/doxygen/ASTMatchersMacros_8h.html">ASTMatchersMacros.h</a>.
|
|
</p></li>
|
|
<li><b>Matcher creation functions</b><p>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
|
|
<a href="LibASTMatchersReference.html#callee1Anchor">callee</a>.</p></li>
|
|
</ul>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|
|
|