xref: /openbsd-src/gnu/llvm/clang/docs/LibTooling.rst (revision a9ac8606c53d55cee9c3a39778b249c51df111ef)
1e5dd7070Spatrick==========
2e5dd7070SpatrickLibTooling
3e5dd7070Spatrick==========
4e5dd7070Spatrick
5e5dd7070SpatrickLibTooling is a library to support writing standalone tools based on Clang.
6e5dd7070SpatrickThis document will provide a basic walkthrough of how to write a tool using
7e5dd7070SpatrickLibTooling.
8e5dd7070Spatrick
9e5dd7070SpatrickFor the information on how to setup Clang Tooling for LLVM see
10e5dd7070Spatrick:doc:`HowToSetupToolingForLLVM`
11e5dd7070Spatrick
12e5dd7070SpatrickIntroduction
13e5dd7070Spatrick------------
14e5dd7070Spatrick
15e5dd7070SpatrickTools built with LibTooling, like Clang Plugins, run ``FrontendActions`` over
16e5dd7070Spatrickcode.
17e5dd7070Spatrick
18e5dd7070Spatrick..  See FIXME for a tutorial on how to write FrontendActions.
19e5dd7070Spatrick
20e5dd7070SpatrickIn this tutorial, we'll demonstrate the different ways of running Clang's
21e5dd7070Spatrick``SyntaxOnlyAction``, which runs a quick syntax check, over a bunch of code.
22e5dd7070Spatrick
23e5dd7070SpatrickParsing a code snippet in memory
24e5dd7070Spatrick--------------------------------
25e5dd7070Spatrick
26e5dd7070SpatrickIf you ever wanted to run a ``FrontendAction`` over some sample code, for
27e5dd7070Spatrickexample to unit test parts of the Clang AST, ``runToolOnCode`` is what you
28e5dd7070Spatricklooked for.  Let me give you an example:
29e5dd7070Spatrick
30e5dd7070Spatrick.. code-block:: c++
31e5dd7070Spatrick
32e5dd7070Spatrick  #include "clang/Tooling/Tooling.h"
33e5dd7070Spatrick
34e5dd7070Spatrick  TEST(runToolOnCode, CanSyntaxCheckCode) {
35e5dd7070Spatrick    // runToolOnCode returns whether the action was correctly run over the
36e5dd7070Spatrick    // given code.
37e5dd7070Spatrick    EXPECT_TRUE(runToolOnCode(std::make_unique<clang::SyntaxOnlyAction>(), "class X {};"));
38e5dd7070Spatrick  }
39e5dd7070Spatrick
40e5dd7070SpatrickWriting a standalone tool
41e5dd7070Spatrick-------------------------
42e5dd7070Spatrick
43e5dd7070SpatrickOnce you unit tested your ``FrontendAction`` to the point where it cannot
44e5dd7070Spatrickpossibly break, it's time to create a standalone tool.  For a standalone tool
45e5dd7070Spatrickto run clang, it first needs to figure out what command line arguments to use
46e5dd7070Spatrickfor a specified file.  To that end we create a ``CompilationDatabase``.  There
47e5dd7070Spatrickare different ways to create a compilation database, and we need to support all
48e5dd7070Spatrickof them depending on command-line options.  There's the ``CommonOptionsParser``
49e5dd7070Spatrickclass that takes the responsibility to parse command-line parameters related to
50e5dd7070Spatrickcompilation databases and inputs, so that all tools share the implementation.
51e5dd7070Spatrick
52e5dd7070SpatrickParsing common tools options
53e5dd7070Spatrick^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54e5dd7070Spatrick
55e5dd7070Spatrick``CompilationDatabase`` can be read from a build directory or the command line.
56e5dd7070SpatrickUsing ``CommonOptionsParser`` allows for explicit specification of a compile
57e5dd7070Spatrickcommand line, specification of build path using the ``-p`` command-line option,
58e5dd7070Spatrickand automatic location of the compilation database using source files paths.
59e5dd7070Spatrick
60e5dd7070Spatrick.. code-block:: c++
61e5dd7070Spatrick
62e5dd7070Spatrick  #include "clang/Tooling/CommonOptionsParser.h"
63e5dd7070Spatrick  #include "llvm/Support/CommandLine.h"
64e5dd7070Spatrick
65e5dd7070Spatrick  using namespace clang::tooling;
66e5dd7070Spatrick
67e5dd7070Spatrick  // Apply a custom category to all command-line options so that they are the
68e5dd7070Spatrick  // only ones displayed.
69e5dd7070Spatrick  static llvm::cl::OptionCategory MyToolCategory("my-tool options");
70e5dd7070Spatrick
71e5dd7070Spatrick  int main(int argc, const char **argv) {
72e5dd7070Spatrick    // CommonOptionsParser constructor will parse arguments and create a
73e5dd7070Spatrick    // CompilationDatabase.  In case of error it will terminate the program.
74e5dd7070Spatrick    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
75e5dd7070Spatrick
76e5dd7070Spatrick    // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList()
77e5dd7070Spatrick    // to retrieve CompilationDatabase and the list of input file paths.
78e5dd7070Spatrick  }
79e5dd7070Spatrick
80e5dd7070SpatrickCreating and running a ClangTool
81e5dd7070Spatrick^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
82e5dd7070Spatrick
83e5dd7070SpatrickOnce we have a ``CompilationDatabase``, we can create a ``ClangTool`` and run
84e5dd7070Spatrickour ``FrontendAction`` over some code.  For example, to run the
85e5dd7070Spatrick``SyntaxOnlyAction`` over the files "a.cc" and "b.cc" one would write:
86e5dd7070Spatrick
87e5dd7070Spatrick.. code-block:: c++
88e5dd7070Spatrick
89e5dd7070Spatrick  // A clang tool can run over a number of sources in the same process...
90e5dd7070Spatrick  std::vector<std::string> Sources;
91e5dd7070Spatrick  Sources.push_back("a.cc");
92e5dd7070Spatrick  Sources.push_back("b.cc");
93e5dd7070Spatrick
94e5dd7070Spatrick  // We hand the CompilationDatabase we created and the sources to run over into
95e5dd7070Spatrick  // the tool constructor.
96e5dd7070Spatrick  ClangTool Tool(OptionsParser.getCompilations(), Sources);
97e5dd7070Spatrick
98e5dd7070Spatrick  // The ClangTool needs a new FrontendAction for each translation unit we run
99e5dd7070Spatrick  // on.  Thus, it takes a FrontendActionFactory as parameter.  To create a
100e5dd7070Spatrick  // FrontendActionFactory from a given FrontendAction type, we call
101e5dd7070Spatrick  // newFrontendActionFactory<clang::SyntaxOnlyAction>().
102e5dd7070Spatrick  int result = Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
103e5dd7070Spatrick
104e5dd7070SpatrickPutting it together --- the first tool
105e5dd7070Spatrick^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
106e5dd7070Spatrick
107e5dd7070SpatrickNow we combine the two previous steps into our first real tool.  A more advanced
108e5dd7070Spatrickversion of this example tool is also checked into the clang tree at
109e5dd7070Spatrick``tools/clang-check/ClangCheck.cpp``.
110e5dd7070Spatrick
111e5dd7070Spatrick.. code-block:: c++
112e5dd7070Spatrick
113e5dd7070Spatrick  // Declares clang::SyntaxOnlyAction.
114e5dd7070Spatrick  #include "clang/Frontend/FrontendActions.h"
115e5dd7070Spatrick  #include "clang/Tooling/CommonOptionsParser.h"
116e5dd7070Spatrick  #include "clang/Tooling/Tooling.h"
117e5dd7070Spatrick  // Declares llvm::cl::extrahelp.
118e5dd7070Spatrick  #include "llvm/Support/CommandLine.h"
119e5dd7070Spatrick
120e5dd7070Spatrick  using namespace clang::tooling;
121e5dd7070Spatrick  using namespace llvm;
122e5dd7070Spatrick
123e5dd7070Spatrick  // Apply a custom category to all command-line options so that they are the
124e5dd7070Spatrick  // only ones displayed.
125e5dd7070Spatrick  static cl::OptionCategory MyToolCategory("my-tool options");
126e5dd7070Spatrick
127e5dd7070Spatrick  // CommonOptionsParser declares HelpMessage with a description of the common
128e5dd7070Spatrick  // command-line options related to the compilation database and input files.
129e5dd7070Spatrick  // It's nice to have this help message in all tools.
130e5dd7070Spatrick  static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
131e5dd7070Spatrick
132e5dd7070Spatrick  // A help message for this specific tool can be added afterwards.
133e5dd7070Spatrick  static cl::extrahelp MoreHelp("\nMore help text...\n");
134e5dd7070Spatrick
135e5dd7070Spatrick  int main(int argc, const char **argv) {
136e5dd7070Spatrick    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
137e5dd7070Spatrick    ClangTool Tool(OptionsParser.getCompilations(),
138e5dd7070Spatrick                   OptionsParser.getSourcePathList());
139e5dd7070Spatrick    return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
140e5dd7070Spatrick  }
141e5dd7070Spatrick
142e5dd7070SpatrickRunning the tool on some code
143e5dd7070Spatrick^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
144e5dd7070Spatrick
145e5dd7070SpatrickWhen you check out and build clang, clang-check is already built and available
146e5dd7070Spatrickto you in bin/clang-check inside your build directory.
147e5dd7070Spatrick
148e5dd7070SpatrickYou can run clang-check on a file in the llvm repository by specifying all the
149e5dd7070Spatrickneeded parameters after a "``--``" separator:
150e5dd7070Spatrick
151e5dd7070Spatrick.. code-block:: bash
152e5dd7070Spatrick
153e5dd7070Spatrick  $ cd /path/to/source/llvm
154e5dd7070Spatrick  $ export BD=/path/to/build/llvm
155e5dd7070Spatrick  $ $BD/bin/clang-check tools/clang/tools/clang-check/ClangCheck.cpp -- \
156e5dd7070Spatrick        clang++ -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS \
157e5dd7070Spatrick        -Itools/clang/include -I$BD/include -Iinclude \
158e5dd7070Spatrick        -Itools/clang/lib/Headers -c
159e5dd7070Spatrick
160e5dd7070SpatrickAs an alternative, you can also configure cmake to output a compile command
161e5dd7070Spatrickdatabase into its build directory:
162e5dd7070Spatrick
163e5dd7070Spatrick.. code-block:: bash
164e5dd7070Spatrick
165e5dd7070Spatrick  # Alternatively to calling cmake, use ccmake, toggle to advanced mode and
166e5dd7070Spatrick  # set the parameter CMAKE_EXPORT_COMPILE_COMMANDS from the UI.
167e5dd7070Spatrick  $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
168e5dd7070Spatrick
169e5dd7070SpatrickThis creates a file called ``compile_commands.json`` in the build directory.
170e5dd7070SpatrickNow you can run :program:`clang-check` over files in the project by specifying
171e5dd7070Spatrickthe build path as first argument and some source files as further positional
172e5dd7070Spatrickarguments:
173e5dd7070Spatrick
174e5dd7070Spatrick.. code-block:: bash
175e5dd7070Spatrick
176e5dd7070Spatrick  $ cd /path/to/source/llvm
177e5dd7070Spatrick  $ export BD=/path/to/build/llvm
178e5dd7070Spatrick  $ $BD/bin/clang-check -p $BD tools/clang/tools/clang-check/ClangCheck.cpp
179e5dd7070Spatrick
180e5dd7070Spatrick
181e5dd7070Spatrick.. _libtooling_builtin_includes:
182e5dd7070Spatrick
183e5dd7070SpatrickBuiltin includes
184e5dd7070Spatrick^^^^^^^^^^^^^^^^
185e5dd7070Spatrick
186e5dd7070SpatrickClang tools need their builtin headers and search for them the same way Clang
187e5dd7070Spatrickdoes.  Thus, the default location to look for builtin headers is in a path
188e5dd7070Spatrick``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool
189e5dd7070Spatrickbinary.  This works out-of-the-box for tools running from llvm's toplevel
190e5dd7070Spatrickbinary directory after building clang-resource-headers, or if the tool is
191e5dd7070Spatrickrunning from the binary directory of a clang install next to the clang binary.
192e5dd7070Spatrick
193e5dd7070SpatrickTips: if your tool fails to find ``stddef.h`` or similar headers, call the tool
194e5dd7070Spatrickwith ``-v`` and look at the search paths it looks through.
195e5dd7070Spatrick
196e5dd7070SpatrickLinking
197e5dd7070Spatrick^^^^^^^
198e5dd7070Spatrick
199e5dd7070SpatrickFor a list of libraries to link, look at one of the tools' CMake files (for
200e5dd7070Spatrickexample `clang-check/CMakeList.txt
201*a9ac8606Spatrick<https://github.com/llvm/llvm-project/blob/main/clang/tools/clang-check/CMakeLists.txt>`_).
202