[clang-tools-extra] r202164 - Adding documentation for clang-tidy.

Sean Silva silvas at purdue.edu
Sat Mar 1 16:27:54 PST 2014


Cool. Hopefully this will help attract contributors to scratch their itches!


On Tue, Feb 25, 2014 at 11:46 AM, Alexander Kornienko <alexfh at google.com>wrote:

> Author: alexfh
> Date: Tue Feb 25 10:46:13 2014
> New Revision: 202164
>
> URL: http://llvm.org/viewvc/llvm-project?rev=202164&view=rev
> Log:
> Adding documentation for clang-tidy.
>
> Summary:
> Contains a short user's manual and some instructions on writing
> clang-tidy checks.
>
> Reviewers: klimek, djasper
>
> Reviewed By: klimek
>
> CC: cfe-commits
>
> Differential Revision: http://llvm-reviews.chandlerc.com/D2880
>
> Added:
>     clang-tools-extra/trunk/docs/clang-tidy.rst
> Modified:
>     clang-tools-extra/trunk/docs/index.rst
>
> Added: clang-tools-extra/trunk/docs/clang-tidy.rst
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy.rst?rev=202164&view=auto
>
> ==============================================================================
> --- clang-tools-extra/trunk/docs/clang-tidy.rst (added)
> +++ clang-tools-extra/trunk/docs/clang-tidy.rst Tue Feb 25 10:46:13 2014
> @@ -0,0 +1,298 @@
> +==========
> +Clang-Tidy
> +==========
> +
> +: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
> +of how to do this see `How To Setup Tooling For LLVM`_ ). You can also
> specify
> +compilation options on the command line after ``--``:
> +
> +.. code-block:: bash
> +
> +  $ 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
> +``-checks=`` and ``-disable-checks=`` options. :program:`clang-tidy`
> selects the
> +checks with names matching the regular expression specified by the
> ``-checks=``
> +option and not matching the one specified by the ``-disable-checks=``
> option.
> +
> +The ``-list-checks`` option lists all the enabled checks. It can be used
> with or
> +without ``-checks=`` and/or ``-disable-checks=``.
> +
> +There are currently three groups of checks:
> +
> +* Checks related to the LLVM coding conventions have names starting with
> +  ``llvm-``.
> +
> +* Checks related to the Google coding conventions have names starting with
> +  ``google-``.
> +
> +* Clang static analyzer checks are named starting with
> ``clang-analyzer-``.
> +
> +
> +The ``-fix`` flag instructs :program:`clang-format` to fix found errors if
> +supported by corresponding checks.
> +
> +An overview of all the command-line options:
> +
> +.. code-block:: bash
> +
> +  $ clang-tidy -help
> +  USAGE: clang-tidy [options] <source0> [... <sourceN>]
> +
> +  OPTIONS:
> +
> +  General options:
> +
> +    -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
> +
> +  clang-tidy options:
> +
> +    -checks=<string>         - Regular expression matching the names of
> +                               the checks to be run.
> +    -disable-checks=<string> - Regular expression matching the names of
> +                               the checks to disable.
> +    -fix                     - Fix detected errors if possible.
> +    -list-checks             - List all enabled checks and exit.
> +    -p=<string>              - Build path
> +
> +  -p <build-path> is used to read a compile command database.
> +
> +    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.
> +
> +  <source0> ... specify the paths of source files. These paths are
> +    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.
> +
> +
> +.. _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.
> +
> +Checks can plug 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 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.
> +
> +.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html
> +.. _PPCallbacks:
> http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.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.
> +  â"oeâ" EURO â" EURO ClangTidy.h                   # Interfaces for users and
> checks.
> +  â"oeâ" EURO â" EURO ClangTidyModule.h             # Interface for clang-tidy
> modules.
> +  â"oeâ" EURO â" EURO ClangTidyModuleRegistry.h     # Interface for registering of
> modules.
> +     ...
> +  â"oeâ" EURO â" EURO google/                       # Google clang-tidy module.
> +  â"'Â Â  â"oeâ" EURO â" EURO GoogleTidyModule.cpp
> +  â"'Â Â  â"oeâ" EURO â" EURO GoogleTidyModule.h
> +          ...
> +  â"oeâ" EURO â" EURO llvm/                         # LLVM clang-tidy module.
> +  â"'Â Â  â"oeâ" EURO â" EURO LLVMTidyModule.cpp
> +  â"'Â Â  â"oeâ" EURO â" EURO LLVMTidyModule.h
> +          ...
> +  â""â" EURO â" EURO tool/                         # Sources of the clang-tidy
> binary.
> +          ...
> +  test/clang-tidy/                  # Integration tests.
> +      ...
> +  unittests/clang-tidy/
> +  â"oeâ" EURO â" EURO ClangTidyTest.h
> +  â"oeâ" EURO â" EURO GoogleModuleTest.cpp
> +  â"oeâ" EURO â" EURO LLVMModuleTest.cpp
> +      ...
> +
> +
> +Writing a clang-tidy Check
> +--------------------------
> +
> +So you have an idea of a useful check for :program:`clang-tidy`.
> +
> +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 LLVM and
> Google
> +modules already).
> +
> +After choosing the module, you need to create a class for your check:
> +
> +.. code-block:: c++
> +
> +  #include "../ClangTidy.h"
> +
> +  namespace clang {
> +  namespace tidy {
> +
> +  class MyCheck : public ClangTidyCheck {
> +  };
> +
> +  } // namespace tidy
> +  } // namespace clang
> +
> +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:
> +    void registerMatchers(ast_matchers::MatchFinder *Finder);
> +    void check(ast_matchers::MatchFinder::MatchResult &Result);
> +  };
> +
> +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) {
> +    const CXXConstructorDecl *Ctor =
> +        Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
> +    // 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();
> +    diag(Loc, "Single-argument constructors must be explicit")
> +        << FixItHint::CreateInsertion(Loc, "explicit ");
> +  }
> +
> +(The full code for this check resides in
> +``clang-tidy/google/GoogleTidyModule.cpp``).
> +
> +
> +Registering your Check
> +----------------------
> +
> +The check should be registered in the corresponding module with a
> distinct name:
> +
> +.. code-block:: c++
> +
> +  class MyModule : public ClangTidyModule {
> +   public:
> +    virtual void
> +    addCheckFactories(ClangTidyCheckFactories &CheckFactories)
> LLVM_OVERRIDE {
> +      CheckFactories.addCheckFactory(
> +          "my-explicit-constructor",
> +          new ClangTidyCheckFactory<ExplicitConstructorCheck>());
> +    }
> +  };
> +
> +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;
> +
>
> Modified: clang-tools-extra/trunk/docs/index.rst
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/index.rst?rev=202164&r1=202163&r2=202164&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/docs/index.rst (original)
> +++ clang-tools-extra/trunk/docs/index.rst Tue Feb 25 10:46:13 2014
> @@ -16,6 +16,7 @@ Contents
>     :maxdepth: 1
>
>     clang-modernize
> +   clang-tidy
>     modularize
>     module-map-checker
>     pp-trace
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140301/3851acfc/attachment.html>


More information about the cfe-commits mailing list