Question about custom Clang static analyzer checker registration in clang-tidy without using plugin


I have a question about how to register custom checkers without using a plugin. The background is, I have been working on a checker and I was able to come up with a solution to integrate into our code review system by using AnalysisConsumer and load custom checkers using plugins. However, the team of our company who works on clang-tidy integration requests me to do that in clang-tidy, instead of a separate set of things.

The way clang-tidy is used in the code review system is to create ClangTidyASTConsumerFactory and then create a ClangTidyASTConsumer, which is later used to parse the codebase. Therefore the goal here is to find a way to let the users of clang libraries, especially ClangTidyASTConsumer{,Factory}, to let AnalysisConsumer pickup custom checkers statically linked into the program;

Currently the checker registration is very deep in the stack, the only places it looks for checkers are a set of builtin checkers and plugins. There are a few directions I can think of

  1. Add some arguments to AnalysisConsumer constructor and pass it down to createCheckerManager, and add logic there to look for checkers passed in; however, this is problematic because all the users of AnalysisConsumer, such as ClangTidyASTConsumer, needs to expose the arguments as well;

  2. Have some static variable that stores the list of checkers factories, and expose a function that allows user to add checkers factories to it. Later the ClangCheckerRegistry picks up the checkers in the list. This is the ordinary way, but the existence of a static variable looks ugly and not thread-safe.

  3. Like registerBuiltinCheckers, add a weak function registerCustomCheckers, initially empty, and client code is allowed to override it, filled in with their custom checkers. In ClangCheckerRegistry it invokes the function, just after it invokes the registerBuiltinCheckers. This is the least intrusive way but the drawback is if there are multiple places in the system that needs to add a checker, it is not very convenient.

What’s the best approach, or is there other better approach? I am more than happy to help and send out some patch to add some mechanism. I want to hear the opinions from Clang developers and get blessed by the direction, before I actually start on it, to avoid any arguments.

Hi Li,

I haven’t used plugins myself, but I can see two solutions side-stepping the problem.

1) Could you upstream your checker and put it into “alpha”, and then turn it on via flag?
2) If (1) is impossible [though upstreaming into “alpha” should not be too hard], you could fork clang and add your changes there,
and then (hopefully) regularly rebase vs. trunk.

The problem with the plugin infrastructure is that Clang does not guarantee a stable API.
Even though things would probably work, there’s no guarantee they won’t break with a new release,
and if you use plugins you would get all the associated disadvantages (no straightforward injection, have to care about library being found, etc)
without the usual advantages (plugin might unexpectedly stop working).

Though if you absolutely must use plugins, I think it would be possible to come up with an API for doing so.