<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>