hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: ilya-biryukov, mgorny, klimek.

This will be used together with https://reviews.llvm.org/D40548 for the global 
index source (experimental).


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41178

Files:
  clangd/CMakeLists.txt
  clangd/index/Index.h
  clangd/index/SymbolFromYAML.cpp
  clangd/index/SymbolFromYAML.h
  unittests/clangd/SymbolCollectorTests.cpp

Index: unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "index/SymbolCollector.h"
+#include "index/SymbolFromYAML.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
@@ -103,6 +104,12 @@
   runSymbolCollector(Header, Main);
   EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Foo"), QName("Foo::f"),
                                             QName("f1"), QName("f2")));
+
+  std::string YAMLContent = SymbolToYAML(Symbols);
+  auto SymbolsReadFromYAML = SymbolFromYAML(YAMLContent);
+  EXPECT_THAT(SymbolsReadFromYAML,
+              UnorderedElementsAre(QName("Foo"), QName("Foo::f"), QName("f1"),
+                                   QName("f2")));
 }
 
 } // namespace
Index: clangd/index/SymbolFromYAML.h
===================================================================
--- /dev/null
+++ clangd/index/SymbolFromYAML.h
@@ -0,0 +1,28 @@
+//===--- SymbolFromYAML.h ----------------------------------------*- C++-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
+
+#include "Index.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+
+// Read symbols from a YAML-format string.
+SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent);
+
+// Convert symbols to a YAML-format string.
+std::string SymbolToYAML(const SymbolSlab& Symbols);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_FROM_YAML_H
Index: clangd/index/SymbolFromYAML.cpp
===================================================================
--- /dev/null
+++ clangd/index/SymbolFromYAML.cpp
@@ -0,0 +1,154 @@
+//===--- SymbolFromYAML.cpp --------------------------------------*- C++-*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFromYAML.h"
+
+#include "Index.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Errc.h"
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
+
+namespace llvm {
+namespace yaml {
+
+using clang::clangd::Symbol;
+using clang::clangd::SymbolID;
+using clang::clangd::SymbolLocation;
+using clang::index::SymbolInfo;
+using clang::index::SymbolLanguage;
+using clang::index::SymbolKind;
+
+// Helpers to (de)serialize the SymbolID underlying data as std::array is not
+// supported in YAML I/O.
+struct NPArray {
+  NPArray(IO &) {}
+  NPArray(IO &, std::array<uint8_t, 20> HashValue) {
+    Value = {HashValue.begin(), HashValue.end()};
+  }
+  std::array<uint8_t, 20> denormalize(IO &) {
+    assert(Value.size() == 20);
+    std::array<uint8_t, 20> Result;
+    std::copy(Value.begin(), Value.end(), Result.begin());
+    return Result;
+  }
+
+  std::vector<uint8_t> Value;
+};
+
+template <> struct MappingTraits<class SymbolID> {
+  static void mapping(IO &IO, SymbolID &ID) {
+    MappingNormalization<NPArray, std::array<uint8_t, 20>> NPArry(
+        IO, ID.HashValue);
+    IO.mapOptional("Value", NPArry->Value);
+  }
+};
+
+template <> struct MappingTraits<SymbolLocation> {
+  static void mapping(IO &IO, SymbolLocation &Value) {
+    IO.mapRequired("StartOffset", Value.StartOffset);
+    IO.mapRequired("EndOffset", Value.EndOffset);
+    IO.mapRequired("FilePath", Value.FilePath);
+  }
+};
+
+template <> struct MappingTraits<SymbolInfo> {
+  static void mapping(IO &io, SymbolInfo &SymInfo) {
+    // FIXME: expose other fields?
+    io.mapRequired("Kind", SymInfo.Kind);
+    io.mapRequired("Lang", SymInfo.Lang);
+  }
+};
+
+template<> struct MappingTraits<Symbol> {
+  static void mapping(IO &IO, Symbol &Sym) {
+    IO.mapRequired("ID", Sym.ID);
+    IO.mapRequired("QualifiedName", Sym.QualifiedName);
+    IO.mapRequired("SymInfo", Sym.SymInfo);
+    IO.mapRequired("CanonicalDeclaration", Sym.CanonicalDeclaration);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<SymbolLanguage> {
+  static void enumeration(IO &IO, SymbolLanguage &Value) {
+    IO.enumCase(Value, "C", SymbolLanguage::C);
+    IO.enumCase(Value, "Cpp", SymbolLanguage::CXX);
+    IO.enumCase(Value, "ObjC", SymbolLanguage::ObjC);
+    IO.enumCase(Value, "Swift", SymbolLanguage::Swift);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<SymbolKind> {
+  static void enumeration(IO &IO, SymbolKind &Value) {
+#define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)
+
+    DEFINE_ENUM(Unknown);
+    DEFINE_ENUM(Function);
+    DEFINE_ENUM(Module);
+    DEFINE_ENUM(Namespace);
+    DEFINE_ENUM(NamespaceAlias);
+    DEFINE_ENUM(Macro);
+    DEFINE_ENUM(Enum);
+    DEFINE_ENUM(Struct);
+    DEFINE_ENUM(Class);
+    DEFINE_ENUM(Protocol);
+    DEFINE_ENUM(Extension);
+    DEFINE_ENUM(Union);
+    DEFINE_ENUM(TypeAlias);
+    DEFINE_ENUM(Function);
+    DEFINE_ENUM(Variable);
+    DEFINE_ENUM(Field);
+    DEFINE_ENUM(EnumConstant);
+    DEFINE_ENUM(InstanceMethod);
+    DEFINE_ENUM(ClassMethod);
+    DEFINE_ENUM(StaticMethod);
+    DEFINE_ENUM(InstanceProperty);
+    DEFINE_ENUM(ClassProperty);
+    DEFINE_ENUM(StaticProperty);
+    DEFINE_ENUM(Constructor);
+    DEFINE_ENUM(Destructor);
+    DEFINE_ENUM(ConversionFunction);
+    DEFINE_ENUM(Parameter);
+    DEFINE_ENUM(Using);
+
+#undef DEFINE_ENUM
+  }
+};
+
+} // namespace yaml
+} // namespace llvm
+
+namespace clang {
+namespace clangd {
+
+SymbolSlab SymbolFromYAML(llvm::StringRef YAMLContent) {
+  std::vector<Symbol> S;
+  llvm::yaml::Input Yin(YAMLContent);
+  Yin >> S;
+  SymbolSlab Syms;
+  for (auto& Sym : S)
+    Syms.insert(std::move(Sym));
+  return Syms;
+}
+
+std::string SymbolToYAML(const SymbolSlab& Symbols) {
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  llvm::yaml::Output Yout(OS);
+  for (auto &Pair : Symbols) {
+    Symbol MutableSymbol = Pair.second;
+    Yout<< MutableSymbol;
+  }
+  return OS.str();
+}
+
+} // namespace clangd
+} // namespace clang
Index: clangd/index/Index.h
===================================================================
--- clangd/index/Index.h
+++ clangd/index/Index.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/YAMLTraits.h"
 
 #include <array>
 #include <string>
@@ -53,6 +54,7 @@
   friend llvm::hash_code hash_value(const SymbolID &ID) {
     return hash_value(ArrayRef<uint8_t>(ID.HashValue));
   }
+  friend struct llvm::yaml::MappingTraits<class SymbolID>;
 
   std::array<uint8_t, 20> HashValue;
 };
Index: clangd/CMakeLists.txt
===================================================================
--- clangd/CMakeLists.txt
+++ clangd/CMakeLists.txt
@@ -21,6 +21,7 @@
   Trace.cpp
   index/Index.cpp
   index/SymbolCollector.cpp
+  index/SymbolFromYAML.cpp
 
   LINK_LIBS
   clangAST
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to