mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 11:06:33 +00:00
[clangd] Add BuiltinHeaders
config option (#129459)
This option, under `CompileFlags`, governs whether clangd uses its own built-in headers (`Clangd` option value) or the built-in headers of the driver in the file's compile command (`QueryDriver` option value, applicable to cases where `--query-driver` is used to instruct clangd to ask the driver for its system include paths). The default value is `Clangd`, preserving clangd's current defaut behaviour. Fixes clangd/clangd#2074
This commit is contained in:
parent
a892a5dc5e
commit
85d60a441a
@ -59,6 +59,7 @@ struct Config {
|
||||
std::optional<std::string> FixedCDBPath;
|
||||
};
|
||||
|
||||
enum class BuiltinHeaderPolicy { Clangd, QueryDriver };
|
||||
/// Controls how the compile command for the current file is determined.
|
||||
struct {
|
||||
/// Edits to apply to the compile command, in sequence.
|
||||
@ -66,6 +67,10 @@ struct Config {
|
||||
Edits;
|
||||
/// Where to search for compilation databases for this file's flags.
|
||||
CDBSearchSpec CDBSearch = {CDBSearchSpec::Ancestors, std::nullopt};
|
||||
|
||||
/// Whether to use clangd's own builtin headers, or ones from the system
|
||||
/// include extractor, if available.
|
||||
BuiltinHeaderPolicy BuiltinHeaders = BuiltinHeaderPolicy::Clangd;
|
||||
} CompileFlags;
|
||||
|
||||
enum class BackgroundPolicy { Build, Skip };
|
||||
|
@ -290,6 +290,18 @@ struct FragmentCompiler {
|
||||
});
|
||||
}
|
||||
|
||||
if (F.BuiltinHeaders) {
|
||||
if (auto Val =
|
||||
compileEnum<Config::BuiltinHeaderPolicy>("BuiltinHeaders",
|
||||
*F.BuiltinHeaders)
|
||||
.map("Clangd", Config::BuiltinHeaderPolicy::Clangd)
|
||||
.map("QueryDriver", Config::BuiltinHeaderPolicy::QueryDriver)
|
||||
.value())
|
||||
Out.Apply.push_back([Val](const Params &, Config &C) {
|
||||
C.CompileFlags.BuiltinHeaders = *Val;
|
||||
});
|
||||
}
|
||||
|
||||
if (F.CompilationDatabase) {
|
||||
std::optional<Config::CDBSearchSpec> Spec;
|
||||
if (**F.CompilationDatabase == "Ancestors") {
|
||||
|
@ -170,6 +170,14 @@ struct Fragment {
|
||||
/// - Ancestors: search all parent directories (the default)
|
||||
/// - std::nullopt: do not use a compilation database, just default flags.
|
||||
std::optional<Located<std::string>> CompilationDatabase;
|
||||
|
||||
/// Controls whether Clangd should use its own built-in system headers (like
|
||||
/// stddef.h), or use the system headers from the query driver. Use the
|
||||
/// option value 'Clangd' (default) to indicate Clangd's headers, and use
|
||||
/// 'QueryDriver' to indicate QueryDriver's headers. `Clangd` is the
|
||||
/// fallback if no query driver is supplied or if the query driver regex
|
||||
/// string fails to match the compiler used in the CDB.
|
||||
std::optional<Located<std::string>> BuiltinHeaders;
|
||||
};
|
||||
CompileFlagsBlock CompileFlags;
|
||||
|
||||
|
@ -104,6 +104,10 @@ private:
|
||||
if (auto Values = scalarValues(N))
|
||||
F.Remove = std::move(*Values);
|
||||
});
|
||||
Dict.handle("BuiltinHeaders", [&](Node &N) {
|
||||
if (auto BuiltinHeaders = scalarValue(N, "BuiltinHeaders"))
|
||||
F.BuiltinHeaders = *BuiltinHeaders;
|
||||
});
|
||||
Dict.handle("CompilationDatabase", [&](Node &N) {
|
||||
F.CompilationDatabase = scalarValue(N, "CompilationDatabase");
|
||||
});
|
||||
|
@ -30,6 +30,7 @@
|
||||
// in the paths that are explicitly included by the user.
|
||||
|
||||
#include "CompileCommands.h"
|
||||
#include "Config.h"
|
||||
#include "GlobalCompilationDatabase.h"
|
||||
#include "support/Logger.h"
|
||||
#include "support/Threading.h"
|
||||
@ -401,22 +402,30 @@ extractSystemIncludesAndTarget(const DriverArgs &InputArgs,
|
||||
if (!Info)
|
||||
return std::nullopt;
|
||||
|
||||
// The built-in headers are tightly coupled to parser builtins.
|
||||
// (These are clang's "resource dir", GCC's GCC_INCLUDE_DIR.)
|
||||
// We should keep using clangd's versions, so exclude the queried builtins.
|
||||
// They're not specially marked in the -v output, but we can get the path
|
||||
// with `$DRIVER -print-file-name=include`.
|
||||
if (auto BuiltinHeaders =
|
||||
run({Driver, "-print-file-name=include"}, /*OutputIsStderr=*/false)) {
|
||||
auto Path = llvm::StringRef(*BuiltinHeaders).trim();
|
||||
if (!Path.empty() && llvm::sys::path::is_absolute(Path)) {
|
||||
auto Size = Info->SystemIncludes.size();
|
||||
llvm::erase(Info->SystemIncludes, Path);
|
||||
vlog("System includes extractor: builtin headers {0} {1}", Path,
|
||||
(Info->SystemIncludes.size() != Size)
|
||||
? "excluded"
|
||||
: "not found in driver's response");
|
||||
switch (Config::current().CompileFlags.BuiltinHeaders) {
|
||||
case Config::BuiltinHeaderPolicy::Clangd: {
|
||||
// The built-in headers are tightly coupled to parser builtins.
|
||||
// (These are clang's "resource dir", GCC's GCC_INCLUDE_DIR.)
|
||||
// We should keep using clangd's versions, so exclude the queried
|
||||
// builtins. They're not specially marked in the -v output, but we can
|
||||
// get the path with `$DRIVER -print-file-name=include`.
|
||||
if (auto BuiltinHeaders = run({Driver, "-print-file-name=include"},
|
||||
/*OutputIsStderr=*/false)) {
|
||||
auto Path = llvm::StringRef(*BuiltinHeaders).trim();
|
||||
if (!Path.empty() && llvm::sys::path::is_absolute(Path)) {
|
||||
auto Size = Info->SystemIncludes.size();
|
||||
llvm::erase(Info->SystemIncludes, Path);
|
||||
vlog("System includes extractor: builtin headers {0} {1}", Path,
|
||||
(Info->SystemIncludes.size() != Size)
|
||||
? "excluded"
|
||||
: "not found in driver's response");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Config::BuiltinHeaderPolicy::QueryDriver:
|
||||
vlog("System includes extractor: Using builtin headers from query driver.");
|
||||
break;
|
||||
}
|
||||
|
||||
log("System includes extractor: successfully executed {0}\n\tgot includes: "
|
||||
|
@ -58,6 +58,9 @@ Semantic Highlighting
|
||||
Compile flags
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
- Added `BuiltinHeaders` config key which controls whether clangd's built-in
|
||||
headers are used or ones extracted from the driver.
|
||||
|
||||
Hover
|
||||
^^^^^
|
||||
|
||||
@ -112,7 +115,7 @@ Changes in existing checks
|
||||
<clang-tidy/checks/bugprone/unchecked-optional-access>` fixing false
|
||||
positives from smart pointer accessors repeated in checking ``has_value``
|
||||
and accessing ``value``. The option `IgnoreSmartPointerDereference` should
|
||||
no longer be needed and will be removed. Also fixing false positive from
|
||||
no longer be needed and will be removed. Also fixing false positive from
|
||||
const reference accessors to objects containing optional member.
|
||||
|
||||
- Improved :doc:`bugprone-unsafe-functions
|
||||
@ -135,7 +138,7 @@ Changes in existing checks
|
||||
|
||||
- Improved :doc:`performance/unnecessary-value-param
|
||||
<clang-tidy/checks/performance/unnecessary-value-param>` check performance by
|
||||
tolerating fix-it breaking compilation when functions is used as pointers
|
||||
tolerating fix-it breaking compilation when functions is used as pointers
|
||||
to avoid matching usage of functions within the current compilation unit.
|
||||
|
||||
- Improved :doc:`performance-move-const-arg
|
||||
|
Loading…
x
Reference in New Issue
Block a user