Skip to content

Commit 8ce99da

Browse files
[clang-tidy] Add more documentation about check development (NFC)
- Mention pp-trace - CMake configuration - Overriding registerPPCallbacks - Overriding isLanguageVersionSupported - Check development tips - Guide to useful documentation - Using the Transformer library - Developing your check incrementally - Creating private matchers - Unit testing helper code - Making your check robust - Documenting your check - Describe the Inputs test folder Differential Revision: https://reviews.llvm.org/D117939
1 parent 075e3fd commit 8ce99da

File tree

1 file changed

+222
-3
lines changed

1 file changed

+222
-3
lines changed

clang-tools-extra/docs/clang-tidy/Contributing.rst

Lines changed: 222 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ There are a few tools particularly useful when developing clang-tidy checks:
2222
check, it will create the check, update the CMake file and create a test;
2323
* ``rename_check.py`` does what the script name suggests, renames an existing
2424
check;
25+
* :program:`pp-trace` logs method calls on `PPCallbacks` for a source file
26+
and is invaluable in understanding the preprocessor mechanism;
2527
* :program:`clang-query` is invaluable for interactive prototyping of AST
2628
matchers and exploration of the Clang AST;
2729
* `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``)
@@ -70,6 +72,14 @@ let's start!
7072
.. _Using Clang Tools: https://clang.llvm.org/docs/ClangTools.html
7173
.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
7274

75+
When you `configure the CMake build <https://llvm.org/docs/GettingStarted.html#local-llvm-configuration>`_,
76+
make sure that you enable the ``clang`` and ``clang-tools-extra`` projects to
77+
build :program:`clang-tidy`.
78+
Because your new check will have associated documentation, you will also want to install
79+
`Sphinx <https://www.sphinx-doc.org/en/master/>`_ and enable it in the CMake configuration.
80+
To save build time of the core Clang libraries you may want to only enable the ``X86``
81+
target in the CMake configuration.
82+
7383

7484
The Directory Structure
7585
-----------------------
@@ -215,11 +225,215 @@ can further inspect them and report diagnostics.
215225
and `clang-tidy/google/ExplicitConstructorCheck.cpp
216226
<https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-tidy/google/ExplicitConstructorCheck.cpp>`_).
217227

