Since IncludeCleaner has some support for IWYU keep pragmas, we can suggest it as a fix-it.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This is a bit tricky - we'd like to offer more fixes in several scenarios (e.g. replace a header with the transitive includes you're relying on), but some of those require more complex implementation.
On one hand, presenting only one automated fix will bias users towards that option.
On the other hand, it's not clear when the more complex fixes will be ready and this solves a real problem.
I'm inclined toward landing it, but will leave this up to @kadircet
clang-tools-extra/clangd/IncludeCleaner.cpp | ||
---|---|---|
502 | this FIXME is addressed by this change | |
511 | "directive" isn't accurate here I think What about just: "add IWYU pragma: keep"? |
as discussed offline I agree that we should have this, as no matter how hard we try there are going to be cases that we can't get right due to ADL/template instantiations or depending on 3rd party code that cannot be edited and also doesn't have relevant pragmas inside.
my hesitation about having them at this stage is, we won't be able to:
- get feedback around most of these issues as people will just put a pragma and be done with it.
- fix them going forward, even after implementation gets better, we won't be able to diagnose these headers and "falsely" issued pragmas will keep includes around.
Hence i'd like to hear a little bit more about what kind of false positives you're facing often enough to need this as an automated fix at this stage, to see if there's something we can do to improve the implementation first.
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp | ||
---|---|---|
1795 | can you also have a test with an include that already has a trailing comment? |
I had another idea about offering the export pragma when in a header file but I don't know if that's going too far
One of the main issues I have is due to templates not being instantiated which can result in symbols that are actually used not being picked up as the template instantiation that uses them isn't actually instantiated.
Unfortunately this isn't something that can be easily fixed without tanking performance.
I had another idea about offering the export pragma when in a header file but I don't know if that's going too far
There are definitely cases where this is conceptually "right" fix, but it's hard to guess that in clangd (well at least without having some codebase wide analysis), and offering it all the time would definitely confuse users.
One of the main issues I have is due to templates not being instantiated which can result in symbols that are actually used not being picked up as the template instantiation that uses them isn't actually instantiated.
I guess you're talking about having the template pattern in the main file, but all the instantiations are in dependents of the code. My mental model was around making the dependents have the include for the type, instead of having it in the file providing the template pattern (header). Does that make sense?
This kind of breaks down when there's actually some types used by all the instantiations, as you'd want them to be included by the header. But I think we should be able to diagnose these cases, as usage of this type should be non-dependent (at least in the cases I can think of), so this sounds like a bug/improvement.
A specific example i encountered is clang/Tooling/DiagnosticsYaml.h Which defines template specializations for inputting/outputting yaml io. That file must be included if you ever want to emit diagnostics as YAML, but the typical use case is to just use the operator<< on a yaml stream. This function internally will use those specializations, but as clangd doesn't look into the function calls and expand all those instantiations, they are treated as being unused(There's many bugs already related to this) and as such the header is marked as being unused.
A specific example i encountered is clang/Tooling/DiagnosticsYaml.h Which defines template specializations for inputting/outputting yaml io. That file must be included if you ever want to emit diagnostics as YAML, but the typical use case is to just use the operator<< on a yaml stream. This function internally will use those specializations, but as clangd doesn't look into the function calls and expand all those instantiations, they are treated as being unused(There's many bugs already related to this) and as such the header is marked as being unused.
i see makes sense. this falls in the "adl through templates" bucket, which is annoying and doesn't seem to be as rare in the wild. so we probably need to figure something out here.
as mentioned above i've hesitations for having this automatically available but it's a state we want to get at eventually. i guess there's not much point in delaying that, so LGTM (after comments already raised are addressed), sorry for the late reply and thanks for the patch!
this FIXME is addressed by this change