hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: kadircet, arphaman, jkorous, MaskRay, ioeric, 
ilya-biryukov.

This would save us 8 bytes per ref, and buy us ~50MB in total for llvm
index (from ~350MB to ~300 MB).

The char pointer must be null-terminated, and llvm::StringSaver
guarantees it.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53427

Files:
  clangd/CodeComplete.cpp
  clangd/FindSymbols.cpp
  clangd/Quality.cpp
  clangd/XRefs.cpp
  clangd/index/Index.cpp
  clangd/index/Index.h
  clangd/index/Merge.cpp
  clangd/index/Serialization.cpp
  clangd/index/SymbolCollector.cpp
  clangd/index/YAMLSerialization.cpp
  clangd/index/dex/Dex.cpp
  clangd/index/dex/dexp/Dexp.cpp
  unittests/clangd/CodeCompleteTests.cpp
  unittests/clangd/DexTests.cpp
  unittests/clangd/FileIndexTests.cpp
  unittests/clangd/IndexTests.cpp
  unittests/clangd/SerializationTests.cpp
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -53,8 +53,8 @@
   return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
 }
 MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
-MATCHER_P(DeclURI, P, "") { return arg.CanonicalDeclaration.FileURI == P; }
-MATCHER_P(DefURI, P, "") { return arg.Definition.FileURI == P; }
+MATCHER_P(DeclURI, P, "") { return arg.CanonicalDeclaration.fileURI() == P; }
+MATCHER_P(DefURI, P, "") { return arg.Definition.fileURI() == P; }
 MATCHER_P(IncludeHeader, P, "") {
   return (arg.IncludeHeaders.size() == 1) &&
          (arg.IncludeHeaders.begin()->IncludeHeader == P);
Index: unittests/clangd/SerializationTests.cpp
===================================================================
--- unittests/clangd/SerializationTests.cpp
+++ unittests/clangd/SerializationTests.cpp
@@ -110,7 +110,7 @@
   EXPECT_EQ(Sym1.Signature, "");
   EXPECT_EQ(Sym1.Documentation, "Foo doc");
   EXPECT_EQ(Sym1.ReturnType, "int");
-  EXPECT_EQ(Sym1.CanonicalDeclaration.FileURI, "file:///path/foo.h");
+  EXPECT_EQ(Sym1.CanonicalDeclaration.fileURI(), "file:///path/foo.h");
   EXPECT_EQ(Sym1.Origin, SymbolOrigin::Static);
   EXPECT_TRUE(Sym1.Flags & Symbol::IndexedForCodeCompletion);
   EXPECT_FALSE(Sym1.Flags & Symbol::Deprecated);
@@ -121,7 +121,7 @@
   EXPECT_THAT(Sym2, QName("clang::Foo2"));
   EXPECT_EQ(Sym2.Signature, "-sig");
   EXPECT_EQ(Sym2.ReturnType, "");
-  EXPECT_EQ(Sym2.CanonicalDeclaration.FileURI, "file:///path/bar.h");
+  EXPECT_EQ(Sym2.CanonicalDeclaration.fileURI(), "file:///path/bar.h");
   EXPECT_FALSE(Sym2.Flags & Symbol::IndexedForCodeCompletion);
   EXPECT_TRUE(Sym2.Flags & Symbol::Deprecated);
 
@@ -133,7 +133,7 @@
                        testing::SizeIs(1))));
   auto Ref1 = ParsedYAML->Refs->begin()->second.front();
   EXPECT_EQ(Ref1.Kind, RefKind::Reference);
-  EXPECT_EQ(Ref1.Location.FileURI, "file:///path/foo.cc");
+  EXPECT_EQ(Ref1.Location.fileURI(), "file:///path/foo.cc");
 }
 
 std::vector<std::string> YAMLFromSymbols(const SymbolSlab &Slab) {
Index: unittests/clangd/IndexTests.cpp
===================================================================
--- unittests/clangd/IndexTests.cpp
+++ unittests/clangd/IndexTests.cpp
@@ -36,7 +36,7 @@
          std::make_tuple(Range.start.line, Range.start.character,
                          Range.end.line, Range.end.character);
 }