228+
If you need to interact with macros or preprocessor directives, you will want to
229+
override the method ``registerPPCallbacks``. The ``add_new_check.py`` script
230+
does not generate an override for this method in the starting point for your
231+
new check.
232+
233+
If your check applies only under a specific set of language options, be sure
234+
to override the method ``isLanguageVersionSupported`` to reflect that.
235+
236+
Check development tips
237+
----------------------
238+
239+
Writing your first check can be a daunting task, particularly if you are unfamiliar
240+
with the LLVM and Clang code bases. Here are some suggestions for orienting yourself
241+
in the codebase and working on your check incrementally.
242+
243+
Guide to useful documentation
244+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
245+
246+
Many of the support classes created for LLVM are used by Clang, such as `StringRef
247+
<https://llvm.org/docs/ProgrammersManual.html#the-stringref-class>`_
248+
and `SmallVector <https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h>`_.
249+
These and other commonly used classes are described in the `Important and useful LLVM APIs
250+
<https://llvm.org/docs/ProgrammersManual.html#important-and-useful-llvm-apis>`_ and
251+
`Picking the Right Data Structure for the Task
252+
<https://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task>`_
253+
sections of the `LLVM Programmer's Manual
254+
<https://llvm.org/docs/ProgrammersManual.html>`_. You don't need to memorize all the
255+
details of these classes; the generated `doxygen documentation <https://llvm.org/doxygen/>`_
256+
has everything if you need it. In the header `LLVM/ADT/STLExtras.h
257+
<https://llvm.org/doxygen/STLExtras_8h.html>`_ you'll find useful versions of the STL
258+
algorithms that operate on LLVM containers, such as `llvm::all_of
259+
<https://llvm.org/doxygen/STLExtras_8h.html#func-members>`_.
260+
261+
Clang is implemented on top of LLVM and introduces its own set of classes that you
262+
will interact with while writing your check. When a check issues diagnostics and
263+
fix-its, these are associated with locations in the source code. Source code locations,
264+
source files, ranges of source locations and the `SourceManager
265+
<https://clang.llvm.org/doxygen/classclang_1_1SourceManager.html>`_ class provide
266+
the mechanisms for describing such locations. These and
267+
other topics are described in the `"Clang" CFE Internals Manual
268+
<https://clang.llvm.org/docs/InternalsManual.html>`_. Whereas the doxygen generated
269+
documentation serves as a reference to the internals of Clang, this document serves
270+
as a guide to other developers. Topics in that manual of interest to a check developer
271+
are:
272+
273+
- `The Clang "Basic" Library
274+
<https://clang.llvm.org/docs/InternalsManual.html#the-clang-basic-library>`_ for
275+
information about diagnostics, fix-it hints and source locations.
276+
- `The Lexer and Preprocessor Library
277+
<https://clang.llvm.org/docs/InternalsManual.html#the-lexer-and-preprocessor-library>`_
278+
for information about tokens, lexing (transforming characters into tokens) and the
279+
preprocessor.
280+
- `The AST Library
281+
<https://clang.llvm.org/docs/InternalsManual.html#the-lexer-and-preprocessor-library>`_
282+
for information about how C++ source statements are represented as an abstract syntax
283+
tree (AST).
284+
285+
Most checks will interact with C++ source code via the AST. Some checks will interact
286+
with the preprocessor. The input source file is lexed and preprocessed and then parsed
287+
into the AST. Once the AST is fully constructed, the check is run by applying the check's
288+
registered AST matchers against the AST and invoking the check with the set of matched
289+
nodes from the AST. Monitoring the actions of the preprocessor is detached from the
290+
AST construction, but a check can collect information during preprocessing for later
291+
use by the check when nodes are matched by the AST.
292+
293+
Every syntactic (and sometimes semantic) element of the C++ source code is represented by
294+
different classes in the AST. You select the portions of the AST you're interested in
295+
by composing AST matcher functions. You will want to study carefully the `AST Matcher
296+
Reference <https://clang.llvm.org/docs/LibASTMatchersReference.html>`_ to understand
297+
the relationship between the different matcher functions.
298+
299+
Using the Transformer library
300+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
301+
302+
The Transformer library allows you to write a check that transforms source code by
303+
expressing the transformation as a ``RewriteRule``. The Transformer library provides
304+
functions for composing edits to source code to create rewrite rules. Unless you need
305+
to perform low-level source location manipulation, you may want to consider writing your
306+
check with the Transformer library. The `Clang Transformer Tutorial
307+
<https://clang.llvm.org/docs/ClangTransformerTutorial.html>`_ describes the Transformer
308+
library in detail.
309+
310+
To use the Transformer library, make the following changes to the code generated by
311+
the ``add_new_check.py`` script:
312+
313+
- Include ``../utils/TransformerClangTidyCheck.h`` instead of ``../ClangTidyCheck.h``
314+
- Change the base class of your check from ``ClangTidyCheck`` to ``TransformerClangTidyCheck``
315+
- Delete the override of the ``registerMatchers`` and ``check`` methods in your check class.
316+
- Write a function that creates the ``RewriteRule`` for your check.
317+
- Call the function in your check's constructor to pass the rewrite rule to
318+
``TransformerClangTidyCheck``'s constructor.
319+
320+
Developing your check incrementally
321+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
322+
323+
The best way to develop your check is to start with the simple test cases and increase
324+
complexity incrementally. The test file created by the ``add_new_check.py`` script is
325+
a starting point for your test cases. A rough outline of the process looks like this:
326+
327+
- Write a test case for your check.
328+
- Prototype matchers on the test file using :program:`clang-query`.
329+
- Capture the working matchers in the ``registerMatchers`` method.
330+
- Issue the necessary diagnostics and fix-its in the ``check`` method.
331+
- Add the necessary ``CHECK-MESSAGES`` and ``CHECK-FIXES`` annotations to your
332+
test case to validate the diagnostics and fix-its.
333+
- Build the target ``check-clang-tool`` to confirm the test passes.
334+
- Repeat the process until all aspects of your check are covered by tests.
335+
336+
The quickest way to prototype your matcher is to use :program:`clang-query` to
337+
interactively build up your matcher. For complicated matchers, build up a matching
338+
expression incrementally and use :program:`clang-query`'s ``let`` command to save named
339+
matching expressions to simplify your matcher. Just like breaking up a huge function
340+
into smaller chunks with intention-revealing names can help you understand a complex
341+
algorithm, breaking up a matcher into smaller matchers with intention-revealing names
342+
can help you understand a complicated matcher. Once you have a working matcher, the
343+
C++ API will be virtually identical to your interactively constructed matcher. You can
344+
use local variables to preserve your intention-revealing names that you applied to
345+
nested matchers.
346+
347+
Creating private matchers
348+
^^^^^^^^^^^^^^^^^^^^^^^^^
349+
350+
Sometimes you want to match a specific aspect of the AST that isn't provided by the
351+
existing AST matchers. You can create your own private matcher using the same
352+
infrastructure as the public matchers. A private matcher can simplify the processing
353+
in your ``check`` method by eliminating complex hand-crafted AST traversal of the
354+
matched nodes. Using the private matcher allows you to select the desired portions
355+
of the AST directly in the matcher and refer to it by a bound name in the ``check``
356+
method.
357+
358+
Unit testing helper code
359+
^^^^^^^^^^^^^^^^^^^^^^^^
360+
361+
Private custom matchers are a good example of auxiliary support code for your check
362+
that can be tested with a unit test. It will be easier to test your matchers or
363+
other support classes by writing a unit test than by writing a ``FileCheck`` integration
364+
test. The ``ASTMatchersTests`` target contains unit tests for the public AST matcher
365+
classes and is a good source of testing idioms for matchers.
366+
367+
Making your check robust
368+
^^^^^^^^^^^^^^^^^^^^^^^^
369+
370+
Once you've covered your check with the basic "happy path" scenarios, you'll want to
371+
torture your check with as many edge cases as you can cover in order to ensure your
372+
check is robust. Running your check on a large code base, such as Clang/LLVM, is a
373+
good way to catch things you forgot to account for in your matchers. However, the
374+
LLVM code base may be insufficient for testing purposes as it was developed against a
375+
particular set of coding styles and quality measures. The larger the corpus of code
376+
the check is tested against, the higher confidence the community will have in the
377+
check's efficacy and false positive rate.
378+
379+
Some suggestions to ensure your check is robust:
380+
381+
- Create header files that contain code matched by your check.
382+
- Validate that fix-its are properly applied to test header files with
383+
:program:`clang-tidy`. You will need to perform this test manually until
384+
automated support for checking messages and fix-its is added to the
385+
``check_clang_tidy.py`` script.
386+
- Define macros that contain code matched by your check.
387+
- Define template classes that contain code matched by your check.
388+
- Define template specializations that contain code matched by your check.
389+
- Test your check under both Windows and Linux environments.
390+
- Watch out for high false positive rates. Ideally, a check would have no false
391+
positives, but given that matching against an AST is not control- or data flow-
392+
sensitive, a number of false positives are expected. The higher the false
393+
positive rate, the less likely the check will be adopted in practice.
394+
Mechanisms should be put in place to help the user manage false positives.
395+
- There are two primary mechanisms for managing false positives: supporting a
396+
code pattern which allows the programmer to silence the diagnostic in an ad
397+
hoc manner and check configuration options to control the behavior of the check.
398+
- Consider supporting a code pattern to allow the programmer to silence the
399+
diagnostic whenever such a code pattern can clearly express the programmer's
400+
intent. For example, allowing an explicit cast to ``void`` to silence an
401+
unused variable diagnostic.
402+
- Consider adding check configuration options to allow the user to opt into
403+
more aggressive checking behavior without burdening users for the common
404+
high-confidence cases.
405+
406+
Documenting your check
407+
^^^^^^^^^^^^^^^^^^^^^^
408+
409+
The ``add_new_check.py`` script creates entries in the
410+
`release notes <https://clang.llvm.org/extra/ReleaseNotes.html>`_, the list of
411+
checks and a new file for the check documentation itself. It is recommended that you
412+
have a concise summation of what your check does in a single sentence that is repeated
413+
in the release notes, as the first sentence in the doxygen comments in the header file
414+
for your check class and as the first sentence of the check documentation. Avoid the
415+
phrase "this check" in your check summation and check documentation.
416+
417+
If your check relates to a published coding guideline (C++ Core Guidelines, MISRA, etc.)
418+
or style guide, provide links to the relevant guideline or style guide sections in your
419+
check documentation.
420+
421+
Provide enough examples of the diagnostics and fix-its provided by the check so that a
422+
user can easily understand what will happen to their code when the check is run.
423+
If there are exceptions or limitations to your check, document them thoroughly. This
424+
will help users understand the scope of the diagnostics and fix-its provided by the check.
425+
426+
Building the target ``docs-clang-tools-html`` will run the Sphinx documentation generator
427+
and create documentation HTML files in the tools/clang/tools/extra/docs/html directory in
428+
your build tree. Make sure that your check is correctly shown in the release notes and the
429+
list of checks. Make sure that the formatting and structure of your check's documentation
430+
looks correct.
431+
218432

