@@ -41,6 +41,8 @@ struct VariantEntry {
41
41
llvm::Optional<clang::clangd::Symbol> Symbol;
42
42
llvm::Optional<RefBundle> Refs;
43
43
llvm::Optional<clang::clangd::Relation> Relation;
44
+ llvm::Optional<clang::clangd::IncludeGraphNode> Source;
45
+ llvm::Optional<clang::tooling::CompileCommand> Cmd;
44
46
};
45
47
// A class helps YAML to serialize the 32-bit encoded position (Line&Column),
46
48
// as YAMLIO can't directly map bitfields.
@@ -49,10 +51,16 @@ struct YPosition {
49
51
uint32_t Column;
50
52
};
51
53
54
+ // avoid ODR violation of specialization for non-owned CompileCommand
55
+ struct CompileCommandYAML : clang::tooling::CompileCommand {};
56
+
52
57
} // namespace
53
58
namespace llvm {
54
59
namespace yaml {
55
60
61
+ using clang::clangd::FileDigest;
62
+ using clang::clangd::IncludeGraph;
63
+ using clang::clangd::IncludeGraphNode;
56
64
using clang::clangd::Ref;
57
65
using clang::clangd::RefKind;
58
66
using clang::clangd::Relation;
@@ -65,6 +73,7 @@ using clang::index::SymbolInfo;
65
73
using clang::index::SymbolKind;
66
74
using clang::index::SymbolLanguage;
67
75
using clang::index::SymbolRole;
76
+ using clang::tooling::CompileCommand;
68
77
69
78
// Helper to (de)serialize the SymbolID. We serialize it as a hex string.
70
79
struct NormalizedSymbolID {
@@ -308,6 +317,59 @@ template <> struct MappingTraits<Relation> {
308
317
}
309
318
};
310
319
320
+ struct NormalizedSourceFlag {
321
+ NormalizedSourceFlag (IO &) {}
322
+ NormalizedSourceFlag (IO &, IncludeGraphNode::SourceFlag O) {
323
+ Flag = static_cast <uint8_t >(O);
324
+ }
325
+
326
+ IncludeGraphNode::SourceFlag denormalize (IO &) {
327
+ return static_cast <IncludeGraphNode::SourceFlag>(Flag);
328
+ }
329
+
330
+ uint8_t Flag = 0 ;
331
+ };
332
+
333
+ struct NormalizedFileDigest {
334
+ NormalizedFileDigest (IO &) {}
335
+ NormalizedFileDigest (IO &, const FileDigest &Digest) {
336
+ HexString = llvm::toHex (Digest);
337
+ }
338
+
339
+ FileDigest denormalize (IO &I) {
340
+ FileDigest Digest;
341
+ if (HexString.size () == Digest.size () * 2 &&
342
+ llvm::all_of (HexString, llvm::isHexDigit)) {
343
+ memcpy (Digest.data (), llvm::fromHex (HexString).data (), Digest.size ());
344
+ } else {
345
+ I.setError (std::string (" Bad hex file digest: " ) + HexString);
346
+ }
347
+ return Digest;
348
+ }
349
+
350
+ std::string HexString;
351
+ };
352
+
353
+ template <> struct MappingTraits <IncludeGraphNode> {
354
+ static void mapping (IO &IO, IncludeGraphNode &Node) {
355
+ IO.mapRequired (" URI" , Node.URI );
356
+ MappingNormalization<NormalizedSourceFlag, IncludeGraphNode::SourceFlag>
357
+ NSourceFlag (IO, Node.Flags);
358
+ IO.mapRequired (" Flags" , NSourceFlag->Flag );
359
+ MappingNormalization<NormalizedFileDigest, FileDigest> NDigest (IO,
360
+ Node.Digest );
361
+ IO.mapRequired (" Digest" , NDigest->HexString );
362
+ IO.mapRequired (" DirectIncludes" , Node.DirectIncludes );
363
+ }
364
+ };
365
+
366
+ template <> struct MappingTraits <CompileCommandYAML> {
367
+ static void mapping (IO &IO, CompileCommandYAML &Cmd) {
368
+ IO.mapRequired (" Directory" , Cmd.Directory );
369
+ IO.mapRequired (" CommandLine" , Cmd.CommandLine );
370
+ }
371
+ };
372
+
311
373
template <> struct MappingTraits <VariantEntry> {
312
374
static void mapping (IO &IO, VariantEntry &Variant) {
313
375
if (IO.mapTag (" !Symbol" , Variant.Symbol .hasValue ())) {
@@ -322,6 +384,15 @@ template <> struct MappingTraits<VariantEntry> {
322
384
if (!IO.outputting ())
323
385
Variant.Relation .emplace ();
324
386
MappingTraits<Relation>::mapping (IO, *Variant.Relation );
387
+ } else if (IO.mapTag (" !Source" , Variant.Source .hasValue ())) {
388
+ if (!IO.outputting ())
389
+ Variant.Source .emplace ();
390
+ MappingTraits<IncludeGraphNode>::mapping (IO, *Variant.Source );
391
+ } else if (IO.mapTag (" !Cmd" , Variant.Cmd .hasValue ())) {
392
+ if (!IO.outputting ())
393
+ Variant.Cmd .emplace ();
394
+ MappingTraits<CompileCommandYAML>::mapping (
395
+ IO, static_cast <CompileCommandYAML &>(*Variant.Cmd ));
325
396
}
326
397
}
327
398
};
@@ -351,6 +422,18 @@ void writeYAML(const IndexFileOut &O, llvm::raw_ostream &OS) {
351
422
Entry.Relation = R;
352
423
Yout << Entry;
353
424
}
425
+ if (O.Sources ) {
426
+ for (const auto &Source : *O.Sources ) {
427
+ VariantEntry Entry;
428
+ Entry.Source = Source.getValue ();
429
+ Yout << Entry;
430
+ }
431
+ }
432
+ if (O.Cmd ) {
433
+ VariantEntry Entry;
434
+ Entry.Cmd = *O.Cmd ;
435
+ Yout << Entry;
436
+ }
354
437
}
355
438
356
439
llvm::Expected<IndexFileIn> readYAML (llvm::StringRef Data) {
@@ -361,6 +444,8 @@ llvm::Expected<IndexFileIn> readYAML(llvm::StringRef Data) {
361
444
Arena; // store the underlying data of Position::FileURI.
362
445
llvm::UniqueStringSaver Strings (Arena);
363
446
llvm::yaml::Input Yin (Data, &Strings);
447
+ IncludeGraph Sources;
448
+ llvm::Optional<tooling::CompileCommand> Cmd;
364
449
while (Yin.setCurrentDocument ()) {
365
450
llvm::yaml::EmptyContext Ctx;
366
451
VariantEntry Variant;
@@ -375,13 +460,27 @@ llvm::Expected<IndexFileIn> readYAML(llvm::StringRef Data) {
375
460
Refs.insert (Variant.Refs ->first , Ref);
376
461
if (Variant.Relation )
377
462
Relations.insert (*Variant.Relation );
463
+ if (Variant.Source ) {
464
+ auto &IGN = Variant.Source .getValue ();
465
+ auto Entry = Sources.try_emplace (IGN.URI ).first ;
466
+ Entry->getValue () = std::move (IGN);
467
+ // Fixup refs to refer to map keys which will live on
468
+ Entry->getValue ().URI = Entry->getKey ();
469
+ for (auto &Include : Entry->getValue ().DirectIncludes )
470
+ Include = Sources.try_emplace (Include).first ->getKey ();
471
+ }
472
+ if (Variant.Cmd )
473
+ Cmd = *Variant.Cmd ;
378
474
Yin.nextDocument ();
379
475
}
380
476
381
477
IndexFileIn Result;
382
478
Result.Symbols .emplace (std::move (Symbols).build ());
383
479
Result.Refs .emplace (std::move (Refs).build ());
384
480
Result.Relations .emplace (std::move (Relations).build ());
481
+ if (Sources.size ())
482
+ Result.Sources = std::move (Sources);
483
+ Result.Cmd = std::move (Cmd);
385
484
return std::move (Result);
386
485
}
387
486
0 commit comments