Thanks Artem for explaining.
What happened is, I got it work using the plugin system. On the other hand, the clang-tidy team in our company (not Clang’s clang-tidy team) wants me to integrate into clang-tidy, and they are not happy about the plugin approach (maybe based on reasons George listed). They want a mechanism registering checkers that are out of Clang source tree, but still statically linked, instead of being dynamically loaded as plugin. I can try asking them to reply to this thread.
What I’m doing is providing a git repository with a new module (and one for the tests), with a patch to allow the statically linked part. That’s also how I back ported some existing checks.
Not sure how you could have a way of registering checks outside clang-tidy but still statically linked. You have to modify something to enable static linking.
Let me try to resolve the confusion I might have caused. Kan has come up with a static analyzer checker that addresses incorrect use of an internal API (so it doesn’t make sense upstream). We can’t use dynamically loaded plugins for a number of reasons, so we’d like to have a way to use statically-linked static analyzer checkers with minimal modification to Clang sources (ideally, one-two lines or just linking in a library that would register the checker in a constructor of a global object). I wasn’t aware of something like that being possible in the static analyzer, so I’ve suggested that Kan asks this here.
Thanks for your clarification!
To me, the proposed design seems questionable, as it would require us to have a global singleton,
which is always quite ugly, and can cause problems down the road (e.g. what if we want to launch two analyses from a single clang invocation?)
I thought you guys had your own fork already?
Could you still push for having the checker in your fork?
I understand you are afraid of merge conflicts, but registering a checker would just require a new file combined with a line in Checkers.td.
Tablegen file for checkers in theory could conflict when a new checker is added on the line next to it, but that could be made very unlikely if you e.g. group it at the bottom of the file.
I think that would be a better approach than using singletons and relying on the order of static constructors.
How do you solve this problem for clang-tidy?
Hmm. Just curious - what happens if you link the checker statically, then make an empty .so file (whatever that means) with the same name (it probably doesn't even need to be on a file system anywhere) and -load it?
Never mind, that's unlikely to work.
All right, so approach #1 by Kan with passing arguments through AnalysisConsumer seems to have no problems at all, as long as there's an example somewhere in the /examples/ directory that anybody could use and see if it works. As far as i understand, it doesn't cause any globals to be introduced whatsoever, and keeps all the logic on your side or in clang-tidy. Not sure if this boils down to moving the globals to clang-tidy. I also understand that it'd be quite some coding, but hopefully it'd be good code
Approach #3 with weak functions may also work, and you can totally come up with an infrastructure on your private library side to make it possible to add checkers from multiple places within the library. At the same time it would prevent multiple private libraries from being used simultaneously (weak function being the global thingy) and i'm not sure if it works on all OSes.
Approach #2 with a global sort-of-vector of checkers to check out when filling the checker registry is indeed the scariest - it might "just work" now, but nobody knows what happens when the number of singletons starts growing, so i kinda understand why they don't like to see this sort of stuff in clang, even if it's purely religious i guess we'd rather not.