===============================================================
Tutorial for building tools using LibTooling and LibASTMatchers
===============================================================

This document is intended to show how to build a useful source-to-source
translation tool based on Clang's `LibTooling <LibTooling.html>`_. It is
explicitly aimed at people who are new to Clang, so all you should need
is a working knowledge of C++ and the command line.

In order to work on the compiler, you need some basic knowledge of the
abstract syntax tree (AST). To this end, the reader is incouraged to
skim the :doc:`Introduction to the Clang
AST <IntroductionToTheClangAST>`

Step 0: Obtaining Clang
=======================

As Clang is part of the LLVM project, you'll need to download LLVM's
source code first. Both Clang and LLVM are in the same git repository,
under different directories. For further information, see the `getting
started guide <https://llvm.org/docs/GettingStarted.html>`_.

.. code-block:: console

      cd ~/clang-llvm
      git clone https://github.com/llvm/llvm-project.git

Next you need to obtain the CMake build system and Ninja build tool.

.. code-block:: console

      cd ~/clang-llvm
      git clone https://github.com/martine/ninja.git
      cd ninja
      git checkout release
      ./bootstrap.py
      sudo cp ninja /usr/bin/

      cd ~/clang-llvm
      git clone git://cmake.org/stage/cmake.git
      cd cmake
      git checkout next
      ./bootstrap
      make
      sudo make install

Okay. Now we'll build Clang!

.. code-block:: console

      cd ~/clang-llvm
      mkdir build && cd build
      cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_BUILD_TESTS=ON  # Enable tests; default is off.
      ninja
      ninja check       # Test LLVM only.
      ninja clang-test  # Test Clang only.
      ninja install

And we're live.

All of the tests should pass.

Finally, we want to set Clang as its own compiler.

.. code-block:: console

      cd ~/clang-llvm/build
      ccmake ../llvm

The second command will bring up a GUI for configuring Clang. You need
to set the entry for ``CMAKE_CXX_COMPILER``. Press ``'t'`` to turn on
advanced mode. Scroll down to ``CMAKE_CXX_COMPILER``, and set it to
``/usr/bin/clang++``, or wherever you installed it. Press ``'c'`` to
configure, then ``'g'`` to generate CMake's files.

Finally, run ninja one last time, and you're done.

Step 1: Create a ClangTool
==========================

Now that we have enough background knowledge, it's time to create the
simplest productive ClangTool in existence: a syntax checker. While this
already exists as ``clang-check``, it's important to understand what's
going on.

First, we'll need to create a new directory for our tool and tell CMake
that it exists. As this is not going to be a core clang tool, it will
live in the ``clang-tools-extra`` repository.

.. code-block:: console

      cd ~/clang-llvm
      mkdir clang-tools-extra/loop-convert
      echo 'add_subdirectory(loop-convert)' >> clang-tools-extra/CMakeLists.txt
      vim clang-tools-extra/loop-convert/CMakeLists.txt

CMakeLists.txt should have the following contents:

::

      set(LLVM_LINK_COMPONENTS support)

      add_clang_executable(loop-convert
        LoopConvert.cpp
        )
      target_link_libraries(loop-convert
        PRIVATE
        clangTooling
        clangBasic
        clangASTMatchers
        )

With that done, Ninja will be able to compile our tool. Let's give it
something to compile! Put the following into
``clang-tools-extra/loop-convert/LoopConvert.cpp``. A detailed explanation of
why the different parts are needed can be found in the `LibTooling
documentation <LibTooling.html>`_.

.. code-block:: c++

      // Declares clang::SyntaxOnlyAction.
      #include "clang/Frontend/FrontendActions.h"
      #include "clang/Tooling/CommonOptionsParser.h"
      #include "clang/Tooling/Tooling.h"
      // Declares llvm::cl::extrahelp.
      #include "llvm/Support/CommandLine.h"

      using namespace clang::tooling;
      using namespace llvm;

      // Apply a custom category to all command-line options so that they are the
      // only ones displayed.
      static llvm::cl::OptionCategory MyToolCategory("my-tool options");

      // CommonOptionsParser declares HelpMessage with a description of the common
      // command-line options related to the compilation database and input files.
      // It's nice to have this help message in all tools.
      static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);

      // A help message for this specific tool can be added afterwards.
      static cl::extrahelp MoreHelp("\nMore help text...\n");

      int main(int argc, const char **argv) {
        CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
        ClangTool Tool(OptionsParser.getCompilations(),
                       OptionsParser.getSourcePathList());
        return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
      }

And that's it! You can compile our new tool by running ninja from the
``build`` directory.

