[cfe-dev] [clang-tdy] RFC: Support for plugin modules.

Aaron Ballman via cfe-dev cfe-dev at lists.llvm.org
Tue Jun 23 06:24:21 PDT 2020


On Tue, Jun 23, 2020 at 8:42 AM Nathan James via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
>
> Dear List,
>
> I've heard a few small discussions about this topic and they seem to be
> positive so I thought I'd query it here to see what the consensus is.
>
> The general idea is to add a `add-plugin` command line option to clang-
> tidy, akin to the plugins clang supports. This will be used to load one
> or more plugins that link additional ClangTidyModules to better enable
> users to utilise their own custom clang-tidy checks.
>
> Currently the only way to do that is to download the entire llvm
> source, create the module and link it into clang-tidy the same way all
> the built-in modules are linked.
>
> Under this new proposal one could just get the required libraries. Then
> build their module out of tree and tell clang-tidy to link at runtime
> with `-add-plugin=<path-to-module>` command line option.
>
> A typical modules source code could be as simple as this for just one
> check
>
> -----------------------------------------------------------------------
>
> #include "ClangTidy.h"
> #include "ClangTidyCheck.h"
> #include "ClangTidyModule.h"
> #include "ClangTidyModuleRegistry.h"
>
> using namespace clang;
> using namespace clang::tidy;
> using namespace clang::ast_matchers;
> using namespace llvm;
>
> class AwesomeFunctionCheck : public ClangTidyCheck {
> public:
>   using ClangTidyCheck::ClangTidyCheck;
>
>   void registerMatchers(MatchFinder *Finder) override {
>     Finder->addMatcher(
>         functionDecl(unless(matchesName("Awesome$"))).bind("Function"),
> this);
>   }
>   void check(const MatchFinder::MatchResult &Result) override {
>     const auto *Function =
> Result.Nodes.getNodeAs<FunctionDecl>("Function");
>     diag(Function->getLocation(), "Function '%0' is not sufficiently
> awesome")
>         << Function
>         << FixItHint::CreateReplacement(
>                Function->getLocation(),
>                (Function->getName() + "Awesome").str());
>   }
> };
>
> class MyPluginModule : public ClangTidyModule {
> public:
>   void addCheckFactories(ClangTidyCheckFactories &CheckFactories)
> override {
>     CheckFactories.registerCheck<AwesomeFunctionCheck>(
>         "my-plugin-awesome-function");
>   }
> };
>
> // Register the MyPluginModule using this statically initialized
> variable.
> static ClangTidyModuleRegistry::Add<MyPluginModule>
>     X("my-plugin-module", "Adds my plugin checks.");
>
> -----------------------------------------------------------------------
>
> Obviously larger code bases may want multiple different checks in which
> case it would be nicer to seperate the checks out into their own
> implementation files (The way clang tidy is written now).
>
> Once a plugin is linked its checks will still need to be turned on
> using the `Checks` option from config files or the `checks` command
> line option.
>
> There will also need to be some documentation detailing how to create
> plugins. https://clang.llvm.org/extra/clang-tidy/Contributing.html
> already has some useful information but not everything needed for this purpose.
>
> On the point of getting the required libraries I'm not too sure how
> everything is packaged. From what I can see the clangTidy libraries are
> packaged but the headers aren't. That would probably need addressing as
> well.

I recently had a use case at work where we wanted to write a
clang-tidy plugin but couldn't due to the lack of infrastructure and
so we wound up writing a clang static analyzer plugin instead.
Unfortunately, because LLVM-based plugin systems do not work on
Windows, this functionality still wouldn't have helped us out for our
needs. That said, I'm still 100% behind the proposal -- even with the
general plugin limitations this is a feature I have often wished for
and been surprised wasn't supported.

~Aaron


More information about the cfe-dev mailing list