22 #include "llvm/ADT/Optional.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/Errc.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/StringSaver.h"
29 #include "llvm/Support/YAMLTraits.h"
30 #include "llvm/Support/raw_ostream.h"
38 std::pair<clang::clangd::SymbolID, std::vector<clang::clangd::Ref>>;
41 llvm::Optional<clang::clangd::Symbol> Symbol;
42 llvm::Optional<RefBundle>
Refs;
43 llvm::Optional<clang::clangd::Relation> Relation;
44 llvm::Optional<clang::clangd::IncludeGraphNode> Source;
45 llvm::Optional<clang::tooling::CompileCommand> Cmd;
55 struct CompileCommandYAML : clang::tooling::CompileCommand {};
74 using clang::index::SymbolLanguage;
75 using clang::index::SymbolRole;
76 using clang::tooling::CompileCommand;
101 Flag = static_cast<uint8_t>(F);
105 return static_cast<Symbol::SymbolFlag>(
Flag);
114 Origin = static_cast<uint8_t>(O);
122 template <>
struct MappingTraits<YPosition> {
123 static void mapping(IO &IO, YPosition &Value) {
124 IO.mapRequired(
"Line", Value.Line);
125 IO.mapRequired(
"Column", Value.Column);
151 assert(IO.getContext() &&
152 "Expecting an UniqueStringSaver to allocate data");
153 return static_cast<llvm::UniqueStringSaver *>(IO.getContext())
163 MappingNormalization<NormalizedFileURI, const char *> NFile(IO,
165 IO.mapRequired(
"FileURI", NFile->URI);
166 MappingNormalization<NormalizedPosition, SymbolLocation::Position> NStart(
168 IO.mapRequired(
"Start", NStart->P);
169 MappingNormalization<NormalizedPosition, SymbolLocation::Position> NEnd(
171 IO.mapRequired(
"End", NEnd->P);
178 io.mapRequired(
"Kind", SymInfo.Kind);
179 io.mapRequired(
"Lang", SymInfo.Lang);
184 struct MappingTraits<
clang::clangd::Symbol::IncludeHeaderWithReferences> {
192 template <>
struct MappingTraits<
Symbol> {
194 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, Sym.
ID);
195 MappingNormalization<NormalizedSymbolFlag, Symbol::SymbolFlag> NSymbolFlag(
197 MappingNormalization<NormalizedSymbolOrigin, SymbolOrigin> NSymbolOrigin(
199 IO.mapRequired(
"ID", NSymbolID->HexString);
200 IO.mapRequired(
"Name", Sym.
Name);
201 IO.mapRequired(
"Scope", Sym.
Scope);
202 IO.mapRequired(
"SymInfo", Sym.
SymInfo);
206 IO.mapOptional(
"References", Sym.
References, 0u);
207 IO.mapOptional(
"Origin", NSymbolOrigin->Origin);
208 IO.mapOptional(
"Flags", NSymbolFlag->Flag);
209 IO.mapOptional(
"Signature", Sym.
Signature);
210 IO.mapOptional(
"TemplateSpecializationArgs",
215 IO.mapOptional(
"Type", Sym.
Type);
220 template <>
struct ScalarEnumerationTraits<SymbolLanguage> {
222 IO.enumCase(Value,
"C", SymbolLanguage::C);
223 IO.enumCase(Value,
"Cpp", SymbolLanguage::CXX);
224 IO.enumCase(Value,
"ObjC", SymbolLanguage::ObjC);
225 IO.enumCase(Value,
"Swift", SymbolLanguage::Swift);
231 #define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)
266 template <>
struct MappingTraits<RefBundle> {
268 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO,
270 IO.mapRequired(
"ID", NSymbolID->HexString);
271 IO.mapRequired(
"References",
Refs.second);
284 template <>
struct MappingTraits<
Ref> {
286 MappingNormalization<NormalizedRefKind, RefKind> NKind(IO, R.
Kind);
287 IO.mapRequired(
"Kind", NKind->Kind);
288 IO.mapRequired(
"Location", R.
Location);
295 Kind = static_cast<uint8_t>(R);
305 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, ID);
306 IO.mapRequired(
"ID", NSymbolID->HexString);
312 MappingNormalization<NormalizedSymbolRole, RelationKind> NRole(
315 IO.mapRequired(
"Predicate", NRole->Kind);
323 Flag = static_cast<uint8_t>(O);
327 return static_cast<IncludeGraphNode::SourceFlag>(
Flag);
341 if (
HexString.size() == Digest.size() * 2 &&
342 llvm::all_of(
HexString, llvm::isHexDigit)) {
343 memcpy(Digest.data(), llvm::fromHex(
HexString).data(), Digest.size());
345 I.setError(std::string(
"Bad hex file digest: ") +
HexString);
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,
361 IO.mapRequired(
"Digest", NDigest->HexString);
362 IO.mapRequired(
"DirectIncludes", Node.DirectIncludes);
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);
373 template <>
struct MappingTraits<VariantEntry> {
374 static void mapping(IO &IO, VariantEntry &Variant) {
375 if (IO.mapTag(
"!Symbol", Variant.Symbol.hasValue())) {
376 if (!IO.outputting())
377 Variant.Symbol.emplace();
379 }
else if (IO.mapTag(
"!Refs", Variant.Refs.hasValue())) {
380 if (!IO.outputting())
381 Variant.Refs.emplace();
383 }
else if (IO.mapTag(
"!Relations", Variant.Relation.hasValue())) {
384 if (!IO.outputting())
385 Variant.Relation.emplace();
387 }
else if (IO.mapTag(
"!Source", Variant.Source.hasValue())) {
388 if (!IO.outputting())
389 Variant.Source.emplace();
391 }
else if (IO.mapTag(
"!Cmd", Variant.Cmd.hasValue())) {
392 if (!IO.outputting())
393 Variant.Cmd.emplace();
395 IO, static_cast<CompileCommandYAML &>(*Variant.Cmd));
408 for (
const auto &Sym : *O.
Symbols) {
414 for (
auto &Sym : *O.
Refs) {
426 for (
const auto &Source : *O.
Sources) {
428 Entry.Source = Source.getValue();
439 llvm::Expected<IndexFileIn>
readYAML(llvm::StringRef Data) {
443 llvm::BumpPtrAllocator
446 llvm::yaml::Input Yin(Data, &
Strings);
448 llvm::Optional<tooling::CompileCommand> Cmd;
449 while (Yin.setCurrentDocument()) {
450 llvm::yaml::EmptyContext
Ctx;
451 VariantEntry Variant;
452 yamlize(Yin, Variant,
true,
Ctx);
454 return llvm::errorCodeToError(Yin.error());
457 Symbols.insert(*Variant.Symbol);
459 for (
const auto &
Ref : Variant.Refs->second)
460 Refs.insert(Variant.Refs->first,
Ref);
461 if (Variant.Relation)
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);
469 for (
auto &Include :
Entry->getValue().DirectIncludes)
470 Include = Sources.try_emplace(Include).first->getKey();
478 Result.Symbols.emplace(std::move(
Symbols).build());
479 Result.Refs.emplace(std::move(
Refs).build());
480 Result.Relations.emplace(std::move(Relations).build());
482 Result.Sources = std::move(Sources);
483 Result.Cmd = std::move(Cmd);
484 return std::move(Result);
490 llvm::raw_string_ostream
OS(Buf);
499 RefBundle
Refs = {Data.first, Data.second};
502 llvm::raw_string_ostream
OS(Buf);
512 llvm::raw_string_ostream
OS(Buf);
523 llvm::raw_string_ostream
OS(Buf);
531 llvm::Expected<clangd::Symbol>
535 if (YAMLInput.error())
536 return llvm::make_error<llvm::StringError>(
537 llvm::formatv(
"Unable to deserialize Symbol from YAML: {0}",
YAML),
538 llvm::inconvertibleErrorCode());
539 YAMLInput >> Deserialized;
544 llvm::UniqueStringSaver *
Strings) {
547 if (YAMLInput.error())
548 return llvm::make_error<llvm::StringError>(
549 llvm::formatv(
"Unable to deserialize Symbol from YAML: {0}",
YAML),
550 llvm::inconvertibleErrorCode());
551 YAMLInput >> Deserialized;