diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h --- a/clang-tools-extra/clangd/ConfigFragment.h +++ b/clang-tools-extra/clangd/ConfigFragment.h @@ -162,6 +162,22 @@ /// This is checked for translation units only, not headers they include. /// Legal values are "Build" or "Skip". llvm::Optional> Background; + /// An external index uses data source outside of clangd itself. This is + /// usually prepared using clangd-indexer. + /// Exactly one source (File/Server) should be configured. + struct ExternalBlock { + /// Path to an index file generated by clangd-indexer. Relative paths may + /// be used, if config fragment is associated with a directory. + llvm::Optional> File; + /// Address and port number for a clangd-index-server. e.g. + /// `123.1.1.1:13337`. + llvm::Optional> Server; + /// Source root governed by this index. Default is the directory + /// associated with the config fragment. Absolute in case of user config + /// and relative otherwise. Should always use forward-slashes. + llvm::Optional> MountPoint; + }; + llvm::Optional> External; }; IndexBlock Index; diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp --- a/clang-tools-extra/clangd/ConfigYAML.cpp +++ b/clang-tools-extra/clangd/ConfigYAML.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - #include "ConfigFragment.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" @@ -111,6 +110,22 @@ DictParser Dict("Index", this); Dict.handle("Background", [&](Node &N) { F.Background = scalarValue(N, "Background"); }); + Dict.handle("External", [&](Node &N) { + Fragment::IndexBlock::ExternalBlock External; + parse(External, N); + F.External.emplace(std::move(External)); + F.External->Range = N.getSourceRange(); + }); + Dict.parse(N); + } + + void parse(Fragment::IndexBlock::ExternalBlock &F, Node &N) { + DictParser Dict("External", this); + Dict.handle("File", [&](Node &N) { F.File = scalarValue(N, "File"); }); + Dict.handle("Server", + [&](Node &N) { F.Server = scalarValue(N, "Server"); }); + Dict.handle("MountPoint", + [&](Node &N) { F.MountPoint = scalarValue(N, "MountPoint"); }); Dict.parse(N); } diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp --- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp @@ -10,6 +10,7 @@ #include "ConfigFragment.h" #include "ConfigTesting.h" #include "Protocol.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/SourceMgr.h" @@ -142,6 +143,25 @@ ASSERT_THAT(Results, IsEmpty()); } +TEST(ParseYAML, ExternalBlock) { + CapturedDiags Diags; + Annotations YAML(R"yaml( +Index: + External: + File: "foo" + Server: ^"bar" + MountPoint: "baz" + )yaml"); + auto Results = + Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback()); + ASSERT_EQ(Results.size(), 1u); + ASSERT_TRUE(Results[0].Index.External); + EXPECT_THAT(*Results[0].Index.External.getValue()->File, Val("foo")); + EXPECT_THAT(*Results[0].Index.External.getValue()->MountPoint, Val("baz")); + ASSERT_THAT(Diags.Diagnostics, IsEmpty()); + EXPECT_THAT(*Results[0].Index.External.getValue()->Server, Val("bar")); +} + } // namespace } // namespace config } // namespace clangd