2014-02-26 00:46:13 +08:00
|
|
|
==========
|
|
|
|
Clang-Tidy
|
|
|
|
==========
|
|
|
|
|
2016-02-08 23:09:39 +08:00
|
|
|
.. contents::
|
|
|
|
|
|
|
|
See also:
|
|
|
|
|
2015-08-28 02:10:07 +08:00
|
|
|
.. toctree::
|
|
|
|
:maxdepth: 1
|
|
|
|
|
2016-02-08 23:09:39 +08:00
|
|
|
The list of clang-tidy checks <checks/list>
|
2015-08-28 02:10:07 +08:00
|
|
|
|
2014-02-26 00:46:13 +08:00
|
|
|
:program:`clang-tidy` is a clang-based C++ linter tool. Its purpose is to
|
|
|
|
provide an extensible framework for diagnosing and fixing typical programming
|
|
|
|
errors, like style violations, interface misuse, or bugs that can be deduced via
|
|
|
|
static analysis. :program:`clang-tidy` is modular and provides a convenient
|
|
|
|
interface for writing new checks.
|
|
|
|
|
|
|
|
|
|
|
|
Using clang-tidy
|
|
|
|
================
|
|
|
|
|
|
|
|
:program:`clang-tidy` is a `LibTooling`_-based tool, and it's easier to work
|
|
|
|
with if you set up a compile command database for your project (for an example
|
2014-07-16 21:26:51 +08:00
|
|
|
of how to do this see `How To Setup Tooling For LLVM`_). You can also specify
|
2014-02-26 00:46:13 +08:00
|
|
|
compilation options on the command line after ``--``:
|
|
|
|
|
2014-09-28 05:33:33 +08:00
|
|
|
.. code-block:: console
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
$ clang-tidy test.cpp -- -Imy_project/include -DMY_DEFINES ...
|
|
|
|
|
|
|
|
:program:`clang-tidy` has its own checks and can also run Clang static analyzer
|
|
|
|
checks. Each check has a name and the checks to run can be chosen using the
|
2014-05-16 21:07:18 +08:00
|
|
|
``-checks=`` option, which specifies a comma-separated list of positive and
|
|
|
|
negative (prefixed with ``-``) globs. Positive globs add subsets of checks,
|
|
|
|
negative globs remove them. For example,
|
2014-02-26 00:46:13 +08:00
|
|
|
|
2014-09-28 05:33:33 +08:00
|
|
|
.. code-block:: console
|
2014-05-16 21:07:18 +08:00
|
|
|
|
2015-07-27 21:41:30 +08:00
|
|
|
$ clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-alpha*
|
2014-05-16 21:07:18 +08:00
|
|
|
|
|
|
|
will disable all default checks (``-*``) and enable all ``clang-analyzer-*``
|
|
|
|
checks except for ``clang-analyzer-alpha*`` ones.
|
|
|
|
|
|
|
|
The ``-list-checks`` option lists all the enabled checks. When used without
|
2015-07-27 21:41:30 +08:00
|
|
|
``-checks=``, it shows checks enabled by default. Use ``-checks=*`` to see all
|
2014-05-16 21:07:18 +08:00
|
|
|
available checks or with any other value of ``-checks=`` to see which checks are
|
|
|
|
enabled by this value.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
2014-07-16 21:26:51 +08:00
|
|
|
There are currently the following groups of checks:
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
* Checks related to the LLVM coding conventions have names starting with
|
|
|
|
``llvm-``.
|
|
|
|
|
|
|
|
* Checks related to the Google coding conventions have names starting with
|
|
|
|
``google-``.
|
|
|
|
|
2015-08-31 21:17:43 +08:00
|
|
|
* Checks named ``modernize-*`` advocate the usage of modern (currently "modern"
|
|
|
|
means "C++11") language constructs.
|
|
|
|
|
|
|
|
* The ``readability-`` checks target readability-related issues that don't
|
|
|
|
relate to any particular coding style.
|
|
|
|
|
|
|
|
* Checks with names starting with ``misc-`` the checks that we didn't have a
|
|
|
|
better category for.
|
2014-05-16 21:07:18 +08:00
|
|
|
|
2014-02-26 00:46:13 +08:00
|
|
|
* Clang static analyzer checks are named starting with ``clang-analyzer-``.
|
|
|
|
|
2014-07-16 21:26:51 +08:00
|
|
|
Clang diagnostics are treated in a similar way as check diagnostics. Clang
|
|
|
|
diagnostics are displayed by clang-tidy and can be filtered out using
|
|
|
|
``-checks=`` option. However, the ``-checks=`` option does not affect
|
|
|
|
compilation arguments, so it can not turn on Clang warnings which are not
|
2016-01-14 01:36:41 +08:00
|
|
|
already turned on in build configuration. The ``-warnings-as-errors=`` option
|
|
|
|
upgrades any warnings emitted under the ``-checks=`` flag to errors (but it
|
|
|
|
does not enable any checks itself).
|
2014-07-16 21:26:51 +08:00
|
|
|
|
|
|
|
Clang diagnostics have check names starting with ``clang-diagnostic-``.
|
|
|
|
Diagnostics which have a corresponding warning option, are named
|
|
|
|
``clang-diagostic-<warning-option>``, e.g. Clang warning controlled by
|
|
|
|
``-Wliteral-conversion`` will be reported with check name
|
|
|
|
``clang-diagnostic-literal-conversion``.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
2014-07-11 02:59:25 +08:00
|
|
|
The ``-fix`` flag instructs :program:`clang-tidy` to fix found errors if
|
2014-02-26 00:46:13 +08:00
|
|
|
supported by corresponding checks.
|
|
|
|
|
|
|
|
An overview of all the command-line options:
|
|
|
|
|
2014-09-28 05:33:33 +08:00
|
|
|
.. code-block:: console
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
$ clang-tidy -help
|
|
|
|
USAGE: clang-tidy [options] <source0> [... <sourceN>]
|
|
|
|
|
|
|
|
OPTIONS:
|
|
|
|
|
2016-02-08 08:19:29 +08:00
|
|
|
Generic Options:
|
2014-02-26 00:46:13 +08:00
|
|
|
|
2016-02-08 08:19:29 +08:00
|
|
|
-help - Display available options (-help-hidden for more)
|
|
|
|
-help-list - Display list of available options (-help-list-hidden for more)
|
|
|
|
-version - Display the version of this program
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
clang-tidy options:
|
|
|
|
|
2016-02-08 08:19:29 +08:00
|
|
|
-analyze-temporary-dtors -
|
|
|
|
Enable temporary destructor-aware analysis in
|
|
|
|
clang-analyzer- checks.
|
|
|
|
This option overrides the value read from a
|
|
|
|
.clang-tidy file.
|
|
|
|
-checks=<string> -
|
|
|
|
Comma-separated list of globs with optional '-'
|
|
|
|
prefix. Globs are processed in order of
|
|
|
|
appearance in the list. Globs without '-'
|
|
|
|
prefix add checks with matching names to the
|
|
|
|
set, globs with the '-' prefix remove checks
|
|
|
|
with matching names from the set of enabled
|
|
|
|
checks. This option's value is appended to the
|
|
|
|
value of the 'Checks' option in .clang-tidy
|
|
|
|
file, if any.
|
|
|
|
-config=<string> -
|
|
|
|
Specifies a configuration in YAML/JSON format:
|
|
|
|
-config="{Checks: '*',
|
|
|
|
CheckOptions: [{key: x,
|
|
|
|
value: y}]}"
|
|
|
|
When the value is empty, clang-tidy will
|
|
|
|
attempt to find a file named .clang-tidy for
|
|
|
|
each source file in its parent directories.
|
|
|
|
-dump-config -
|
|
|
|
Dumps configuration in the YAML format to
|
|
|
|
stdout. This option can be used along with a
|
|
|
|
file name (and '--' if the file is outside of a
|
|
|
|
project with configured compilation database).
|
|
|
|
The configuration used for this file will be
|
|
|
|
printed.
|
|
|
|
Use along with -checks=* to include
|
|
|
|
configuration of all checks.
|
|
|
|
-enable-check-profile -
|
|
|
|
Enable per-check timing profiles, and print a
|
|
|
|
report to stderr.
|
|
|
|
-export-fixes=<filename> -
|
|
|
|
YAML file to store suggested fixes in. The
|
|
|
|
stored fixes can be applied to the input sorce
|
|
|
|
code with clang-apply-replacements.
|
|
|
|
-extra-arg=<string> - Additional argument to append to the compiler command line
|
|
|
|
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line
|
|
|
|
-fix -
|
|
|
|
Apply suggested fixes. Without -fix-errors
|
|
|
|
clang-tidy will bail out if any compilation
|
|
|
|
errors were found.
|
|
|
|
-fix-errors -
|
|
|
|
Apply suggested fixes even if compilation
|
|
|
|
errors were found. If compiler errors have
|
|
|
|
attached fix-its, clang-tidy will apply them as
|
|
|
|
well.
|
|
|
|
-header-filter=<string> -
|
|
|
|
Regular expression matching the names of the
|
|
|
|
headers to output diagnostics from. Diagnostics
|
|
|
|
from the main file of each translation unit are
|
|
|
|
always displayed.
|
|
|
|
Can be used together with -line-filter.
|
|
|
|
This option overrides the 'HeaderFilter' option
|
|
|
|
in .clang-tidy file, if any.
|
|
|
|
-line-filter=<string> -
|
|
|
|
List of files with line ranges to filter the
|
|
|
|
warnings. Can be used together with
|
|
|
|
-header-filter. The format of the list is a
|
|
|
|
JSON array of objects:
|
|
|
|
[
|
|
|
|
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
|
|
|
|
{"name":"file2.h"}
|
|
|
|
]
|
|
|
|
-list-checks -
|
|
|
|
List all enabled checks and exit. Use with
|
|
|
|
-checks=* to list all available checks.
|
|
|
|
-p=<string> - Build path
|
|
|
|
-system-headers - Display the errors from system headers.
|
|
|
|
-warnings-as-errors=<string> -
|
|
|
|
Upgrades warnings to errors. Same format as
|
|
|
|
'-checks'.
|
|
|
|
This option's value is appended to the value of
|
|
|
|
the 'WarningsAsErrors' option in .clang-tidy
|
|
|
|
file, if any.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
-p <build-path> is used to read a compile command database.
|
|
|
|
|
2014-12-03 22:03:03 +08:00
|
|
|
For example, it can be a CMake build directory in which a file named
|
|
|
|
compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
|
|
CMake option to get this output). When no build path is specified,
|
|
|
|
a search for compile_commands.json will be attempted through all
|
|
|
|
parent paths of the first input file . See:
|
|
|
|
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
|
|
|
|
example of setting up Clang Tooling on a source tree.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
<source0> ... specify the paths of source files. These paths are
|
2014-12-03 22:03:03 +08:00
|
|
|
looked up in the compile command database. If the path of a file is
|
|
|
|
absolute, it needs to point into CMake's source tree. If the path is
|
|
|
|
relative, the current working directory needs to be in the CMake
|
|
|
|
source tree and the file must be in a subdirectory of the current
|
|
|
|
working directory. "./" prefixes in the relative files will be
|
|
|
|
automatically removed, but the rest of a relative path must be a
|
|
|
|
suffix of a path in the compile command database.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
2016-02-08 08:19:29 +08:00
|
|
|
|
2014-09-28 05:25:26 +08:00
|
|
|
Configuration files:
|
|
|
|
clang-tidy attempts to read configuration for each source file from a
|
|
|
|
.clang-tidy file located in the closest parent directory of the source
|
|
|
|
file. If any configuration options have a corresponding command-line
|
|
|
|
option, command-line option takes precedence. The effective
|
2014-12-03 22:03:03 +08:00
|
|
|
configuration can be inspected using -dump-config:
|
|
|
|
|
|
|
|
$ clang-tidy -dump-config - --
|
|
|
|
---
|
|
|
|
Checks: '-*,some-check'
|
2016-02-08 08:19:29 +08:00
|
|
|
WarningsAsErrors: ''
|
2014-12-03 22:03:03 +08:00
|
|
|
HeaderFilterRegex: ''
|
|
|
|
AnalyzeTemporaryDtors: false
|
|
|
|
User: user
|
2016-02-08 08:19:29 +08:00
|
|
|
CheckOptions:
|
2014-12-03 22:03:03 +08:00
|
|
|
- key: some-check.SomeOption
|
|
|
|
value: 'some value'
|
|
|
|
...
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
.. _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 clang-tidy.
|
|
|
|
|
2016-02-08 23:09:39 +08:00
|
|
|
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
|
2014-02-26 00:46:13 +08:00
|
|
|
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 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.
|
|
|
|
|
2016-02-08 23:09:39 +08:00
|
|
|
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 suggest, renames an existsing
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
2014-02-26 00:46:13 +08:00
|
|
|
.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html
|
|
|
|
.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html
|
2016-02-08 23:09:39 +08:00
|
|
|
.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
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.
|
2015-07-27 21:41:30 +08:00
|
|
|
|-- ClangTidy.h # Interfaces for users and checks.
|
|
|
|
|-- ClangTidyModule.h # Interface for clang-tidy modules.
|
|
|
|
|-- ClangTidyModuleRegistry.h # Interface for registering of modules.
|
2014-02-26 00:46:13 +08:00
|
|
|
...
|
2015-07-27 21:41:30 +08:00
|
|
|
|-- google/ # Google clang-tidy module.
|
2015-08-28 02:10:07 +08:00
|
|
|
|-+
|
|
|
|
|-- GoogleTidyModule.cpp
|
|
|
|
|-- GoogleTidyModule.h
|
2014-02-26 00:46:13 +08:00
|
|
|
...
|
2015-07-27 21:41:30 +08:00
|
|
|
|-- llvm/ # LLVM clang-tidy module.
|
2015-08-28 02:10:07 +08:00
|
|
|
|-+
|
|
|
|
|-- LLVMTidyModule.cpp
|
|
|
|
|-- LLVMTidyModule.h
|
2014-02-26 00:46:13 +08:00
|
|
|
...
|
2015-07-27 21:41:30 +08:00
|
|
|
|-- tool/ # Sources of the clang-tidy binary.
|
2014-02-26 00:46:13 +08:00
|
|
|
...
|
|
|
|
test/clang-tidy/ # Integration tests.
|
|
|
|
...
|
2014-10-03 15:08:22 +08:00
|
|
|
unittests/clang-tidy/ # Unit tests.
|
2015-07-27 21:41:30 +08:00
|
|
|
|-- ClangTidyTest.h
|
|
|
|
|-- GoogleModuleTest.cpp
|
|
|
|
|-- LLVMModuleTest.cpp
|
2014-02-26 00:46:13 +08:00
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
Writing a clang-tidy Check
|
|
|
|
--------------------------
|
|
|
|
|
|
|
|
So you have an idea of a useful check for :program:`clang-tidy`.
|
|
|
|
|
2016-02-20 19:42:13 +08:00
|
|
|
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. If the check
|
|
|
|
verifies conformance of the code to a certain coding style, it probably deserves
|
|
|
|
a separate module and a directory in ``clang-tidy/``. There are already modules
|
|
|
|
implementing checks related to:
|
|
|
|
|
|
|
|
* `C++ Core Guidelines
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/>`_
|
|
|
|
* `CERT Secure Coding Standards
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/cert/>`_
|
|
|
|
* `Google Style Guide
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/>`_
|
|
|
|
* `LLVM Style
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/llvm/>`_
|
|
|
|
* `modernizing C/C++ code
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/modernize/>`_
|
|
|
|
* potential `performance problems
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/performance/>`_
|
|
|
|
* various `readability issues
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/readability/>`_
|
|
|
|
* and `miscellaneous checks
|
|
|
|
<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/misc/>`_
|
|
|
|
that we couldn't find a better category for.
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
After choosing the module, you need to create a class for your check:
|
|
|
|
|
|
|
|
.. code-block:: c++
|
|
|
|
|
|
|
|
#include "../ClangTidy.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace tidy {
|
2016-02-20 19:42:13 +08:00
|
|
|
namespace some_module {
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
class MyCheck : public ClangTidyCheck {
|
2016-02-20 19:42:13 +08:00
|
|
|
public:
|
|
|
|
MyCheck(StringRef Name, ClangTidyContext *Context)
|
|
|
|
: ClangTidyCheck(Name, Context) {}
|
2014-02-26 00:46:13 +08:00
|
|
|
};
|
|
|
|
|
2016-02-20 19:42:13 +08:00
|
|
|
} // namespace some_module
|
2014-02-26 00:46:13 +08:00
|
|
|
} // namespace tidy
|
|
|
|
} // namespace clang
|
|
|
|
|
2016-02-20 19:42:13 +08:00
|
|
|
Constructor of the check receives the ``Name`` and ``Context`` parameters, and
|
|
|
|
must forward them to the ``ClangTidyCheck`` constructor.
|
|
|
|
|
2014-02-26 00:46:13 +08:00
|
|
|
Next, you need to decide whether it should operate on the preprocessor level or
|
|
|
|
on the AST level. Let's imagine that we need to work with the AST in our check.
|
|
|
|
In this case we need to override two methods:
|
|
|
|
|
|
|
|
.. code-block:: c++
|
|
|
|
|
|
|
|
...
|
|
|
|
class ExplicitConstructorCheck : public ClangTidyCheck {
|
|
|
|
public:
|
2014-09-28 05:25:26 +08:00
|
|
|
ExplicitConstructorCheck(StringRef Name, ClangTidyContext *Context)
|
|
|
|
: ClangTidyCheck(Name, Context) {}
|
2014-03-03 21:36:30 +08:00
|
|
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
|
|
|
void check(ast_matchers::MatchFinder::MatchResult &Result) override;
|
2014-02-26 00:46:13 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
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 ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
|
|
|
Finder->addMatcher(constructorDecl().bind("ctor"), this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
|
2016-02-20 19:42:13 +08:00
|
|
|
const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
|
2014-02-26 00:46:13 +08:00
|
|
|
// Do not be confused: isExplicit means 'explicit' keyword is present,
|
|
|
|
// isImplicit means that it's a compiler-generated constructor.
|
|
|
|
if (Ctor->isOutOfLine() || Ctor->isExplicit() || Ctor->isImplicit())
|
|
|
|
return;
|
|
|
|
if (Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1)
|
|
|
|
return;
|
|
|
|
SourceLocation Loc = Ctor->getLocation();
|
2015-12-29 21:28:10 +08:00
|
|
|
diag(Loc, "single-argument constructors must be explicit")
|
2014-02-26 00:46:13 +08:00
|
|
|
<< FixItHint::CreateInsertion(Loc, "explicit ");
|
|
|
|
}
|
|
|
|
|
|
|
|
(The full code for this check resides in
|
2016-02-20 19:42:13 +08:00
|
|
|
`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>`_).
|
2014-02-26 00:46:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
Registering your Check
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
The check should be registered in the corresponding module with a distinct name:
|
|
|
|
|
|
|
|
.. code-block:: c++
|
|
|
|
|
|
|
|
class MyModule : public ClangTidyModule {
|
|
|
|
public:
|
2014-03-03 21:36:30 +08:00
|
|
|
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
|
2014-09-28 05:25:26 +08:00
|
|
|
CheckFactories.registerCheck<ExplicitConstructorCheck>(
|
|
|
|
"my-explicit-constructor");
|
2014-02-26 00:46:13 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
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 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 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;
|
|
|
|
|
2014-09-08 22:56:37 +08:00
|
|
|
|
2014-09-28 05:25:26 +08:00
|
|
|
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 {
|
2014-09-28 05:47:01 +08:00
|
|
|
const unsigned SomeOption1;
|
|
|
|
const std::string SomeOption2;
|
2014-09-28 05:25:26 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
MyCheck(StringRef Name, ClangTidyContext *Context)
|
|
|
|
: ClangTidyCheck(Name, Context),
|
2014-09-28 05:47:01 +08:00
|
|
|
SomeOption(Options.get("SomeOption1", -1U)),
|
|
|
|
SomeOption(Options.get("SomeOption2", "some default")) {}
|
2014-09-28 05:25:26 +08:00
|
|
|
|
2014-12-03 22:03:03 +08:00
|
|
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
|
2014-09-28 05:47:01 +08:00
|
|
|
Options.store(Opts, "SomeOption1", SomeOption1);
|
|
|
|
Options.store(Opts, "SomeOption2", SomeOption2);
|
2014-09-28 05:25:26 +08:00
|
|
|
}
|
|
|
|
...
|
|
|
|
|
2014-09-28 05:47:01 +08:00
|
|
|
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
|
|
|
|
|
2014-12-03 22:03:03 +08:00
|
|
|
CheckOptions:
|
2014-09-28 05:47:01 +08:00
|
|
|
- key: my-check.SomeOption1
|
|
|
|
value: 123
|
|
|
|
- key: my-check.SomeOption2
|
|
|
|
value: 'some other value'
|
2014-12-03 22:03:03 +08:00
|
|
|
|
|
|
|
If you need to specify check options on a command line, you can use the inline
|
|
|
|
YAML format:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ...
|
2014-09-28 05:47:01 +08:00
|
|
|
|
2014-09-28 05:25:26 +08:00
|
|
|
|
2014-10-03 15:08:22 +08:00
|
|
|
Testing Checks
|
|
|
|
--------------
|
|
|
|
|
|
|
|
: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.
|
|
|
|
|
2015-08-21 02:16:13 +08:00
|
|
|
The ``check_clang_tidy.py`` script provides an easy way to test both
|
2014-10-03 15:08:22 +08:00
|
|
|
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. To use the 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.
|
|
|
|
|
2015-08-21 02:16:13 +08:00
|
|
|
Here's an example of a test using the ``check_clang_tidy.py`` script:
|
2014-10-03 15:08:22 +08:00
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
2015-08-21 02:16:13 +08:00
|
|
|
// RUN: %python %S/check_clang_tidy.py %s google-readability-casting %t
|
2014-10-03 15:08:22 +08:00
|
|
|
|
|
|
|
void f(int a) {
|
|
|
|
int b = (int)a;
|
2015-02-23 09:12:41 +08:00
|
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting]
|
2014-10-03 15:08:22 +08:00
|
|
|
// CHECK-FIXES: int b = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
.. _lit: http://llvm.org/docs/CommandGuide/lit.html
|
|
|
|
.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html
|
|
|
|
|
|
|
|
|
2014-09-08 22:56:37 +08:00
|
|
|
Running clang-tidy on LLVM
|
|
|
|
--------------------------
|
|
|
|
|
|
|
|
To test a check it's best to try it out on a larger code base. LLVM and Clang
|
2016-02-20 19:42:13 +08:00
|
|
|
are the natural targets as you already have the source code around. The most
|
2014-09-08 22:56:37 +08:00
|
|
|
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
|
2015-08-31 21:17:43 +08:00
|
|
|
``-checks=-*,modernize-use-override`` will run the ``modernize-use-override``
|
|
|
|
check only.
|
2014-09-08 22:56:37 +08:00
|
|
|
|
|
|
|
* 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
|
|
|
|
checkers. 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.
|
2014-09-08 23:04:35 +08:00
|
|
|
|