.. code-block:: console

      cd ~/clang-llvm/build
      ninja

You should now be able to run the syntax checker, which is located in
``~/clang-llvm/build/bin``, on any source file. Try it!

.. code-block:: console

      echo "int main() { return 0; }" > test.cpp
      bin/loop-convert test.cpp --

Note the two dashes after we specify the source file. The additional
options for the compiler are passed after the dashes rather than loading
them from a compilation database - there just aren't any options needed
right now.

Intermezzo: Learn AST matcher basics
====================================

Clang recently introduced the :doc:`ASTMatcher
library <LibASTMatchers>` to provide a simple, powerful, and
concise way to describe specific patterns in the AST. Implemented as a
DSL powered by macros and templates (see
`ASTMatchers.h <../doxygen/ASTMatchers_8h_source.html>`_ if you're
curious), matchers offer the feel of algebraic data types common to
functional programming languages.

For example, suppose you wanted to examine only binary operators. There
is a matcher to do exactly that, conveniently named ``binaryOperator``.
I'll give you one guess what this matcher does:

.. code-block:: c++

      binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))))

Shockingly, it will match against addition expressions whose left hand
side is exactly the literal 0. It will not match against other forms of
0, such as ``'\0'`` or ``NULL``, but it will match against macros that
expand to 0. The matcher will also not match against calls to the
overloaded operator ``'+'``, as there is a separate ``operatorCallExpr``
matcher to handle overloaded operators.

There are AST matchers to match all the different nodes of the AST,
narrowing matchers to only match AST nodes fulfilling specific criteria,
and traversal matchers to get from one kind of AST node to another. For
a complete list of AST matchers, take a look at the `AST Matcher
References <LibASTMatchersReference.html>`_

All matcher that are nouns describe entities in the AST and can be
bound, so that they can be referred to whenever a match is found. To do
so, simply call the method ``bind`` on these matchers, e.g.:

.. code-block:: c++

      variable(hasType(isInteger())).bind("intvar")

Step 2: Using AST matchers
==========================

Okay, on to using matchers for real. Let's start by defining a matcher
which will capture all ``for`` statements that define a new variable
initialized to zero. Let's start with matching all ``for`` loops:

.. code-block:: c++

      forStmt()

Next, we want to specify that a single variable is declared in the first
portion of the loop, so we can extend the matcher to

.. code-block:: c++

      forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl()))))

Finally, we can add the condition that the variable is initialized to
zero.

.. code-block:: c++

      forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
        hasInitializer(integerLiteral(equals(0))))))))

