Skip to content

coveooss/clang-tidy-plugin-examples

Repository files navigation

clang-tidy plugins

This folder contains clang-tidy plugins.

Slides

The knowledge related to this repo was presented at a C++ meetup event on Febraury 21st, 2024. You can find the slides from this presentation in clang-tidy-coveo.pdf.

Quick Start

To build the plugins, first, you'll need LLVM/Clang version 16. On Ubuntu, you can install them with the script installClang16.sh (see testcpp.yml for more details). Then,

CC=clang-16 CXX=clang++-16 cmake -B build -G Ninja -S .
cmake --build build

To use the plugin,

  1. You can list the plugin with
    clang-tidy-16 \
            --checks='*' \
            --load build/lib/libAwesomePrefixCheck.so \
            --list-checks \
        | grep coveo-awesomeprefixcheck
  2. To use the plugin, you need to compile the code you want to use the plugin on, and to export the compile database with CMAKE_EXPORT_COMPILE_COMMANDS=ON
    cmake -B buildRepoUsingPlugin -S repo-using-plugin \
        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
    cmake --build buildRepoUsingPlugin
  3. That's it, you can now use the plugin!
    clang-tidy-16 \
        --checks='coveo-awesomeprefixcheck' \
        --load build/lib/libAwesomePrefixCheck.so \
        -p buildRepoUsingPlugin/compile_commands.json \
        repo-using-plugin/src/code.cpp

How to iterate quickly

Writing a clang-tidy check, finding a file in another repository where the check would apply and running the check on that file can get tedious quickly. Luckily for us, there is a better way.

Create a stub of the code that you want to replace, like in the file src/replace_cglpath_by_std/CGLPathStub.h. Then, use the methods that you want to replace in a function, like in the file src/replace_cglpath_by_std/TestCallsReplacementsPath.cpp. Separates const uses from mutable uses to make sure you don't inadvertently remove constness. Then, write your custom check, for instance, coveo-replacecglpathbystdcheck. Write a file that contains the code that you expect to have after your check has run, like src/replace_cglpath_by_std/ExpectedTestCallsReplacementsPath.cpp. Now, to test, create a script similar to src/replace_cglpath_by_std/testReplacePath.sh. This script also has an option that allows you to update the expected file ExpectedTestCallsReplacementsPath.cpp with

src/replace_cglpath_by_std/testReplacePath.sh build 1

where build is your build directory and 1 is the value that the variable updateExpected takes. Note that if you don't want to update the expected file, the script has default values for its parameters, so you can just call

src/replace_cglpath_by_std/testReplacePath.sh

and it will look for a build directory build in your current working directory. If you want to run clang-tidy manually, take a look inside the script testReplacePath.sh to see how to do it.

As ExpectedTestCallsReplacementsPath.cpp illustrates, you can sometimes go one step further and write an end to end test. In that example, you can uncomment TEST_WITH_PATH_BEING_AN_ALIAS_OF_STD_FILESYSTEM so that the header src/replace_cglpath_by_std/CGLPathIsStdfilesystemPath.h is included instead of CGLPathStub.h. As the header name suggests, Path is defined as using Path = std::filesystem::path in CGLPathIsStdfilesystemPath.h instead of being stubbed. This is the end goal of the check: replacing our in-house path implementation CGLFile::Path by the standard std::filesystem::path. TEST_WITH_PATH_BEING_AN_ALIAS_OF_STD_FILESYSTEM allows testing just that. Finally, to test automatically, compile ExpectedTestCallsReplacementsPath.cpp as illustrated in src/replace_cglpath_by_std/CMakeLists.txt with the target TestCallsReplacementsPathWithStd.

References

Every Stephen Kelly references above were written/filmed before that clang-tidy introduce plugins.

About

Examples of clang-tidy plugins

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •