[cfe-dev] ClangD - Add option to not Drop diagnostics outside the main file?

Simon Marchi via cfe-dev cfe-dev at lists.llvm.org
Fri Aug 10 11:10:48 PDT 2018


On 2018-08-09 18:35, Dan Walmsley via cfe-dev wrote:
> Hi,
> 
>   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:
> https://github.com/llvm-mirror/clang-tools-extra/blame/86961faaaf0b56b1c5dac2ed979987879cbc5294/clangd/Diagnostics.cpp#L376
> 
> 
> 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.
> 
> Dan

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.

Simon



More information about the cfe-dev mailing list