Merged to 8.0 along with the follow-ups in r351538.
On Thu, Jan 17, 2019 at 7:35 PM Eugene Zelenko via cfe-commits <cfe-commits@lists.llvm.org> wrote: > > Author: eugenezelenko > Date: Thu Jan 17 10:31:34 2019 > New Revision: 351463 > > URL: http://llvm.org/viewvc/llvm-project?rev=351463&view=rev > Log: > [Documentation] Add a chapter about Clang-tidy integrations. > > Patch by Marina Kalashina. > > Differential Revision: https://reviews.llvm.org/D54945 > > Added: > clang-tools-extra/trunk/docs/clang-tidy/Contributing.rst > clang-tools-extra/trunk/docs/clang-tidy/Integrations.rst > Modified: > clang-tools-extra/trunk/docs/clang-tidy/index.rst > > Added: clang-tools-extra/trunk/docs/clang-tidy/Contributing.rst > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/Contributing.rst?rev=351463&view=auto > ============================================================================== > --- clang-tools-extra/trunk/docs/clang-tidy/Contributing.rst (added) > +++ clang-tools-extra/trunk/docs/clang-tidy/Contributing.rst Thu Jan 17 > 10:31:34 2019 > @@ -0,0 +1,507 @@ > +================ > +Getting Involved > +================ > + > +:program:`clang-tidy` has several own checks and can run Clang static > analyzer > +checks, but its power is in the ability to easily write custom checks. > + > +Checks are organized in modules, which can be linked into > :program:`clang-tidy` > +with minimal or no code changes in :program:`clang-tidy`. > + > +Checks can plug into the analysis on the preprocessor level using > `PPCallbacks`_ > +or on the AST level using `AST Matchers`_. When an error is found, checks can > +report them in a way similar to how Clang diagnostics work. A fix-it hint > can be > +attached to a diagnostic message. > + > +The interface provided by :program:`clang-tidy` makes it easy to write useful > +and precise checks in just a few lines of code. If you have an idea for a > good > +check, the rest of this document explains how to do this. > + > +There are a few tools particularly useful when developing clang-tidy checks: > + * ``add_new_check.py`` is a script to automate the process of adding a new > + check, it will create the check, update the CMake file and create a test; > + * ``rename_check.py`` does what the script name suggests, renames an > existing > + check; > + * :program:`clang-query` is invaluable for interactive prototyping of AST > + matchers and exploration of the Clang AST; > + * `clang-check`_ with the ``-ast-dump`` (and optionally > ``-ast-dump-filter``) > + provides a convenient way to dump AST of a C++ program. > + > +If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, > +:program:`clang-tidy` will not be built with support for the > +``clang-analyzer-*`` checks or the ``mpi-*`` checks. > + > + > +.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html > +.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html > +.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html > + > + > +Choosing the Right Place for your Check > +--------------------------------------- > + > +If you have an idea of a check, you should decide whether it should be > +implemented as a: > + > ++ *Clang diagnostic*: if the check is generic enough, targets code patterns > that > + most probably are bugs (rather than style or readability issues), can be > + implemented effectively and with extremely low false positive rate, it may > + make a good Clang diagnostic. > + > ++ *Clang static analyzer check*: if the check requires some sort of control > flow > + analysis, it should probably be implemented as a static analyzer check. > + > ++ *clang-tidy check* is a good choice for linter-style checks, checks that > are > + related to a certain coding style, checks that address code readability, > etc. > + > + > +Preparing your Workspace > +------------------------ > + > +If you are new to LLVM development, you should read the `Getting Started with > +the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ > +documents to check out and build LLVM, Clang and Clang Extra Tools with > CMake. > + > +Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, > and > +let's start! > + > +.. _Getting Started with the LLVM System: > http://llvm.org/docs/GettingStarted.html > +.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html > + > + > +The Directory Structure > +----------------------- > + > +:program:`clang-tidy` source code resides in the > +``llvm/tools/clang/tools/extra`` directory and is structured as follows: > + > +:: > + > + clang-tidy/ # Clang-tidy core. > + |-- ClangTidy.h # Interfaces for users and checks. > + |-- ClangTidyModule.h # Interface for clang-tidy modules. > + |-- ClangTidyModuleRegistry.h # Interface for registering of modules. > + ... > + |-- google/ # Google clang-tidy module. > + |-+ > + |-- GoogleTidyModule.cpp > + |-- GoogleTidyModule.h > + ... > + |-- llvm/ # LLVM clang-tidy module. > + |-+ > + |-- LLVMTidyModule.cpp > + |-- LLVMTidyModule.h > + ... > + |-- objc/ # Objective-C clang-tidy module. > + |-+ > + |-- ObjCTidyModule.cpp > + |-- ObjCTidyModule.h > + ... > + |-- tool/ # Sources of the clang-tidy binary. > + ... > + test/clang-tidy/ # Integration tests. > + ... > + unittests/clang-tidy/ # Unit tests. > + |-- ClangTidyTest.h > + |-- GoogleModuleTest.cpp > + |-- LLVMModuleTest.cpp > + |-- ObjCModuleTest.cpp > + ... > + > + > +Writing a clang-tidy Check > +-------------------------- > + > +So you have an idea of a useful check for :program:`clang-tidy`. > + > +First, if you're not familiar with LLVM development, read through the > `Getting > +Started with LLVM`_ document for instructions on setting up your workflow and > +the `LLVM Coding Standards`_ document to familiarize yourself with the coding > +style used in the project. For code reviews we mostly use `LLVM > Phabricator`_. > + > +.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html > +.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html > +.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html > + > +Next, you need to decide which module the check belongs to. Modules > +are located in subdirectories of `clang-tidy/ > +<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/>`_ > +and contain checks targeting a certain aspect of code quality (performance, > +readability, etc.), certain coding style or standard (Google, LLVM, CERT, > etc.) > +or a widely used API (e.g. MPI). Their names are same as user-facing check > +groups names described :ref:`above <checks-groups-table>`. > + > +After choosing the module and the name for the check, run the > +``clang-tidy/add_new_check.py`` script to create the skeleton of the check > and > +plug it to :program:`clang-tidy`. It's the recommended way of adding new > checks. > + > +If we want to create a `readability-awesome-function-names`, we would run: > + > +.. code-block:: console > + > + $ clang-tidy/add_new_check.py readability awesome-function-names > + > + > +The ``add_new_check.py`` script will: > + * create the class for your check inside the specified module's directory > and > + register it in the module and in the build system; > + * create a lit test file in the ``test/clang-tidy/`` directory; > + * create a documentation file and include it into the > + ``docs/clang-tidy/checks/list.rst``. > + > +Let's see in more detail at the check class definition: > + > +.. code-block:: c++ > + > + ... > + > + #include "../ClangTidy.h" > + > + namespace clang { > + namespace tidy { > + namespace readability { > + > + ... > + class AwesomeFunctionNamesCheck : public ClangTidyCheck { > + public: > + AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) > + : ClangTidyCheck(Name, Context) {} > + void registerMatchers(ast_matchers::MatchFinder *Finder) override; > + void check(const ast_matchers::MatchFinder::MatchResult &Result) > override; > + }; > + > + } // namespace readability > + } // namespace tidy > + } // namespace clang > + > + ... > + > +Constructor of the check receives the ``Name`` and ``Context`` parameters, > and > +must forward them to the ``ClangTidyCheck`` constructor. > + > +In our case the check needs to operate on the AST level and it overrides the > +``registerMatchers`` and ``check`` methods. If we wanted to analyze code on > the > +preprocessor level, we'd need instead to override the ``registerPPCallbacks`` > +method. > + > +In the ``registerMatchers`` method we create an AST Matcher (see `AST > Matchers`_ > +for more information) that will find the pattern in the AST that we want to > +inspect. The results of the matching are passed to the ``check`` method, > which > +can further inspect them and report diagnostics. > + > +.. code-block:: c++ > + > + using namespace ast_matchers; > + > + void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { > + Finder->addMatcher(functionDecl().bind("x"), this); > + } > + > + void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult > &Result) { > + const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x"); > + if (MatchedDecl->getName().startswith("awesome_")) > + return; > + diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") > + << MatchedDecl > + << FixItHint::CreateInsertion(MatchedDecl->getLocation(), > "awesome_"); > + } > + > +(If you want to see an example of a useful check, look at > +`clang-tidy/google/ExplicitConstructorCheck.h > +<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.h>`_ > +and `clang-tidy/google/ExplicitConstructorCheck.cpp > +<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_). > + > + > +Registering your Check > +---------------------- > + > +(The ``add_new_check.py`` takes care of registering the check in an existing > +module. If you want to create a new module or know the details, read on.) > + > +The check should be registered in the corresponding module with a distinct > name: > + > +.. code-block:: c++ > + > + class MyModule : public ClangTidyModule { > + public: > + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override > { > + CheckFactories.registerCheck<ExplicitConstructorCheck>( > + "my-explicit-constructor"); > + } > + }; > + > +Now we need to register the module in the ``ClangTidyModuleRegistry`` using a > +statically initialized variable: > + > +.. code-block:: c++ > + > + static ClangTidyModuleRegistry::Add<MyModule> X("my-module", > + "Adds my lint checks."); > + > + > +When using LLVM build system, we need to use the following hack to ensure the > +module is linked into the :program:`clang-tidy` binary: > + > +Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable: > + > +.. code-block:: c++ > + > + // This anchor is used to force the linker to link in the generated object > file > + // and thus register the MyModule. > + volatile int MyModuleAnchorSource = 0; > + > +And this to the main translation unit of the :program:`clang-tidy` binary (or > +the binary you link the ``clang-tidy`` library in) > +``clang-tidy/tool/ClangTidyMain.cpp``: > + > +.. code-block:: c++ > + > + // This anchor is used to force the linker to link the MyModule. > + extern volatile int MyModuleAnchorSource; > + static int MyModuleAnchorDestination = MyModuleAnchorSource; > + > + > +Configuring Checks > +------------------ > + > +If a check needs configuration options, it can access check-specific options > +using the ``Options.get<Type>("SomeOption", DefaultValue)`` call in the check > +constructor. In this case the check should also override the > +``ClangTidyCheck::storeOptions`` method to make the options provided by the > +check discoverable. This method lets :program:`clang-tidy` know which options > +the check implements and what the current values are (e.g. for the > +``-dump-config`` command line option). > + > +.. code-block:: c++ > + > + class MyCheck : public ClangTidyCheck { > + const unsigned SomeOption1; > + const std::string SomeOption2; > + > + public: > + MyCheck(StringRef Name, ClangTidyContext *Context) > + : ClangTidyCheck(Name, Context), > + SomeOption(Options.get("SomeOption1", -1U)), > + SomeOption(Options.get("SomeOption2", "some default")) {} > + > + void storeOptions(ClangTidyOptions::OptionMap &Opts) override { > + Options.store(Opts, "SomeOption1", SomeOption1); > + Options.store(Opts, "SomeOption2", SomeOption2); > + } > + ... > + > +Assuming the check is registered with the name "my-check", the option can > then > +be set in a ``.clang-tidy`` file in the following way: > + > +.. code-block:: yaml > + > + CheckOptions: > + - key: my-check.SomeOption1 > + value: 123 > + - key: my-check.SomeOption2 > + value: 'some other value' > + > +If you need to specify check options on a command line, you can use the > inline > +YAML format: > + > +.. code-block:: console > + > + $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: > y}]}" ... > + > + > +Testing Checks > +-------------- > + > +To run tests for :program:`clang-tidy` use the command: > + > +.. code-block:: console > + > + $ ninja check-clang-tools > + > +:program:`clang-tidy` checks can be tested using either unit tests or > +`lit`_ tests. Unit tests may be more convenient to test complex replacements > +with strict checks. `Lit`_ tests allow using partial text matching and > regular > +expressions which makes them more suitable for writing compact tests for > +diagnostic messages. > + > +The ``check_clang_tidy.py`` script provides an easy way to test both > +diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test > +file, runs :program:`clang-tidy` and verifies messages and fixes with two > +separate `FileCheck`_ invocations: once with FileCheck's directive > +prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, > +and once with the directive prefix set to ``CHECK-FIXES``, running > +against the fixed code (i.e., the code after generated fix-its are > +applied). In particular, ``CHECK-FIXES:`` can be used to check > +that code was not modified by fix-its, by checking that it is present > +unchanged in the fixed code. The full set of `FileCheck`_ directives > +is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), > though > +typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) > +are sufficient for clang-tidy tests. Note that the `FileCheck`_ > +documentation mostly assumes the default prefix (``CHECK``), and hence > +describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. > +Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for > +clang-tidy tests. > + > +An additional check enabled by ``check_clang_tidy.py`` ensures that > +if `CHECK-MESSAGES:` is used in a file then every warning or error > +must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` > +instead, if you want to **also** ensure that all the notes are checked. > + > +To use the ``check_clang_tidy.py`` script, put a .cpp file with the > +appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use > +``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against > +diagnostic messages and fixed code. > + > +It's advised to make the checks as specific as possible to avoid checks > matching > +to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` > +substitutions and distinct function and variable names in the test code. > + > +Here's an example of a test using the ``check_clang_tidy.py`` script (the > full > +source code is at `test/clang-tidy/google-readability-casting.cpp`_): > + > +.. code-block:: c++ > + > + // RUN: %check_clang_tidy %s google-readability-casting %t > + > + void f(int a) { > + int b = (int)a; > + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same > type [google-readability-casting] > + // CHECK-FIXES: int b = a; > + } > + > +To check more than one scenario in the same test file use > +``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or > +``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. > +With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` > +directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and > ``CHECK-FIXES-SUFFIX-NAME``. > + > +Here's an example: > + > +.. code-block:: c++ > + > + // RUN: %check_clang_tidy -check-suffix=USING-A %s > misc-unused-using-decls %t -- -- -DUSING_A > + // RUN: %check_clang_tidy -check-suffix=USING-B %s > misc-unused-using-decls %t -- -- -DUSING_B > + // RUN: %check_clang_tidy %s misc-unused-using-decls %t > + ... > + // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} > + // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} > + // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} > + // CHECK-FIXES-USING-A-NOT: using a::A;$ > + // CHECK-FIXES-USING-B-NOT: using a::B;$ > + // CHECK-FIXES-NOT: using a::C;$ > + > + > +There are many dark corners in the C++ language, and it may be difficult to > make > +your check work perfectly in all cases, especially if it issues fix-it > hints. The > +most frequent pitfalls are macros and templates: > + > +1. code written in a macro body/template definition may have a different > meaning > + depending on the macro expansion/template instantiation; > +2. multiple macro expansions/template instantiations may result in the same > code > + being inspected by the check multiple times (possibly, with different > + meanings, see 1), and the same warning (or a slightly different one) may > be > + issued by the check multiple times; :program:`clang-tidy` will deduplicate > + _identical_ warnings, but if the warnings are slightly different, all of > them > + will be shown to the user (and used for applying fixes, if any); > +3. making replacements to a macro body/template definition may be fine for > some > + macro expansions/template instantiations, but easily break some other > + expansions/instantiations. > + > +.. _lit: http://llvm.org/docs/CommandGuide/lit.html > +.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html > +.. _test/clang-tidy/google-readability-casting.cpp: > http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp > + > + > +Running clang-tidy on LLVM > +-------------------------- > + > +To test a check it's best to try it out on a larger code base. LLVM and Clang > +are the natural targets as you already have the source code around. The most > +convenient way to run :program:`clang-tidy` is with a compile command > database; > +CMake can automatically generate one, for a description of how to enable it > see > +`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place > and > +a working version of :program:`clang-tidy` is in ``PATH`` the entire code > base > +can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script > executes > +:program:`clang-tidy` with the default set of checks on every translation > unit > +in the compile command database and displays the resulting warnings and > errors. > +The script provides multiple configuration flags. > + > +* The default set of checks can be overridden using the ``-checks`` argument, > + taking the identical format as :program:`clang-tidy` does. For example > + ``-checks=-*,modernize-use-override`` will run the > ``modernize-use-override`` > + check only. > + > +* To restrict the files examined you can provide one or more regex arguments > + that the file names are matched against. > + ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy > + checks. It may also be necessary to restrict the header files warnings are > + displayed from using the ``-header-filter`` flag. It has the same behavior > + as the corresponding :program:`clang-tidy` flag. > + > +* To apply suggested fixes ``-fix`` can be passed as an argument. This > gathers > + all changes in a temporary directory and applies them. Passing ``-format`` > + will run clang-format over changed lines. > + > + > +On checks profiling > +------------------- > + > +:program:`clang-tidy` can collect per-check profiling info, and output it > +for each processed source file (translation unit). > + > +To enable profiling info collection, use the ``-enable-check-profile`` > argument. > +The timings will be output to ``stderr`` as a table. Example output: > + > +.. code-block:: console > + > + $ clang-tidy -enable-check-profile -checks=-*,readability-function-size > source.cpp > + > ===-------------------------------------------------------------------------=== > + clang-tidy checks profiling > + > ===-------------------------------------------------------------------------=== > + Total Execution Time: 1.0282 seconds (1.0258 wall clock) > + > + ---User Time--- --System Time-- --User+System-- ---Wall Time--- > --- Name --- > + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) > readability-function-size > + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) > Total > + > +It can also store that data as JSON files for further processing. Example > output: > + > +.. code-block:: console > + > + $ clang-tidy -enable-check-profile -store-check-profile=. > -checks=-*,readability-function-size source.cpp > + $ # Note that there won't be timings table printed to the console. > + $ ls /tmp/out/ > + 20180516161318717446360-source.cpp.json > + $ cat 20180516161318717446360-source.cpp.json > + { > + "file": "/path/to/source.cpp", > + "timestamp": "2018-05-16 16:13:18.717446360", > + "profile": { > + "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, > + "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, > + "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 > + } > + } > + > +There is only one argument that controls profile storage: > + > +* ``-store-check-profile=<prefix>`` > + > + By default reports are printed in tabulated format to stderr. When this > option > + is passed, these per-TU profiles are instead stored as JSON. > + If the prefix is not an absolute path, it is considered to be relative to > the > + directory from where you have run :program:`clang-tidy`. All ``.`` and > ``..`` > + patterns in the path are collapsed, and symlinks are resolved. > + > + Example: > + Let's suppose you have a source file named ``example.cpp``, located in the > + ``/source`` directory. Only the input filename is used, not the full path > + to the source file. Additionally, it is prefixed with the current > timestamp. > + > + * If you specify ``-store-check-profile=/tmp``, then the profile will be > saved > + to ``/tmp/<ISO8601-like timestamp>-example.cpp.json`` > + > + * If you run :program:`clang-tidy` from within ``/foo`` directory, and > specify > + ``-store-check-profile=.``, then the profile will still be saved to > + ``/foo/<ISO8601-like timestamp>-example.cpp.json`` > > Added: clang-tools-extra/trunk/docs/clang-tidy/Integrations.rst > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/Integrations.rst?rev=351463&view=auto > ============================================================================== > --- clang-tools-extra/trunk/docs/clang-tidy/Integrations.rst (added) > +++ clang-tools-extra/trunk/docs/clang-tidy/Integrations.rst Thu Jan 17 > 10:31:34 2019 > @@ -0,0 +1,117 @@ > +================================== > +Clang-tidy IDE/Editor Integrations > +================================== > + > +.. _Clangd: https://clang.llvm.org/extra/clangd.html > + > +Apart from being a standalone tool, :program:`clang-tidy` is integrated into > +various IDEs, code analyzers, and editors. Besides, it is currently being > +integrated into Clangd_. The following table shows the most > +well-known :program:`clang-tidy` integrations in detail. > + > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +| | Feature > > | > ++======================================+========================+=================================+==========================+=========================================+==========================+ > +| **Tool** | On-the-fly inspection | Check list > configuration (GUI) | Options to checks (GUI) | Configuration via > ``.clang-tidy`` files | Custom clang-tidy binary | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|A.L.E. for Vim | \+\ | > \-\ | \-\ | \-\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Clang Power Tools for Visual Studio | \-\ | > \+\ | \-\ | \+\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Clangd | \+\ | > \-\ | \-\ | \-\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|CLion IDE | \+\ | > \+\ | \+\ | \+\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|CodeChecker | \-\ | > \-\ | \-\ | \-\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|CPPCheck | \-\ | > \-\ | \-\ | \-\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|CPPDepend | \-\ | > \-\ | \-\ | \-\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Flycheck for Emacs | \+\ | > \-\ | \-\ | \+\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|KDevelop IDE | \-\ | > \+\ | \+\ | \+\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Qt Creator IDE | \+\ | > \+\ | \-\ | \-\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|ReSharper C++ for Visual Studio | \+\ | > \+\ | \-\ | \+\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Syntastic for Vim | \+\ | > \-\ | \-\ | \-\ > | \+\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > +|Visual Assist for Visual Studio | \+\ | > \+\ | \-\ | \-\ > | \-\ | > ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ > + > +**IDEs** > + > +.. _CLion: https://www.jetbrains.com/clion/ > +.. _integrates clang-tidy: > https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html > + > +CLion_ 2017.2 and later `integrates clang-tidy`_ as an extension to the > +built-in code analyzer. Starting from 2018.2 EAP, CLion allows using > +:program:`clang-tidy` via Clangd. Inspections and applicable quick-fixes are > +performed on the fly, and checks can be configured in standard command line > +format. In this integration, you can switch to the :program:`clang-tidy` > +binary different from the bundled one, pass the configuration in > +``.clang-tidy`` files instead of using the IDE settings, and configure > +options for particular checks. > + > +.. _KDevelop: https://www.kdevelop.org/ > +.. _kdev-clang-tidy: https://github.com/KDE/kdev-clang-tidy/ > + > +KDevelop_ with the kdev-clang-tidy_ plugin, starting from version 5.1, > performs > +static analysis using :program:`clang-tidy`. The plugin launches the > +:program:`clang-tidy` binary from the specified location and parses its > +output to provide a list of issues. > + > +.. _QtCreator: https://www.qt.io/ > +.. _Clang Code Model: http://doc.qt.io/qtcreator/creator-clang-codemodel.html > + > +QtCreator_ 4.6 integrates :program:`clang-tidy` warnings into the editor > +diagnostics under the `Clang Code Model`_. To employ :program:`clang-tidy` > +inspection in QtCreator, you need to create a copy of one of the presets and > +choose the checks to be performed in the Clang Code Model Warnings menu. > + > +.. _MS Visual Studio: https://visualstudio.microsoft.com/ > +.. _ReSharper C++: > https://www.jetbrains.com/help/resharper/Clang_Tidy_Integration.html > +.. _Visual Assist: https://docs.wholetomato.com/default.asp?W761 > +.. _Clang Power Tools: > https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools > +.. _clang-tidy-vs: > https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-tidy-vs > + > +`MS Visual Studio`_ has a native clang-tidy-vs_ plugin and also can integrate > +:program:`clang-tidy` by means of three other tools. The `ReSharper C++`_ > +extension, version 2017.3 and later, provides seamless :program:`clang-tidy` > +integration: checks and quick-fixes run alongside native inspections. Apart > +from that, ReSharper C++ incorporates :program:`clang-tidy` as a separate > +step of its code clean-up process. `Visual Assist`_ build 2210 includes a > +subset of :program:`clang-tidy` checklist to inspect the code as you edit. > +Another way to bring :program:`clang-tidy` functionality to Visual Studio is > +the `Clang Power Tools`_ plugin, which includes most of the > +:program:`clang-tidy` checks and runs them during compilation or as a > separate > +step of code analysis. > + > +**Editors** > + > +.. _Flycheck: https://github.com/ch1bo/flycheck-clang-tidy > +.. _Syntastic: https://github.com/vim-syntastic/syntastic > +.. _A.L.E.: https://github.com/w0rp/ale > +.. _Emacs24: https://www.gnu.org/s/emacs/ > +.. _Vim: https://www.vim.org/ > + > +Emacs24_, when expanded with the Flycheck_ plugin, incorporates the > +:program:`clang-tidy` inspection into the syntax analyzer. For Vim_, you can > +use Syntastic_, which includes :program:`clang-tidy`, or `A.L.E.`_, > +a lint engine that applies :program:`clang-tidy` along with other linters. > + > +**Analyzers** > + > +.. _CPPDepend: https://www.cppdepend.com/cppdependv2018 > +.. _CPPCheck: https://sourceforge.net/p/cppcheck/news/ > +.. _CodeChecker: https://github.com/Ericsson/codechecker > +.. _plugin: https://github.com/Ericsson/CodeCheckerEclipsePlugin > + > +:program:`clang-tidy` is integrated in CPPDepend_ starting from version > 2018.1 > +and CPPCheck_ 1.82. CPPCheck integration lets you import Visual Studio > +solutions and run the :program:`clang-tidy` inspection on them. The > +CodeChecker_ application of version 5.3 or later, which also comes as a > plugin_ > +for Eclipse, supports :program:`clang-tidy` as a static analysis instrument > and > +allows to use a custom :program:`clang-tidy` binary. > > Modified: clang-tools-extra/trunk/docs/clang-tidy/index.rst > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/index.rst?rev=351463&r1=351462&r2=351463&view=diff > ============================================================================== > --- clang-tools-extra/trunk/docs/clang-tidy/index.rst (original) > +++ clang-tools-extra/trunk/docs/clang-tidy/index.rst Thu Jan 17 10:31:34 2019 > @@ -10,6 +10,8 @@ See also: > :maxdepth: 1 > > The list of clang-tidy checks <checks/list> > + Clang-tidy IDE/Editor Integrations <Integrations> > + Getting Involved <Contributing> > > :program:`clang-tidy` is a clang-based C++ "linter" tool. Its purpose is to > provide an extensible framework for diagnosing and fixing typical programming > @@ -310,511 +312,3 @@ the parenthesis) whitespaces can be used > > .. _LibTooling: http://clang.llvm.org/docs/LibTooling.html > .. _How To Setup Tooling For LLVM: > http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html > - > - > -Getting Involved > -================ > - > -:program:`clang-tidy` has several own checks and can run Clang static > analyzer > -checks, but its power is in the ability to easily write custom checks. > - > -Checks are organized in modules, which can be linked into > :program:`clang-tidy` > -with minimal or no code changes in :program:`clang-tidy`. > - > -Checks can plug into the analysis on the preprocessor level using > `PPCallbacks`_ > -or on the AST level using `AST Matchers`_. When an error is found, checks can > -report them in a way similar to how Clang diagnostics work. A fix-it hint > can be > -attached to a diagnostic message. > - > -The interface provided by :program:`clang-tidy` makes it easy to write useful > -and precise checks in just a few lines of code. If you have an idea for a > good > -check, the rest of this document explains how to do this. > - > -There are a few tools particularly useful when developing clang-tidy checks: > - * ``add_new_check.py`` is a script to automate the process of adding a new > - check, it will create the check, update the CMake file and create a test; > - * ``rename_check.py`` does what the script name suggests, renames an > existing > - check; > - * :program:`clang-query` is invaluable for interactive prototyping of AST > - matchers and exploration of the Clang AST; > - * `clang-check`_ with the ``-ast-dump`` (and optionally > ``-ast-dump-filter``) > - provides a convenient way to dump AST of a C++ program. > - > -If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, > -:program:`clang-tidy` will not be built with support for the > -``clang-analyzer-*`` checks or the ``mpi-*`` checks. > - > - > -.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html > -.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html > -.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html > - > - > -Choosing the Right Place for your Check > ---------------------------------------- > - > -If you have an idea of a check, you should decide whether it should be > -implemented as a: > - > -+ *Clang diagnostic*: if the check is generic enough, targets code patterns > that > - most probably are bugs (rather than style or readability issues), can be > - implemented effectively and with extremely low false positive rate, it may > - make a good Clang diagnostic. > - > -+ *Clang static analyzer check*: if the check requires some sort of control > flow > - analysis, it should probably be implemented as a static analyzer check. > - > -+ *clang-tidy check* is a good choice for linter-style checks, checks that > are > - related to a certain coding style, checks that address code readability, > etc. > - > - > -Preparing your Workspace > ------------------------- > - > -If you are new to LLVM development, you should read the `Getting Started with > -the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ > -documents to check out and build LLVM, Clang and Clang Extra Tools with > CMake. > - > -Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, > and > -let's start! > - > -.. _Getting Started with the LLVM System: > http://llvm.org/docs/GettingStarted.html > -.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html > - > - > -The Directory Structure > ------------------------ > - > -:program:`clang-tidy` source code resides in the > -``llvm/tools/clang/tools/extra`` directory and is structured as follows: > - > -:: > - > - clang-tidy/ # Clang-tidy core. > - |-- ClangTidy.h # Interfaces for users and checks. > - |-- ClangTidyModule.h # Interface for clang-tidy modules. > - |-- ClangTidyModuleRegistry.h # Interface for registering of modules. > - ... > - |-- google/ # Google clang-tidy module. > - |-+ > - |-- GoogleTidyModule.cpp > - |-- GoogleTidyModule.h > - ... > - |-- llvm/ # LLVM clang-tidy module. > - |-+ > - |-- LLVMTidyModule.cpp > - |-- LLVMTidyModule.h > - ... > - |-- objc/ # Objective-C clang-tidy module. > - |-+ > - |-- ObjCTidyModule.cpp > - |-- ObjCTidyModule.h > - ... > - |-- tool/ # Sources of the clang-tidy binary. > - ... > - test/clang-tidy/ # Integration tests. > - ... > - unittests/clang-tidy/ # Unit tests. > - |-- ClangTidyTest.h > - |-- GoogleModuleTest.cpp > - |-- LLVMModuleTest.cpp > - |-- ObjCModuleTest.cpp > - ... > - > - > -Writing a clang-tidy Check > --------------------------- > - > -So you have an idea of a useful check for :program:`clang-tidy`. > - > -First, if you're not familiar with LLVM development, read through the > `Getting > -Started with LLVM`_ document for instructions on setting up your workflow and > -the `LLVM Coding Standards`_ document to familiarize yourself with the coding > -style used in the project. For code reviews we mostly use `LLVM > Phabricator`_. > - > -.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html > -.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html > -.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html > - > -Next, you need to decide which module the check belongs to. Modules > -are located in subdirectories of `clang-tidy/ > -<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/>`_ > -and contain checks targeting a certain aspect of code quality (performance, > -readability, etc.), certain coding style or standard (Google, LLVM, CERT, > etc.) > -or a widely used API (e.g. MPI). Their names are same as user-facing check > -groups names described :ref:`above <checks-groups-table>`. > - > -After choosing the module and the name for the check, run the > -``clang-tidy/add_new_check.py`` script to create the skeleton of the check > and > -plug it to :program:`clang-tidy`. It's the recommended way of adding new > checks. > - > -If we want to create a `readability-awesome-function-names`, we would run: > - > -.. code-block:: console > - > - $ clang-tidy/add_new_check.py readability awesome-function-names > - > - > -The ``add_new_check.py`` script will: > - * create the class for your check inside the specified module's directory > and > - register it in the module and in the build system; > - * create a lit test file in the ``test/clang-tidy/`` directory; > - * create a documentation file and include it into the > - ``docs/clang-tidy/checks/list.rst``. > - > -Let's see in more detail at the check class definition: > - > -.. code-block:: c++ > - > - ... > - > - #include "../ClangTidy.h" > - > - namespace clang { > - namespace tidy { > - namespace readability { > - > - ... > - class AwesomeFunctionNamesCheck : public ClangTidyCheck { > - public: > - AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) > - : ClangTidyCheck(Name, Context) {} > - void registerMatchers(ast_matchers::MatchFinder *Finder) override; > - void check(const ast_matchers::MatchFinder::MatchResult &Result) > override; > - }; > - > - } // namespace readability > - } // namespace tidy > - } // namespace clang > - > - ... > - > -Constructor of the check receives the ``Name`` and ``Context`` parameters, > and > -must forward them to the ``ClangTidyCheck`` constructor. > - > -In our case the check needs to operate on the AST level and it overrides the > -``registerMatchers`` and ``check`` methods. If we wanted to analyze code on > the > -preprocessor level, we'd need instead to override the ``registerPPCallbacks`` > -method. > - > -In the ``registerMatchers`` method we create an AST Matcher (see `AST > Matchers`_ > -for more information) that will find the pattern in the AST that we want to > -inspect. The results of the matching are passed to the ``check`` method, > which > -can further inspect them and report diagnostics. > - > -.. code-block:: c++ > - > - using namespace ast_matchers; > - > - void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { > - Finder->addMatcher(functionDecl().bind("x"), this); > - } > - > - void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult > &Result) { > - const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x"); > - if (MatchedDecl->getName().startswith("awesome_")) > - return; > - diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") > - << MatchedDecl > - << FixItHint::CreateInsertion(MatchedDecl->getLocation(), > "awesome_"); > - } > - > -(If you want to see an example of a useful check, look at > -`clang-tidy/google/ExplicitConstructorCheck.h > -<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.h>`_ > -and `clang-tidy/google/ExplicitConstructorCheck.cpp > -<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_). > - > - > -Registering your Check > ----------------------- > - > -(The ``add_new_check.py`` takes care of registering the check in an existing > -module. If you want to create a new module or know the details, read on.) > - > -The check should be registered in the corresponding module with a distinct > name: > - > -.. code-block:: c++ > - > - class MyModule : public ClangTidyModule { > - public: > - void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override > { > - CheckFactories.registerCheck<ExplicitConstructorCheck>( > - "my-explicit-constructor"); > - } > - }; > - > -Now we need to register the module in the ``ClangTidyModuleRegistry`` using a > -statically initialized variable: > - > -.. code-block:: c++ > - > - static ClangTidyModuleRegistry::Add<MyModule> X("my-module", > - "Adds my lint checks."); > - > - > -When using LLVM build system, we need to use the following hack to ensure the > -module is linked into the :program:`clang-tidy` binary: > - > -Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable: > - > -.. code-block:: c++ > - > - // This anchor is used to force the linker to link in the generated object > file > - // and thus register the MyModule. > - volatile int MyModuleAnchorSource = 0; > - > -And this to the main translation unit of the :program:`clang-tidy` binary (or > -the binary you link the ``clang-tidy`` library in) > -``clang-tidy/tool/ClangTidyMain.cpp``: > - > -.. code-block:: c++ > - > - // This anchor is used to force the linker to link the MyModule. > - extern volatile int MyModuleAnchorSource; > - static int MyModuleAnchorDestination = MyModuleAnchorSource; > - > - > -Configuring Checks > ------------------- > - > -If a check needs configuration options, it can access check-specific options > -using the ``Options.get<Type>("SomeOption", DefaultValue)`` call in the check > -constructor. In this case the check should also override the > -``ClangTidyCheck::storeOptions`` method to make the options provided by the > -check discoverable. This method lets :program:`clang-tidy` know which options > -the check implements and what the current values are (e.g. for the > -``-dump-config`` command line option). > - > -.. code-block:: c++ > - > - class MyCheck : public ClangTidyCheck { > - const unsigned SomeOption1; > - const std::string SomeOption2; > - > - public: > - MyCheck(StringRef Name, ClangTidyContext *Context) > - : ClangTidyCheck(Name, Context), > - SomeOption(Options.get("SomeOption1", -1U)), > - SomeOption(Options.get("SomeOption2", "some default")) {} > - > - void storeOptions(ClangTidyOptions::OptionMap &Opts) override { > - Options.store(Opts, "SomeOption1", SomeOption1); > - Options.store(Opts, "SomeOption2", SomeOption2); > - } > - ... > - > -Assuming the check is registered with the name "my-check", the option can > then > -be set in a ``.clang-tidy`` file in the following way: > - > -.. code-block:: yaml > - > - CheckOptions: > - - key: my-check.SomeOption1 > - value: 123 > - - key: my-check.SomeOption2 > - value: 'some other value' > - > -If you need to specify check options on a command line, you can use the > inline > -YAML format: > - > -.. code-block:: console > - > - $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: > y}]}" ... > - > - > -Testing Checks > --------------- > - > -To run tests for :program:`clang-tidy` use the command: > - > -.. code-block:: console > - > - $ ninja check-clang-tools > - > -:program:`clang-tidy` checks can be tested using either unit tests or > -`lit`_ tests. Unit tests may be more convenient to test complex replacements > -with strict checks. `Lit`_ tests allow using partial text matching and > regular > -expressions which makes them more suitable for writing compact tests for > -diagnostic messages. > - > -The ``check_clang_tidy.py`` script provides an easy way to test both > -diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test > -file, runs :program:`clang-tidy` and verifies messages and fixes with two > -separate `FileCheck`_ invocations: once with FileCheck's directive > -prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, > -and once with the directive prefix set to ``CHECK-FIXES``, running > -against the fixed code (i.e., the code after generated fix-its are > -applied). In particular, ``CHECK-FIXES:`` can be used to check > -that code was not modified by fix-its, by checking that it is present > -unchanged in the fixed code. The full set of `FileCheck`_ directives > -is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), > though > -typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) > -are sufficient for clang-tidy tests. Note that the `FileCheck`_ > -documentation mostly assumes the default prefix (``CHECK``), and hence > -describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. > -Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for > -clang-tidy tests. > - > -An additional check enabled by ``check_clang_tidy.py`` ensures that > -if `CHECK-MESSAGES:` is used in a file then every warning or error > -must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` > -instead, if you want to **also** ensure that all the notes are checked. > - > -To use the ``check_clang_tidy.py`` script, put a .cpp file with the > -appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use > -``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against > -diagnostic messages and fixed code. > - > -It's advised to make the checks as specific as possible to avoid checks > matching > -to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` > -substitutions and distinct function and variable names in the test code. > - > -Here's an example of a test using the ``check_clang_tidy.py`` script (the > full > -source code is at `test/clang-tidy/google-readability-casting.cpp`_): > - > -.. code-block:: c++ > - > - // RUN: %check_clang_tidy %s google-readability-casting %t > - > - void f(int a) { > - int b = (int)a; > - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same > type [google-readability-casting] > - // CHECK-FIXES: int b = a; > - } > - > -To check more than one scenario in the same test file use > -``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or > -``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. > -With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` > -directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and > ``CHECK-FIXES-SUFFIX-NAME``. > - > -Here's an example: > - > -.. code-block:: c++ > - > - // RUN: %check_clang_tidy -check-suffix=USING-A %s > misc-unused-using-decls %t -- -- -DUSING_A > - // RUN: %check_clang_tidy -check-suffix=USING-B %s > misc-unused-using-decls %t -- -- -DUSING_B > - // RUN: %check_clang_tidy %s misc-unused-using-decls %t > - ... > - // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} > - // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} > - // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} > - // CHECK-FIXES-USING-A-NOT: using a::A;$ > - // CHECK-FIXES-USING-B-NOT: using a::B;$ > - // CHECK-FIXES-NOT: using a::C;$ > - > - > -There are many dark corners in the C++ language, and it may be difficult to > make > -your check work perfectly in all cases, especially if it issues fix-it > hints. The > -most frequent pitfalls are macros and templates: > - > -1. code written in a macro body/template definition may have a different > meaning > - depending on the macro expansion/template instantiation; > -2. multiple macro expansions/template instantiations may result in the same > code > - being inspected by the check multiple times (possibly, with different > - meanings, see 1), and the same warning (or a slightly different one) may > be > - issued by the check multiple times; :program:`clang-tidy` will deduplicate > - _identical_ warnings, but if the warnings are slightly different, all of > them > - will be shown to the user (and used for applying fixes, if any); > -3. making replacements to a macro body/template definition may be fine for > some > - macro expansions/template instantiations, but easily break some other > - expansions/instantiations. > - > -.. _lit: http://llvm.org/docs/CommandGuide/lit.html > -.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html > -.. _test/clang-tidy/google-readability-casting.cpp: > http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp > - > - > -Running clang-tidy on LLVM > --------------------------- > - > -To test a check it's best to try it out on a larger code base. LLVM and Clang > -are the natural targets as you already have the source code around. The most > -convenient way to run :program:`clang-tidy` is with a compile command > database; > -CMake can automatically generate one, for a description of how to enable it > see > -`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place > and > -a working version of :program:`clang-tidy` is in ``PATH`` the entire code > base > -can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script > executes > -:program:`clang-tidy` with the default set of checks on every translation > unit > -in the compile command database and displays the resulting warnings and > errors. > -The script provides multiple configuration flags. > - > -* The default set of checks can be overridden using the ``-checks`` argument, > - taking the identical format as :program:`clang-tidy` does. For example > - ``-checks=-*,modernize-use-override`` will run the > ``modernize-use-override`` > - check only. > - > -* To restrict the files examined you can provide one or more regex arguments > - that the file names are matched against. > - ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy > - checks. It may also be necessary to restrict the header files warnings are > - displayed from using the ``-header-filter`` flag. It has the same behavior > - as the corresponding :program:`clang-tidy` flag. > - > -* To apply suggested fixes ``-fix`` can be passed as an argument. This > gathers > - all changes in a temporary directory and applies them. Passing ``-format`` > - will run clang-format over changed lines. > - > - > -On checks profiling > -------------------- > - > -:program:`clang-tidy` can collect per-check profiling info, and output it > -for each processed source file (translation unit). > - > -To enable profiling info collection, use the ``-enable-check-profile`` > argument. > -The timings will be output to ``stderr`` as a table. Example output: > - > -.. code-block:: console > - > - $ clang-tidy -enable-check-profile -checks=-*,readability-function-size > source.cpp > - > ===-------------------------------------------------------------------------=== > - clang-tidy checks profiling > - > ===-------------------------------------------------------------------------=== > - Total Execution Time: 1.0282 seconds (1.0258 wall clock) > - > - ---User Time--- --System Time-- --User+System-- ---Wall Time--- > --- Name --- > - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) > readability-function-size > - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) > Total > - > -It can also store that data as JSON files for further processing. Example > output: > - > -.. code-block:: console > - > - $ clang-tidy -enable-check-profile -store-check-profile=. > -checks=-*,readability-function-size source.cpp > - $ # Note that there won't be timings table printed to the console. > - $ ls /tmp/out/ > - 20180516161318717446360-source.cpp.json > - $ cat 20180516161318717446360-source.cpp.json > - { > - "file": "/path/to/source.cpp", > - "timestamp": "2018-05-16 16:13:18.717446360", > - "profile": { > - "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, > - "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, > - "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 > - } > - } > - > -There is only one argument that controls profile storage: > - > -* ``-store-check-profile=<prefix>`` > - > - By default reports are printed in tabulated format to stderr. When this > option > - is passed, these per-TU profiles are instead stored as JSON. > - If the prefix is not an absolute path, it is considered to be relative to > the > - directory from where you have run :program:`clang-tidy`. All ``.`` and > ``..`` > - patterns in the path are collapsed, and symlinks are resolved. > - > - Example: > - Let's suppose you have a source file named ``example.cpp``, located in the > - ``/source`` directory. Only the input filename is used, not the full path > - to the source file. Additionally, it is prefixed with the current > timestamp. > - > - * If you specify ``-store-check-profile=/tmp``, then the profile will be > saved > - to ``/tmp/<ISO8601-like timestamp>-example.cpp.json`` > - > - * If you run :program:`clang-tidy` from within ``/foo`` directory, and > specify > - ``-store-check-profile=.``, then the profile will still be saved to > - ``/foo/<ISO8601-like timestamp>-example.cpp.json`` > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits