<div dir="ltr">Thanks Milian and Gábor,<div>I'd been a bit reluctant about using filename heuristics but both your experience and concrete suggestions are compelling.</div><div>This has the side benefit that it could reasonably fit inside the CompilationDatabase abstraction, and if we had a high quality implementation we could even make this behavior the default for compile_commands.json processing in all tools. (Headers etc shouldn't be *enumerated* of course, but if a tool explicitly asks how to compile one...)</div><div>I'll try this idea out and see how it works, unless someone gets to it first.</div><div>Cheers, Sam</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Mar 26, 2018 at 9:49 PM Gábor Márton <<a href="mailto:martongabesz@gmail.com">martongabesz@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
In a YCM extension, we have the following heuristics to get compile<br>
flags for a header:<br>
- Try to find a TU for the header in the compile DB by using the<br>
basename of the header.<br>
- If still not found then try to browse the DB to find one TU which<br>
uses the directory of our header as an include path (-I, -isystem).<br>
- If still not found then we try to get the first sibling TU in the<br>
directory of the header file.<br>
- If still not found then fall back to the first entry in the compile<br>
DB and use its flags.<br>
<br>
In the last 3 years it has been working remarkable well for us (7<br>
users). It handles nicely the cases when we add a new header.<br>
It may be a bit slow on very large projects and it does not handle<br>
multiplatform builds.<br>
I hope you find some of these ideas helpful. The extension is available here:<br>
<a href="https://github.com/martong/ycm_extra_conf.jsondb/blob/master/ycm_jsondb_core.py#L160" rel="noreferrer" target="_blank">https://github.com/martong/ycm_extra_conf.jsondb/blob/master/ycm_jsondb_core.py#L160</a><br>
<br>
Cheers,<br>
Gabor<br>
<br>
On Mon, Mar 26, 2018 at 11:21 AM, Milian Wolff via cfe-dev<br>
<<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
> On Montag, 26. März 2018 10:22:05 CEST Sam McCall via cfe-dev wrote:<br>
>> Thanks for trying things out, and sorry for the bad header-file experience.<br>
>><br>
>> On Mon, Mar 26, 2018 at 4:05 AM Jan Včelák via cfe-dev <<br>
>><br>
>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
>> > Hello list,<br>
>> ><br>
>> > thank you for all the work on clangd. I tried it for the first time<br>
>> > with VSCode and I'm really impressed how useful it is just out of the<br>
>> > box.<br>
>> ><br>
>> > I however encountered a problem with code completion in header files<br>
>> > and I would like to know if it's a bug in clangd or a problem in my<br>
>> > setup.<br>
>><br>
>> Yeah, this is a known missing feature - guessing the right compile flags<br>
>> for headers.<br>
>> If you have a compilation database (e.g. compile_commands.json) that<br>
>> provides compile commands for headers, then clangd works as expected.<br>
>> However most build systems don't provide this information. (Bazel, for one,<br>
>> does).<br>
>><br>
>> When there's no compile command provided, we fall back to 'clang<br>
>> $filename'. Clang treats .h files as C.<br>
>> But it's also missing a bunch of other information: include paths, defines<br>
>> etc that are likely required to get useful results.<br>
>> So I don't think just diverging from clang here will actually help many<br>
>> projects (feel free to try this out by editing compile_commands.json - if<br>
>> this works for you it'd be good to know).<br>
>><br>
>> What can we do then? A few ideas:<br>
>> - we can preprocess all the files from compile_commands.json on startup (<br>
>> <a href="https://reviews.llvm.org/D41911" rel="noreferrer" target="_blank">https://reviews.llvm.org/D41911</a> is the start of this). But we can't<br>
>> guarantee we get to the file you care about in time, so behavior will be<br>
>> erratic.<br>
>> - we can pick a compile command arbitrarily and take its flags, which will<br>
>> get include paths and defines right if they're uniform across the project<br>
>> - we can just refuse to provide any diagnostics/completions where we don't<br>
>> have a known-good set of flags.<br>
><br>
> Another trick that we apply in KDevelop:<br>
><br>
> - Try to find the *.cpp file for the header based on some file naming<br>
> heuristics and use that instead.<br>
><br>
> This works well in the majority of cases, but fails for system headers,<br>
> header-only utilities, and headers you just started to write where the<br>
> accompanying *.cpp file is still empty.<br>
><br>
> Bye<br>
><br>
> --<br>
> Milian Wolff<br>
> <a href="mailto:mail@milianw.de" target="_blank">mail@milianw.de</a><br>
> <a href="http://milianw.de" rel="noreferrer" target="_blank">http://milianw.de</a><br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
><br>
</blockquote></div>