It is fairly easy to read and understand the matcher definition ("match
loops whose init portion declares a single variable which is initialized
to the integer literal 0"), but deciding that every piece is necessary
is more difficult. Note that this matcher will not match loops whose
variables are initialized to ``'\0'``, ``0.0``, ``NULL``, or any form of
zero besides the integer 0.

The last step is giving the matcher a name and binding the ``ForStmt``
as we will want to do something with it:

.. code-block:: c++

      StatementMatcher LoopMatcher =
        forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
          hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");

Once you have defined your matchers, you will need to add a little more
scaffolding in order to run them. Matchers are paired with a
``MatchCallback`` and registered with a ``MatchFinder`` object, then run
from a ``ClangTool``. More code!

Add the following to ``LoopConvert.cpp``:

.. code-block:: c++

      #include "clang/ASTMatchers/ASTMatchers.h"
      #include "clang/ASTMatchers/ASTMatchFinder.h"

      using namespace clang;
      using namespace clang::ast_matchers;

      StatementMatcher LoopMatcher =
        forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
          hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");

      class LoopPrinter : public MatchFinder::MatchCallback {
      public :
        virtual void run(const MatchFinder::MatchResult &Result) {
          if (const ForStmt *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop"))
            FS->dump();
        }
      };

And change ``main()`` to:

.. code-block:: c++

      int main(int argc, const char **argv) {
        CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
        ClangTool Tool(OptionsParser.getCompilations(),
                       OptionsParser.getSourcePathList());

        LoopPrinter Printer;
        MatchFinder Finder;
        Finder.addMatcher(LoopMatcher, &Printer);

        return Tool.run(newFrontendActionFactory(&Finder).get());
      }

Now, you should be able to recompile and run the code to discover for
loops. Create a new file with a few examples, and test out our new
handiwork:

.. code-block:: console

      cd ~/clang-llvm/llvm/llvm_build/
      ninja loop-convert
      vim ~/test-files/simple-loops.cc
      bin/loop-convert ~/test-files/simple-loops.cc

Step 3.5: More Complicated Matchers
===================================

Our simple matcher is capable of discovering for loops, but we would
still need to filter out many more ourselves. We can do a good portion
of the remaining work with some cleverly chosen matchers, but first we
need to decide exactly which properties we want to allow.

How can we characterize for loops over arrays which would be eligible
for translation to range-based syntax? Range based loops over arrays of
size ``N`` that:

-  start at index ``0``
-  iterate consecutively
-  end at index ``N-1``

We already check for (1), so all we need to add is a check to the loop's
condition to ensure that the loop's index variable is compared against
``N`` and another check to ensure that the increment step just
increments this same variable. The matcher for (2) is straightforward:
require a pre- or post-increment of the same variable declared in the
init portion.

Unfortunately, such a matcher is impossible to write. Matchers contain
no logic for comparing two arbitrary AST nodes and determining whether
or not they are equal, so the best we can do is matching more than we
would like to allow, and punting extra comparisons to the callback.

In any case, we can start building this sub-matcher. We can require that
the increment step be a unary increment like this:

.. code-block:: c++

      hasIncrement(unaryOperator(hasOperatorName("++")))

Specifying what is incremented introduces another quirk of Clang's AST:
Usages of variables are represented as ``DeclRefExpr``'s ("declaration
reference expressions") because they are expressions which refer to
variable declarations. To find a ``unaryOperator`` that refers to a
specific declaration, we can simply add a second condition to it:

.. code-block:: c++

      hasIncrement(unaryOperator(
        hasOperatorName("++"),
        hasUnaryOperand(declRefExpr())))

Furthermore, we can restrict our matcher to only match if the
incremented variable is an integer:

.. code-block:: c++

      hasIncrement(unaryOperator(
        hasOperatorName("++"),
        hasUnaryOperand(declRefExpr(to(varDecl(hasType(isInteger())))))))

And the last step will be to attach an identifier to this variable, so
that we can retrieve it in the callback:

.. code-block:: c++

      hasIncrement(unaryOperator(
        hasOperatorName("++"),
        hasUnaryOperand(declRefExpr(to(
          varDecl(hasType(isInteger())).bind("incrementVariable"))))))

We can add this code to the definition of ``LoopMatcher`` and make sure
that our program, outfitted with the new matcher, only prints out loops
that declare a single variable initialized to zero and have an increment
step consisting of a unary increment of some variable.

Now, we just need to add a matcher to check if the condition part of the
``for`` loop compares a variable against the size of the array. There is
only one problem - we don't know which array we're iterating over
without looking at the body of the loop! We are again restricted to
approximating the result we want with matchers, filling in the details
in the callback. So we start with:

.. code-block:: c++

      hasCondition(binaryOperator(hasOperatorName("<"))

It makes sense to ensure that the left-hand side is a reference to a
variable, and that the right-hand side has integer type.

.. code-block:: c++

      hasCondition(binaryOperator(
        hasOperatorName("<"),
        hasLHS(declRefExpr(to(varDecl(hasType(isInteger()))))),
        hasRHS(expr(hasType(isInteger())))))

Why? Because it doesn't work. Of the three loops provided in
``test-files/simple.cpp``, zero of them have a matching condition. A
quick look at the AST dump of the first for loop, produced by the
previous iteration of loop-convert, shows us the answer:

::

      (ForStmt 0x173b240
        (DeclStmt 0x173afc8
          0x173af50 "int i =
            (IntegerLiteral 0x173afa8 'int' 0)")
        <<>>
        (BinaryOperator 0x173b060 '_Bool' '<'
          (ImplicitCastExpr 0x173b030 'int'
            (DeclRefExpr 0x173afe0 'int' lvalue Var 0x173af50 'i' 'int'))
          (ImplicitCastExpr 0x173b048 'int'
            (DeclRefExpr 0x173b008 'const int' lvalue Var 0x170fa80 'N' 'const int')))
        (UnaryOperator 0x173b0b0 'int' lvalue prefix '++'
          (DeclRefExpr 0x173b088 'int' lvalue Var 0x173af50 'i' 'int'))
        (CompoundStatement ...

We already know that the declaration and increments both match, or this
loop wouldn't have been dumped. The culprit lies in the implicit cast
applied to the first operand (i.e. the LHS) of the less-than operator,
an L-value to R-value conversion applied to the expression referencing
``i``. Thankfully, the matcher library offers a solution to this problem
in the form of ``ignoringParenImpCasts``, which instructs the matcher to
ignore implicit casts and parentheses before continuing to match.
Adjusting the condition operator will restore the desired match.

.. code-block:: c++

      hasCondition(binaryOperator(
        hasOperatorName("<"),
        hasLHS(ignoringParenImpCasts(declRefExpr(
          to(varDecl(hasType(isInteger())))))),
        hasRHS(expr(hasType(isInteger())))))

After adding binds to the expressions we wished to capture and
extracting the identifier strings into variables, we have array-step-2
completed.

Step 4: Retrieving Matched Nodes
================================

So far, the matcher callback isn't very interesting: it just dumps the
loop's AST. At some point, we will need to make changes to the input
source code. Next, we'll work on using the nodes we bound in the
previous step.

The ``MatchFinder::run()`` callback takes a
``MatchFinder::MatchResult&`` as its parameter. We're most interested in
its ``Context`` and ``Nodes`` members. Clang uses the ``ASTContext``
class to represent contextual information about the AST, as the name
implies, though the most functionally important detail is that several
operations require an ``ASTContext*`` parameter. More immediately useful
is the set of matched nodes, and how we retrieve them.

Since we bind three variables (identified by ConditionVarName,
InitVarName, and IncrementVarName), we can obtain the matched nodes by
using the ``getNodeAs()`` member function.

In ``LoopConvert.cpp`` add

.. code-block:: c++

      #include "clang/AST/ASTContext.h"

Change ``LoopMatcher`` to

.. code-block:: c++

      StatementMatcher LoopMatcher =
          forStmt(hasLoopInit(declStmt(
                      hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0))))
                                        .bind("initVarName")))),
                  hasIncrement(unaryOperator(
                      hasOperatorName("++"),
                      hasUnaryOperand(declRefExpr(
                          to(varDecl(hasType(isInteger())).bind("incVarName")))))),
                  hasCondition(binaryOperator(
                      hasOperatorName("<"),
                      hasLHS(ignoringParenImpCasts(declRefExpr(
                          to(varDecl(hasType(isInteger())).bind("condVarName"))))),
                      hasRHS(expr(hasType(isInteger())))))).bind("forLoop");

And change ``LoopPrinter::run`` to

.. code-block:: c++

      void LoopPrinter::run(const MatchFinder::MatchResult &Result) {
        ASTContext *Context = Result.Context;
        const ForStmt *FS = Result.Nodes.getNodeAs<ForStmt>("forLoop");
        // We do not want to convert header files!
        if (!FS || !Context->getSourceManager().isWrittenInMainFile(FS->getForLoc()))
          return;
        const VarDecl *IncVar = Result.Nodes.getNodeAs<VarDecl>("incVarName");
        const VarDecl *CondVar = Result.Nodes.getNodeAs<VarDecl>("condVarName");
        const VarDecl *InitVar = Result.Nodes.getNodeAs<VarDecl>("initVarName");

        if (!areSameVariable(IncVar, CondVar) || !areSameVariable(IncVar, InitVar))
          return;
        llvm::outs() << "Potential array-based loop discovered.\n";
      }

Clang associates a ``VarDecl`` with each variable to represent the variable's
declaration. Since the "canonical" form of each declaration is unique by
address, all we need to do is make sure neither ``ValueDecl`` (base class of
``VarDecl``) is ``NULL`` and compare the canonical Decls.

.. code-block:: c++

      static bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) {
        return First && Second &&
               First->getCanonicalDecl() == Second->getCanonicalDecl();
      }

If execution reaches the end of ``LoopPrinter::run()``, we know that the
loop shell that looks like

.. code-block:: c++

      for (int i= 0; i < expr(); ++i) { ... }

For now, we will just print a message explaining that we found a loop.
The next section will deal with recursively traversing the AST to
discover all changes needed.

As a side note, it's not as trivial to test if two expressions are the same,
though Clang has already done the hard work for us by providing a way to
canonicalize expressions:

.. code-block:: c++

      static bool areSameExpr(ASTContext *Context, const Expr *First,
                              const Expr *Second) {
        if (!First || !Second)
          return false;
        llvm::FoldingSetNodeID FirstID, SecondID;
        First->Profile(FirstID, *Context, true);
        Second->Profile(SecondID, *Context, true);
        return FirstID == SecondID;
      }

This code relies on the comparison between two
``llvm::FoldingSetNodeIDs``. As the documentation for
``Stmt::Profile()`` indicates, the ``Profile()`` member function builds
a description of a node in the AST, based on its properties, along with
those of its children. ``FoldingSetNodeID`` then serves as a hash we can
use to compare expressions. We will need ``areSameExpr`` later. Before
you run the new code on the additional loops added to
test-files/simple.cpp, try to figure out which ones will be considered
potentially convertible.
