<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">hi Alexander,<div class=""><br class=""></div><div class="">Thanks for your clarification!</div><div class=""><br class=""></div><div class="">To me, the proposed design seems questionable, as it would require us to have a global singleton,</div><div class="">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?)</div><div class="">I thought you guys had your own fork already?</div><div class="">Could you still push for having the checker in your fork?</div><div class="">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.</div><div class="">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.</div><div class="">I think that would be a better approach than using singletons and relying on the order of static constructors.</div><div class=""><br class=""></div><div class="">How do you solve this problem for clang-tidy?</div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Mar 14, 2018, at 1:19 AM, Alexander Kornienko <<a href="mailto:alexfh@google.com" class="">alexfh@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">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.<br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Mar 13, 2018 at 9:46 PM via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=""><div class="">Thanks Artem for explaining.<br class=""><div class=""><br class="">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.<br class=""></div></div><br class=""></div><div id="m_-9013371601725585445origbody" class=""><div style="background:#f2f2f2" class="">----- Original Message -----<br class="">From: Artem Dergachev <<a href="mailto:noqnoqneo@gmail.com" target="_blank" class="">noqnoqneo@gmail.com</a>><br class="">To: <a href="mailto:likan_999.student@sina.com" target="_blank" class="">likan_999.student@sina.com</a>, George Karpenkov <<a href="mailto:ekarpenkov@apple.com" target="_blank" class="">ekarpenkov@apple.com</a>><br class="">Cc: cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>><br class="">Subject: Re: [cfe-dev] Question about custom Clang static analyzer checker registration in clang-tidy without using plugin<br class="">Date: 2018-03-14 03:07<br class=""></div><br class=""><br class="">I still don't understand your approach. There's the current plugin <br class="">system that auto-registers checkers (the trick with "-cc1 -load" <br class="">demonstrated by examples/analyzer-plugin/MainCallChecker.cpp) and <br class="">there's the normal way of writing a checker in clang source tree (like <br class="">all default checkers are written) that semi-automatically (through the <br class="">registerChecker<>() call) puts the checker into the checker registry and <br class="">makes it automatically accessible to clang-tidy when it links to the <br class="">updated checkers library.<br class="">Because none of these approaches seem to have any problems with checker <br class="">registration, could you describe what exactly are you doing that causes <br class="">problems with checker registration?<br class="">On 13/03/2018 11:11 AM, via cfe-dev wrote:<br class="">> Hi George,<br class="">><br class="">> Thanks for the fast response. I totally agree with your point of the disadvantages of using plugins. My question was exactly how to avoid using plugins. Maybe I had some misunderstanding, does the "plugin" you talked about not only include dynamic libraries, but also include registering checkers in programs that uses clang as a library?<br class="">><br class="">> For the 2 solutions you propsed, they are good suggestions, but unfortunately they won't work in our specific situation. The checker I am adding is very company specific, and involves specific class in company's code base; I believe it is impossible to make it public, because it will reveal company's internal codebase; also it is useless to public because the situation it tries to analyze is very ad-hoc, company specific, thus won't apply to other people's code at all.<br class="">><br class="">> As for rebasing against upstream, that's not feasible as well because this involves maintenance cost. I am at a large company where I don't have control or any influence on the process it sync third-party libraries with upstream, neither does the clang-tidy team of our company. That's why they suggest me doing it upstream.<br class="">><br class="">> The 3 approaches in my original question was in fact about modifying upstream to expose the checker registration process, so that not only us, but other people could also benefit from it. If there is such an API, then in a program that uses clang as a library, they can call the exposed API to register their own checker, before using AnalysisConsumer to do a static analysis.<br class="">><br class="">> Neither of the 3 approaches I proposed uses plugin architecture. It is just caller program who instantiates checker (or some form of checker factory), then hands it over to Clang, therefore there is no need to worry about how Clang can find the libraries.<br class="">><br class="">> I am more then happy if there are other ideas and I can contribute my manpower to coming up with some patches.<br class="">><br class="">> Best,<br class="">> Kan Li<br class="">><br class="">> ----- Original Message -----<br class="">> From: George Karpenkov <<a href="mailto:ekarpenkov@apple.com" target="_blank" class="">ekarpenkov@apple.com</a>><br class="">> To: Li Kan <<a href="mailto:likan_999.student@sina.com" target="_blank" class="">likan_999.student@sina.com</a>><br class="">> Cc: <a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class="">> Subject: Re: [cfe-dev] Question about custom Clang static analyzer checker registration in clang-tidy without using plugin<br class="">> Date: 2018-03-14 01:05<br class="">><br class="">><br class="">> Hi Li,<br class="">> I haven’t used plugins myself, but I can see two solutions side-stepping the problem.<br class="">> 1) Could you upstream your checker and put it into “alpha”, and then turn it on via flag?<br class="">> 2) If (1) is impossible [though upstreaming into “alpha” should not be too hard], you could fork clang and add your changes there,<br class="">> and then (hopefully) regularly rebase vs. trunk.<br class="">> The problem with the plugin infrastructure is that Clang does not guarantee a stable API.<br class="">> Even though things would probably work, there’s no guarantee they won’t break with a new release,<br class="">> and if you use plugins you would get all the associated disadvantages (no straightforward injection, have to care about library being found, etc)<br class="">> without the usual advantages (plugin might unexpectedly stop working).<br class="">> Though if you absolutely must use plugins, I think it would be possible to come up with an API for doing so.<br class="">> George<br class="">>> On Mar 12, 2018, at 6:20 PM, Li Kan via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class="">>><br class="">>> Hi,<br class="">>><br class="">>> 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.<br class="">>><br class="">>> 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;<br class="">>><br class="">>> 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<br class="">>> 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;<br class="">>> 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.<br class="">>> 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.<br class="">>><br class="">>> 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.<br class="">>><br class="">>><br class="">>> _______________________________________________<br class="">>> cfe-dev mailing list<br class="">>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class="">>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class="">> _______________________________________________<br class="">> cfe-dev mailing list<br class="">> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class="">> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class=""></div>_______________________________________________<br class="">
cfe-dev mailing list<br class="">
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class="">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class="">
</blockquote></div></div></div>
</div></blockquote></div><br class=""></div></body></html>