[PATCH] D77385: [clangd] Add index inspection helper tool

2020-04-03 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

Yeah, I think adding a dump/export command to dexp would be nice.
We'd have to make dexp keep the parsed input file around, or just the path and 
reopen it when the command is issued, but that seems OK to me.

(One of the costs of adding a new binary is you have to at least build it to 
keep the code from rotting, and linking binaries is often the bottleneck for 
iterating with `check-clangd`)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77385/new/

https://reviews.llvm.org/D77385



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77385: [clangd] Add index inspection helper tool

2020-04-03 Thread Mark Nauwelaerts via Phabricator via cfe-commits
mnauw added a comment.

Thanks for having a look at this patch.  My use-case/goal would be to have a 
way to run/do a command that reads some index and dumps it (in e.g. YAML) to 
(e.g.) stdout. That way it can be inspected/viewed all at once by plain viewer. 
 And not only symbols, refs, but also recorded paths (that form the 
include-graph).  The latter in particular was/is useful when investigating some 
not-entirely-consistent symlink-resolution issues.  The goal is not necessarily 
a separate binary, so if it's ok to extend dexp to achieve the former (e.g. by 
adding option(s)) then I can also update to patch that way accordingly.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77385/new/

https://reviews.llvm.org/D77385



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77385: [clangd] Add index inspection helper tool

2020-04-03 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

Thanks for the patch!

We already have one introspection tool called `dexp` have you give it a try? It 
can read both RIFF and YAML and allows you to run queries on the index.

If it is not enough for your use case, can you describe it a little more? Maybe 
it would be easier to extend dexp to accommodate your use case instead of 
introducing a new binary.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77385/new/

https://reviews.llvm.org/D77385



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77385: [clangd] Add index inspection helper tool

2020-04-03 Thread Mark Nauwelaerts via Phabricator via cfe-commits
mnauw created this revision.
mnauw added a reviewer: sammccall.
mnauw added a project: clang-tools-extra.
Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, 
ilya-biryukov, mgorny.
Herald added a project: clang.

Add a standalone executable that can read indexed data and output in requested 
format.

Typical use is to read RIFF data to dump to YAML for inspection of indexed 
data.  The YAML (de)serialization has also been extended to aid in this regard.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77385

Files:
  clang-tools-extra/clangd/CMakeLists.txt
  clang-tools-extra/clangd/index-dump/CMakeLists.txt
  clang-tools-extra/clangd/index-dump/IndexDumpMain.cpp
  clang-tools-extra/clangd/index/YAMLSerialization.cpp
  clang-tools-extra/clangd/test/CMakeLists.txt

Index: clang-tools-extra/clangd/test/CMakeLists.txt
===
--- clang-tools-extra/clangd/test/CMakeLists.txt
+++ clang-tools-extra/clangd/test/CMakeLists.txt
@@ -13,6 +13,7 @@
   ClangdTests
   # No tests for these, but we should still make sure they build.
   clangd-indexer
+  clangd-index-dump
   dexp
   )
 
Index: clang-tools-extra/clangd/index/YAMLSerialization.cpp
===
--- clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -41,6 +41,8 @@
   llvm::Optional Symbol;
   llvm::Optional Refs;
   llvm::Optional Relation;
+  llvm::Optional Source;
+  llvm::Optional Cmd;
 };
 // A class helps YAML to serialize the 32-bit encoded position (Line),
 // as YAMLIO can't directly map bitfields.
@@ -53,6 +55,9 @@
 namespace llvm {
 namespace yaml {
 
+using clang::clangd::FileDigest;
+using clang::clangd::IncludeGraph;
+using clang::clangd::IncludeGraphNode;
 using clang::clangd::Ref;
 using clang::clangd::RefKind;
 using clang::clangd::Relation;
@@ -65,6 +70,7 @@
 using clang::index::SymbolKind;
 using clang::index::SymbolLanguage;
 using clang::index::SymbolRole;
+using clang::tooling::CompileCommand;
 
 // Helper to (de)serialize the SymbolID. We serialize it as a hex string.
 struct NormalizedSymbolID {
@@ -308,6 +314,76 @@
   }
 };
 
+struct NormalizedSourceFlag {
+  NormalizedSourceFlag(IO &) {}
+  NormalizedSourceFlag(IO &, IncludeGraphNode::SourceFlag O) {
+Flag = static_cast(O);
+  }
+
+  IncludeGraphNode::SourceFlag denormalize(IO &) {
+return static_cast(Flag);
+  }
+
+  uint8_t Flag = 0;
+};
+
+struct NormalizedFileDigest {
+  NormalizedFileDigest(IO &) {}
+  NormalizedFileDigest(IO &, const FileDigest ) {
+HexString = llvm::toHex(Digest);
+  }
+
+  static FileDigest fromRaw(llvm::StringRef Raw) {
+FileDigest Digest;
+assert(Raw.size() == sizeof(Digest));
+memcpy(Digest.data(), Raw.data(), Raw.size());
+return Digest;
+  }
+
+  static llvm::Expected fromStr(llvm::StringRef Str) {
+const int RawSize = sizeof(FileDigest);
+if (Str.size() != RawSize * 2)
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Bad ID length");
+for (char C : Str)
+  if (!llvm::isHexDigit(C))
+return llvm::createStringError(llvm::inconvertibleErrorCode(),
+   "Bad hex ID");
+return fromRaw(llvm::fromHex(Str));
+  }
+
+  FileDigest denormalize(IO ) {
+auto Digest = fromStr(HexString);
+if (!Digest) {
+  I.setError(llvm::toString(Digest.takeError()));
+  return FileDigest();
+}
+return *Digest;
+  }
+
+  std::string HexString;
+};
+
+template <> struct MappingTraits {
+  static void mapping(IO , IncludeGraphNode ) {
+IO.mapRequired("URI", Node.URI);
+MappingNormalization
+NSourceFlag(IO, Node.Flags);
+IO.mapRequired("Flags", NSourceFlag->Flag);
+MappingNormalization NDigest(IO,
+   Node.Digest);
+IO.mapRequired("Digest", NDigest->HexString);
+IO.mapRequired("DirectIncludes", Node.DirectIncludes);
+  }
+};
+
+template <> struct MappingTraits {
+  static void mapping(IO , CompileCommand ) {
+IO.mapRequired("Directory", Cmd.Directory);
+IO.mapRequired("CommandLine", Cmd.CommandLine);
+  }
+};
+
 template <> struct MappingTraits {
   static void mapping(IO , VariantEntry ) {
 if (IO.mapTag("!Symbol", Variant.Symbol.hasValue())) {
@@ -322,6 +398,14 @@
   if (!IO.outputting())
 Variant.Relation.emplace();
   MappingTraits::mapping(IO, *Variant.Relation);
+} else if (IO.mapTag("!Source", Variant.Source.hasValue())) {
+  if (!IO.outputting())
+Variant.Source.emplace();
+  MappingTraits::mapping(IO, *Variant.Source);
+} else if (IO.mapTag("!Cmd", Variant.Cmd.hasValue())) {
+  if (!IO.outputting())
+Variant.Cmd.emplace();
+  MappingTraits::mapping(IO, *Variant.Cmd);
 }
   }
 };
@@ -351,6 +435,18 @@
   Entry.Relation = R;