Cool. Hopefully this will help attract contributors to scratch their itches!
On Tue, Feb 25, 2014 at 11:46 AM, Alexander Kornienko <[email protected]>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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
