clangd/vscode-clangd

C header interpreted with C++ rules, showing errors when there are none.

LukaDeka opened this issue · 11 comments

Header file is showing me errors when I try to use the keyword "new" as a variable name, even though it's not a reserved keyword in C. It's most likely interpreted with C++ rules. File compiles and runs normally with both GCC and clang. There are no error highlighting when I change the variable name to something else.

It's also showing an error, when I don't typecast malloc's output to (StackNode*) with error:
Cannot initialize a variable of type 'StackNode *' (aka '_StackNode *') with an rvalue of type 'void *'

This weird behavior only happens in the header file.

(errors as comments.)

// main.h
static inline void push(uint16_t value) {
    StackNode* new = (StackNode*) malloc(sizeof(StackNode));  // Expected unqualified-id
    new->value = value;                                       // Expected a type
    new->next = top;                                          // Expected a type
    top = new;                                                // Expected a type
}

Logs

/usr/lib/llvm-14/bin/clang -xobjective-c++-header -resource-dir=/home/luka/.vscode-server/data/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/17.0.3/clangd_17.0.3/lib/clang/17 -- /home/luka/Prog/SideProjects/VM/main.h
I[01:17:57.375] ASTWorker building file /home/luka/Prog/SideProjects/VM/main.c version 1 with command clangd fallback
[/home/luka/Prog/SideProjects/VM]
/usr/lib/llvm-14/bin/clang -resource-dir=/home/luka/.vscode-server/data/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/17.0.3/clangd_17.0.3/lib/clang/17 -- /home/luka/Prog/SideProjects/VM/main.c
I[01:17:57.377] --> textDocument/clangd.fileStatus
I[01:17:57.377] --> textDocument/clangd.fileStatus
I[01:17:57.377] --> textDocument/clangd.fileStatus
I[01:17:57.377] --> textDocument/clangd.fileStatus
I[01:17:57.378] --> textDocument/clangd.fileStatus
I[01:17:57.378] --> textDocument/clangd.fileStatus
I[01:17:57.417] Built preamble of size 387712 for file /home/luka/Prog/SideProjects/VM/main.c version 1 in 0.04 seconds
I[01:17:57.417] --> workspace/semanticTokens/refresh(31)
I[01:17:57.417] --> textDocument/clangd.fileStatus
I[01:17:57.419] <-- reply(31)
I[01:17:57.434] --> textDocument/publishDiagnostics
I[01:17:57.434] --> textDocument/inactiveRegions
I[01:17:57.435] --> textDocument/clangd.fileStatus
I[01:17:57.442] <-- textDocument/semanticTokens/full/delta(727)
I[01:17:57.443] --> reply:textDocument/semanticTokens/full/delta(727) 1 ms
I[01:17:57.443] --> textDocument/clangd.fileStatus

System information
clangd extension version: v0.1.28
Operating system: Win11, VSC running in WSL2 Ubuntu 22.04.4 LTS

Have you followed the project setup steps at https://clangd.llvm.org/installation#project-setup, including in particular generating a compile_commands.json file?

Have you followed the project setup steps at https://clangd.llvm.org/installation#project-setup, including in particular generating a compile_commands.json file?

I wasn't, since I was only using the clangd extention for VSC. I added a compile_commands.json file to the directory, with the following contents:

[
    {
      "directory": "~/Prog/SideProjects/VM",
      "command": "clang -g main.c -o bin/main -Wall -lm",
      "file": "main.c"
    }
  ]

The issue persisted.

I don't know much about build tools though. I'm simply using make like this:

main: main.c main.h Makefile
	clang -g main.c -o bin/main -Wall -lm

I tried removing compile_commands.json and adding compile_flags.txt with the contents:

-g
-o
bin/main
-Wall
-lm

but nothing changed.

I suggest going with compile_commands.json (not compile_flags.txt), and generating it using a tool like Bear by running bear -- make (where make is your build command).

If that doesn't help, please feel free to share clangd logs for further diagnosis.

Again, I don't have clangd installed on my linux distro, but rather as an extension on VSCode. I provided the logs already in my main post, from "OUTPUT" in VSCode, after selecting "clangd" as the stream. I do not wish to overcomplicate things by installing additional programs and adding unnecessary files, when I'm only running a single-line compilation and run command in the terminal.

Again, I don't have clangd installed on my linux distro, but rather as an extension on VSCode.

(Note that this doesn't really make a difference for how to use clangd. Whether you've installed it from your distro's repo, or the vscode extension downloaded it, you're using a clangd server binary that works the same way.)

I do not wish to overcomplicate things by installing additional programs and adding unnecessary files, when I'm only running a single-line compilation and run command in the terminal.

Ok, here is an alternative solution that does not involve compile_commands.json: create a .clangd file in your project directory containing:

If:
  PathMatch: .*\.h

CompileFlags:
  Add: [-xc-header]

This tells clangd to treat all .h files in the project as C headers.

I do think that, over time, as your project grows, the experience of using clangd will be better when using compile_commands.json (for exampe, it allows the project to be indexed and features like "find references" to work project-wide).

I added the .clangd file with those contents, but the errors are still there.

As my friend told me, the C header file is most likely being interpreted as a C++ header file, and disallowing the use of the reserved new keyword (and the required typecasting).

Is there additional helpful information I can provide about the bug? I couldn't figure out where to add the verbose flag.

Is there additional helpful information I can provide about the bug?

The clangd log should help us figure out what's going on. The "clangd" dropdown in the "Output" view is the right place to get it, but please include the complete log starting from clangd startup.

I couldn't figure out where to add the verbose flag.

You can add "--log=verbose" to "clangd.arguments" in vscode's settings.

Even though I reloaded the program and WSL multiple times yesterday, it now lets me use new as a variable name and I don't have to explicitly typecast the return value of malloc. I suspect it might've been a WSL issue, rather than clangd's extensions'. Therefore, I'm closing this issue. Thank you for your assistance.

Nevermind, after another reload of the extension, the same issue reappeared. Here is the attached log with the --log=verbose flag.
clangd_verbose_log.txt

I might've figured out what's causing the errors. When adding the.clangd file in the main directory, the .h file is correctly identified as a C header. When excluding it, clangd thinks it's a C++ header file.

.clangd contents:

If:
  PathMatch: .*\.h

CompileFlags:
  Add: [-xc-header]
  

Yeah, it looks like the log from the previous comment was from before you used the .clangd file, and it sounds like using the .clangd file fixed it. So that's behaving as expected then.