[clang-tools-extra] 85d60a4 - [clangd] Add `BuiltinHeaders` config option (#129459)

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 8 16:16:41 PST 2025


Author: Khalil Estell
Date: 2025-03-08T19:16:37-05:00
New Revision: 85d60a441ab810e25605fb4555971b1d0a996e5c

URL: https://github.com/llvm/llvm-project/commit/85d60a441ab810e25605fb4555971b1d0a996e5c
DIFF: https://github.com/llvm/llvm-project/commit/85d60a441ab810e25605fb4555971b1d0a996e5c.diff

LOG: [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

Added: 
    

Modified: 
    clang-tools-extra/clangd/Config.h
    clang-tools-extra/clangd/ConfigCompile.cpp
    clang-tools-extra/clangd/ConfigFragment.h
    clang-tools-extra/clangd/ConfigYAML.cpp
    clang-tools-extra/clangd/SystemIncludeExtractor.cpp
    clang-tools-extra/docs/ReleaseNotes.rst

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h
index 586d031d58481..3f8a3c9b060f6 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -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 };

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp
index aa2561e081047..31530c206acd7 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -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") {

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h
index 9535b20253b13..6f95474b9c008 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -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;
 

diff  --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp
index 95cc5c1f9f1cf..a46d45df0d319 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -104,6 +104,10 @@ class Parser {
       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");
     });

diff  --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index c1c2e9fab9664..9399b910025b6 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -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: "

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 453617efaae26..951b7f20af4c8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -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


        


More information about the cfe-commits mailing list