ClangD - Add option to not Drop diagnostics outside the main file?


Im integrating clangd into an open source IDE (we used to use libclang)

Any how if I have:

main.cpp and it includes header1.h

and header1.h includes header2.h

and header2.h is missing.

I start to get diagnostics saying x type is not defined (even though it is, because once the missing file is hit, the analysis stops)

I noticed at this line:

The diagnostic from the missing file is dropped. If I had the option to receive diagnostics from outside the main file, this would be really useful for this scenario.

The user could then see immediately that there was a diagnostic in header1.h and fix it.

Thanks in advance for any advice on this matter.


I also noticed this, and agree some improvement is needed in this area.

I have some concerns about how to make this work with the current LSP spec though. Headers are by nature going to be included multiple times, and could have different set of diagnostics for each time they are included. The LSP doesn't deal well with that, it assumes that a single file has a single set of diagnostics. If we emit two publishDiagnostics (one for the main file and one for the header file), we have these problems:

- If both a.c and b.c include header.h, let's say you open a.c and we emit some diagnostics for header.h. Then you open b.c and we produce a new set of diagnostics for header.h, which will overwrite the previous ones. Then as you edit the two files, more publishDiagnostics are sent, so the diagnostics for header.h will switch back and forth between the two.

- When reading compiler output in the terminal, the order is very important. You usually read the first message, since the rest may just be a consequence of that first error. If we emit two publishDiagnostics, most IDEs will probably display them in an arbitrary order. For example, my IDE groups the diagnostics by file in a "problems" view:

* main.c
** error: Unknown type 'zzz'
** error: ...
... lots of other files ...
* zzz.h:
** error: Syntax error that causes the zzz type not to be defined.

In a normal compiler output, you would see the error in zzz.h first and deal with that). But here, when you see the error in main.c and there is nothing that tips you that the error in zzz.h may be the actual cause.

What we might need in the protocol is a way to publish diagnostics in file X that were encountered when building file Y. Like by adding an optional uri field to the Diagnostic interface. It would essentially say, when building the file for which I am providing diagnostics, I encountered an error in this other file. In the publishDiagnostics notification regarding a.c, we could then notify about an error in header.h. Then, when analyzing b.c, we could emit a distinct error in header.h. In the IDEs, we could then group them like this:

* a.c
** header.h: error: some error
** a.c: error: some error caused by the previous one
* b.c
** header.h: error: some other error
** b.c: error: some error caused by the previous one

This could also help for .c files that are generated, for example from .y files. The compiler will emit when compiling the .c file, but the error will be about the .y file, because of #line directives.