-MATCHER_P(FileURI, F, "") { return arg.Location.FileURI == F; }
+MATCHER_P(FileURI, F, "") { return arg.Location.fileURI() == F; }
 
 TEST(SymbolLocation, Position) {
   using Position = SymbolLocation::Position;
@@ -206,8 +206,8 @@
   Symbol L, R;
   L.ID = R.ID = SymbolID("hello");
   L.Name = R.Name = "Foo";                           // same in both
-  L.CanonicalDeclaration.FileURI = "file:///left.h"; // differs
-  R.CanonicalDeclaration.FileURI = "file:///right.h";
+  L.CanonicalDeclaration.setFileURI("file:///left.h"); // differs
+  R.CanonicalDeclaration.setFileURI("file:///right.h");
   L.References = 1;
   R.References = 2;
   L.Signature = "()";                   // present in left only
@@ -218,7 +218,7 @@
 
   Symbol M = mergeSymbol(L, R);
   EXPECT_EQ(M.Name, "Foo");
-  EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:///left.h");
+  EXPECT_EQ(M.CanonicalDeclaration.fileURI(), "file:///left.h");
   EXPECT_EQ(M.References, 3u);
   EXPECT_EQ(M.Signature, "()");
   EXPECT_EQ(M.CompletionSnippetSuffix, "{$1:0}");
@@ -231,20 +231,20 @@
   Symbol L, R;
 
   L.ID = R.ID = SymbolID("hello");
-  L.CanonicalDeclaration.FileURI = "file:/left.h";
-  R.CanonicalDeclaration.FileURI = "file:/right.h";
+  L.CanonicalDeclaration.setFileURI("file:/left.h");
+  R.CanonicalDeclaration.setFileURI("file:/right.h");
   L.Name = "left";
   R.Name = "right";
 
   Symbol M = mergeSymbol(L, R);
-  EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/left.h");
-  EXPECT_EQ(M.Definition.FileURI, "");
+  EXPECT_EQ(M.CanonicalDeclaration.fileURI(), "file:/left.h");
+  EXPECT_EQ(M.Definition.fileURI(), "");
   EXPECT_EQ(M.Name, "left");
 
-  R.Definition.FileURI = "file:/right.cpp"; // Now right will be favored.
+  R.Definition.setFileURI("file:/right.cpp"); // Now right will be favored.
   M = mergeSymbol(L, R);
-  EXPECT_EQ(M.CanonicalDeclaration.FileURI, "file:/right.h");
-  EXPECT_EQ(M.Definition.FileURI, "file:/right.cpp");
+  EXPECT_EQ(M.CanonicalDeclaration.fileURI(), "file:/right.h");
+  EXPECT_EQ(M.Definition.fileURI(), "file:/right.cpp");
   EXPECT_EQ(M.Name, "right");
 }
 
@@ -317,20 +317,20 @@
                                    IncludeHeaderWithRef("new", 1u)));
 
   // Only merge references of the same includes but do not merge new #includes.
-  L.Definition.FileURI = "file:/left.h";
+  L.Definition.setFileURI("file:/left.h");
   M = mergeSymbol(L, R);
   EXPECT_THAT(M.IncludeHeaders,
               UnorderedElementsAre(IncludeHeaderWithRef("common", 2u)));
 
   // Definitions are the same.
-  R.Definition.FileURI = "file:/right.h";
+  R.Definition.setFileURI("file:/right.h");
   M = mergeSymbol(L, R);
   EXPECT_THAT(M.IncludeHeaders,
               UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
                                    IncludeHeaderWithRef("new", 1u)));
 
   // Definitions are different.
-  R.Definition.FileURI = "file:/right.h";
+  R.Definition.setFileURI("file:/right.h");
   M = mergeSymbol(L, R);
   EXPECT_THAT(M.IncludeHeaders,
               UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
Index: unittests/clangd/FileIndexTests.cpp
===================================================================
--- unittests/clangd/FileIndexTests.cpp
+++ unittests/clangd/FileIndexTests.cpp
@@ -37,8 +37,8 @@
          std::make_tuple(Range.start.line, Range.start.character,
                          Range.end.line, Range.end.character);
 }
