Clangd can't parse source correctly when just `--` option is included in `command` field of compile_commands.json

Hello,

I’m trying to use clangd together with CMake, VSCode, and Renesas CC-RX/CC-RL/CC-RH compilers which are used for single chip microcontrollers Renesas RX/RL78/RH850 families. These compilers use LLVM technology but command line options are quite different from clang compilres due to historical reason of compatibility with their previous generation compileres.

But I face the following issue. I’m looking for a possibility that this issue will be fixed. At first, is this by design?

  • clangd can’t parse source correctly when just -- option is included in command field of compile_commands.json for the source.

EXMAPLE of WITHOUT -- ===> OK:

[
{
“directory”: “C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build”,
“command”: “C:\Renesas2\CMake\bin\cmake.exe -P RENESAS-CompilerWrapper.cmake …\src\main.c -oCMakeFiles\RH850_CCRH_cmake_wrapper_script.dir\src\main.c.obj -c -I…\src\inc”,
“file”: “…\src\main.c”,
“output”: “CMakeFiles\RH850_CCRH_cmake_wrapper_script.dir\src\main.c.obj”
}
]

EXMAPLE of WITH -- ===> NG: (:point_right: and :point_left: are inserted below.)

[
{
“directory”: “C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build”,
“command”: “C:\Renesas2\CMake\bin\cmake.exe -P RENESAS-CompilerWrapper.cmake :point_right:-- :point_left: …\src\main.c -oCMakeFiles\RH850_CCRH_cmake_wrapper_script.dir\src\main.c.obj -c -I…\src\inc”,
“file”: “…\src\main.c”,
“output”: “CMakeFiles\RH850_CCRH_cmake_wrapper_script.dir\src\main.c.obj”
}
]

I looked a log which was generated with clangd’s --log=verbose option, I noticed the following difference.

WITHOUT -- ===> OK: (:arrow_right: and :arrow_left: are inserted below.)

I[16:43:39.839] ASTWorker building file c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c version 27 with command
[C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build]
“C:\Renesas2\CMake\bin\cmake.exe” -P :arrow_right:-c “-I…\src\inc” :arrow_left: “-resource-dir=c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6” – “c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c”
V[16:43:39.865] Driver produced command: cc1 -cc1 -triple x86_64-pc-windows-msvc19.35.32215 -fsyntax-only -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -P -fcoverage-compilation-dir=C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build -resource-dir “c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6” :arrow_right:-I “…\src\inc” :arrow_left: -internal-isystem “c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6\include” -internal-isystem “C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include” -internal-isystem “C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\atlmfc\include” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\winrt” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt” -fdebug-compilation-dir=C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.35.32215 -fdelayed-template-parsing -no-round-trip-args -faddrsig -x c “c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c”

WITH -- ===> NG: (:question: is inserted below.)

