clangd / vscode-clangd

Visual Studio Code extension for clangd
https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd
MIT License
592 stars 97 forks source link

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

Closed LukaDeka closed 2 months ago

LukaDeka commented 2 months ago

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

HighCommander4 commented 2 months ago

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

LukaDeka commented 2 months ago

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.

HighCommander4 commented 2 months ago

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.

LukaDeka commented 2 months ago

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.

HighCommander4 commented 2 months ago

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).

LukaDeka commented 2 months ago

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.

HighCommander4 commented 2 months ago

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.

LukaDeka commented 2 months ago

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.

LukaDeka commented 2 months ago

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

LukaDeka commented 2 months ago

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]
HighCommander4 commented 2 months ago

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.