head 1.1; branch 1.1.1; access; symbols netbsd-10-2-RELEASE:1.1.1.7 netbsd-9-5-RELEASE:1.1.1.6 netbsd-11-0-RELEASE:1.1.1.7 netbsd-11-0-RC7:1.1.1.7 netbsd-11-0-RC6:1.1.1.7 netbsd-11-0-RC5:1.1.1.7 netbsd-11-0-RC4:1.1.1.7 netbsd-11-0-RC3:1.1.1.7 netbsd-11-0-RC2:1.1.1.7 netbsd-11-0-RC1:1.1.1.7 perseant-exfatfs-base-20250801:1.1.1.7 netbsd-11:1.1.1.7.0.10 netbsd-11-base:1.1.1.7 netbsd-10-1-RELEASE:1.1.1.7 perseant-exfatfs-base-20240630:1.1.1.7 perseant-exfatfs:1.1.1.7.0.8 perseant-exfatfs-base:1.1.1.7 netbsd-8-3-RELEASE:1.1.1.5 netbsd-9-4-RELEASE:1.1.1.6 netbsd-10-0-RELEASE:1.1.1.7 netbsd-10-0-RC6:1.1.1.7 netbsd-10-0-RC5:1.1.1.7 netbsd-10-0-RC4:1.1.1.7 netbsd-10-0-RC3:1.1.1.7 netbsd-10-0-RC2:1.1.1.7 netbsd-10-0-RC1:1.1.1.7 netbsd-10:1.1.1.7.0.6 netbsd-10-base:1.1.1.7 netbsd-9-3-RELEASE:1.1.1.6 cjep_sun2x:1.1.1.7.0.4 cjep_sun2x-base:1.1.1.7 cjep_staticlib_x-base1:1.1.1.7 netbsd-9-2-RELEASE:1.1.1.6 cjep_staticlib_x:1.1.1.7.0.2 cjep_staticlib_x-base:1.1.1.7 netbsd-9-1-RELEASE:1.1.1.6 phil-wifi-20200421:1.1.1.7 phil-wifi-20200411:1.1.1.7 phil-wifi-20200406:1.1.1.7 netbsd-8-2-RELEASE:1.1.1.5 netbsd-9-0-RELEASE:1.1.1.6 netbsd-9-0-RC2:1.1.1.6 netbsd-9-0-RC1:1.1.1.6 netbsd-9:1.1.1.6.0.2 netbsd-9-base:1.1.1.6 phil-wifi-20190609:1.1.1.6 netbsd-8-1-RELEASE:1.1.1.5 netbsd-8-1-RC1:1.1.1.5 pgoyette-compat-merge-20190127:1.1.1.5.24.1 pgoyette-compat-20190127:1.1.1.6 pgoyette-compat-20190118:1.1.1.6 pgoyette-compat-1226:1.1.1.6 pgoyette-compat-1126:1.1.1.6 pgoyette-compat-1020:1.1.1.6 pgoyette-compat-0930:1.1.1.6 pgoyette-compat-0906:1.1.1.6 netbsd-7-2-RELEASE:1.1.1.5 pgoyette-compat-0728:1.1.1.6 clang-337282:1.1.1.6 netbsd-8-0-RELEASE:1.1.1.5 phil-wifi:1.1.1.5.0.26 phil-wifi-base:1.1.1.5 pgoyette-compat-0625:1.1.1.5 netbsd-8-0-RC2:1.1.1.5 pgoyette-compat-0521:1.1.1.5 pgoyette-compat-0502:1.1.1.5 pgoyette-compat-0422:1.1.1.5 netbsd-8-0-RC1:1.1.1.5 pgoyette-compat-0415:1.1.1.5 pgoyette-compat-0407:1.1.1.5 pgoyette-compat-0330:1.1.1.5 pgoyette-compat-0322:1.1.1.5 pgoyette-compat-0315:1.1.1.5 netbsd-7-1-2-RELEASE:1.1.1.5 pgoyette-compat:1.1.1.5.0.24 pgoyette-compat-base:1.1.1.5 netbsd-7-1-1-RELEASE:1.1.1.5 clang-319952:1.1.1.5 matt-nb8-mediatek:1.1.1.5.0.22 matt-nb8-mediatek-base:1.1.1.5 clang-309604:1.1.1.5 perseant-stdc-iso10646:1.1.1.5.0.20 perseant-stdc-iso10646-base:1.1.1.5 netbsd-8:1.1.1.5.0.18 netbsd-8-base:1.1.1.5 prg-localcount2-base3:1.1.1.5 prg-localcount2-base2:1.1.1.5 prg-localcount2-base1:1.1.1.5 prg-localcount2:1.1.1.5.0.16 prg-localcount2-base:1.1.1.5 pgoyette-localcount-20170426:1.1.1.5 bouyer-socketcan-base1:1.1.1.5 pgoyette-localcount-20170320:1.1.1.5 netbsd-7-1:1.1.1.5.0.14 netbsd-7-1-RELEASE:1.1.1.5 netbsd-7-1-RC2:1.1.1.5 clang-294123:1.1.1.5 netbsd-7-nhusb-base-20170116:1.1.1.5 bouyer-socketcan:1.1.1.5.0.12 bouyer-socketcan-base:1.1.1.5 clang-291444:1.1.1.5 pgoyette-localcount-20170107:1.1.1.5 netbsd-7-1-RC1:1.1.1.5 pgoyette-localcount-20161104:1.1.1.5 netbsd-7-0-2-RELEASE:1.1.1.5 localcount-20160914:1.1.1.5 netbsd-7-nhusb:1.1.1.5.0.10 netbsd-7-nhusb-base:1.1.1.5 clang-280599:1.1.1.5 pgoyette-localcount-20160806:1.1.1.5 pgoyette-localcount-20160726:1.1.1.5 pgoyette-localcount:1.1.1.5.0.8 pgoyette-localcount-base:1.1.1.5 netbsd-7-0-1-RELEASE:1.1.1.5 clang-261930:1.1.1.5 netbsd-7-0:1.1.1.5.0.6 netbsd-7-0-RELEASE:1.1.1.5 netbsd-7-0-RC3:1.1.1.5 netbsd-7-0-RC2:1.1.1.5 netbsd-7-0-RC1:1.1.1.5 clang-237755:1.1.1.5 clang-232565:1.1.1.5 clang-227398:1.1.1.5 tls-maxphys-base:1.1.1.5 tls-maxphys:1.1.1.5.0.4 netbsd-7:1.1.1.5.0.2 netbsd-7-base:1.1.1.5 clang-215315:1.1.1.5 clang-209886:1.1.1.5 yamt-pagecache:1.1.1.4.0.4 yamt-pagecache-base9:1.1.1.4 tls-earlyentropy:1.1.1.4.0.2 tls-earlyentropy-base:1.1.1.5 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1.1.4 riastradh-drm2-base3:1.1.1.4 clang-202566:1.1.1.4 clang-201163:1.1.1.4 clang-199312:1.1.1.3 clang-198450:1.1.1.2 clang-196603:1.1.1.1 clang-195771:1.1.1.1 LLVM:1.1.1; locks; strict; comment @# @; 1.1 date 2013.11.28.14.14.47; author joerg; state Exp; branches 1.1.1.1; next ; commitid ow8OybrawrB1f3fx; 1.1.1.1 date 2013.11.28.14.14.47; author joerg; state Exp; branches; next 1.1.1.2; commitid ow8OybrawrB1f3fx; 1.1.1.2 date 2014.01.05.15.37.41; author joerg; state Exp; branches; next 1.1.1.3; commitid wh3aCSIWykURqWjx; 1.1.1.3 date 2014.01.15.21.26.16; author joerg; state Exp; branches; next 1.1.1.4; commitid NQXlzzA0SPkc5glx; 1.1.1.4 date 2014.02.14.20.07.00; author joerg; state Exp; branches 1.1.1.4.2.1 1.1.1.4.4.1; next 1.1.1.5; commitid annVkZ1sc17rF6px; 1.1.1.5 date 2014.05.30.18.14.37; author joerg; state Exp; branches 1.1.1.5.4.1 1.1.1.5.24.1 1.1.1.5.26.1; next 1.1.1.6; commitid 8q0kdlBlCn09GACx; 1.1.1.6 date 2018.07.17.18.32.10; author joerg; state Exp; branches; next 1.1.1.7; commitid wDzL46ALjrCZgwKA; 1.1.1.7 date 2019.11.13.22.19.10; author joerg; state dead; branches; next ; commitid QD8YATxuNG34YJKB; 1.1.1.4.2.1 date 2014.08.10.07.08.03; author tls; state Exp; branches; next ; commitid t01A1TLTYxkpGMLx; 1.1.1.4.4.1 date 2014.02.14.20.07.00; author yamt; state dead; branches; next 1.1.1.4.4.2; commitid WSrDtL5nYAUyiyBx; 1.1.1.4.4.2 date 2014.05.22.16.18.19; author yamt; state Exp; branches; next ; commitid WSrDtL5nYAUyiyBx; 1.1.1.5.4.1 date 2014.05.30.18.14.37; author tls; state dead; branches; next 1.1.1.5.4.2; commitid jTnpym9Qu0o4R1Nx; 1.1.1.5.4.2 date 2014.08.19.23.47.19; author tls; state Exp; branches; next ; commitid jTnpym9Qu0o4R1Nx; 1.1.1.5.24.1 date 2018.07.28.04.33.07; author pgoyette; state Exp; branches; next ; commitid 1UP1xAIUxv1ZgRLA; 1.1.1.5.26.1 date 2019.06.10.21.45.09; author christos; state Exp; branches; next 1.1.1.5.26.2; commitid jtc8rnCzWiEEHGqB; 1.1.1.5.26.2 date 2020.04.13.07.46.20; author martin; state dead; branches; next ; commitid X01YhRUPVUDaec4C; desc @@ 1.1 log @Initial revision @ text @========== LibTooling ========== LibTooling is a library to support writing standalone tools based on Clang. This document will provide a basic walkthrough of how to write a tool using LibTooling. For the information on how to setup Clang Tooling for LLVM see :doc:`HowToSetupToolingForLLVM` Introduction ------------ Tools built with LibTooling, like Clang Plugins, run ``FrontendActions`` over code. .. See FIXME for a tutorial on how to write FrontendActions. In this tutorial, we'll demonstrate the different ways of running Clang's ``SyntaxOnlyAction``, which runs a quick syntax check, over a bunch of code. Parsing a code snippet in memory -------------------------------- If you ever wanted to run a ``FrontendAction`` over some sample code, for example to unit test parts of the Clang AST, ``runToolOnCode`` is what you looked for. Let me give you an example: .. code-block:: c++ #include "clang/Tooling/Tooling.h" TEST(runToolOnCode, CanSyntaxCheckCode) { // runToolOnCode returns whether the action was correctly run over the // given code. EXPECT_TRUE(runToolOnCode(new clang::SyntaxOnlyAction, "class X {};")); } Writing a standalone tool ------------------------- Once you unit tested your ``FrontendAction`` to the point where it cannot possibly break, it's time to create a standalone tool. For a standalone tool to run clang, it first needs to figure out what command line arguments to use for a specified file. To that end we create a ``CompilationDatabase``. There are different ways to create a compilation database, and we need to support all of them depending on command-line options. There's the ``CommonOptionsParser`` class that takes the responsibility to parse command-line parameters related to compilation databases and inputs, so that all tools share the implementation. Parsing common tools options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``CompilationDatabase`` can be read from a build directory or the command line. Using ``CommonOptionsParser`` allows for explicit specification of a compile command line, specification of build path using the ``-p`` command-line option, and automatic location of the compilation database using source files paths. .. code-block:: c++ #include "clang/Tooling/CommonOptionsParser.h" using namespace clang::tooling; int main(int argc, const char **argv) { // CommonOptionsParser constructor will parse arguments and create a // CompilationDatabase. In case of error it will terminate the program. CommonOptionsParser OptionsParser(argc, argv); // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList() // to retrieve CompilationDatabase and the list of input file paths. } Creating and running a ClangTool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Once we have a ``CompilationDatabase``, we can create a ``ClangTool`` and run our ``FrontendAction`` over some code. For example, to run the ``SyntaxOnlyAction`` over the files "a.cc" and "b.cc" one would write: .. code-block:: c++ // A clang tool can run over a number of sources in the same process... std::vector Sources; Sources.push_back("a.cc"); Sources.push_back("b.cc"); // We hand the CompilationDatabase we created and the sources to run over into // the tool constructor. ClangTool Tool(OptionsParser.getCompilations(), Sources); // The ClangTool needs a new FrontendAction for each translation unit we run // on. Thus, it takes a FrontendActionFactory as parameter. To create a // FrontendActionFactory from a given FrontendAction type, we call // newFrontendActionFactory(). int result = Tool.run(newFrontendActionFactory()); Putting it together --- the first tool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now we combine the two previous steps into our first real tool. This example tool is also checked into the clang tree at ``tools/clang-check/ClangCheck.cpp``. .. 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; // 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..."); int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return Tool.run(newFrontendActionFactory()); } Running the tool on some code ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you check out and build clang, clang-check is already built and available to you in bin/clang-check inside your build directory. You can run clang-check on a file in the llvm repository by specifying all the needed parameters after a "``--``" separator: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check tools/clang/tools/clang-check/ClangCheck.cpp -- \ clang++ -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS \ -Itools/clang/include -I$BD/include -Iinclude \ -Itools/clang/lib/Headers -c As an alternative, you can also configure cmake to output a compile command database into its build directory: .. code-block:: bash # Alternatively to calling cmake, use ccmake, toggle to advanced mode and # set the parameter CMAKE_EXPORT_COMPILE_COMMANDS from the UI. $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . This creates a file called ``compile_commands.json`` in the build directory. Now you can run :program:`clang-check` over files in the project by specifying the build path as first argument and some source files as further positional arguments: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check -p $BD tools/clang/tools/clang-check/ClangCheck.cpp .. _libtooling_builtin_includes: Builtin includes ^^^^^^^^^^^^^^^^ Clang tools need their builtin headers and search for them the same way Clang does. Thus, the default location to look for builtin headers is in a path ``$(dirname /path/to/tool)/../lib/clang/3.4/include`` relative to the tool binary. This works out-of-the-box for tools running from llvm's toplevel binary directory after building clang-headers, or if the tool is running from the binary directory of a clang install next to the clang binary. Tips: if your tool fails to find ``stddef.h`` or similar headers, call the tool with ``-v`` and look at the search paths it looks through. Linking ^^^^^^^ For a list of libraries to link, look at one of the tools' Makefiles (for example `clang-check/Makefile `_). @ 1.1.1.1 log @Import Clang 3.4rc1 r195771. @ text @@ 1.1.1.2 log @Import clang 3.5svn r198450. @ text @a62 1 #include "llvm/Support/CommandLine.h" a65 4 // Apply a custom category to all command-line options so that they are the // only ones displayed. llvm::cl::OptionCategory MyToolCategory("my-tool options"); d69 1 a69 1 CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); a117 4 // Apply a custom category to all command-line options so that they are the // only ones displayed. cl::OptionCategory MyToolCategory("my-tool options"); d127 1 a127 1 CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); d179 1 a179 1 ``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool @ 1.1.1.3 log @Import Clang 3.5svn r199312 @ text @d107 2 a108 2 Now we combine the two previous steps into our first real tool. A more advanced version of this example tool is also checked into the clang tree at @ 1.1.1.4 log @Import Clang 3.5svn r201163. @ text @d69 1 a69 1 static llvm::cl::OptionCategory MyToolCategory("my-tool options"); d125 1 a125 1 static cl::OptionCategory MyToolCategory("my-tool options"); d138 1 a138 1 OptionsParser.getSourcePathList()); @ 1.1.1.4.2.1 log @Rebase. @ text @d102 1 a102 1 int result = Tool.run(newFrontendActionFactory().get()); d139 1 a139 1 return Tool.run(newFrontendActionFactory().get()); @ 1.1.1.5 log @Import Clang 3.5svn r209886. @ text @d102 1 a102 1 int result = Tool.run(newFrontendActionFactory().get()); d139 1 a139 1 return Tool.run(newFrontendActionFactory().get()); @ 1.1.1.5.26.1 log @Sync with HEAD @ text @d133 1 a133 1 static cl::extrahelp MoreHelp("\nMore help text...\n"); @ 1.1.1.5.26.2 log @Mostly merge changes from HEAD upto 20200411 @ text @@ 1.1.1.5.24.1 log @Sync with HEAD @ text @d133 1 a133 1 static cl::extrahelp MoreHelp("\nMore help text...\n"); @ 1.1.1.6 log @Import clang r337282 from trunk @ text @d133 1 a133 1 static cl::extrahelp MoreHelp("\nMore help text...\n"); @ 1.1.1.7 log @Mark old LLVM instance as dead. @ text @@ 1.1.1.5.4.1 log @file LibTooling.rst was added on branch tls-maxphys on 2014-08-19 23:47:19 +0000 @ text @d1 201 @ 1.1.1.5.4.2 log @Rebase to HEAD as of a few days ago. @ text @a0 201 ========== LibTooling ========== LibTooling is a library to support writing standalone tools based on Clang. This document will provide a basic walkthrough of how to write a tool using LibTooling. For the information on how to setup Clang Tooling for LLVM see :doc:`HowToSetupToolingForLLVM` Introduction ------------ Tools built with LibTooling, like Clang Plugins, run ``FrontendActions`` over code. .. See FIXME for a tutorial on how to write FrontendActions. In this tutorial, we'll demonstrate the different ways of running Clang's ``SyntaxOnlyAction``, which runs a quick syntax check, over a bunch of code. Parsing a code snippet in memory -------------------------------- If you ever wanted to run a ``FrontendAction`` over some sample code, for example to unit test parts of the Clang AST, ``runToolOnCode`` is what you looked for. Let me give you an example: .. code-block:: c++ #include "clang/Tooling/Tooling.h" TEST(runToolOnCode, CanSyntaxCheckCode) { // runToolOnCode returns whether the action was correctly run over the // given code. EXPECT_TRUE(runToolOnCode(new clang::SyntaxOnlyAction, "class X {};")); } Writing a standalone tool ------------------------- Once you unit tested your ``FrontendAction`` to the point where it cannot possibly break, it's time to create a standalone tool. For a standalone tool to run clang, it first needs to figure out what command line arguments to use for a specified file. To that end we create a ``CompilationDatabase``. There are different ways to create a compilation database, and we need to support all of them depending on command-line options. There's the ``CommonOptionsParser`` class that takes the responsibility to parse command-line parameters related to compilation databases and inputs, so that all tools share the implementation. Parsing common tools options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``CompilationDatabase`` can be read from a build directory or the command line. Using ``CommonOptionsParser`` allows for explicit specification of a compile command line, specification of build path using the ``-p`` command-line option, and automatic location of the compilation database using source files paths. .. code-block:: c++ #include "clang/Tooling/CommonOptionsParser.h" #include "llvm/Support/CommandLine.h" using namespace clang::tooling; // 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"); int main(int argc, const char **argv) { // CommonOptionsParser constructor will parse arguments and create a // CompilationDatabase. In case of error it will terminate the program. CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList() // to retrieve CompilationDatabase and the list of input file paths. } Creating and running a ClangTool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Once we have a ``CompilationDatabase``, we can create a ``ClangTool`` and run our ``FrontendAction`` over some code. For example, to run the ``SyntaxOnlyAction`` over the files "a.cc" and "b.cc" one would write: .. code-block:: c++ // A clang tool can run over a number of sources in the same process... std::vector Sources; Sources.push_back("a.cc"); Sources.push_back("b.cc"); // We hand the CompilationDatabase we created and the sources to run over into // the tool constructor. ClangTool Tool(OptionsParser.getCompilations(), Sources); // The ClangTool needs a new FrontendAction for each translation unit we run // on. Thus, it takes a FrontendActionFactory as parameter. To create a // FrontendActionFactory from a given FrontendAction type, we call // newFrontendActionFactory(). int result = Tool.run(newFrontendActionFactory().get()); Putting it together --- the first tool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now we combine the two previous steps into our first real tool. A more advanced version of this example tool is also checked into the clang tree at ``tools/clang-check/ClangCheck.cpp``. .. 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 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..."); int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return Tool.run(newFrontendActionFactory().get()); } Running the tool on some code ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you check out and build clang, clang-check is already built and available to you in bin/clang-check inside your build directory. You can run clang-check on a file in the llvm repository by specifying all the needed parameters after a "``--``" separator: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check tools/clang/tools/clang-check/ClangCheck.cpp -- \ clang++ -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS \ -Itools/clang/include -I$BD/include -Iinclude \ -Itools/clang/lib/Headers -c As an alternative, you can also configure cmake to output a compile command database into its build directory: .. code-block:: bash # Alternatively to calling cmake, use ccmake, toggle to advanced mode and # set the parameter CMAKE_EXPORT_COMPILE_COMMANDS from the UI. $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . This creates a file called ``compile_commands.json`` in the build directory. Now you can run :program:`clang-check` over files in the project by specifying the build path as first argument and some source files as further positional arguments: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check -p $BD tools/clang/tools/clang-check/ClangCheck.cpp .. _libtooling_builtin_includes: Builtin includes ^^^^^^^^^^^^^^^^ Clang tools need their builtin headers and search for them the same way Clang does. Thus, the default location to look for builtin headers is in a path ``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool binary. This works out-of-the-box for tools running from llvm's toplevel binary directory after building clang-headers, or if the tool is running from the binary directory of a clang install next to the clang binary. Tips: if your tool fails to find ``stddef.h`` or similar headers, call the tool with ``-v`` and look at the search paths it looks through. Linking ^^^^^^^ For a list of libraries to link, look at one of the tools' Makefiles (for example `clang-check/Makefile `_). @ 1.1.1.4.4.1 log @file LibTooling.rst was added on branch yamt-pagecache on 2014-05-22 16:18:19 +0000 @ text @d1 201 @ 1.1.1.4.4.2 log @sync with head. for a reference, the tree before this commit was tagged as yamt-pagecache-tag8. this commit was splitted into small chunks to avoid a limitation of cvs. ("Protocol error: too many arguments") @ text @a0 201 ========== LibTooling ========== LibTooling is a library to support writing standalone tools based on Clang. This document will provide a basic walkthrough of how to write a tool using LibTooling. For the information on how to setup Clang Tooling for LLVM see :doc:`HowToSetupToolingForLLVM` Introduction ------------ Tools built with LibTooling, like Clang Plugins, run ``FrontendActions`` over code. .. See FIXME for a tutorial on how to write FrontendActions. In this tutorial, we'll demonstrate the different ways of running Clang's ``SyntaxOnlyAction``, which runs a quick syntax check, over a bunch of code. Parsing a code snippet in memory -------------------------------- If you ever wanted to run a ``FrontendAction`` over some sample code, for example to unit test parts of the Clang AST, ``runToolOnCode`` is what you looked for. Let me give you an example: .. code-block:: c++ #include "clang/Tooling/Tooling.h" TEST(runToolOnCode, CanSyntaxCheckCode) { // runToolOnCode returns whether the action was correctly run over the // given code. EXPECT_TRUE(runToolOnCode(new clang::SyntaxOnlyAction, "class X {};")); } Writing a standalone tool ------------------------- Once you unit tested your ``FrontendAction`` to the point where it cannot possibly break, it's time to create a standalone tool. For a standalone tool to run clang, it first needs to figure out what command line arguments to use for a specified file. To that end we create a ``CompilationDatabase``. There are different ways to create a compilation database, and we need to support all of them depending on command-line options. There's the ``CommonOptionsParser`` class that takes the responsibility to parse command-line parameters related to compilation databases and inputs, so that all tools share the implementation. Parsing common tools options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``CompilationDatabase`` can be read from a build directory or the command line. Using ``CommonOptionsParser`` allows for explicit specification of a compile command line, specification of build path using the ``-p`` command-line option, and automatic location of the compilation database using source files paths. .. code-block:: c++ #include "clang/Tooling/CommonOptionsParser.h" #include "llvm/Support/CommandLine.h" using namespace clang::tooling; // 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"); int main(int argc, const char **argv) { // CommonOptionsParser constructor will parse arguments and create a // CompilationDatabase. In case of error it will terminate the program. CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList() // to retrieve CompilationDatabase and the list of input file paths. } Creating and running a ClangTool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Once we have a ``CompilationDatabase``, we can create a ``ClangTool`` and run our ``FrontendAction`` over some code. For example, to run the ``SyntaxOnlyAction`` over the files "a.cc" and "b.cc" one would write: .. code-block:: c++ // A clang tool can run over a number of sources in the same process... std::vector Sources; Sources.push_back("a.cc"); Sources.push_back("b.cc"); // We hand the CompilationDatabase we created and the sources to run over into // the tool constructor. ClangTool Tool(OptionsParser.getCompilations(), Sources); // The ClangTool needs a new FrontendAction for each translation unit we run // on. Thus, it takes a FrontendActionFactory as parameter. To create a // FrontendActionFactory from a given FrontendAction type, we call // newFrontendActionFactory(). int result = Tool.run(newFrontendActionFactory()); Putting it together --- the first tool ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now we combine the two previous steps into our first real tool. A more advanced version of this example tool is also checked into the clang tree at ``tools/clang-check/ClangCheck.cpp``. .. 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 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..."); int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return Tool.run(newFrontendActionFactory()); } Running the tool on some code ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you check out and build clang, clang-check is already built and available to you in bin/clang-check inside your build directory. You can run clang-check on a file in the llvm repository by specifying all the needed parameters after a "``--``" separator: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check tools/clang/tools/clang-check/ClangCheck.cpp -- \ clang++ -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS \ -Itools/clang/include -I$BD/include -Iinclude \ -Itools/clang/lib/Headers -c As an alternative, you can also configure cmake to output a compile command database into its build directory: .. code-block:: bash # Alternatively to calling cmake, use ccmake, toggle to advanced mode and # set the parameter CMAKE_EXPORT_COMPILE_COMMANDS from the UI. $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . This creates a file called ``compile_commands.json`` in the build directory. Now you can run :program:`clang-check` over files in the project by specifying the build path as first argument and some source files as further positional arguments: .. code-block:: bash $ cd /path/to/source/llvm $ export BD=/path/to/build/llvm $ $BD/bin/clang-check -p $BD tools/clang/tools/clang-check/ClangCheck.cpp .. _libtooling_builtin_includes: Builtin includes ^^^^^^^^^^^^^^^^ Clang tools need their builtin headers and search for them the same way Clang does. Thus, the default location to look for builtin headers is in a path ``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool binary. This works out-of-the-box for tools running from llvm's toplevel binary directory after building clang-headers, or if the tool is running from the binary directory of a clang install next to the clang binary. Tips: if your tool fails to find ``stddef.h`` or similar headers, call the tool with ``-v`` and look at the search paths it looks through. Linking ^^^^^^^ For a list of libraries to link, look at one of the tools' Makefiles (for example `clang-check/Makefile `_). @