I[16:44:47.949] ASTWorker building file c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c version 27 with command
[C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build]
“C:\Renesas2\CMake\bin\cmake.exe” -P :question:“-resource-dir=c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6” – “c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c”
V[16:44:47.961] <<< {“id”:174,“jsonrpc”:“2.0”,“method”:“textDocument/codeAction”,“params”:{“context”:{“diagnostics”:[],“triggerKind”:2},“range”:{“end”:{“character”:0,“line”:0},“start”:{“character”:0,“line”:0}},“textDocument”:{“uri”:“file:///c%3A/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/src/main.c”}}}

I[16:44:47.961] <-- textDocument/codeAction(174)
V[16:44:47.971] Driver produced command: cc1 -cc1 -triple x86_64-pc-windows-msvc19.35.32215 -fsyntax-only -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -P -fcoverage-compilation-dir=C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build -resource-dir “c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6” :question:-internal-isystem “c:\Users\UserName\AppData\Roaming\Code\User\globalStorage\llvm-vs-code-extensions.vscode-clangd\install\15.0.6\clangd_15.0.6\lib\clang\15.0.6\include” -internal-isystem “C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\include” -internal-isystem “C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\atlmfc\include” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\winrt” -internal-isystem “C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\cppwinrt” -fdebug-compilation-dir=C:/Renesas/GitHubDesktop/workspaces/work_vscode/TestCMakeCCxx/RH850_CCRH_cmake_wrapper_script/build -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.35.32215 -fdelayed-template-parsing -no-round-trip-args -faddrsig -x c “c:\Renesas\GitHubDesktop\workspaces\work_vscode\TestCMakeCCxx\RH850_CCRH_cmake_wrapper_script\src\main.c”

I tried the following setting, but it doesn’t solve the issue.

CompileFlags:
  Remove:
    - --

clangd version is as follows.

>clangd --version
clangd version 15.0.6 (https://github.com/llvm/llvm-project 088f33605d8a61ff519c580a71b1dd57d16a03f8)
Features: windows+grpc
Platform: x86_64-pc-windows-msvc

The following zip file contains source files, setting files, and screen snapshots. (The screen snapshots include Japanese characters of VSCode.)

github.com/NoMaY-jp/Renesas_VSCode_Extensions_tips_for_Renesas_CC_compilers/wiki/data/issue_clangd_RH850_CCRH_cmake_wrapper_script_20230321.zip

Best regards,
NoMaY

P.S.

As of today, I’m using Windows’ CMD.EXE command line trick as a workaround and one of actual compile_command.json is here.

  • Use -^- instead of --.

Best regards,
NoMaY

I believe the meaning of -- in a clang command line is that the arguments that follow are inputs, not options. It’s a way of e.g. being able to parse an input file whose name begins with a -, without that file name being interpreted as an option name.

So, if the command contains options like -I after the --, those options will not be picked up by clangd.

One thing that seems strange about your compile commands is that the executable is cmake.exe? Usually it should be a compiler executable like clang.exe. CMake may well have a different interpretation of -- than clang, which makes the command work when run on the command line, but clangd doesn’t understand this interpretation.

I think this needs to be solved at the level of the program/script that is generating the compile_commands.json, to generate a compile command that clangd can understand.

Hello HighCommander4,

Thanks to your suggestion, probably I understood the reason. The manpage of the getopt() says as following. To be honest, I’m not familiar with Linux, but for Linux users, it is one of common sense. So, this issue is closed. And I’ll continue to use the current workaround (or consider another workaround).

https://manpages.debian.org/testing/manpages-dev/getopt.3.en.html

The special argument “–” forces an end of option-scanning regardless of the scanning mode.

Regarding the executable, I use cmake scripts as compiler drivers. Commonly compiler drivers are written using C or C++ native code programming. But, in my case, it is enough to use script language and CMake’s built-in script mode can be used very quickly. The compilers itself are Renesas CC-RX/CC-RL/CC-RH compilers and these compilers are called from inside my cmake scripts.

But my cmake scripts needs CMake script mode’s -- option and it causes the conflict problem of this issue.

And early version of my .clangd for Renesas CC-RH compiler is as follows. I’m going to add more settings in Remove field to remove Renesas CC-RH compiler’s options which are not compatible with clang’s options. In fact, almost options are not compatible. But it seems that -I, -D, @ and language standard option are essential for MS’s IntelliSense-like feature which is provided by clangd and VSCode.

CompileFlags:
  Remove:
    - -Xcpu=*
    - -O*
    - -g*
    - -Xcharacter_set=*
    - -Xpass_source
    - -Xcref=*
    - -nologo
  Add:
    - -U__llvm__
    - -D_CLANGD=1
    - -D__INTELLISENSE__=1
    - --include=../.vscode/c_cpp_intellisense_helper.h
Diagnostics:
  Suppress:
    - drv_unknown_argument
    - builtin_redeclare
    - redefinition_different_typedef
    - -Wignored-pragmas # for invalid pragma
    - -Winvalid-token-paste # for invalid pragma
    - -Wmain-return-type # for void main(void or arguments)

Once again, thank you very much.

Best regards,
NoMaY