Re: clangd cannot handle tree_nocb.h

From: Nick Desaulniers
Date: Fri Apr 14 2023 - 18:48:09 EST


On Thu, Apr 13, 2023 at 5:53 PM Joel Fernandes <joel@xxxxxxxxxxxxxxxxx> wrote:
>
> Hello!
>
> I have been trying to get clangd working properly with tree_nocb.h. clangd
> trips quite badly when trying to build tree_nocb.h to generate ASTs.

Hi Joel,
Thanks for the report. What are you using clangd for? I'll bet
something interesting.

I've never used it myself, so I don't know where to even begin with
how to reproduce the issue.

It might be worth filing a bug upstream at
https://github.com/llvm/llvm-project/issues
or internally under the component
Language Platforms > C++ > Clang > Tools > Clangd
with detailed steps to reproduce (and what the observed error actually
is). Feel free to cc me, though I don't know the first thing about
clangd.

>
> I get something like this in the clangd logs showing it 'infers' how to build
> tree_nocb.h because it could not find a command in compile_commands.json:
>
> ASTWorker building file [..]/tree_nocb.h version 9 with command inferred from
> [..]/kernel/rcu/tree.c
>
> This leads to all hell breaking lose with complaints about missing rcu_data
> struct definition and so forth.
>
> So far I came up with a workaround as follows, but is there a better way?
>
> 1. Open compile_commands.json and add a new entry as follows, with a
> definition "-DNOCB_H_CLANGD_PARSE". Otherwise the entry is indentical to how
> tree.c is built.
>
> {
> "arguments": [
> "/usr/bin/clang",
> "-Wp,-MMD,kernel/rcu/.treenocb.o.d",
> "-nostdinc",
> "-I./arch/x86/include",
> "-I./arch/x86/include/generated",
> "-I./include",
> "-I./arch/x86/include/uapi",
> [...]
> "-Wformat-zero-length",
> "-Wnonnull",
> "-Wformat-insufficient-args",
> "-Wno-sign-compare",
> "-Wno-pointer-to-enum-cast",
> "-Wno-tautological-constant-out-of-range-compare",
> "-Wno-unaligned-access",
> "-DKBUILD_MODFILE=\"kernel/rcu/tree\"",
> "-DKBUILD_BASENAME=\"tree\"",
> "-DKBUILD_MODNAME=\"tree\"",
> "-D__KBUILD_MODNAME=kmod_tree",
> "-DNOCB_H_CLANGD_PARSE",
> "-c",
> "-I",
> "/s/",
> "-I",
> "/s/",
> "-o",
> "kernel/rcu/tree_nocb.h.o",
> "kernel/rcu/tree_nocb.h"
> ],
> "directory": "/usr/local/google/home/joelaf/repo/linux-master",
> "file": "/usr/local/google/home/joelaf/repo/linux-master/kernel/rcu/tree_nocb.h",
> "output": "/usr/local/google/home/joelaf/repo/linux-master/kernel/rcu/tree_nocb.h.o"
> },
>
> 2.
> Then in kernel/tree/tree_nocb.h, I do the following right in the beginning.
> (Thanks to paulmck@ for this idea).
>
> #ifdef NOCB_H_CLANGD_PARSE
> #include "tree.c"
> #endif
>
> 3. To prevent the above inclusion of tree.c from recursively including
> tree_nocb.h, I do the following at the end of tree.c
>
> +#ifndef NOCB_H_CLANGD_PARSE
> #include "tree_nocb.h"
> -#include "tree_plugin.h"
> +#endif
> +#include "tree_plugin.h"
>
> With that it works, but if I ever generate compile_commands.json again, then
> I'll have to again modify compile_commands.json manually to make my editor
> work again with clangd.
>
> So I guess my questions are:
>
> 1. Is there a 'standard' procedure to solve something like this?
>
> 2. How do we fix this the right way?
> One way would be for scripts/clang-tools/gen_compile_commands.py to parse
> header files and generate suitable compile_commands.json based on
> meta-data in the header file.
>
> 3. How do we fix this for other header files in general? Do we have to make hacks like
> above (sad face) or can we come up with a standard way to make it work for kernel
> sources?
>
> Thank you!
>
> - Joel
>
>
>
>
>
>


--
Thanks,
~Nick Desaulniers