219433
Registering your Check
220434
----------------------
221435

222-
(The ``add_new_check.py`` takes care of registering the check in an existing
436+
(The ``add_new_check.py`` script takes care of registering the check in an existing
223437
module. If you want to create a new module or know the details, read on.)
224438

225439
The check should be registered in the corresponding module with a distinct name:
@@ -316,7 +530,9 @@ YAML format:
316530
Testing Checks
317531
--------------
318532

319-
To run tests for :program:`clang-tidy` use the command:
533+
To run tests for :program:`clang-tidy`, build the ``check-clang-tools`` target.
534+
For instance, if you configured your CMake build with the ninja project generator,
535+
use the command:
320536

321537
.. code-block:: console
322538
@@ -394,7 +610,6 @@ Here's an example:
394610
// CHECK-FIXES-USING-B-NOT: using a::B;$
395611
// CHECK-FIXES-NOT: using a::C;$
396612

397-
398613
There are many dark corners in the C++ language, and it may be difficult to make
399614
your check work perfectly in all cases, especially if it issues fix-it hints. The
400615
most frequent pitfalls are macros and templates:
@@ -411,6 +626,10 @@ most frequent pitfalls are macros and templates:
411626
macro expansions/template instantiations, but easily break some other
412627
expansions/instantiations.
413628

629+
If you need multiple files to exercise all the aspects of your check, it is
630+
recommended you place them in a subdirectory named for the check under ``Inputs``.
631+
This keeps the test directory from getting cluttered.
632+
414633
.. _lit: https://llvm.org/docs/CommandGuide/lit.html
415634
.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html
416635
.. _test/clang-tidy/google-readability-casting.cpp: https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp

0 commit comments

Comments
 (0)