Index: clangd/ClangdLSPServer.h =================================================================== --- clangd/ClangdLSPServer.h +++ clangd/ClangdLSPServer.h @@ -126,9 +126,10 @@ void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags); - /// Set the compile commands directory to \p P. + /// Set the compile commands directory to \p P. An empty Optional value + /// means to not use an explicit compile commands directory path. /// Only valid for directory-based CDB, no-op and error log on InMemoryCDB; - void setCompileCommandsDir(Path P); + void setCompileCommandsDir(llvm::Optional P); /// Returns a CDB that should be used to get compile commands for the /// current instance of ClangdLSPServer. Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -613,14 +613,14 @@ CachingCDB->invalidate(File); } -void ClangdLSPServer::CompilationDB::setCompileCommandsDir(Path P) { +void ClangdLSPServer::CompilationDB::setCompileCommandsDir(llvm::Optional P) { if (!IsDirectoryBased) { elog("Trying to set compile commands dir while using in-memory compilation " "database"); return; } static_cast(CDB.get()) - ->setCompileCommandsDir(P); + ->setCompileCommandsDir(std::move (P)); CachingCDB->clear(); } Index: clangd/GlobalCompilationDatabase.h =================================================================== --- clangd/GlobalCompilationDatabase.h +++ clangd/GlobalCompilationDatabase.h @@ -63,7 +63,7 @@ tooling::CompileCommand getFallbackCommand(PathRef File) const override; /// Set the compile commands directory to \p P. - void setCompileCommandsDir(Path P); + void setCompileCommandsDir(llvm::Optional P); /// Sets the extra flags that should be added to a file. void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags); Index: clangd/GlobalCompilationDatabase.cpp =================================================================== --- clangd/GlobalCompilationDatabase.cpp +++ clangd/GlobalCompilationDatabase.cpp @@ -60,7 +60,7 @@ return C; } -void DirectoryBasedGlobalCompilationDatabase::setCompileCommandsDir(Path P) { +void DirectoryBasedGlobalCompilationDatabase::setCompileCommandsDir(llvm::Optional P) { std::lock_guard Lock(Mutex); CompileCommandsDir = P; CompilationDatabases.clear(); Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -358,7 +358,14 @@ /// "initialize" request and for the "workspace/didChangeConfiguration" /// notification since the data received is described as 'any' type in LSP. struct ClangdConfigurationParamsChange { - llvm::Optional compilationDatabasePath; + /// Path to the directory containing the compile_commands.json file to use. + /// The outer Optional is empty if the compilationDatabasePath field was not + /// present at all in the request. + /// The inner Optional is empty if the compilationDatabasePath field was + /// preset, but the value was null. + /// If the value of the compilationDatabasePath in the request is a string, + /// both Optionals are instantiated. + llvm::Optional> compilationDatabasePath; // The changes that happened to the compilation database. // The key of the map is a file name. Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -609,11 +609,22 @@ O.map("compilationCommand", CDbUpdate.compilationCommand); } -bool fromJSON(const json::Value &Params, +bool fromJSON(const json::Value &Settings, ClangdConfigurationParamsChange &CCPC) { - json::ObjectMapper O(Params); - return O && O.map("compilationDatabasePath", CCPC.compilationDatabasePath) && - O.map("compilationDatabaseChanges", CCPC.compilationDatabaseChanges); + json::ObjectMapper O(Settings); + const json::Value *P = Settings.getAsObject()->get("compilationDatabasePath"); + + if (P) { + // The field is present. + CCPC.compilationDatabasePath.emplace(); + llvm::Optional S = P->getAsString(); + if (S) { + // The field has a string value. + CCPC.compilationDatabasePath->emplace(*S); + } + } + + return O && O.map("compilationDatabaseChanges", CCPC.compilationDatabaseChanges); } bool fromJSON(const json::Value &Params, ReferenceParams &R) { Index: test/clangd/compile-commands-path.test =================================================================== --- test/clangd/compile-commands-path.test +++ test/clangd/compile-commands-path.test @@ -39,4 +39,11 @@ # CHECK-NEXT: { # CHECK-NEXT: "message": "MACRO is two", --- +{"jsonrpc":"2.0","id":0,"method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabasePath":null}}} +# CHECK: "method": "textDocument/publishDiagnostics", +# CHECK-NEXT: "params": { +# CHECK-NEXT: "diagnostics": [ +# CHECK-NEXT: { +# CHECK-NEXT: "message": "MACRO is not defined", +--- {"jsonrpc":"2.0","id":10000,"method":"shutdown"}