brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.2 KiB · 4ede4ea Raw
817 lines · plain
1================2Getting Involved3================4 5:program:`clang-tidy` has several own checks and can run Clang static analyzer6checks, but its power is in the ability to easily write custom checks.7 8Checks are organized in modules, which can be linked into :program:`clang-tidy`9with minimal or no code changes in :program:`clang-tidy`.10 11Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_12or on the AST level using `AST Matchers`_. When an error is found, checks can13report them in a way similar to how Clang diagnostics work. A fix-it hint can be14attached to a diagnostic message.15 16The interface provided by :program:`clang-tidy` makes it easy to write useful17and precise checks in just a few lines of code. If you have an idea for a good18check, the rest of this document explains how to do this.19 20There are a few tools particularly useful when developing clang-tidy checks:21  * ``add_new_check.py`` is a script to automate the process of adding a new22    check; it will create the check, update the CMake file and create a test.23  * ``rename_check.py`` does what the script name suggests, renames an existing24    check.25  * :program:`pp-trace` logs method calls on `PPCallbacks` for a source file26    and is invaluable in understanding the preprocessor mechanism.27  * :program:`clang-query` is invaluable for interactive prototyping of AST28    matchers and exploration of the Clang AST;29  * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``)30    provides a convenient way to dump AST of a C++ program.31 32If CMake is configured with ``CLANG_TIDY_ENABLE_STATIC_ANALYZER=NO``,33:program:`clang-tidy` will not be built with support for the34``clang-analyzer-*`` checks or the ``mpi-*`` checks.35 36If CMake is configured with ``CLANG_TIDY_ENABLE_QUERY_BASED_CUSTOM_CHECKS=NO``,37:program:`clang-tidy` will not be built with support for query based checks. 38 39 40.. _AST Matchers: https://clang.llvm.org/docs/LibASTMatchers.html41.. _PPCallbacks: https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html42.. _clang-check: https://clang.llvm.org/docs/ClangCheck.html43 44 45Choosing the Right Place for your Check46---------------------------------------47 48If you have an idea of a check, you should decide whether it should be49implemented as a:50 51+ *Clang diagnostic*: if the check is generic enough, targets code patterns that52  most probably are bugs (rather than style or readability issues), can be53  implemented effectively and with extremely low false-positive rate, it may54  make a good Clang diagnostic.55 56+ *Clang static analyzer check*: if the check requires some sort of control flow57  analysis, it should probably be implemented as a static analyzer check.58 59+ *clang-tidy check* is a good choice for linter-style checks, checks that are60  related to a certain coding style, checks that address code readability, etc.61 62 63Preparing your Workspace64------------------------65 66If you are new to LLVM development, you should read the `Getting Started with67the LLVM System`_, `Using Clang Tools`_ and `How To Setup Clang Tooling For68LLVM`_ documents to check out and build LLVM, Clang and Clang Extra Tools with69CMake.70 71Once you are done, change to the ``llvm/clang-tools-extra`` directory, and72let's start!73 74.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html75.. _Using Clang Tools: https://clang.llvm.org/docs/ClangTools.html76.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html77 78When you `configure the CMake build <https://llvm.org/docs/GettingStarted.html#local-llvm-configuration>`_,79make sure that you enable the ``clang`` and ``clang-tools-extra`` projects to80build :program:`clang-tidy`.81Because your new check will have associated documentation, you will also want to install82`Sphinx <https://www.sphinx-doc.org/en/master/>`_ and enable it in the CMake configuration.83To save build time of the core Clang libraries, you may want to only enable the ``X86``84target in the CMake configuration.85 86 87The Directory Structure88-----------------------89 90:program:`clang-tidy` source code resides in the91``llvm/clang-tools-extra`` directory and is structured as follows:92 93::94 95  clang-tidy/                       # Clang-tidy core.96  |-- ClangTidy.h                   # Interfaces for users.97  |-- ClangTidyCheck.h              # Interfaces for checks.98  |-- ClangTidyModule.h             # Interface for clang-tidy modules.99  |-- ClangTidyModuleRegistry.h     # Interface for registering of modules.100     ...101  |-- google/                       # Google clang-tidy module.102  |-+103    |-- GoogleTidyModule.cpp104    |-- GoogleTidyModule.h105          ...106  |-- llvm/                         # LLVM clang-tidy module.107  |-+108    |-- LLVMTidyModule.cpp109    |-- LLVMTidyModule.h110          ...111  |-- objc/                         # Objective-C clang-tidy module.112  |-+113    |-- ObjCTidyModule.cpp114    |-- ObjCTidyModule.h115          ...116  |-- tool/                         # Sources of the clang-tidy binary.117          ...118  test/clang-tidy/                  # Integration tests.119      ...120  unittests/clang-tidy/             # Unit tests.121  |-- ClangTidyTest.h122  |-- GoogleModuleTest.cpp123  |-- LLVMModuleTest.cpp124  |-- ObjCModuleTest.cpp125      ...126 127 128Writing a clang-tidy Check129--------------------------130 131So you have an idea of a useful check for :program:`clang-tidy`.132 133First, if you're not familiar with LLVM development, read through the `Getting Started 134with the LLVM System`_ document for instructions on setting up your workflow and135the `LLVM Coding Standards`_ document to familiarize yourself with the coding136style used in the project. For code reviews, we currently use `LLVM Github`_,137though historically we used Phabricator.138 139.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html140.. _LLVM Coding Standards: https://llvm.org/docs/CodingStandards.html141.. _LLVM Github: https://github.com/llvm/llvm-project142 143Next, you need to decide which module the check belongs to. Modules144are located in subdirectories of `clang-tidy/145<https://github.com/llvm/llvm-project/tree/main/clang-tools-extra/clang-tidy/>`_146and contain checks targeting a certain aspect of code quality (performance,147readability, etc.), a certain coding style or standard (Google, LLVM, CERT, etc.)148or a widely used API (e.g. MPI). Their names are the same as the user-facing149check group names described :ref:`above <checks-groups-table>`.150 151After choosing the module and the name for the check, run the152``clang-tidy/add_new_check.py`` script to create the skeleton of the check and153plug it to :program:`clang-tidy`. It's the recommended way of adding new checks.154 155By default, the new check will apply only to C++ code. If it should apply under156different language options, use the ``--language`` script's parameter.157 158If we want to create a `readability-awesome-function-names`, we would run:159 160.. code-block:: console161 162  $ clang-tidy/add_new_check.py readability awesome-function-names163 164 165The ``add_new_check.py`` script will:166  * create the class for your check inside the specified module's directory and167    register it in the module and in the build system;168  * create a lit test file in the ``test/clang-tidy/`` directory;169  * create a documentation file and include it into the170    ``docs/clang-tidy/checks/list.rst``.171 172Let's look at the check class definition in more detail:173 174.. code-block:: c++175 176  ...177 178  #include "../ClangTidyCheck.h"179 180  namespace clang::tidy::readability {181 182  ...183  class AwesomeFunctionNamesCheck : public ClangTidyCheck {184  public:185    AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context)186        : ClangTidyCheck(Name, Context) {}187    void registerMatchers(ast_matchers::MatchFinder *Finder) override;188    void check(const ast_matchers::MatchFinder::MatchResult &Result) override;189    bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {190      return LangOpts.CPlusPlus;191    }192  };193 194  } // namespace clang::tidy::readability195 196  ...197 198Constructor of the check receives the ``Name`` and ``Context`` parameters, and199must forward them to the ``ClangTidyCheck`` constructor.200 201In our case the check needs to operate on the AST level and it overrides the202``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the203preprocessor level, we'd need instead to override the ``registerPPCallbacks``204method.205 206In the ``registerMatchers`` method, we create an AST Matcher (see `AST Matchers`_207for more information) that will find the pattern in the AST that we want to208inspect. The results of the matching are passed to the ``check`` method, which209can further inspect them and report diagnostics.210 211.. code-block:: c++212 213  using namespace ast_matchers;214 215  void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) {216    Finder->addMatcher(functionDecl().bind("x"), this);217  }218 219  void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) {220    const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");221    if (!MatchedDecl->getIdentifier() || MatchedDecl->getName().startswith("awesome_"))222      return;223    diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome")224        << MatchedDecl225        << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");226  }227 228(If you want to see an example of a useful check, look at229`clang-tidy/google/ExplicitConstructorCheck.h230<https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h>`_231and `clang-tidy/google/ExplicitConstructorCheck.cpp232<https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_).233 234If you need to interact with macros or preprocessor directives, you will want to235override the method ``registerPPCallbacks``.  The ``add_new_check.py`` script236does not generate an override for this method in the starting point for your237new check.238 239Check development tips240----------------------241 242Writing your first check can be a daunting task, particularly if you are unfamiliar243with the LLVM and Clang code bases.  Here are some suggestions for orienting yourself244in the codebase and working on your check incrementally.245 246Guide to useful documentation247^^^^^^^^^^^^^^^^^^^^^^^^^^^^^248 249Many of the support classes created for LLVM are used by Clang, such as `StringRef250<https://llvm.org/docs/ProgrammersManual.html#the-stringref-class>`_251and `SmallVector <https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h>`_.252These and other commonly used classes are described in the `Important and useful LLVM APIs253<https://llvm.org/docs/ProgrammersManual.html#important-and-useful-llvm-apis>`_ and254`Picking the Right Data Structure for the Task255<https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task>`_256sections of the `LLVM Programmer's Manual257<https://llvm.org/docs/ProgrammersManual.html>`_.  You don't need to memorize all the258details of these classes; the generated `doxygen documentation <https://llvm.org/doxygen/>`_259has everything if you need it.  In the header `LLVM/ADT/STLExtras.h260<https://llvm.org/doxygen/STLExtras_8h.html>`_ you'll find useful versions of the STL261algorithms that operate on LLVM containers, such as `llvm::all_of262<https://llvm.org/doxygen/STLExtras_8h.html#func-members>`_.263 264Clang is implemented on top of LLVM and introduces its own set of classes that you265will interact with while writing your check.  When a check issues diagnostics and266fix-its, these are associated with locations in the source code.  Source code locations,267source files, ranges of source locations and the `SourceManager268<https://clang.llvm.org/doxygen/classclang_1_1SourceManager.html>`_ class provide269the mechanisms for describing such locations.  These and270other topics are described in the `"Clang" CFE Internals Manual271<https://clang.llvm.org/docs/InternalsManual.html>`_.  Whereas the doxygen generated272documentation serves as a reference to the internals of Clang, this document serves273as a guide to other developers.  Topics in that manual of interest to a check developer274are:275 276- `The Clang "Basic" Library277  <https://clang.llvm.org/docs/InternalsManual.html#the-clang-basic-library>`_ for278  information about diagnostics, fix-it hints and source locations.279- `The Lexer and Preprocessor Library280  <https://clang.llvm.org/docs/InternalsManual.html#the-lexer-and-preprocessor-library>`_281  for information about tokens, lexing (transforming characters into tokens) and the282  preprocessor.283- `The AST Library284  <https://clang.llvm.org/docs/InternalsManual.html#the-ast-library>`_285  for information about how C++ source statements are represented as an abstract syntax286  tree (AST).287 288Most checks will interact with C++ source code via the AST.  Some checks will interact289with the preprocessor.  The input source file is lexed and preprocessed and then parsed290into the AST.  Once the AST is fully constructed, the check is run by applying the check's291registered AST matchers against the AST and invoking the check with the set of matched292nodes from the AST.  Monitoring the actions of the preprocessor is detached from the293AST construction, but a check can collect information during preprocessing for later294use by the check when nodes are matched by the AST.295 296Every syntactic (and sometimes semantic) element of the C++ source code is represented by297different classes in the AST.  You select the portions of the AST you're interested in298by composing AST matcher functions.  You will want to study carefully the `AST Matcher299Reference <https://clang.llvm.org/docs/LibASTMatchersReference.html>`_ to understand300the relationship between the different matcher functions.301 302Using the Transformer library303^^^^^^^^^^^^^^^^^^^^^^^^^^^^^304 305The Transformer library allows you to write a check that transforms source code by306expressing the transformation as a ``RewriteRule``.  The Transformer library provides307functions for composing edits to source code to create rewrite rules.  Unless you need308to perform low-level source location manipulation, you may want to consider writing your309check with the Transformer library.  The `Clang Transformer Tutorial310<https://clang.llvm.org/docs/ClangTransformerTutorial.html>`_ describes the Transformer311library in detail.312 313To use the Transformer library, make the following changes to the code generated by314the ``add_new_check.py`` script:315 316- Include ``../utils/TransformerClangTidyCheck.h`` instead of ``../ClangTidyCheck.h``317- Change the base class of your check from ``ClangTidyCheck`` to ``TransformerClangTidyCheck``318- Delete the override of the ``registerMatchers`` and ``check`` methods in your check class.319- Write a function that creates the ``RewriteRule`` for your check.320- Call the function in your check's constructor to pass the rewrite rule to321  ``TransformerClangTidyCheck``'s constructor.322 323Developing your check incrementally324^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^325 326The best way to develop your check is to start with simple test cases and increase327complexity incrementally.  The test file created by the ``add_new_check.py`` script is328a starting point for your test cases.  A rough outline of the process looks like this:329 330- Write a test case for your check.331- Prototype matchers on the test file using :program:`clang-query`.332- Capture the working matchers in the ``registerMatchers`` method.333- Issue the necessary diagnostics and fix-its in the ``check`` method.334- Add the necessary ``CHECK-MESSAGES`` and ``CHECK-FIXES`` annotations to your335  test case to validate the diagnostics and fix-its.336- Build the target ``check-clang-tools`` to confirm the test passes.337- Repeat the process until all aspects of your check are covered by tests.338 339The quickest way to prototype your matcher is to use :program:`clang-query` to340interactively build up your matcher.  For complicated matchers, build up a matching341expression incrementally and use :program:`clang-query`'s ``let`` command to save named342matching expressions to simplify your matcher.343 344.. code-block:: console345 346  clang-query> let c1 cxxRecordDecl()347  clang-query> match c1348 349Alternatively, pressing the tab key after a previous matcher's open parentheses 350would also show which matchers can be chained with the previous matcher, 351though some matchers that work may not be listed. Note that tab completion 352does not currently work on Windows.353 354Just like breaking up a huge function into smaller chunks with 355intention-revealing names can help you understand a complex algorithm, breaking 356up a matcher into smaller matchers with intention-revealing names can help 357you understand a complicated matcher.  358 359Once you have a working :program:`clang-query` matcher, the C++ API matchers 360will be the same or similar to your interactively constructed matcher (there 361can be cases where they differ slightly). You can use local variables to preserve 362your intention-revealing names that you applied to nested matchers.363 364Creating private matchers365^^^^^^^^^^^^^^^^^^^^^^^^^366 367Sometimes you want to match a specific aspect of the AST that isn't provided by the368existing AST matchers.  You can create your own private matcher using the same369infrastructure as the public matchers.  A private matcher can simplify the processing370in your ``check`` method by eliminating complex hand-crafted AST traversal of the371matched nodes.  Using the private matcher allows you to select the desired portions372of the AST directly in the matcher and refer to it by a bound name in the ``check``373method.374 375Unit testing helper code376^^^^^^^^^^^^^^^^^^^^^^^^377 378Private custom matchers are a good example of auxiliary support code for your check379that can be tested with a unit test.  It will be easier to test your matchers or380other support classes by writing a unit test than by writing a ``FileCheck`` integration381test.  The ``ASTMatchersTests`` target contains unit tests for the public AST matcher382classes and is a good source of testing idioms for matchers.383 384You can build the Clang-tidy unit tests by building the ``ClangTidyTests`` target.385Test targets in LLVM and Clang are excluded from the "build all" style action of386IDE-based CMake generators, so you need to explicitly build the target for the unit387tests to be built.388 389Making your check robust390^^^^^^^^^^^^^^^^^^^^^^^^391 392Once you've covered your check with the basic "happy path" scenarios, you'll want to393torture your check with as many edge cases as you can cover in order to ensure your394check is robust.  Running your check on a large code base, such as Clang/LLVM, is a395good way to catch things you forgot to account for in your matchers.  However, the396LLVM code base may be insufficient for testing purposes as it was developed against a397particular set of coding styles and quality measures.  The larger the corpus of code398the check is tested against, the higher confidence the community will have in the399check's efficacy and false-positive rate.400 401Some suggestions to ensure your check is robust:402 403- Create header files that contain code matched by your check.404- Validate that fix-its are properly applied to test header files with405  :program:`clang-tidy`.  You will need to perform this test manually until406  automated support for checking messages and fix-its is added to the407  ``check_clang_tidy.py`` script.408- Define macros that contain code matched by your check.409- Define template classes that contain code matched by your check.410- Define template specializations that contain code matched by your check.411- Test your check under both Windows and Linux environments.412- Watch out for high false-positive rates.  Ideally, a check would have no false413  positives, but given that matching against an AST is not control- or data flow-414  sensitive, a number of false positives are expected.  The higher the415  false-positive rate, the less likely the check will be adopted in practice.416  Mechanisms should be put in place to help the user manage false positives.417- There are two primary mechanisms for managing false positives: supporting a418  code pattern which allows the programmer to silence the diagnostic in an ad419  hoc manner and check configuration options to control the behavior of the check.420- Consider supporting a code pattern to allow the programmer to silence the421  diagnostic whenever such a code pattern can clearly express the programmer's422  intent.  For example, allowing an explicit cast to ``void`` to silence an423  unused variable diagnostic.424- Consider adding check configuration options to allow the user to opt into425  more aggressive checking behavior without burdening users for the common426  high-confidence cases.427 428Documenting your check429^^^^^^^^^^^^^^^^^^^^^^430 431The ``add_new_check.py`` script creates entries in the432`release notes <https://clang.llvm.org/extra/ReleaseNotes.html>`_, the list of433checks and a new file for the check documentation itself.  It is recommended that you434have a concise summary of what your check does in a single sentence that is repeated435in the release notes, as the first sentence in the doxygen comments in the header file436for your check class and as the first sentence of the check documentation.  Avoid the437phrase "this check" in your check summary and check documentation.438 439If your check relates to a published coding guideline (C++ Core Guidelines, SEI CERT, etc.)440or style guide, provide links to the relevant guideline or style guide sections in your441check documentation.442 443Provide enough examples of the diagnostics and fix-its provided by the check so that a444user can easily understand what will happen to their code when the check is run.445If there are exceptions or limitations to your check, document them thoroughly.  This446will help users understand the scope of the diagnostics and fix-its provided by the check.447 448Building the target ``docs-clang-tools-html`` will run the Sphinx documentation generator449and create HTML documentation files in the tools/clang/tools/extra/docs/html directory in450your build tree.  Make sure that your check is correctly shown in the release notes and the451list of checks.  Make sure that the formatting and structure of your check's documentation452look correct.453 454 455Registering your Check456----------------------457 458(The ``add_new_check.py`` script takes care of registering the check in an existing459module. If you want to create a new module or know the details, read on.)460 461The check should be registered in the corresponding module with a distinct name:462 463.. code-block:: c++464 465  class MyModule : public ClangTidyModule {466   public:467    void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {468      CheckFactories.registerCheck<ExplicitConstructorCheck>(469          "my-explicit-constructor");470    }471  };472 473Now we need to register the module in the ``ClangTidyModuleRegistry`` using a474statically initialized variable:475 476.. code-block:: c++477 478  static ClangTidyModuleRegistry::Add<MyModule> X("my-module",479                                                  "Adds my lint checks.");480 481 482When using LLVM build system, we need to use the following hack to ensure the483module is linked into the :program:`clang-tidy` binary:484 485Add this near the ``ClangTidyModuleRegistry::Add<MyModule>`` variable:486 487.. code-block:: c++488 489  // This anchor is used to force the linker to link in the generated object file490  // and thus register the MyModule.491  volatile int MyModuleAnchorSource = 0;492 493And this to the main translation unit of the :program:`clang-tidy` binary (or494the binary you link the ``clang-tidy`` library in)495``clang-tidy/ClangTidyForceLinker.h``:496 497.. code-block:: c++498 499  // This anchor is used to force the linker to link the MyModule.500  extern volatile int MyModuleAnchorSource;501  static int MyModuleAnchorDestination = MyModuleAnchorSource;502 503 504Configuring Checks505------------------506 507If a check needs configuration options, it can access check-specific options508using the ``Options.get<Type>("SomeOption", DefaultValue)`` call in the check509constructor. In this case, the check should also override the510``ClangTidyCheck::storeOptions`` method to make the options provided by the511check discoverable. This method lets :program:`clang-tidy` know which options512the check implements and what the current values are (e.g. for the513``-dump-config`` command-line option).514 515.. code-block:: c++516 517  class MyCheck : public ClangTidyCheck {518    const unsigned SomeOption1;519    const std::string SomeOption2;520 521  public:522    MyCheck(StringRef Name, ClangTidyContext *Context)523      : ClangTidyCheck(Name, Context),524        SomeOption1(Options.get("SomeOption1", -1U)),525        SomeOption2(Options.get("SomeOption2", "some default")) {}526 527    void storeOptions(ClangTidyOptions::OptionMap &Opts) override {528      Options.store(Opts, "SomeOption1", SomeOption1);529      Options.store(Opts, "SomeOption2", SomeOption2);530    }531    ...532 533Assuming the check is registered with the name "my-check", the option can then534be set in a ``.clang-tidy`` file in the following way:535 536.. code-block:: yaml537 538  CheckOptions:539    my-check.SomeOption1: 123540    my-check.SomeOption2: 'some other value'541 542If you need to specify check options on a command line, you can use the inline543YAML format:544 545.. code-block:: console546 547  $ clang-tidy -config="{CheckOptions: {a: b, x: y}}" ...548 549 550Testing Checks551--------------552 553To run tests for :program:`clang-tidy`, build the ``check-clang-tools`` target.554For instance, if you configured your CMake build with the ninja project generator,555use the command:556 557.. code-block:: console558 559  $ ninja check-clang-tools560 561:program:`clang-tidy` checks can be tested using either unit tests or562`lit`_ tests. Unit tests may be more convenient to test complex replacements563with strict checks. `Lit`_ tests allow using partial text matching and regular564expressions which makes them more suitable for writing compact tests for565diagnostic messages.566 567The ``check_clang_tidy.py`` script provides an easy way to test both568diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test569file, runs :program:`clang-tidy` and verifies messages and fixes with two570separate `FileCheck`_ invocations: once with FileCheck's directive571prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages,572and once with the directive prefix set to ``CHECK-FIXES``, running573against the fixed code (i.e., the code after generated fix-its are574applied). In particular, ``CHECK-FIXES:`` can be used to check575that code was not modified by fix-its, by checking that it is present576unchanged in the fixed code. The full set of `FileCheck`_ directives577is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though578typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``)579are sufficient for clang-tidy tests. Note that the `FileCheck`_580documentation mostly assumes the default prefix (``CHECK``), and hence581describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc.582Replace ``CHECK`` with either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for583clang-tidy tests.584 585An additional check enabled by ``check_clang_tidy.py`` ensures that586if `CHECK-MESSAGES:` is used in a file then every warning or error587must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:``588instead, if you want to **also** ensure that all the notes are checked.589 590To use the ``check_clang_tidy.py`` script, put a .cpp file with the591appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use592``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against593diagnostic messages and fixed code.594 595It's advised to make the checks as specific as possible to avoid checks matching596incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]``597substitutions and distinct function and variable names in the test code.598 599Here's an example of a test using the ``check_clang_tidy.py`` script (the full600source code is at `test/clang-tidy/checkers/google/readability-casting.cpp`_):601 602.. code-block:: c++603 604  // RUN: %check_clang_tidy %s google-readability-casting %t605 606  void f(int a) {607    int b = (int)a;608    // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting]609    // CHECK-FIXES: int b = a;610  }611 612To check more than one scenario in the same test file, use613``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or614``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``.615With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*``616directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``.617 618Here's an example:619 620.. code-block:: c++621 622   // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A623   // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B624   // RUN: %check_clang_tidy %s misc-unused-using-decls %t625   ...626   // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}}627   // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}}628   // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}}629   // CHECK-FIXES-USING-A-NOT: using a::A;$630   // CHECK-FIXES-USING-B-NOT: using a::B;$631   // CHECK-FIXES-NOT: using a::C;$632 633There are many dark corners in the C++ language, and it may be difficult to make634your check work perfectly in all cases, especially if it issues fix-it hints. The635most frequent pitfalls are macros and templates:636 6371. Code written in a macro body/template definition may have a different meaning638   depending on the macro expansion/template instantiation.6392. Multiple macro expansions/template instantiations may result in the same code640   being inspected by the check multiple times (possibly, with different641   meanings, see 1), and the same warning (or a slightly different one) may be642   issued by the check multiple times; :program:`clang-tidy` will deduplicate643   _identical_ warnings, but if the warnings are slightly different, all of them644   will be shown to the user (and used for applying fixes, if any).6453. Making replacements to a macro body/template definition may be fine for some646   macro expansions/template instantiations, but easily break some other647   expansions/instantiations.648 649If you need multiple files to exercise all the aspects of your check, it is650recommended you place them in a subdirectory named for the check under the ``Inputs``651directory for the module containing your check.  This keeps the test directory from652getting cluttered.653 654If you need to validate how your check interacts with system header files, a set655of simulated system header files is located in the ``checkers/Inputs/Headers``656directory.  The path to this directory is available in a lit test with the variable657``%clang_tidy_headers``.658 659.. _lit: https://llvm.org/docs/CommandGuide/lit.html660.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html661.. _test/clang-tidy/checkers/google/readability-casting.cpp: https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/test/clang-tidy/checkers/google/readability-casting.cpp662 663 664Submitting a Pull Request665-------------------------666 667Before submitting a pull request, contributors are encouraged to run668:program:`clang-tidy` and :program:`clang-format` on their changes to ensure669code quality and catch potential issues. While :program:`clang-tidy` is not670currently enforced in CI, following this practice helps maintain code671consistency and prevent common errors.672 673Here's a useful command to check your staged changes:674 675.. code-block:: console676 677  $ git diff --staged -U0 | ./clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py \678      -j $(nproc) -path build/ -p1 -only-check-in-db679  $ git clang-format680 681Note that some warnings may be false positives or require careful consideration682before fixing. Use your judgment and feel free to discuss in the pull request683if you're unsure about a particular warning.684 685 686Out-of-tree check plugins687-------------------------688 689 690Developing an out-of-tree check as a plugin largely follows the steps691outlined above, including creating a new module and doing the hacks to 692register the module. The plugin is a shared library whose code lives outside693the clang-tidy build system. Build and link this shared library against694LLVM as done for other kinds of Clang plugins. If using CMake, use the keyword695``MODULE`` while invoking ``add_library`` or ``llvm_add_library``.696 697The plugin can be loaded by passing `-load` to `clang-tidy` in addition to the698names of the checks to enable.699 700.. code-block:: console701 702  $ clang-tidy --checks=-*,my-explicit-constructor -list-checks -load myplugin.so703 704There are no expectations regarding ABI and API stability, so the plugin must be705compiled against the version of clang-tidy that will be loading the plugin.706 707The plugins can use threads, TLS, or any other facilities available to in-tree708code which is accessible from the external headers.709 710Note that testing out-of-tree checks might involve getting ``llvm-lit`` from an LLVM 711installation compiled from source. See `Getting Started with the LLVM System`_ for ways 712to do so.713 714Alternatively, get `lit`_ following the `test-suite guide`_ and get the `FileCheck`_ binary, 715and write a version of `check_clang_tidy.py`_ to suit your needs.716 717.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html718.. _test-suite guide: https://llvm.org/docs/TestSuiteGuide.html719.. _lit: https://llvm.org/docs/CommandGuide/lit.html720.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html721.. _check_clang_tidy.py: https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/test/clang-tidy/check_clang_tidy.py722 723Running clang-tidy on LLVM724--------------------------725 726To test a check, it's best to try it out on a larger code base. LLVM and Clang727are the natural targets as you already have the source code around. The most728convenient way to run :program:`clang-tidy` is with a compile command database;729CMake can automatically generate one; for a description of how to enable it, see730`How To Setup Clang Tooling For LLVM`_. Once ``compile_commands.json`` is in731place and a working version of :program:`clang-tidy` is in ``PATH`` the entire732code base can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script733executes :program:`clang-tidy` with the default set of checks on every734translation unit in the compile command database and displays the resulting735warnings and errors. The script provides multiple configuration flags.736 737.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html738 739 740* The default set of checks can be overridden using the ``-checks`` argument,741  taking the identical format as :program:`clang-tidy` does. For example,742  ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override``743  check only.744 745* To restrict the files examined, you can provide one or more regex arguments746  that the file names are matched against.747  ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze `clang-tidy`748  checks. It may also be necessary to restrict the header files that warnings749  are displayed from by using the ``-header-filter`` and ``-exclude-header-filter`` flags. 750  They have the same behavior as the corresponding :program:`clang-tidy` flags.751 752* To apply suggested fixes, ``-fix`` can be passed as an argument. This gathers753  all changes in a temporary directory and applies them. Passing ``-format``754  will run clang-format over changed lines.755 756 757On checks profiling758-------------------759 760:program:`clang-tidy` can collect per-check profiling info, and output it761for each processed source file (translation unit).762 763To enable profiling info collection, use the ``-enable-check-profile`` argument.764The timings will be output to ``stderr`` as a table. Example output:765 766.. code-block:: console767 768  $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp769  ===-------------------------------------------------------------------------===770                            clang-tidy checks profiling771  ===-------------------------------------------------------------------------===772    Total Execution Time: 1.0282 seconds (1.0258 wall clock)773 774     ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---775     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  readability-function-size776     0.9136 (100.0%)   0.1146 (100.0%)   1.0282 (100.0%)   1.0258 (100.0%)  Total777 778It can also store that data as JSON files for further processing. Example output:779 780.. code-block:: console781 782  $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp783  $ # Note that there won't be timings table printed to the console.784  $ ls /tmp/out/785  20180516161318717446360-source.cpp.json786  $ cat 20180516161318717446360-source.cpp.json787  {788  "file": "/path/to/source.cpp",789  "timestamp": "2018-05-16 16:13:18.717446360",790  "profile": {791    "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,792    "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,793    "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01794  }795  }796 797There is only one argument that controls profile storage:798 799* ``-store-check-profile=<prefix>``800 801  By default, reports are printed in tabulated format to stderr. When this option802  is passed, these per-TU profiles are instead stored as JSON.803  If the prefix is not an absolute path, it is considered to be relative to the804  directory from where you have run :program:`clang-tidy`. All ``.`` and ``..``805  patterns in the path are collapsed, and symlinks are resolved.806 807  Example:808  Let's suppose you have a source file named ``example.cpp``, located in the809  ``/source`` directory. Only the input filename is used, not the full path810  to the source file. Additionally, it is prefixed with the current timestamp.811 812  * If you specify ``-store-check-profile=/tmp``, then the profile will be saved813    to ``/tmp/<ISO8601-like timestamp>-example.cpp.json``814 815  * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify816    ``-store-check-profile=.``, then the profile will still be saved to817    ``/foo/<ISO8601-like timestamp>-example.cpp.json``