Sorry about the delayed reply, I only saw this thread when it popped up again today.
I would like to suggest something different: move Clang Static Analyzer to clang-tools-extra. Build it either as a separate binary or compile it into the clang-tidy binary. Then let clang -analyze delegate to that binary for backwards compatibility.
Speaking as an outsider in the peanut gallery who does very little static analysis, this is very appealing to me. It would save binary size in clang and make building and testing clang faster, if the developer isn’t working in the static analyzer space.
A bit +1 to this from me as well.
Generally we already have a cmake flag for this, -DCLANG_ENABLE_STATIC_ANALYZER=OFF (defaults to ON). This flag is definitely a must-have for people who try to make their clang binary as tiny as possible. But i understand that this flag is not exceptionally discoverable and a lot of people probably suffer unnecessarily long compile times simply because they didn’t discover it.
I’m aware of this flag, but it doesn’t quite do what I want: I want clang-tidy to have the static analyzer, but I don’t want my compiler to have it. It’d be nice if there was a setting that allowed putting the analyzer in clang-tidy but not in clang, and to make clang -analyze shell out to clang-tidy for backwards compat.
I agree that the analyzer is in the compiler mainly for historical reasons, and that we wouldn’t move it form clang-tidy into the compiler if it was only in clang-tidy. This suggests that that’s the future we should work towards.
Maybe i should do something similar to SemaDiagnosticBuilder, i.e. sub-class DiagnosticBuilder and steal diagnostics from it in my superclass destructor, so that to convert them to our path diagnostics, WDYT?
That's not going to break the source compatibility (apart from the few checks where people put their DiagnosticBuilder into a local variable, they'll have to change the type of that variable), but neither would it introduce a look-alike interface because it's still literally the same interface and it's already kind of expected to be polymorphic.
P.S. We could provide such diagnostic builder to our own AST-based checkers as well. That way we can see if it's indeed a better API for emitting path-insensitive warnings than BugReporter::EmitBasicReport(), which is pretty likely. And if so, i'll readily recommend it for use in any path-insensitive tool that emits warnings. This would also be an indication that our API is the best in long term.
P.P.S. Such API would in its out-of-the-box shape not allow Clang-Tidy to add the typical path-sensitive pieces (event piece, control flow piece, etc.) to the report. But if you ever want to do this sort of stuff, it should be a matter of simply extending our superclass a little bit.
> Maybe i should do something similar to SemaDiagnosticBuilder, i.e. > sub-class DiagnosticBuilder and steal diagnostics from it in my > superclass destructor, so that to convert them to our path > diagnostics, WDYT?
That sounds like abuse of inheritance Subclassing DiagnosticBuilder to hijack its output (which is stored in DiagnosticsEngine BTW!) is too clever. The current Clang's diagnostics subsystem has a lot of quirks already. I think diagnostics that start from DiagnosticBuilder should be reported by DiagnosticsEngine to the DiagnosticConsumer.
If we want to reuse DiagnosticBuilder, WDYT about a custom DiagnosticConsumer instead?
P.S. We could provide such diagnostic builder to our own AST-based checkers as well. That way we can see if it's indeed a better API for emitting path-insensitive warnings than BugReporter::EmitBasicReport(), which is pretty likely. And if so, i'll readily recommend it for use in any path-insensitive tool that emits warnings. This would also be an indication that our API is the best in long term.
P.P.S. Such API would in its out-of-the-box shape not allow Clang-Tidy to add the typical path-sensitive pieces (event piece, control flow piece, etc.) to the report. But if you ever want to do this sort of stuff, it should be a matter of simply extending our superclass a little bit.
That does sound interesting, however, I'd prefer to try to figure out ways to converge the two APIs (Clang's diagnostic subsystem and BugReporter) instead of building more ways of doing the same stuff. However, I'm not sure about the best way to do it. These APIs are definitely built with different thoughts towards performance. Clang's diagnostic subsystem is super-optimized to the point of trying hard to not even dynamically allocate memory; all this while trying to present an OOP interface, which, however, leaks the underlying implementation by exposing the concepts of "in-flight diagnostic", "delayed diagnostic" etc. Static Analyzer diagnostic subsystem is more OOP-like in its implementation as well, with various path pieces for example.
Maybe i should do something similar to SemaDiagnosticBuilder, i.e. sub-class DiagnosticBuilder and steal diagnostics from it in my superclass destructor, so that to convert them to our path diagnostics, WDYT?
That sounds like abuse of inheritance Subclassing DiagnosticBuilder to hijack its output (which is stored in DiagnosticsEngine BTW!) is too clever. The current Clang's diagnostics subsystem has a lot of quirks already. I think diagnostics that start from DiagnosticBuilder should be reported by DiagnosticsEngine to the DiagnosticConsumer.
If we want to reuse DiagnosticBuilder, WDYT about a custom DiagnosticConsumer instead?
Wait, we already have that? Nice! Will go that way then.