@@ -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
7484The Directory Structure
7585-----------------------
@@ -215,11 +225,215 @@ can further inspect them and report diagnostics.
215225and `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
219433Registering 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
223437module. If you want to create a new module or know the details, read on.)
224438
225439The 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-
398613There are many dark corners in the C++ language, and it may be difficult to make
399614your check work perfectly in all cases, especially if it issues fix-it hints. The
400615most 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