From 9a30c2b92be357deac5a65e2fa0952d91634de70 Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Thu, 28 Aug 2025 20:46:35 +0200 Subject: [PATCH 1/6] Add --project-root to clangd --- clang-tools-extra/clangd/ClangdServer.cpp | 1 + clang-tools-extra/clangd/ClangdServer.h | 4 ++++ .../clangd/GlobalCompilationDatabase.cpp | 14 +++++++------- .../clangd/GlobalCompilationDatabase.h | 6 +++--- clang-tools-extra/clangd/TUScheduler.cpp | 6 ++++-- clang-tools-extra/clangd/TUScheduler.h | 4 ++++ clang-tools-extra/clangd/tool/Check.cpp | 4 ++-- clang-tools-extra/clangd/tool/ClangdMain.cpp | 10 ++++++++++ 8 files changed, 35 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index ac1e9aa5f0ff1..51230b4506b1a 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -208,6 +208,7 @@ ClangdServer::Options::operator TUScheduler::Options() const { Opts.UpdateDebounce = UpdateDebounce; Opts.ContextProvider = ContextProvider; Opts.PreambleThrottler = PreambleThrottler; + Opts.FallbackProjectRoot = FallbackProjectRoot; return Opts; } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 4a1eae188f7eb..2c56d6f7e6d6c 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -152,6 +152,10 @@ class ClangdServer { /// FIXME: If not set, should use the current working directory. std::optional WorkspaceRoot; + /// If set, fallback command uses this path as its current working directory + /// instead of the file's parent path. + std::optional FallbackProjectRoot; + /// The resource directory is used to find internal headers, overriding /// defaults and -resource-dir compiler flag). /// If std::nullopt, ClangdServer calls diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp index c6afd0bc07cbd..b73697d4ee7e5 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -55,7 +55,7 @@ void actOnAllParentDirectories(PathRef FileName, } // namespace tooling::CompileCommand -GlobalCompilationDatabase::getFallbackCommand(PathRef File) const { +GlobalCompilationDatabase::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { std::vector Argv = {"clang"}; // Clang treats .h files as C by default and files without extension as linker // input, resulting in unhelpful diagnostics. @@ -64,7 +64,7 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef File) const { if (FileExtension.empty() || FileExtension == ".h") Argv.push_back("-xobjective-c++-header"); Argv.push_back(std::string(File)); - tooling::CompileCommand Cmd(llvm::sys::path::parent_path(File), + tooling::CompileCommand Cmd(ProjectRoot ? *ProjectRoot : llvm::sys::path::parent_path(File), llvm::sys::path::filename(File), std::move(Argv), /*Output=*/""); Cmd.Heuristic = "clangd fallback"; @@ -797,8 +797,8 @@ OverlayCDB::getCompileCommand(PathRef File) const { return Cmd; } -tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const { - auto Cmd = DelegatingCDB::getFallbackCommand(File); +tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { + auto Cmd = DelegatingCDB::getFallbackCommand(File, ProjectRoot); std::lock_guard Lock(Mutex); Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(), FallbackFlags.end()); @@ -877,10 +877,10 @@ DelegatingCDB::getProjectModules(PathRef File) const { return Base->getProjectModules(File); } -tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File) const { +tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { if (!Base) - return GlobalCompilationDatabase::getFallbackCommand(File); - return Base->getFallbackCommand(File); + return GlobalCompilationDatabase::getFallbackCommand(File, ProjectRoot); + return Base->getFallbackCommand(File, ProjectRoot); } bool DelegatingCDB::blockUntilIdle(Deadline D) const { diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h index 1d636d73664be..5d1b5cb632154 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h @@ -55,7 +55,7 @@ class GlobalCompilationDatabase { /// Makes a guess at how to build a file. /// The default implementation just runs clang on the file. /// Clangd should treat the results as unreliable. - virtual tooling::CompileCommand getFallbackCommand(PathRef File) const; + virtual tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const; /// If the CDB does any asynchronous work, wait for it to complete. /// For use in tests. @@ -86,7 +86,7 @@ class DelegatingCDB : public GlobalCompilationDatabase { std::unique_ptr getProjectModules(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File) const override; + tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const override; bool blockUntilIdle(Deadline D) const override; @@ -200,7 +200,7 @@ class OverlayCDB : public DelegatingCDB { std::optional getCompileCommand(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File) const override; + tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const override; /// Sets or clears the compilation command for a particular file. /// Returns true if the command was changed (including insertion and removal), diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 035e5e63d8fbb..3dc53767e0ea4 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -723,6 +723,7 @@ class ASTWorker { const GlobalCompilationDatabase &CDB; /// Callback invoked when preamble or main file AST is built. ParsingCallbacks &Callbacks; + std::optional FallbackProjectRoot; Semaphore &Barrier; /// Whether the 'onMainAST' callback ran for the current FileInputs. @@ -840,13 +841,14 @@ ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, : IdleASTs(LRUCache), HeaderIncluders(HeaderIncluders), RunSync(RunSync), UpdateDebounce(Opts.UpdateDebounce), FileName(FileName), ContextProvider(Opts.ContextProvider), CDB(CDB), Callbacks(Callbacks), + FallbackProjectRoot(Opts.FallbackProjectRoot), Barrier(Barrier), Done(false), Status(FileName, Callbacks), PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync, Opts.PreambleThrottler, Status, HeaderIncluders, *this) { // Set a fallback command because compile command can be accessed before // `Inputs` is initialized. Other fields are only used after initialization // from client inputs. - FileInputs.CompileCommand = CDB.getFallbackCommand(FileName); + FileInputs.CompileCommand = CDB.getFallbackCommand(FileName, FallbackProjectRoot); } ASTWorker::~ASTWorker() { @@ -888,7 +890,7 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, if (Cmd) Inputs.CompileCommand = std::move(*Cmd); else - Inputs.CompileCommand = CDB.getFallbackCommand(FileName); + Inputs.CompileCommand = CDB.getFallbackCommand(FileName, FallbackProjectRoot); bool InputsAreTheSame = std::tie(FileInputs.CompileCommand, FileInputs.Contents) == diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index d0da20310a8b2..581a639646527 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -236,6 +236,10 @@ class TUScheduler { /// Typically to inject per-file configuration. /// If the path is empty, context sholud be "generic". std::function ContextProvider; + + /// If set, fallback command uses this path as its current working directory + /// instead of the file's parent path. + std::optional FallbackProjectRoot; }; TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index df8d075e80596..8d49b82d2ca53 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -187,7 +187,7 @@ class Checker { Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic, Cmd.Directory, printArgv(Cmd.CommandLine)); } else { - Cmd = CDB->getFallbackCommand(File); + Cmd = CDB->getFallbackCommand(File, Opts.FallbackProjectRoot); log("Generic fallback command is: [{0}] {1}", Cmd.Directory, printArgv(Cmd.CommandLine)); } @@ -502,7 +502,7 @@ bool check(llvm::StringRef File, const ThreadsafeFS &TFS, config::DiagnosticCallback Diag) const override { config::Fragment F; // If we're timing clang-tidy checks, implicitly disabling the slow ones - // is counterproductive! + // is counterproductive! if (CheckTidyTime.getNumOccurrences()) F.Diagnostics.ClangTidy.FastCheckFilter.emplace("None"); return {std::move(F).compile(Diag)}; diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index f287439f10cab..75d71c5a78f45 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -499,6 +499,14 @@ opt EnableConfig{ init(true), }; +opt ProjectRoot{ + "project-root", + cat(Misc), + desc("Path to use as the current working directory for fallback commands."), + init(""), + ValueOptional, +}; + opt UseDirtyHeaders{"use-dirty-headers", cat(Misc), desc("Use files open in the editor when parsing " "headers instead of reading from the disk"), @@ -906,6 +914,8 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var } if (!ResourceDir.empty()) Opts.ResourceDir = ResourceDir; + if (!ProjectRoot.empty()) + Opts.FallbackProjectRoot = ProjectRoot; Opts.BuildDynamicSymbolIndex = true; #if CLANGD_ENABLE_REMOTE if (RemoteIndexAddress.empty() != ProjectRoot.empty()) { From 82f80c04f0a6cb8d1c759178a707057be9d5ad7d Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Mon, 24 Nov 2025 21:59:31 +0100 Subject: [PATCH 2/6] [clangd] Replace --project-root with --strong-workspace-mode --- clang-tools-extra/clangd/ClangdServer.cpp | 2 +- clang-tools-extra/clangd/ClangdServer.h | 6 +++--- .../clangd/GlobalCompilationDatabase.cpp | 19 ++++++++++++------- .../clangd/GlobalCompilationDatabase.h | 6 +++--- clang-tools-extra/clangd/TUScheduler.cpp | 8 ++++---- clang-tools-extra/clangd/TUScheduler.h | 5 ++--- clang-tools-extra/clangd/tool/Check.cpp | 2 +- clang-tools-extra/clangd/tool/ClangdMain.cpp | 16 ++++++++-------- 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 51230b4506b1a..882515e97eeb7 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -208,7 +208,7 @@ ClangdServer::Options::operator TUScheduler::Options() const { Opts.UpdateDebounce = UpdateDebounce; Opts.ContextProvider = ContextProvider; Opts.PreambleThrottler = PreambleThrottler; - Opts.FallbackProjectRoot = FallbackProjectRoot; + Opts.StrongWorkspaceMode = StrongWorkspaceMode; return Opts; } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 2c56d6f7e6d6c..3f3eaf4115669 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -152,9 +152,9 @@ class ClangdServer { /// FIXME: If not set, should use the current working directory. std::optional WorkspaceRoot; - /// If set, fallback command uses this path as its current working directory - /// instead of the file's parent path. - std::optional FallbackProjectRoot; + /// Sets an alterante mode of operation. Current effects are: + /// - Using the current working directory as the working directory for fallback commands + bool StrongWorkspaceMode; /// The resource directory is used to find internal headers, overriding /// defaults and -resource-dir compiler flag). diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp index b73697d4ee7e5..4f161b38d96a2 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -55,7 +55,7 @@ void actOnAllParentDirectories(PathRef FileName, } // namespace tooling::CompileCommand -GlobalCompilationDatabase::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { +GlobalCompilationDatabase::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { std::vector Argv = {"clang"}; // Clang treats .h files as C by default and files without extension as linker // input, resulting in unhelpful diagnostics. @@ -64,7 +64,12 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef File, std::optional WorkingDir; + if (StrongWorkspaceMode) + llvm::sys::fs::current_path(WorkingDir); + else + WorkingDir = llvm::sys::path::parent_path(File); + tooling::CompileCommand Cmd(WorkingDir, llvm::sys::path::filename(File), std::move(Argv), /*Output=*/""); Cmd.Heuristic = "clangd fallback"; @@ -797,8 +802,8 @@ OverlayCDB::getCompileCommand(PathRef File) const { return Cmd; } -tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { - auto Cmd = DelegatingCDB::getFallbackCommand(File, ProjectRoot); +tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { + auto Cmd = DelegatingCDB::getFallbackCommand(File, StrongWorkspaceMode); std::lock_guard Lock(Mutex); Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(), FallbackFlags.end()); @@ -877,10 +882,10 @@ DelegatingCDB::getProjectModules(PathRef File) const { return Base->getProjectModules(File); } -tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File, std::optional ProjectRoot) const { +tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { if (!Base) - return GlobalCompilationDatabase::getFallbackCommand(File, ProjectRoot); - return Base->getFallbackCommand(File, ProjectRoot); + return GlobalCompilationDatabase::getFallbackCommand(File, StrongWorkspaceMode); + return Base->getFallbackCommand(File, StrongWorkspaceMode); } bool DelegatingCDB::blockUntilIdle(Deadline D) const { diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h index 5d1b5cb632154..a23e8cc162c4e 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h @@ -55,7 +55,7 @@ class GlobalCompilationDatabase { /// Makes a guess at how to build a file. /// The default implementation just runs clang on the file. /// Clangd should treat the results as unreliable. - virtual tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const; + virtual tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const; /// If the CDB does any asynchronous work, wait for it to complete. /// For use in tests. @@ -86,7 +86,7 @@ class DelegatingCDB : public GlobalCompilationDatabase { std::unique_ptr getProjectModules(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const override; + tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const override; bool blockUntilIdle(Deadline D) const override; @@ -200,7 +200,7 @@ class OverlayCDB : public DelegatingCDB { std::optional getCompileCommand(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File, std::optional ProjectRoot = std::nullopt) const override; + tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const override; /// Sets or clears the compilation command for a particular file. /// Returns true if the command was changed (including insertion and removal), diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 3dc53767e0ea4..09bb8d1927e90 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -723,7 +723,7 @@ class ASTWorker { const GlobalCompilationDatabase &CDB; /// Callback invoked when preamble or main file AST is built. ParsingCallbacks &Callbacks; - std::optional FallbackProjectRoot; + bool StrongWorkspaceMode; Semaphore &Barrier; /// Whether the 'onMainAST' callback ran for the current FileInputs. @@ -841,14 +841,14 @@ ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, : IdleASTs(LRUCache), HeaderIncluders(HeaderIncluders), RunSync(RunSync), UpdateDebounce(Opts.UpdateDebounce), FileName(FileName), ContextProvider(Opts.ContextProvider), CDB(CDB), Callbacks(Callbacks), - FallbackProjectRoot(Opts.FallbackProjectRoot), + StrongWorkspaceMode(Opts.StrongWorkspaceMode), Barrier(Barrier), Done(false), Status(FileName, Callbacks), PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync, Opts.PreambleThrottler, Status, HeaderIncluders, *this) { // Set a fallback command because compile command can be accessed before // `Inputs` is initialized. Other fields are only used after initialization // from client inputs. - FileInputs.CompileCommand = CDB.getFallbackCommand(FileName, FallbackProjectRoot); + FileInputs.CompileCommand = CDB.getFallbackCommand(FileName, StrongWorkspaceMode); } ASTWorker::~ASTWorker() { @@ -890,7 +890,7 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, if (Cmd) Inputs.CompileCommand = std::move(*Cmd); else - Inputs.CompileCommand = CDB.getFallbackCommand(FileName, FallbackProjectRoot); + Inputs.CompileCommand = CDB.getFallbackCommand(FileName, StrongWorkspaceMode); bool InputsAreTheSame = std::tie(FileInputs.CompileCommand, FileInputs.Contents) == diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index 581a639646527..d5dbd0e1830d1 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -237,9 +237,8 @@ class TUScheduler { /// If the path is empty, context sholud be "generic". std::function ContextProvider; - /// If set, fallback command uses this path as its current working directory - /// instead of the file's parent path. - std::optional FallbackProjectRoot; + /// Sets an alterante mode of operation. See ClangdServer::Options::StrongWorkspaceMode. + bool StrongWorkspaceMode; }; TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index 8d49b82d2ca53..451cdbce56fea 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -187,7 +187,7 @@ class Checker { Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic, Cmd.Directory, printArgv(Cmd.CommandLine)); } else { - Cmd = CDB->getFallbackCommand(File, Opts.FallbackProjectRoot); + Cmd = CDB->getFallbackCommand(File, Opts.StrongWorkspaceMode); log("Generic fallback command is: [{0}] {1}", Cmd.Directory, printArgv(Cmd.CommandLine)); } diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 7d2db715d37fd..f947171090a46 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -500,12 +500,13 @@ opt EnableConfig{ init(true), }; -opt ProjectRoot{ - "project-root", - cat(Misc), - desc("Path to use as the current working directory for fallback commands."), - init(""), - ValueOptional, +opt StrongWorkspaceMode{ + "strong-workspace-mode", + cat(Features), + desc( + "An alternate mode of operation for clangd, operating more closely to the workspace.\n" + "When enabled, fallback commands use the workspace directory as their working directory instead of the parent folder."), + init(false), }; opt UseDirtyHeaders{"use-dirty-headers", cat(Misc), @@ -915,8 +916,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var } if (!ResourceDir.empty()) Opts.ResourceDir = ResourceDir; - if (!ProjectRoot.empty()) - Opts.FallbackProjectRoot = ProjectRoot; + Opts.StrongWorkspaceMode = StrongWorkspaceMode; Opts.BuildDynamicSymbolIndex = true; #if CLANGD_ENABLE_REMOTE if (RemoteIndexAddress.empty() != ProjectRoot.empty()) { From 03b26a6f54e9e0dc3fe6e26e1e8060f3c6a6d112 Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Tue, 25 Nov 2025 20:25:08 +0100 Subject: [PATCH 3/6] [clangd] Fallback working directory code cleanup --- clang-tools-extra/clangd/ClangdLSPServer.cpp | 2 + clang-tools-extra/clangd/ClangdServer.cpp | 1 - .../clangd/GlobalCompilationDatabase.cpp | 53 +++++++++++-------- .../clangd/GlobalCompilationDatabase.h | 24 ++++++--- clang-tools-extra/clangd/TUScheduler.cpp | 5 +- clang-tools-extra/clangd/TUScheduler.h | 3 -- clang-tools-extra/clangd/tool/Check.cpp | 8 ++- .../GlobalCompilationDatabaseTests.cpp | 14 +++++ 8 files changed, 74 insertions(+), 36 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index f8e6da73bbb1f..3e8bacc715494 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -554,6 +554,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (const auto &Dir = Params.initializationOptions.compilationDatabasePath) CDBOpts.CompileCommandsDir = Dir; CDBOpts.ContextProvider = Opts.ContextProvider; + if (Opts.StrongWorkspaceMode) + CDBOpts.applyWorkingDirectory(std::move(Opts.WorkspaceRoot)); BaseCDB = std::make_unique(CDBOpts); } diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 882515e97eeb7..ac1e9aa5f0ff1 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -208,7 +208,6 @@ ClangdServer::Options::operator TUScheduler::Options() const { Opts.UpdateDebounce = UpdateDebounce; Opts.ContextProvider = ContextProvider; Opts.PreambleThrottler = PreambleThrottler; - Opts.StrongWorkspaceMode = StrongWorkspaceMode; return Opts; } diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp index 4f161b38d96a2..e2ac2d17171be 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp @@ -55,7 +55,7 @@ void actOnAllParentDirectories(PathRef FileName, } // namespace tooling::CompileCommand -GlobalCompilationDatabase::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { +GlobalCompilationDatabase::getFallbackCommand(PathRef File) const { std::vector Argv = {"clang"}; // Clang treats .h files as C by default and files without extension as linker // input, resulting in unhelpful diagnostics. @@ -64,14 +64,10 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef File, bool StrongWorkspace if (FileExtension.empty() || FileExtension == ".h") Argv.push_back("-xobjective-c++-header"); Argv.push_back(std::string(File)); - SmallString<256> WorkingDir; - if (StrongWorkspaceMode) - llvm::sys::fs::current_path(WorkingDir); - else - WorkingDir = llvm::sys::path::parent_path(File); - tooling::CompileCommand Cmd(WorkingDir, - llvm::sys::path::filename(File), std::move(Argv), - /*Output=*/""); + tooling::CompileCommand Cmd( + WorkingDirectory ? *WorkingDirectory : llvm::sys::path::parent_path(File), + llvm::sys::path::filename(File), std::move(Argv), + /*Output=*/""); Cmd.Heuristic = "clangd fallback"; return Cmd; } @@ -354,7 +350,8 @@ bool DirectoryBasedGlobalCompilationDatabase::DirectoryCache::load( DirectoryBasedGlobalCompilationDatabase:: DirectoryBasedGlobalCompilationDatabase(const Options &Opts) - : Opts(Opts), Broadcaster(std::make_unique(*this)) { + : GlobalCompilationDatabase(Opts.WorkingDirectory), Opts(Opts), + Broadcaster(std::make_unique(*this)) { if (!this->Opts.ContextProvider) this->Opts.ContextProvider = [](llvm::StringRef) { return Context::current().clone(); @@ -465,6 +462,17 @@ DirectoryBasedGlobalCompilationDatabase::lookupCDB( return Result; } +void DirectoryBasedGlobalCompilationDatabase::Options::applyWorkingDirectory( + const std::optional &&WorkingDirectory) { + if (WorkingDirectory) + this->WorkingDirectory = *WorkingDirectory; + else { + SmallString<256> CWD; + llvm::sys::fs::current_path(CWD); + this->WorkingDirectory = std::string(CWD); + } +} + // The broadcast thread announces files with new compile commands to the world. // Primarily this is used to enqueue them for background indexing. // @@ -764,8 +772,9 @@ DirectoryBasedGlobalCompilationDatabase::getProjectModules(PathRef File) const { OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base, std::vector FallbackFlags, - CommandMangler Mangler) - : DelegatingCDB(Base), Mangler(std::move(Mangler)), + CommandMangler Mangler, + std::optional WorkingDirectory) + : DelegatingCDB(Base, WorkingDirectory), Mangler(std::move(Mangler)), FallbackFlags(std::move(FallbackFlags)) {} std::optional @@ -802,8 +811,8 @@ OverlayCDB::getCompileCommand(PathRef File) const { return Cmd; } -tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { - auto Cmd = DelegatingCDB::getFallbackCommand(File, StrongWorkspaceMode); +tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const { + auto Cmd = DelegatingCDB::getFallbackCommand(File); std::lock_guard Lock(Mutex); Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(), FallbackFlags.end()); @@ -849,16 +858,18 @@ OverlayCDB::getProjectModules(PathRef File) const { return MDB; } -DelegatingCDB::DelegatingCDB(const GlobalCompilationDatabase *Base) - : Base(Base) { +DelegatingCDB::DelegatingCDB(const GlobalCompilationDatabase *Base, + std::optional WorkingDirectory) + : GlobalCompilationDatabase(WorkingDirectory), Base(Base) { if (Base) BaseChanged = Base->watch([this](const std::vector Changes) { OnCommandChanged.broadcast(Changes); }); } -DelegatingCDB::DelegatingCDB(std::unique_ptr Base) - : DelegatingCDB(Base.get()) { +DelegatingCDB::DelegatingCDB(std::unique_ptr Base, + std::optional WorkingDirectory) + : DelegatingCDB(Base.get(), WorkingDirectory) { BaseOwner = std::move(Base); } @@ -882,10 +893,10 @@ DelegatingCDB::getProjectModules(PathRef File) const { return Base->getProjectModules(File); } -tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File, bool StrongWorkspaceMode) const { +tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File) const { if (!Base) - return GlobalCompilationDatabase::getFallbackCommand(File, StrongWorkspaceMode); - return Base->getFallbackCommand(File, StrongWorkspaceMode); + return GlobalCompilationDatabase::getFallbackCommand(File); + return Base->getFallbackCommand(File); } bool DelegatingCDB::blockUntilIdle(Deadline D) const { diff --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h b/clang-tools-extra/clangd/GlobalCompilationDatabase.h index a23e8cc162c4e..da005f8e19c4c 100644 --- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h +++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h @@ -35,6 +35,8 @@ struct ProjectInfo { /// Provides compilation arguments used for parsing C and C++ files. class GlobalCompilationDatabase { public: + GlobalCompilationDatabase(std::optional WorkingDirectory) + : WorkingDirectory(WorkingDirectory) {} virtual ~GlobalCompilationDatabase() = default; /// If there are any known-good commands for building this file, returns one. @@ -55,7 +57,7 @@ class GlobalCompilationDatabase { /// Makes a guess at how to build a file. /// The default implementation just runs clang on the file. /// Clangd should treat the results as unreliable. - virtual tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const; + virtual tooling::CompileCommand getFallbackCommand(PathRef File) const; /// If the CDB does any asynchronous work, wait for it to complete. /// For use in tests. @@ -69,14 +71,17 @@ class GlobalCompilationDatabase { } protected: + std::optional WorkingDirectory; mutable CommandChanged OnCommandChanged; }; // Helper class for implementing GlobalCompilationDatabases that wrap others. class DelegatingCDB : public GlobalCompilationDatabase { public: - DelegatingCDB(const GlobalCompilationDatabase *Base); - DelegatingCDB(std::unique_ptr Base); + DelegatingCDB(const GlobalCompilationDatabase *Base, + std::optional WorkingDirectory); + DelegatingCDB(std::unique_ptr Base, + std::optional WorkingDirectory); std::optional getCompileCommand(PathRef File) const override; @@ -86,7 +91,7 @@ class DelegatingCDB : public GlobalCompilationDatabase { std::unique_ptr getProjectModules(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const override; + tooling::CompileCommand getFallbackCommand(PathRef File) const override; bool blockUntilIdle(Deadline D) const override; @@ -117,6 +122,12 @@ class DirectoryBasedGlobalCompilationDatabase // Only look for a compilation database in this one fixed directory. // FIXME: fold this into config/context mechanism. std::optional CompileCommandsDir; + // Working directory for fallback commands + // If unset, parent directory of file should be used + std::optional WorkingDirectory; + + void + applyWorkingDirectory(const std::optional &&WorkingDirectory); }; DirectoryBasedGlobalCompilationDatabase(const Options &Opts); @@ -196,11 +207,12 @@ class OverlayCDB : public DelegatingCDB { // Adjuster is applied to all commands, fallback or not. OverlayCDB(const GlobalCompilationDatabase *Base, std::vector FallbackFlags = {}, - CommandMangler Mangler = nullptr); + CommandMangler Mangler = nullptr, + std::optional WorkingDirectory = std::nullopt); std::optional getCompileCommand(PathRef File) const override; - tooling::CompileCommand getFallbackCommand(PathRef File, bool StrongWorkspaceMode = false) const override; + tooling::CompileCommand getFallbackCommand(PathRef File) const override; /// Sets or clears the compilation command for a particular file. /// Returns true if the command was changed (including insertion and removal), diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 09bb8d1927e90..0a8bca76879b7 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -841,14 +841,13 @@ ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB, : IdleASTs(LRUCache), HeaderIncluders(HeaderIncluders), RunSync(RunSync), UpdateDebounce(Opts.UpdateDebounce), FileName(FileName), ContextProvider(Opts.ContextProvider), CDB(CDB), Callbacks(Callbacks), - StrongWorkspaceMode(Opts.StrongWorkspaceMode), Barrier(Barrier), Done(false), Status(FileName, Callbacks), PreamblePeer(FileName, Callbacks, Opts.StorePreamblesInMemory, RunSync, Opts.PreambleThrottler, Status, HeaderIncluders, *this) { // Set a fallback command because compile command can be accessed before // `Inputs` is initialized. Other fields are only used after initialization // from client inputs. - FileInputs.CompileCommand = CDB.getFallbackCommand(FileName, StrongWorkspaceMode); + FileInputs.CompileCommand = CDB.getFallbackCommand(FileName); } ASTWorker::~ASTWorker() { @@ -890,7 +889,7 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, if (Cmd) Inputs.CompileCommand = std::move(*Cmd); else - Inputs.CompileCommand = CDB.getFallbackCommand(FileName, StrongWorkspaceMode); + Inputs.CompileCommand = CDB.getFallbackCommand(FileName); bool InputsAreTheSame = std::tie(FileInputs.CompileCommand, FileInputs.Contents) == diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index d5dbd0e1830d1..d0da20310a8b2 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -236,9 +236,6 @@ class TUScheduler { /// Typically to inject per-file configuration. /// If the path is empty, context sholud be "generic". std::function ContextProvider; - - /// Sets an alterante mode of operation. See ClangdServer::Options::StrongWorkspaceMode. - bool StrongWorkspaceMode; }; TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, diff --git a/clang-tools-extra/clangd/tool/Check.cpp b/clang-tools-extra/clangd/tool/Check.cpp index 451cdbce56fea..6fc2b00cbc063 100644 --- a/clang-tools-extra/clangd/tool/Check.cpp +++ b/clang-tools-extra/clangd/tool/Check.cpp @@ -169,6 +169,8 @@ class Checker { bool buildCommand(const ThreadsafeFS &TFS) { log("Loading compilation database..."); DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS); + if (Opts.StrongWorkspaceMode) + CDBOpts.applyWorkingDirectory(std::move(Opts.WorkspaceRoot)); CDBOpts.CompileCommandsDir = Config::current().CompileFlags.CDBSearch.FixedCDBPath; BaseCDB = @@ -178,8 +180,10 @@ class Checker { getSystemIncludeExtractor(llvm::ArrayRef(Opts.QueryDriverGlobs)); if (Opts.ResourceDir) Mangler.ResourceDir = *Opts.ResourceDir; + CDB = std::make_unique( - BaseCDB.get(), std::vector{}, std::move(Mangler)); + BaseCDB.get(), std::vector{}, std::move(Mangler), + CDBOpts.WorkingDirectory); if (auto TrueCmd = CDB->getCompileCommand(File)) { Cmd = std::move(*TrueCmd); @@ -187,7 +191,7 @@ class Checker { Cmd.Heuristic.empty() ? "from CDB" : Cmd.Heuristic, Cmd.Directory, printArgv(Cmd.CommandLine)); } else { - Cmd = CDB->getFallbackCommand(File, Opts.StrongWorkspaceMode); + Cmd = CDB->getFallbackCommand(File); log("Generic fallback command is: [{0}] {1}", Cmd.Directory, printArgv(Cmd.CommandLine)); } diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp index c9e01e52dac1f..f4ff7d83d7047 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -55,6 +55,20 @@ TEST(GlobalCompilationDatabaseTest, FallbackCommand) { testPath("foo/bar"))); } +TEST(GlobalCompilationDatabaseTest, FallbackWorkingDirectory) { + MockFS TFS; + DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS); + CDBOpts.applyWorkingDirectory(testPath("foo")); + EXPECT_EQ(CDBOpts.WorkingDirectory, testPath("foo")); + + DirectoryBasedGlobalCompilationDatabase DB(CDBOpts); + auto Cmd = DB.getFallbackCommand(testPath("foo/src/bar.cc")); + EXPECT_EQ(Cmd.Directory, testPath("foo")); + EXPECT_THAT(Cmd.CommandLine, + ElementsAre("clang", testPath("foo/src/bar.cc"))); + EXPECT_EQ(Cmd.Output, ""); +} + static tooling::CompileCommand cmd(llvm::StringRef File, llvm::StringRef Arg) { return tooling::CompileCommand( testRoot(), File, {"clang", std::string(Arg), std::string(File)}, ""); From f824d5d303d89b87a82873c9731b19297984e560 Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Wed, 26 Nov 2025 00:30:57 +0100 Subject: [PATCH 4/6] Fix formatting and errors --- clang-tools-extra/clangd/ClangdServer.h | 3 ++- clang-tools-extra/clangd/TUScheduler.cpp | 1 - clang-tools-extra/clangd/tool/ClangdMain.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 3f3eaf4115669..6ed5db517eb5e 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -153,7 +153,8 @@ class ClangdServer { std::optional WorkspaceRoot; /// Sets an alterante mode of operation. Current effects are: - /// - Using the current working directory as the working directory for fallback commands + /// - Using the current working directory as the working directory for + /// fallback commands bool StrongWorkspaceMode; /// The resource directory is used to find internal headers, overriding diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 0a8bca76879b7..035e5e63d8fbb 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -723,7 +723,6 @@ class ASTWorker { const GlobalCompilationDatabase &CDB; /// Callback invoked when preamble or main file AST is built. ParsingCallbacks &Callbacks; - bool StrongWorkspaceMode; Semaphore &Barrier; /// Whether the 'onMainAST' callback ran for the current FileInputs. diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index f947171090a46..39f2a8c8346c6 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -503,9 +503,10 @@ opt EnableConfig{ opt StrongWorkspaceMode{ "strong-workspace-mode", cat(Features), - desc( - "An alternate mode of operation for clangd, operating more closely to the workspace.\n" - "When enabled, fallback commands use the workspace directory as their working directory instead of the parent folder."), + desc("An alternate mode of operation for clangd, operating more closely to " + "the workspace.\n" + "When enabled, fallback commands use the workspace directory as their " + "working directory instead of the parent folder."), init(false), }; From 220b823d46554ddbb694b3518133705efb1b1e71 Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Wed, 26 Nov 2025 17:17:24 +0100 Subject: [PATCH 5/6] [clangd] Make tests compile with new CDB constructor --- clang-tools-extra/clangd/TUScheduler.h | 2 ++ clang-tools-extra/clangd/unittests/ClangdTests.cpp | 2 +- .../clangd/unittests/GlobalCompilationDatabaseTests.cpp | 2 ++ clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp | 2 ++ clang-tools-extra/clangd/unittests/TestFS.cpp | 2 +- 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index d0da20310a8b2..7b7872a4e8595 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -236,6 +236,8 @@ class TUScheduler { /// Typically to inject per-file configuration. /// If the path is empty, context sholud be "generic". std::function ContextProvider; + + bool test; }; TUScheduler(const GlobalCompilationDatabase &CDB, const Options &Opts, diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index 9ea7c3e02411d..b935d91c6bd81 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -1110,7 +1110,7 @@ TEST(ClangdServerTest, FallbackWhenWaitingForCompileCommand) { class DelayedCompilationDatabase : public GlobalCompilationDatabase { public: DelayedCompilationDatabase(Notification &CanReturnCommand) - : CanReturnCommand(CanReturnCommand) {} + : GlobalCompilationDatabase(std::nullopt), CanReturnCommand(CanReturnCommand) {} std::optional getCompileCommand(PathRef File) const override { diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp index f4ff7d83d7047..57a1f40cfa571 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -77,6 +77,8 @@ static tooling::CompileCommand cmd(llvm::StringRef File, llvm::StringRef Arg) { class OverlayCDBTest : public ::testing::Test { class BaseCDB : public GlobalCompilationDatabase { public: + BaseCDB(): GlobalCompilationDatabase(std::nullopt) {} + std::optional getCompileCommand(llvm::StringRef File) const override { if (File == testPath("foo.cc")) diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 43f38e39c8952..59421375d1cdd 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -1329,6 +1329,8 @@ TEST_F(TUSchedulerTests, IncluderCache) { OK = testPath("ok.h"), NotIncluded = testPath("not_included.h"); struct NoHeadersCDB : public GlobalCompilationDatabase { + NoHeadersCDB(): GlobalCompilationDatabase(std::nullopt) {} + std::optional getCompileCommand(PathRef File) const override { if (File == NoCmd || File == NotIncluded || FailAll) diff --git a/clang-tools-extra/clangd/unittests/TestFS.cpp b/clang-tools-extra/clangd/unittests/TestFS.cpp index bb309609eda20..37783cc0f443d 100644 --- a/clang-tools-extra/clangd/unittests/TestFS.cpp +++ b/clang-tools-extra/clangd/unittests/TestFS.cpp @@ -46,7 +46,7 @@ buildTestFS(llvm::StringMap const &Files, MockCompilationDatabase::MockCompilationDatabase(llvm::StringRef Directory, llvm::StringRef RelPathPrefix) - : ExtraClangFlags({"-ffreestanding"}), Directory(Directory), + : GlobalCompilationDatabase(std::nullopt), ExtraClangFlags({"-ffreestanding"}), Directory(Directory), RelPathPrefix(RelPathPrefix) { // -ffreestanding avoids implicit stdc-predef.h. } From a21f748b3379b4d7c3588c008423ef6e565e906d Mon Sep 17 00:00:00 2001 From: Dominicentek Date: Wed, 26 Nov 2025 17:33:12 +0100 Subject: [PATCH 6/6] Run git-clang-format --- clang-tools-extra/clangd/TUScheduler.h | 2 +- clang-tools-extra/clangd/unittests/ClangdTests.cpp | 3 ++- .../clangd/unittests/GlobalCompilationDatabaseTests.cpp | 4 ++-- clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp | 4 ++-- clang-tools-extra/clangd/unittests/TestFS.cpp | 3 ++- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index 7b7872a4e8595..e23a4d63bf297 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -236,7 +236,7 @@ class TUScheduler { /// Typically to inject per-file configuration. /// If the path is empty, context sholud be "generic". std::function ContextProvider; - + bool test; }; diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index b935d91c6bd81..24ca8c93fb2d3 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -1110,7 +1110,8 @@ TEST(ClangdServerTest, FallbackWhenWaitingForCompileCommand) { class DelayedCompilationDatabase : public GlobalCompilationDatabase { public: DelayedCompilationDatabase(Notification &CanReturnCommand) - : GlobalCompilationDatabase(std::nullopt), CanReturnCommand(CanReturnCommand) {} + : GlobalCompilationDatabase(std::nullopt), + CanReturnCommand(CanReturnCommand) {} std::optional getCompileCommand(PathRef File) const override { diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp index 57a1f40cfa571..631cbc1be12e8 100644 --- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp +++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp @@ -77,8 +77,8 @@ static tooling::CompileCommand cmd(llvm::StringRef File, llvm::StringRef Arg) { class OverlayCDBTest : public ::testing::Test { class BaseCDB : public GlobalCompilationDatabase { public: - BaseCDB(): GlobalCompilationDatabase(std::nullopt) {} - + BaseCDB() : GlobalCompilationDatabase(std::nullopt) {} + std::optional getCompileCommand(llvm::StringRef File) const override { if (File == testPath("foo.cc")) diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp index 59421375d1cdd..531067095464c 100644 --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -1329,8 +1329,8 @@ TEST_F(TUSchedulerTests, IncluderCache) { OK = testPath("ok.h"), NotIncluded = testPath("not_included.h"); struct NoHeadersCDB : public GlobalCompilationDatabase { - NoHeadersCDB(): GlobalCompilationDatabase(std::nullopt) {} - + NoHeadersCDB() : GlobalCompilationDatabase(std::nullopt) {} + std::optional getCompileCommand(PathRef File) const override { if (File == NoCmd || File == NotIncluded || FailAll) diff --git a/clang-tools-extra/clangd/unittests/TestFS.cpp b/clang-tools-extra/clangd/unittests/TestFS.cpp index 37783cc0f443d..33efc3651d359 100644 --- a/clang-tools-extra/clangd/unittests/TestFS.cpp +++ b/clang-tools-extra/clangd/unittests/TestFS.cpp @@ -46,7 +46,8 @@ buildTestFS(llvm::StringMap const &Files, MockCompilationDatabase::MockCompilationDatabase(llvm::StringRef Directory, llvm::StringRef RelPathPrefix) - : GlobalCompilationDatabase(std::nullopt), ExtraClangFlags({"-ffreestanding"}), Directory(Directory), + : GlobalCompilationDatabase(std::nullopt), + ExtraClangFlags({"-ffreestanding"}), Directory(Directory), RelPathPrefix(RelPathPrefix) { // -ffreestanding avoids implicit stdc-predef.h. }