<div dir="ltr">Cool. Hopefully this will help attract contributors to scratch their itches!</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 25, 2014 at 11:46 AM, Alexander Kornienko <span dir="ltr"><<a href="mailto:alexfh@google.com" target="_blank">alexfh@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: alexfh<br>
Date: Tue Feb 25 10:46:13 2014<br>
New Revision: 202164<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=202164&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=202164&view=rev</a><br>
Log:<br>
Adding documentation for clang-tidy.<br>
<br>
Summary:<br>
Contains a short user's manual and some instructions on writing<br>
clang-tidy checks.<br>
<br>
Reviewers: klimek, djasper<br>
<br>
Reviewed By: klimek<br>
<br>
CC: cfe-commits<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D2880" target="_blank">http://llvm-reviews.chandlerc.com/D2880</a><br>
<br>
Added:<br>
    clang-tools-extra/trunk/docs/clang-tidy.rst<br>
Modified:<br>
    clang-tools-extra/trunk/docs/index.rst<br>
<br>
Added: clang-tools-extra/trunk/docs/clang-tidy.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy.rst?rev=202164&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy.rst?rev=202164&view=auto</a><br>

==============================================================================<br>
--- clang-tools-extra/trunk/docs/clang-tidy.rst (added)<br>
+++ clang-tools-extra/trunk/docs/clang-tidy.rst Tue Feb 25 10:46:13 2014<br>
@@ -0,0 +1,298 @@<br>
+==========<br>
+Clang-Tidy<br>
+==========<br>
+<br>
+:program:`clang-tidy` is a clang-based C++ linter tool. Its purpose is to<br>
+provide an extensible framework for diagnosing and fixing typical programming<br>
+errors, like style violations, interface misuse, or bugs that can be deduced via<br>
+static analysis. :program:`clang-tidy` is modular and provides a convenient<br>
+interface for writing new checks.<br>
+<br>
+<br>
+Using clang-tidy<br>
+================<br>
+<br>
+:program:`clang-tidy` is a `LibTooling`_-based tool, and it's easier to work<br>
+with if you set up a compile command database for your project (for an example<br>
+of how to do this see `How To Setup Tooling For LLVM`_ ). You can also specify<br>
+compilation options on the command line after ``--``:<br>
+<br>
+.. code-block:: bash<br>
+<br>
+  $ clang-tidy test.cpp -- -Imy_project/include -DMY_DEFINES ...<br>
+<br>
+:program:`clang-tidy` has its own checks and can also run Clang static analyzer<br>
+checks. Each check has a name and the checks to run can be chosen using the<br>
+``-checks=`` and ``-disable-checks=`` options. :program:`clang-tidy` selects the<br>
+checks with names matching the regular expression specified by the ``-checks=``<br>
+option and not matching the one specified by the ``-disable-checks=`` option.<br>
+<br>
+The ``-list-checks`` option lists all the enabled checks. It can be used with or<br>
+without ``-checks=`` and/or ``-disable-checks=``.<br>
+<br>
+There are currently three groups of checks:<br>
+<br>
+* Checks related to the LLVM coding conventions have names starting with<br>
+  ``llvm-``.<br>
+<br>
+* Checks related to the Google coding conventions have names starting with<br>
+  ``google-``.<br>
+<br>
+* Clang static analyzer checks are named starting with ``clang-analyzer-``.<br>
+<br>
+<br>
+The ``-fix`` flag instructs :program:`clang-format` to fix found errors if<br>
+supported by corresponding checks.<br>
+<br>
+An overview of all the command-line options:<br>
+<br>
+.. code-block:: bash<br>
+<br>
+  $ clang-tidy -help<br>
+  USAGE: clang-tidy [options] <source0> [... <sourceN>]<br>
+<br>
+  OPTIONS:<br>
+<br>
+  General options:<br>
+<br>
+    -help                    - Display available options (-help-hidden<br>
+                               for more)<br>
+    -help-list               - Display list of available options<br>
+                               (-help-list-hidden for more)<br>
+    -version                 - Display the version of this program<br>
+<br>
+  clang-tidy options:<br>
+<br>
+    -checks=<string>         - Regular expression matching the names of<br>
+                               the checks to be run.<br>
+    -disable-checks=<string> - Regular expression matching the names of<br>
+                               the checks to disable.<br>
+    -fix                     - Fix detected errors if possible.<br>
+    -list-checks             - List all enabled checks and exit.<br>
+    -p=<string>              - Build path<br>
+<br>
+  -p <build-path> is used to read a compile command database.<br>
+<br>
+    For example, it can be a CMake build directory in which a file named<br>
+    compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON<br>
+    CMake option to get this output). When no build path is specified,<br>
+    a search for compile_commands.json will be attempted through all<br>
+    parent paths of the first input file . See:<br>
+    <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html" target="_blank">http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html</a> for an<br>
+    example of setting up Clang Tooling on a source tree.<br>
+<br>
+  <source0> ... specify the paths of source files. These paths are<br>
+    looked up in the compile command database. If the path of a file is<br>
+    absolute, it needs to point into CMake's source tree. If the path is<br>
+    relative, the current working directory needs to be in the CMake<br>
+    source tree and the file must be in a subdirectory of the current<br>
+    working directory. "./" prefixes in the relative files will be<br>
+    automatically removed, but the rest of a relative path must be a<br>
+    suffix of a path in the compile command database.<br>
+<br>
+<br>
+.. _LibTooling: <a href="http://clang.llvm.org/docs/LibTooling.html" target="_blank">http://clang.llvm.org/docs/LibTooling.html</a><br>
+.. _How To Setup Tooling For LLVM: <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html" target="_blank">http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html</a><br>
+<br>
+<br>
+Getting Involved<br>
+================<br>
+<br>
+:program:`clang-tidy` has several own checks and can run Clang static analyzer<br>
+checks, but its power is in the ability to easily write custom checks.<br>
+<br>
+Checks are organized in modules, which can be linked into :program:`clang-tidy`<br>
+with minimal or no code changes in clang-tidy.<br>
+<br>
+Checks can plug the analysis on the preprocessor level using `PPCallbacks`_ or<br>
+on the AST level using `AST Matchers`_. When an error is found, checks can<br>
+report them in a way similar to how Clang diagnostics work. A fix-it hint can be<br>
+attached to a diagnostic message.<br>
+<br>
+The interface provided by clang-tidy makes it easy to write useful and precise<br>
+checks in just a few lines of code. If you have an idea for a good check, the<br>
+rest of this document explains how to do this.<br>
+<br>
+.. _AST Matchers: <a href="http://clang.llvm.org/docs/LibASTMatchers.html" target="_blank">http://clang.llvm.org/docs/LibASTMatchers.html</a><br>
+.. _PPCallbacks: <a href="http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html</a><br>
+<br>
+<br>
+Choosing the Right Place for your Check<br>
+---------------------------------------<br>
+<br>
+If you have an idea of a check, you should decide whether it should be<br>
+implemented as a:<br>
+<br>
++ *Clang diagnostic*: if the check is generic enough, targets code patterns that<br>
+  most probably are bugs (rather than style or readability issues), can be<br>
+  implemented effectively and with extremely low false positive rate, it may<br>
+  make a good Clang diagnostic.<br>
+<br>
++ *Clang static analyzer check*: if the check requires some sort of control flow<br>
+  analysis, it should probably be implemented as a static analyzer check.<br>
+<br>
++ *clang-tidy check* is a good choice for linter-style checks, checks that are<br>
+  related to a certain coding style, checks that address code readability, etc.<br>
+<br>
+<br>
+Preparing your Workspace<br>
+------------------------<br>
+<br>
+If you are new to LLVM development, you should read the `Getting Started with<br>
+the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_<br>
+documents to check out and build LLVM, Clang and Clang Extra Tools with CMake.<br>
+<br>
+Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and<br>
+let's start!<br>
+<br>
+.. _Getting Started with the LLVM System: <a href="http://llvm.org/docs/GettingStarted.html" target="_blank">http://llvm.org/docs/GettingStarted.html</a><br>
+.. _Using Clang Tools: <a href="http://clang.llvm.org/docs/ClangTools.html" target="_blank">http://clang.llvm.org/docs/ClangTools.html</a><br>
+<br>
+<br>
+The Directory Structure<br>
+-----------------------<br>
+<br>
+:program:`clang-tidy` source code resides in the<br>
+``llvm/tools/clang/tools/extra`` directory and is structured as follows:<br>
+<br>
+::<br>
+<br>
+  clang-tidy/                       # Clang-tidy core.<br>
+  â”œâ”€â”€ ClangTidy.h                   # Interfaces for users and checks.<br>
+  â”œâ”€â”€ ClangTidyModule.h             # Interface for clang-tidy modules.<br>
+  â”œâ”€â”€ ClangTidyModuleRegistry.h     # Interface for registering of modules.<br>
+     ...<br>
+  â”œâ”€â”€ google/                       # Google clang-tidy module.<br>
+  â”‚   â”œâ”€â”€ GoogleTidyModule.cpp<br>
+  â”‚   â”œâ”€â”€ GoogleTidyModule.h<br>
+          ...<br>
+  â”œâ”€â”€ llvm/                         # LLVM clang-tidy module.<br>
+  â”‚   â”œâ”€â”€ LLVMTidyModule.cpp<br>
+  â”‚   â”œâ”€â”€ LLVMTidyModule.h<br>
+          ...<br>
+  â””── tool/                         # Sources of the clang-tidy binary.<br>
+          ...<br>
+  test/clang-tidy/                  # Integration tests.<br>
+      ...<br>
+  unittests/clang-tidy/<br>
+  â”œâ”€â”€ ClangTidyTest.h<br>
+  â”œâ”€â”€ GoogleModuleTest.cpp<br>
+  â”œâ”€â”€ LLVMModuleTest.cpp<br>
+      ...<br>
+<br>
+<br>
+Writing a clang-tidy Check<br>
+--------------------------<br>
+<br>
+So you have an idea of a useful check for :program:`clang-tidy`.<br>
+<br>
+You need to decide which module the check belongs to. If the check verifies<br>
+conformance of the code to a certain coding style, it probably deserves a<br>
+separate module and a directory in ``clang-tidy/`` (there are LLVM and Google<br>
+modules already).<br>
+<br>
+After choosing the module, you need to create a class for your check:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  #include "../ClangTidy.h"<br>
+<br>
+  namespace clang {<br>
+  namespace tidy {<br>
+<br>
+  class MyCheck : public ClangTidyCheck {<br>
+  };<br>
+<br>
+  } // namespace tidy<br>
+  } // namespace clang<br>
+<br>
+Next, you need to decide whether it should operate on the preprocessor level or<br>
+on the AST level. Let's imagine that we need to work with the AST in our check.<br>
+In this case we need to override two methods:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  ...<br>
+  class ExplicitConstructorCheck : public ClangTidyCheck {<br>
+  public:<br>
+    void registerMatchers(ast_matchers::MatchFinder *Finder);<br>
+    void check(ast_matchers::MatchFinder::MatchResult &Result);<br>
+  };<br>
+<br>
+In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_<br>
+for more information) that will find the pattern in the AST that we want to<br>
+inspect. The results of the matching are passed to the ``check`` method, which<br>
+can further inspect them and report diagnostics.<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  using namespace ast_matchers;<br>
+<br>
+  void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) {<br>
+    Finder->addMatcher(constructorDecl().bind("ctor"), this);<br>
+  }<br>
+<br>
+  void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {<br>
+    const CXXConstructorDecl *Ctor =<br>
+        Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");<br>
+    // Do not be confused: isExplicit means 'explicit' keyword is present,<br>
+    // isImplicit means that it's a compiler-generated constructor.<br>
+    if (Ctor->isOutOfLine() || Ctor->isExplicit() || Ctor->isImplicit())<br>
+      return;<br>
+    if (Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1)<br>
+      return;<br>
+    SourceLocation Loc = Ctor->getLocation();<br>
+    diag(Loc, "Single-argument constructors must be explicit")<br>
+        << FixItHint::CreateInsertion(Loc, "explicit ");<br>
+  }<br>
+<br>
+(The full code for this check resides in<br>
+``clang-tidy/google/GoogleTidyModule.cpp``).<br>
+<br>
+<br>
+Registering your Check<br>
+----------------------<br>
+<br>
+The check should be registered in the corresponding module with a distinct name:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  class MyModule : public ClangTidyModule {<br>
+   public:<br>
+    virtual void<br>
+    addCheckFactories(ClangTidyCheckFactories &CheckFactories) LLVM_OVERRIDE {<br>
+      CheckFactories.addCheckFactory(<br>
+          "my-explicit-constructor",<br>
+          new ClangTidyCheckFactory<ExplicitConstructorCheck>());<br>
+    }<br>
+  };<br>
+<br>
+Now we need to register the module in the ``ClangTidyModuleRegistry`` using a<br>
+statically initialized variable:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  static ClangTidyModuleRegistry::Add<MyModule> X("my-module",<br>
+                                                  "Adds my lint checks.");<br>
+<br>
+<br>
+When using LLVM build system, we need to use the following hack to ensure the<br>
+module is linked into the clang-tidy binary:<br>
+<br>
+Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  // This anchor is used to force the linker to link in the generated object file<br>
+  // and thus register the MyModule.<br>
+  volatile int MyModuleAnchorSource = 0;<br>
+<br>
+And this to the main translation unit of the clang-tidy binary (or the binary<br>
+you link the ``clang-tidy`` library in) ``clang-tidy/tool/ClangTidyMain.cpp``:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  // This anchor is used to force the linker to link the MyModule.<br>
+  extern volatile int MyModuleAnchorSource;<br>
+  static int MyModuleAnchorDestination = MyModuleAnchorSource;<br>
+<br>
<br>
Modified: clang-tools-extra/trunk/docs/index.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/index.rst?rev=202164&r1=202163&r2=202164&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/index.rst?rev=202164&r1=202163&r2=202164&view=diff</a><br>

==============================================================================<br>
--- clang-tools-extra/trunk/docs/index.rst (original)<br>
+++ clang-tools-extra/trunk/docs/index.rst Tue Feb 25 10:46:13 2014<br>
@@ -16,6 +16,7 @@ Contents<br>
    :maxdepth: 1<br>
<br>
    clang-modernize<br>
+   clang-tidy<br>
    modularize<br>
    module-map-checker<br>
    pp-trace<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>