clangd: System includes are not found when included from header

This issue appeared after updating from 13.0.1 to 14.0. I am sure, that clangd is able to find system includes using extracted paths from arm-none-eabi-* GCC, because linting of test.cpp files work as expected. When I switch to header file test.hpp system includes are reported to be missing.

test.cpp

#include <cstdint>

#include "test.hpp"

void foo() {}

test.hpp

#pragma once

#include <cstdint>

void foo();

Logs

Paths were redacted, but everything else remained: clangd_14_log_redacted.txt

System information

Output of clangd --version:

clangd version 14.0.0
Features: windows
Platform: x86_64-pc-windows-msvc

Editor/LSP plugin:

Version: 1.66.1
Commit: 8dfae7a5cd50421d10cd99cb873990460525a898
Date: 2022-04-06T14:50:12.141Z
Electron: 17.2.0
Chromium: 98.0.4758.109
Node.js: 16.13.0
V8: 9.8.177.11-electron.0
OS: Windows_NT x64 10.0.19044

Operating system: Windows 10 Enterprise 21H2

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 18

Commits related to this issue

Most upvoted comments

cc @sam-mccall and @kadircet as author/reviewer of the regressing patch

I looked at this a bit and I think I understand the problem:

  • InterpolatingCompilationDatabase runs first, and in the case of a header file, transfers the compile command from the corresponding source file
    • This involves a call to transferTo(), a function whose behaviour the patch modified to return the transferred command in “canonical” form, i.e. where it ends in -- input.
    • The meaning of -- is that every subsequent argument is treated as an input, not an option.
  • QueryDriverDatabase runs next, and it simply appends the -isystem arguments to the command, oblivious to the fact that the command might contain a --.
  • Finally, CommandMangler runs and drops the excess arguments after --, thereby dropping the -isystem arguments.

I guess the fix is to change QueryDriverDatabase to append the -isystem arguments more like this, so it works in the presence of --.

Although this is making me think that this patch, whose motivation seems to have been to affect the behaviour of this call to transferCompileCommand() inside CommandMangler itself, may have broken other things by also changing the behaviour of the transferCompileCommand() call inside InterpolatingCompilationDatabase itself…