-MATCHER_P(FileURI, F, "") { return arg.Location.FileURI == F; }
-MATCHER_P(DeclURI, U, "") { return arg.CanonicalDeclaration.FileURI == U; }
+MATCHER_P(FileURI, F, "") { return arg.Location.fileURI() == F; }
+MATCHER_P(DeclURI, U, "") { return arg.CanonicalDeclaration.fileURI() == U; }
 MATCHER_P(QName, N, "") { return (arg.Scope + arg.Name).str() == N; }
 
 namespace clang {
@@ -63,10 +63,10 @@
   return llvm::make_unique<SymbolSlab>(std::move(Slab).build());
 }
 
-std::unique_ptr<RefSlab> refSlab(const SymbolID &ID, llvm::StringRef Path) {
+std::unique_ptr<RefSlab> refSlab(const SymbolID &ID, const char* Path) {
   RefSlab::Builder Slab;
   Ref R;
-  R.Location.FileURI = Path;
+  R.Location.setFileURI(Path);
   R.Kind = RefKind::Reference;
   Slab.insert(ID, R);
   return llvm::make_unique<RefSlab>(std::move(Slab).build());
Index: unittests/clangd/DexTests.cpp
===================================================================
--- unittests/clangd/DexTests.cpp
+++ unittests/clangd/DexTests.cpp
@@ -644,9 +644,9 @@
 
 TEST(DexTest, ProximityPathsBoosting) {
   auto RootSymbol = symbol("root::abc");
-  RootSymbol.CanonicalDeclaration.FileURI = "unittest:///file.h";
+  RootSymbol.CanonicalDeclaration.setFileURI("unittest:///file.h");
   auto CloseSymbol = symbol("close::abc");
-  CloseSymbol.CanonicalDeclaration.FileURI = "unittest:///a/b/c/d/e/f/file.h";
+  CloseSymbol.CanonicalDeclaration.setFileURI("unittest:///a/b/c/d/e/f/file.h");
 
   std::vector<Symbol> Symbols{CloseSymbol, RootSymbol};
   Dex I(Symbols, RefSlab(), URISchemes);
@@ -669,11 +669,11 @@
 
 TEST(DexTests, Refs) {
   DenseMap<SymbolID, std::vector<Ref>> Refs;
-  auto AddRef = [&](const Symbol& Sym, StringRef Filename, RefKind Kind) {
+  auto AddRef = [&](const Symbol& Sym, const char* Filename, RefKind Kind) {
     auto& SymbolRefs = Refs[Sym.ID];
     SymbolRefs.emplace_back();
     SymbolRefs.back().Kind = Kind;
-    SymbolRefs.back().Location.FileURI = Filename;
+    SymbolRefs.back().Location.setFileURI(Filename);
   };
   auto Foo = symbol("foo");
   auto Bar = symbol("bar");
@@ -686,7 +686,7 @@
   Req.IDs.insert(Foo.ID);
   Req.Filter = RefKind::Declaration | RefKind::Definition;
   Dex(std::vector<Symbol>{Foo, Bar}, Refs, {}).refs(Req, [&](const Ref &R) {
-    Files.push_back(R.Location.FileURI);
+    Files.push_back(R.Location.fileURI());
   });
 
   EXPECT_THAT(Files, ElementsAre("foo.h"));
Index: unittests/clangd/CodeCompleteTests.cpp
===================================================================
--- unittests/clangd/CodeCompleteTests.cpp
+++ unittests/clangd/CodeCompleteTests.cpp
@@ -576,7 +576,7 @@
   ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
   auto BarURI = URI::createFile(BarHeader).toString();
   Symbol Sym = cls("ns::X");
-  Sym.CanonicalDeclaration.FileURI = BarURI;
+  Sym.CanonicalDeclaration.setFileURI(BarURI.c_str());
   Sym.IncludeHeaders.emplace_back(BarURI, 1);
   // Shoten include path based on search dirctory and insert.
   auto Results = completions(Server,
@@ -607,8 +607,8 @@
   Symbol SymY = cls("ns::Y");
   std::string BarHeader = testPath("bar.h");
   auto BarURI = URI::createFile(BarHeader).toString();
-  SymX.CanonicalDeclaration.FileURI = BarURI;
-  SymY.CanonicalDeclaration.FileURI = BarURI;
+  SymX.CanonicalDeclaration.setFileURI(BarURI.c_str());
+  SymY.CanonicalDeclaration.setFileURI(BarURI.c_str());
   SymX.IncludeHeaders.emplace_back("<bar>", 1);
   SymY.IncludeHeaders.emplace_back("<bar>", 1);
   // Shoten include path based on search dirctory and insert.
@@ -1229,7 +1229,7 @@
 
   // Differences in header-to-insert suppress bundling.
   std::string DeclFile = URI::createFile(testPath("foo")).toString();
-  NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile;
+  NoArgsGFunc.CanonicalDeclaration.setFileURI(DeclFile.c_str());
   NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1);
   EXPECT_THAT(
       completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
@@ -1936,7 +1936,7 @@
 TEST(CompletionTest, InsertTheMostPopularHeader) {
   std::string DeclFile = URI::createFile(testPath("foo")).toString();
   Symbol sym = func("Func");
-  sym.CanonicalDeclaration.FileURI = DeclFile;
+  sym.CanonicalDeclaration.setFileURI(DeclFile.c_str());
   sym.IncludeHeaders.emplace_back("\"foo.h\"", 2);
   sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000);
 
@@ -1958,7 +1958,7 @@
 
   std::string DeclFile = URI::createFile(testPath("foo")).toString();
   Symbol sym = func("Func");
-  sym.CanonicalDeclaration.FileURI = DeclFile;
+  sym.CanonicalDeclaration.setFileURI(DeclFile.c_str());
   sym.IncludeHeaders.emplace_back("\"foo.h\"", 2);
   sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000);
 
Index: clangd/index/dex/dexp/Dexp.cpp
===================================================================
--- clangd/index/dex/dexp/Dexp.cpp
+++ clangd/index/dex/dexp/Dexp.cpp
@@ -230,7 +230,7 @@
     RefRequest.IDs.insert(IDs.begin(), IDs.end());
     llvm::Regex RegexFilter(Filter);
     Index->refs(RefRequest, [&RegexFilter](const clang::clangd::Ref &R) {
-      auto U = clang::clangd::URI::parse(R.Location.FileURI);
+      auto U = clang::clangd::URI::parse(R.Location.fileURI());
       if (!U) {
         llvm::outs() << U.takeError();
         return;
Index: clangd/index/dex/Dex.cpp
===================================================================
--- clangd/index/dex/Dex.cpp
+++ clangd/index/dex/Dex.cpp
@@ -52,9 +52,9 @@
   std::vector<Token> Result = generateIdentifierTrigrams(Sym.Name);
   Result.emplace_back(Token::Kind::Scope, Sym.Scope);
   // Skip token generation for symbols with unknown declaration location.
-  if (!Sym.CanonicalDeclaration.FileURI.empty())
+  if (!Sym.CanonicalDeclaration.fileURI().empty())
     for (const auto &ProximityURI :
-         generateProximityURIs(Sym.CanonicalDeclaration.FileURI))
+         generateProximityURIs(Sym.CanonicalDeclaration.fileURI()))
       Result.emplace_back(Token::Kind::ProximityURI, ProximityURI);
   if (Sym.Flags & Symbol::IndexedForCodeCompletion)
     Result.emplace_back(RestrictedForCodeCompletion);
Index: clangd/index/YAMLSerialization.cpp
===================================================================
--- clangd/index/YAMLSerialization.cpp
+++ clangd/index/YAMLSerialization.cpp
@@ -20,8 +20,10 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/StringSaver.h"
 #include "llvm/Support/YAMLTraits.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
@@ -126,9 +128,26 @@
   YPosition P;
 };
 
+struct NormalizedFileURI {
+  NormalizedFileURI(IO &) {}
+  NormalizedFileURI(IO &, const char *FileURI) { URI = FileURI; }
+
+  const char *denormalize(IO &IO) {
+    assert(IO.getContext() &&
+           "Expecting an UniqueStringSaver to allocate data");
+    return static_cast<llvm::UniqueStringSaver *>(IO.getContext())
+        ->save(URI)
+        .data();
+  }
+
+  std::string URI;
+};
+
 template <> struct MappingTraits<SymbolLocation> {
   static void mapping(IO &IO, SymbolLocation &Value) {
-    IO.mapRequired("FileURI", Value.FileURI);
+    MappingNormalization<NormalizedFileURI, const char *> NFile(IO,
+                                                                Value.FileURI);
+    IO.mapRequired("FileURI", NFile->URI);
     MappingNormalization<NormalizedPosition, SymbolLocation::Position> NStart(
         IO, Value.Start);
     IO.mapRequired("Start", NStart->P);
@@ -290,7 +309,9 @@
 Expected<IndexFileIn> readYAML(StringRef Data) {
   SymbolSlab::Builder Symbols;
   RefSlab::Builder Refs;
-  llvm::yaml::Input Yin(Data);
+  llvm::BumpPtrAllocator Arena;
+  llvm::UniqueStringSaver Strings(Arena);
+  llvm::yaml::Input Yin(Data, &Strings);
   do {
     VariantEntry Variant;
     Yin >> Variant;
Index: clangd/index/SymbolCollector.cpp
===================================================================
--- clangd/index/SymbolCollector.cpp
+++ clangd/index/SymbolCollector.cpp
@@ -213,7 +213,7 @@
     return llvm::None;
   FileURIStorage = std::move(*U);
   SymbolLocation Result;
-  Result.FileURI = FileURIStorage;
+  Result.setFileURI(FileURIStorage.c_str());
   auto Range = getTokenRange(TokLoc, SM, LangOpts);
   Result.Start = Range.first;
   Result.End = Range.second;
@@ -508,7 +508,7 @@
             Ref R;
             R.Location.Start = Range.first;
             R.Location.End = Range.second;
-            R.Location.FileURI = *FileURI;
+            R.Location.setFileURI(FileURI->c_str());
             R.Kind = toRefKind(LocAndRole.second);
             Refs.insert(*ID, R);
           }
Index: clangd/index/Serialization.cpp
===================================================================
--- clangd/index/Serialization.cpp
+++ clangd/index/Serialization.cpp
@@ -230,16 +230,16 @@
 
 void writeLocation(const SymbolLocation &Loc, const StringTableOut &Strings,
                    raw_ostream &OS) {
-  writeVar(Strings.index(Loc.FileURI), OS);
+  writeVar(Strings.index(Loc.fileURI()), OS);
   for (const auto &Endpoint : {Loc.Start, Loc.End}) {
     writeVar(Endpoint.line(), OS);
     writeVar(Endpoint.column(), OS);
   }
 }
 
 SymbolLocation readLocation(Reader &Data, ArrayRef<StringRef> Strings) {
   SymbolLocation Loc;
-  Loc.FileURI = Data.consumeString(Strings);
+  Loc.setFileURI(Data.consumeString(Strings).data());
   for (auto *Endpoint : {&Loc.Start, &Loc.End}) {
     Endpoint->setLine(Data.consumeVar());
     Endpoint->setColumn(Data.consumeVar());
@@ -401,16 +401,23 @@
 
   StringTableOut Strings;
   std::vector<Symbol> Symbols;
+  auto InternFileURI = [&](SymbolLocation &Loc) {
+      llvm::StringRef File = Loc.fileURI();
+      Strings.intern(File);
+      Loc.setFileURI(File.data());
+  };
   for (const auto &Sym : *Data.Symbols) {
     Symbols.emplace_back(Sym);
     visitStrings(Symbols.back(), [&](StringRef &S) { Strings.intern(S); });
+    InternFileURI(Symbols.back().CanonicalDeclaration);
+    InternFileURI(Symbols.back().Definition);
   }
   std::vector<std::pair<SymbolID, std::vector<Ref>>> Refs;
   if (Data.Refs) {
     for (const auto &Sym : *Data.Refs) {
       Refs.emplace_back(Sym);
       for (auto &Ref : Refs.back().second)
-        Strings.intern(Ref.Location.FileURI);
+        InternFileURI(Ref.Location);
     }
   }
 
Index: clangd/index/Merge.cpp
===================================================================
--- clangd/index/Merge.cpp
+++ clangd/index/Merge.cpp
@@ -98,11 +98,11 @@
   // Ultimately we should explicit check which index has the file instead.
   llvm::StringSet<> DynamicIndexFileURIs;
   Dynamic->refs(Req, [&](const Ref &O) {
-    DynamicIndexFileURIs.insert(O.Location.FileURI);
+    DynamicIndexFileURIs.insert(O.Location.fileURI());
     Callback(O);
   });
   Static->refs(Req, [&](const Ref &O) {
-    if (!DynamicIndexFileURIs.count(O.Location.FileURI))
+    if (!DynamicIndexFileURIs.count(O.Location.fileURI()))
       Callback(O);
   });
 }
@@ -116,7 +116,7 @@
   // Merge include headers only if both have definitions or both have no
   // definition; otherwise, only accumulate references of common includes.
   bool MergeIncludes =
-      L.Definition.FileURI.empty() == R.Definition.FileURI.empty();
+      L.Definition.fileURI().empty() == R.Definition.fileURI().empty();
   Symbol S = PreferR ? R : L;        // The target symbol we're merging into.
   const Symbol &O = PreferR ? L : R; // The "other" less-preferred symbol.
 
Index: clangd/index/Index.h
===================================================================
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -57,14 +57,22 @@
     uint32_t Column : 12; // 0-based
   };
 
-  // The URI of the source file where a symbol occurs.
-  llvm::StringRef FileURI;
+  llvm::StringRef fileURI() const { return FileURI; }
+  void setFileURI(const char *F) { FileURI = F; }
 
   /// The symbol range, using half-open range [Start, End).
   Position Start;
   Position End;
 
-  explicit operator bool() const { return !FileURI.empty(); }
+  explicit operator bool() const { return !fileURI().empty(); }
+
+  // The URI of the source file where a symbol occurs.
+  // The string must be null-terminated.
+  //
+  // FIXME: make it to private, the main blocker: YAMLSerailization needs to
+  // access this member, and we don't want to introduce YAML dependency into
+  // this file (declaring a friend class).
+  const char *FileURI = nullptr;
 };
 inline bool operator==(const SymbolLocation::Position &L,
                        const SymbolLocation::Position &R) {
@@ -77,12 +85,12 @@
          std::make_tuple(R.line(), R.column());
 }
 inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) {
-  return std::tie(L.FileURI, L.Start, L.End) ==
-         std::tie(R.FileURI, R.Start, R.End);
+  return std::make_tuple(L.fileURI(), L.Start, L.End) ==
+         std::make_tuple(R.fileURI(), R.Start, R.End);
 }
 inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) {
-  return std::tie(L.FileURI, L.Start, L.End) <
-         std::tie(R.FileURI, R.Start, R.End);
+  return std::make_tuple(L.fileURI(), L.Start, L.End) <
+         std::make_tuple(R.fileURI(), R.Start, R.End);
 }
 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
 
@@ -286,8 +294,6 @@
 template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
   CB(S.Name);
   CB(S.Scope);
-  CB(S.CanonicalDeclaration.FileURI);
-  CB(S.Definition.FileURI);
   CB(S.Signature);
   CB(S.CompletionSnippetSuffix);
   CB(S.Documentation);
Index: clangd/index/Index.cpp
===================================================================
--- clangd/index/Index.cpp
+++ clangd/index/Index.cpp
@@ -39,7 +39,7 @@
 raw_ostream &operator<<(raw_ostream &OS, const SymbolLocation &L) {
   if (!L)
     return OS << "(none)";
-  return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column()
+  return OS << L.fileURI() << "[" << L.Start.line() << ":" << L.Start.column()
             << "-" << L.End.line() << ":" << L.End.column() << ")";
 }
 
@@ -113,6 +113,9 @@
 // Copy the underlying data of the symbol into the owned arena.
 static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
   visitStrings(S, [&](StringRef &V) { V = Strings.save(V); });
+  S.CanonicalDeclaration.setFileURI(
+      Strings.save(S.CanonicalDeclaration.fileURI()).data());
+  S.Definition.setFileURI(Strings.save(S.Definition.fileURI()).data());
 }
 
 void SymbolSlab::Builder::insert(const Symbol &S) {
@@ -162,7 +165,8 @@
 void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) {
   auto &M = Refs[ID];
   M.push_back(S);
-  M.back().Location.FileURI = UniqueStrings.save(M.back().Location.FileURI);
+  M.back().Location.setFileURI(
+      UniqueStrings.save(M.back().Location.fileURI()).data());
 }
 
 RefSlab RefSlab::Builder::build() && {
Index: clangd/XRefs.cpp
===================================================================
--- clangd/XRefs.cpp
+++ clangd/XRefs.cpp
@@ -50,14 +50,14 @@
                                        llvm::StringRef HintPath) {
   if (!Loc)
     return llvm::None;
-  auto Uri = URI::parse(Loc.FileURI);
+  auto Uri = URI::parse(Loc.fileURI());
   if (!Uri) {
-    log("Could not parse URI: {0}", Loc.FileURI);
+    log("Could not parse URI: {0}", Loc.fileURI());
     return llvm::None;
   }
   auto Path = URI::resolve(*Uri, HintPath);
   if (!Path) {
-    log("Could not resolve URI: {0}", Loc.FileURI);
+    log("Could not resolve URI: {0}", Loc.fileURI());
     return llvm::None;
   }
   Location LSPLoc;
Index: clangd/Quality.cpp
===================================================================
--- clangd/Quality.cpp
+++ clangd/Quality.cpp
@@ -278,7 +278,7 @@
   // FIXME: Index results always assumed to be at global scope. If Scope becomes
   // relevant to non-completion requests, we should recognize class members etc.
 
-  SymbolURI = IndexResult.CanonicalDeclaration.FileURI;
+  SymbolURI = IndexResult.CanonicalDeclaration.fileURI();
   SymbolScope = IndexResult.Scope;
   IsInstanceMember |= isInstanceMember(IndexResult.SymInfo);
 }
Index: clangd/FindSymbols.cpp
===================================================================
--- clangd/FindSymbols.cpp
+++ clangd/FindSymbols.cpp
@@ -124,10 +124,10 @@
   Index->fuzzyFind(Req, [HintPath, &Top, &Filter](const Symbol &Sym) {
     // Prefer the definition over e.g. a function declaration in a header
     auto &CD = Sym.Definition ? Sym.Definition : Sym.CanonicalDeclaration;
-    auto Uri = URI::parse(CD.FileURI);
+    auto Uri = URI::parse(CD.fileURI());
     if (!Uri) {
       log("Workspace symbol: Could not parse URI '{0}' for symbol '{1}'.",
-          CD.FileURI, Sym.Name);
+          CD.fileURI(), Sym.Name);
       return;
     }
     auto Path = URI::resolve(*Uri, HintPath);
Index: clangd/CodeComplete.cpp
===================================================================
--- clangd/CodeComplete.cpp
+++ clangd/CodeComplete.cpp
@@ -343,7 +343,7 @@
     auto Inserted =
         [&](StringRef Header) -> Expected<std::pair<std::string, bool>> {
       auto ResolvedDeclaring =
-          toHeaderFile(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
+          toHeaderFile(C.IndexResult->CanonicalDeclaration.fileURI(), FileName);
       if (!ResolvedDeclaring)
         return ResolvedDeclaring.takeError();
       auto ResolvedInserted = toHeaderFile(Header, FileName);
@@ -365,7 +365,7 @@
       } else
         log("Failed to generate include insertion edits for adding header "
             "(FileURI='{0}', IncludeHeader='{1}') into {2}",
-            C.IndexResult->CanonicalDeclaration.FileURI, Inc, FileName);
+            C.IndexResult->CanonicalDeclaration.fileURI(), Inc, FileName);
     }
     // Prefer includes that do not need edits (i.e. already exist).
     std::stable_partition(Completion.Includes.begin(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to