1===============================================================
2Tutorial for building tools using LibTooling and LibASTMatchers
3===============================================================
4
5This document is intended to show how to build a useful source-to-source
6translation tool based on Clang's `LibTooling <LibTooling.html>`_. It is
7explicitly aimed at people who are new to Clang, so all you should need
8is a working knowledge of C++ and the command line.
9
10In order to work on the compiler, you need some basic knowledge of the
11abstract syntax tree (AST). To this end, the reader is incouraged to
12skim the :doc:`Introduction to the Clang
13AST <IntroductionToTheClangAST>`
14
15Step 0: Obtaining Clang
16=======================
17
18As Clang is part of the LLVM project, you'll need to download LLVM's
19source code first. Both Clang and LLVM are maintained as Subversion
20repositories, but we'll be accessing them through the git mirror. For
21further information, see the `getting started
22guide <http://llvm.org/docs/GettingStarted.html>`_.
23
24.. code-block:: console
25
26      mkdir ~/clang-llvm && cd ~/clang-llvm
27      git clone http://llvm.org/git/llvm.git
28      cd llvm/tools
29      git clone http://llvm.org/git/clang.git
30
31Next you need to obtain the CMake build system and Ninja build tool. You
32may already have CMake installed, but current binary versions of CMake
33aren't built with Ninja support.
34
35.. code-block:: console
36
37      cd ~/clang-llvm
38      git clone https://github.com/martine/ninja.git
39      cd ninja
40      git checkout release
41      ./bootstrap.py
42      sudo cp ninja /usr/bin/
43
44      cd ~/clang-llvm
45      git clone git://cmake.org/stage/cmake.git
46      cd cmake
47      git checkout next
48      ./bootstrap
49      make
50      sudo make install
51
52Okay. Now we'll build Clang!
53
54.. code-block:: console
55
56      cd ~/clang-llvm
57      mkdir build && cd build
58      cmake -G Ninja ../llvm -DLLVM_BUILD_TESTS=ON  # Enable tests; default is off.
59      ninja
60      ninja check       # Test LLVM only.
61      ninja clang-test  # Test Clang only.
62      ninja install
63
64And we're live.
65
66All of the tests should pass, though there is a (very) small chance that
67you can catch LLVM and Clang out of sync. Running ``'git svn rebase'``
68in both the llvm and clang directories should fix any problems.
69
70Finally, we want to set Clang as its own compiler.
71
72.. code-block:: console
73
74      cd ~/clang-llvm/build
75      ccmake ../llvm
76
77The second command will bring up a GUI for configuring Clang. You need
78to set the entry for ``CMAKE_CXX_COMPILER``. Press ``'t'`` to turn on
79advanced mode. Scroll down to ``CMAKE_CXX_COMPILER``, and set it to
80``/usr/bin/clang++``, or wherever you installed it. Press ``'c'`` to
81configure, then ``'g'`` to generate CMake's files.
82
83Finally, run ninja one last time, and you're done.
84
85Step 1: Create a ClangTool
86==========================
87
88Now that we have enough background knowledge, it's time to create the
89simplest productive ClangTool in existence: a syntax checker. While this
90already exists as ``clang-check``, it's important to understand what's
91going on.
92
93First, we'll need to create a new directory for our tool and tell CMake
94that it exists. As this is not going to be a core clang tool, it will
95live in the ``tools/extra`` repository.
96
97.. code-block:: console
98
99      cd ~/clang-llvm/llvm/tools/clang
100      mkdir tools/extra/loop-convert
101      echo 'add_subdirectory(loop-convert)' >> tools/extra/CMakeLists.txt
102      vim tools/extra/loop-convert/CMakeLists.txt
103
104CMakeLists.txt should have the following contents:
105
106::
107
108      set(LLVM_LINK_COMPONENTS support)
109      set(LLVM_USED_LIBS clangTooling clangBasic clangAST)
110
111      add_clang_executable(loop-convert
112        LoopConvert.cpp
113        )
114      target_link_libraries(loop-convert
115        clangTooling
116        clangBasic
117        clangASTMatchers
118        )
119
120With that done, Ninja will be able to compile our tool. Let's give it
121something to compile! Put the following into
122``tools/extra/loop-convert/LoopConvert.cpp``. A detailed explanation of
123why the different parts are needed can be found in the `LibTooling
124documentation <LibTooling.html>`_.
125
126.. code-block:: c++
127
128      // Declares clang::SyntaxOnlyAction.
129      #include "clang/Frontend/FrontendActions.h"
130      #include "clang/Tooling/CommonOptionsParser.h"
131      #include "clang/Tooling/Tooling.h"
132      // Declares llvm::cl::extrahelp.
133      #include "llvm/Support/CommandLine.h"
134
135      using namespace clang::tooling;
136      using namespace llvm;
137
138      // CommonOptionsParser declares HelpMessage with a description of the common
139      // command-line options related to the compilation database and input files.
140      // It's nice to have this help message in all tools.
141      static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
142
143      // A help message for this specific tool can be added afterwards.
144      static cl::extrahelp MoreHelp("\nMore help text...");
145
146      int main(int argc, const char **argv) {
147        CommonOptionsParser OptionsParser(argc, argv);
148        ClangTool Tool(OptionsParser.getCompilations(),
149                       OptionsParser.getSourcePathList());
150        return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
151      }
152
153And that's it! You can compile our new tool by running ninja from the
154``build`` directory.
155
156.. code-block:: console
157
158      cd ~/clang-llvm/build
159      ninja
160
161You should now be able to run the syntax checker, which is located in
162``~/clang-llvm/build/bin``, on any source file. Try it!
163
164.. code-block:: console
165
166      cat "void main() {}" > test.cpp
167      bin/loop-convert test.cpp --
168
169Note the two dashes after we specify the source file. The additional
170options for the compiler are passed after the dashes rather than loading
171them from a compilation database - there just aren't any options needed
172right now.
173
174Intermezzo: Learn AST matcher basics
175====================================
176
177Clang recently introduced the :doc:`ASTMatcher
178library <LibASTMatchers>` to provide a simple, powerful, and
179concise way to describe specific patterns in the AST. Implemented as a
180DSL powered by macros and templates (see
181`ASTMatchers.h <../doxygen/ASTMatchers_8h_source.html>`_ if you're
182curious), matchers offer the feel of algebraic data types common to
183functional programming languages.
184
185For example, suppose you wanted to examine only binary operators. There
186is a matcher to do exactly that, conveniently named ``binaryOperator``.
187I'll give you one guess what this matcher does:
188
189.. code-block:: c++
190
191      binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))))
192
193Shockingly, it will match against addition expressions whose left hand
194side is exactly the literal 0. It will not match against other forms of
1950, such as ``'\0'`` or ``NULL``, but it will match against macros that
196expand to 0. The matcher will also not match against calls to the
197overloaded operator ``'+'``, as there is a separate ``operatorCallExpr``
198matcher to handle overloaded operators.
199
200There are AST matchers to match all the different nodes of the AST,
201narrowing matchers to only match AST nodes fulfilling specific criteria,
202and traversal matchers to get from one kind of AST node to another. For
203a complete list of AST matchers, take a look at the `AST Matcher
204References <LibASTMatchersReference.html>`_
205
206All matcher that are nouns describe entities in the AST and can be
207bound, so that they can be referred to whenever a match is found. To do
208so, simply call the method ``bind`` on these matchers, e.g.:
209
210.. code-block:: c++
211
212      variable(hasType(isInteger())).bind("intvar")
213
214Step 2: Using AST matchers
215==========================
216
217Okay, on to using matchers for real. Let's start by defining a matcher
218which will capture all ``for`` statements that define a new variable
219initialized to zero. Let's start with matching all ``for`` loops:
220
221.. code-block:: c++
222
223      forStmt()
224
225Next, we want to specify that a single variable is declared in the first
226portion of the loop, so we can extend the matcher to
227
228.. code-block:: c++
229
230      forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl()))))
231
232Finally, we can add the condition that the variable is initialized to
233zero.
234
235.. code-block:: c++
236
237      forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
238        hasInitializer(integerLiteral(equals(0))))))))
239
240It is fairly easy to read and understand the matcher definition ("match
241loops whose init portion declares a single variable which is initialized
242to the integer literal 0"), but deciding that every piece is necessary
243is more difficult. Note that this matcher will not match loops whose
244variables are initialized to ``'\0'``, ``0.0``, ``NULL``, or any form of
245zero besides the integer 0.
246
247The last step is giving the matcher a name and binding the ``ForStmt``
248as we will want to do something with it:
249
250.. code-block:: c++
251
252      StatementMatcher LoopMatcher =
253        forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
254          hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");
255
256Once you have defined your matchers, you will need to add a little more
257scaffolding in order to run them. Matchers are paired with a
258``MatchCallback`` and registered with a ``MatchFinder`` object, then run
259from a ``ClangTool``. More code!
260
261Add the following to ``LoopConvert.cpp``:
262
263.. code-block:: c++
264
265      #include "clang/ASTMatchers/ASTMatchers.h"
266      #include "clang/ASTMatchers/ASTMatchFinder.h"
267
268      using namespace clang;
269      using namespace clang::ast_matchers;
270
271      StatementMatcher LoopMatcher =
272        forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
273          hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");
274
275      class LoopPrinter : public MatchFinder::MatchCallback {
276      public :
277        virtual void run(const MatchFinder::MatchResult &Result) {
278        if (const ForStmt *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop"))
279          FS->dump();
280      };
281
282And change ``main()`` to:
283
284.. code-block:: c++
285
286      int main(int argc, const char **argv) {
287        CommonOptionsParser OptionsParser(argc, argv);
288        ClangTool Tool(OptionsParser.getCompilations(),
289                       OptionsParser.getSourcePathList());
290
291        LoopPrinter Printer;
292        MatchFinder Finder;
293        Finder.addMatcher(LoopMatcher, &Printer);
294
295        return Tool.run(newFrontendActionFactory(&Finder));
296      }
297
298Now, you should be able to recompile and run the code to discover for
299loops. Create a new file with a few examples, and test out our new
300handiwork:
301
302.. code-block:: console
303
304      cd ~/clang-llvm/llvm/llvm_build/
305      ninja loop-convert
306      vim ~/test-files/simple-loops.cc
307      bin/loop-convert ~/test-files/simple-loops.cc
308
309Step 3.5: More Complicated Matchers
310===================================
311
312Our simple matcher is capable of discovering for loops, but we would
313still need to filter out many more ourselves. We can do a good portion
314of the remaining work with some cleverly chosen matchers, but first we
315need to decide exactly which properties we want to allow.
316
317How can we characterize for loops over arrays which would be eligible
318for translation to range-based syntax? Range based loops over arrays of
319size ``N`` that:
320
321-  start at index ``0``
322-  iterate consecutively
323-  end at index ``N-1``
324
325We already check for (1), so all we need to add is a check to the loop's
326condition to ensure that the loop's index variable is compared against
327``N`` and another check to ensure that the increment step just
328increments this same variable. The matcher for (2) is straightforward:
329require a pre- or post-increment of the same variable declared in the
330init portion.
331
332Unfortunately, such a matcher is impossible to write. Matchers contain
333no logic for comparing two arbitrary AST nodes and determining whether
334or not they are equal, so the best we can do is matching more than we
335would like to allow, and punting extra comparisons to the callback.
336
337In any case, we can start building this sub-matcher. We can require that
338the increment step be a unary increment like this:
339
340.. code-block:: c++
341
342      hasIncrement(unaryOperator(hasOperatorName("++")))
343
344Specifying what is incremented introduces another quirk of Clang's AST:
345Usages of variables are represented as ``DeclRefExpr``'s ("declaration
346reference expressions") because they are expressions which refer to
347variable declarations. To find a ``unaryOperator`` that refers to a
348specific declaration, we can simply add a second condition to it:
349
350.. code-block:: c++
351
352      hasIncrement(unaryOperator(
353        hasOperatorName("++"),
354        hasUnaryOperand(declRefExpr())))
355
356Furthermore, we can restrict our matcher to only match if the
357incremented variable is an integer:
358
359.. code-block:: c++
360
361      hasIncrement(unaryOperator(
362        hasOperatorName("++"),
363        hasUnaryOperand(declRefExpr(to(varDecl(hasType(isInteger())))))))
364
365And the last step will be to attach an identifier to this variable, so
366that we can retrieve it in the callback:
367
368.. code-block:: c++
369
370      hasIncrement(unaryOperator(
371        hasOperatorName("++"),
372        hasUnaryOperand(declRefExpr(to(
373          varDecl(hasType(isInteger())).bind("incrementVariable"))))))
374
375We can add this code to the definition of ``LoopMatcher`` and make sure
376that our program, outfitted with the new matcher, only prints out loops
377that declare a single variable initialized to zero and have an increment
378step consisting of a unary increment of some variable.
379
380Now, we just need to add a matcher to check if the condition part of the
381``for`` loop compares a variable against the size of the array. There is
382only one problem - we don't know which array we're iterating over
383without looking at the body of the loop! We are again restricted to
384approximating the result we want with matchers, filling in the details
385in the callback. So we start with:
386
387.. code-block:: c++
388
389      hasCondition(binaryOperator(hasOperatorName("<"))
390
391It makes sense to ensure that the left-hand side is a reference to a
392variable, and that the right-hand side has integer type.
393
394.. code-block:: c++
395
396      hasCondition(binaryOperator(
397        hasOperatorName("<"),
398        hasLHS(declRefExpr(to(varDecl(hasType(isInteger()))))),
399        hasRHS(expr(hasType(isInteger())))))
400
401Why? Because it doesn't work. Of the three loops provided in
402``test-files/simple.cpp``, zero of them have a matching condition. A
403quick look at the AST dump of the first for loop, produced by the
404previous iteration of loop-convert, shows us the answer:
405
406::
407
408      (ForStmt 0x173b240
409        (DeclStmt 0x173afc8
410          0x173af50 "int i =
411            (IntegerLiteral 0x173afa8 'int' 0)")
412        <<>>
413        (BinaryOperator 0x173b060 '_Bool' '<'
414          (ImplicitCastExpr 0x173b030 'int'
415            (DeclRefExpr 0x173afe0 'int' lvalue Var 0x173af50 'i' 'int'))
416          (ImplicitCastExpr 0x173b048 'int'
417            (DeclRefExpr 0x173b008 'const int' lvalue Var 0x170fa80 'N' 'const int')))
418        (UnaryOperator 0x173b0b0 'int' lvalue prefix '++'
419          (DeclRefExpr 0x173b088 'int' lvalue Var 0x173af50 'i' 'int'))
420        (CompoundStatement …
421
422We already know that the declaration and increments both match, or this
423loop wouldn't have been dumped. The culprit lies in the implicit cast
424applied to the first operand (i.e. the LHS) of the less-than operator,
425an L-value to R-value conversion applied to the expression referencing
426``i``. Thankfully, the matcher library offers a solution to this problem
427in the form of ``ignoringParenImpCasts``, which instructs the matcher to
428ignore implicit casts and parentheses before continuing to match.
429Adjusting the condition operator will restore the desired match.
430
431.. code-block:: c++
432
433      hasCondition(binaryOperator(
434        hasOperatorName("<"),
435        hasLHS(ignoringParenImpCasts(declRefExpr(
436          to(varDecl(hasType(isInteger())))))),
437        hasRHS(expr(hasType(isInteger())))))
438
439After adding binds to the expressions we wished to capture and
440extracting the identifier strings into variables, we have array-step-2
441completed.
442
443Step 4: Retrieving Matched Nodes
444================================
445
446So far, the matcher callback isn't very interesting: it just dumps the
447loop's AST. At some point, we will need to make changes to the input
448source code. Next, we'll work on using the nodes we bound in the
449previous step.
450
451The ``MatchFinder::run()`` callback takes a
452``MatchFinder::MatchResult&`` as its parameter. We're most interested in
453its ``Context`` and ``Nodes`` members. Clang uses the ``ASTContext``
454class to represent contextual information about the AST, as the name
455implies, though the most functionally important detail is that several
456operations require an ``ASTContext*`` parameter. More immediately useful
457is the set of matched nodes, and how we retrieve them.
458
459Since we bind three variables (identified by ConditionVarName,
460InitVarName, and IncrementVarName), we can obtain the matched nodes by
461using the ``getNodeAs()`` member function.
462
463In ``LoopActions.cpp``:
464
465.. code-block:: c++
466
467      #include "clang/AST/ASTContext.h"
468
469      void LoopPrinter::run(const MatchFinder::MatchResult &Result) {
470        ASTContext *Context = Result.Context;
471        const ForStmt *FS = Result.Nodes.getStmtAs<ForStmt>(LoopName);
472        // We do not want to convert header files!
473        if (!FS || !Context->getSourceManager().isFromMainFile(FS->getForLoc()))
474          return;
475        const VarDecl *IncVar = Result.Nodes.getNodeAs<VarDecl>(IncrementVarName);
476        const VarDecl *CondVar = Result.Nodes.getNodeAs<VarDecl>(ConditionVarName);
477        const VarDecl *InitVar = Result.Nodes.getNodeAs<VarDecl>(InitVarName);
478
479Now that we have the three variables, represented by their respective
480declarations, let's make sure that they're all the same, using a helper
481function I call ``areSameVariable()``.
482
483.. code-block:: c++
484
485      if (!areSameVariable(IncVar, CondVar) || !areSameVariable(IncVar, InitVar))
486        return;
487      llvm::outs() << "Potential array-based loop discovered.\n";
488    }
489
490If execution reaches the end of ``LoopPrinter::run()``, we know that the
491loop shell that looks like
492
493.. code-block:: c++
494
495      for (int i= 0; i < expr(); ++i) { ... }
496
497For now, we will just print a message explaining that we found a loop.
498The next section will deal with recursively traversing the AST to
499discover all changes needed.
500
501As a side note, here is the implementation of ``areSameVariable``. Clang
502associates a ``VarDecl`` with each variable to represent the variable's
503declaration. Since the "canonical" form of each declaration is unique by
504address, all we need to do is make sure neither ``ValueDecl`` (base
505class of ``VarDecl``) is ``NULL`` and compare the canonical Decls.
506
507.. code-block:: c++
508
509      static bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) {
510        return First && Second &&
511               First->getCanonicalDecl() == Second->getCanonicalDecl();
512      }
513
514It's not as trivial to test if two expressions are the same, though
515Clang has already done the hard work for us by providing a way to
516canonicalize expressions:
517
518.. code-block:: c++
519
520      static bool areSameExpr(ASTContext *Context, const Expr *First,
521                              const Expr *Second) {
522        if (!First || !Second)
523          return false;
524        llvm::FoldingSetNodeID FirstID, SecondID;
525        First->Profile(FirstID, *Context, true);
526        Second->Profile(SecondID, *Context, true);
527        return FirstID == SecondID;
528      }
529
530This code relies on the comparison between two
531``llvm::FoldingSetNodeIDs``. As the documentation for
532``Stmt::Profile()`` indicates, the ``Profile()`` member function builds
533a description of a node in the AST, based on its properties, along with
534those of its children. ``FoldingSetNodeID`` then serves as a hash we can
535use to compare expressions. We will need ``areSameExpr`` later. Before
536you run the new code on the additional loops added to
537test-files/simple.cpp, try to figure out which ones will be considered
538potentially convertible.
539