Go to the documentation of this file.
22 #include "clang/Tooling/CompilationDatabase.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/StringSaver.h"
27 #include "llvm/Support/YAMLTraits.h"
28 #include "llvm/Support/raw_ostream.h"
36 std::pair<clang::clangd::SymbolID, std::vector<clang::clangd::Ref>>;
39 llvm::Optional<clang::clangd::Symbol> Symbol;
40 llvm::Optional<RefBundle>
Refs;
41 llvm::Optional<clang::clangd::Relation> Relation;
42 llvm::Optional<clang::clangd::IncludeGraphNode> Source;
43 llvm::Optional<clang::tooling::CompileCommand> Cmd;
53 struct CompileCommandYAML : clang::tooling::CompileCommand {};
71 using clang::index::SymbolLanguage;
72 using clang::tooling::CompileCommand;
97 Flag =
static_cast<uint8_t
>(F);
107 template <>
struct MappingTraits<YPosition> {
108 static void mapping(IO &IO, YPosition &Value) {
109 IO.mapRequired(
"Line", Value.Line);
110 IO.mapRequired(
"Column", Value.Column);
119 P.Column =
Pos.column();
125 Pos.setColumn(
P.Column);
136 assert(IO.getContext() &&
137 "Expecting an UniqueStringSaver to allocate data");
138 return static_cast<llvm::UniqueStringSaver *
>(IO.getContext())
148 MappingNormalization<NormalizedFileURI, const char *> NFile(IO,
150 IO.mapRequired(
"FileURI", NFile->URI);
151 MappingNormalization<NormalizedPosition, SymbolLocation::Position> NStart(
153 IO.mapRequired(
"Start", NStart->P);
154 MappingNormalization<NormalizedPosition, SymbolLocation::Position> NEnd(
156 IO.mapRequired(
"End", NEnd->P);
163 IO.mapRequired(
"Kind", SymInfo.Kind);
164 IO.mapRequired(
"Lang", SymInfo.Lang);
169 struct MappingTraits<
clang::clangd::Symbol::IncludeHeaderWithReferences> {
177 template <>
struct MappingTraits<
Symbol> {
179 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, Sym.
ID);
180 MappingNormalization<NormalizedSymbolFlag, Symbol::SymbolFlag> NSymbolFlag(
182 IO.mapRequired(
"ID", NSymbolID->HexString);
183 IO.mapRequired(
"Name", Sym.
Name);
184 IO.mapRequired(
"Scope", Sym.
Scope);
185 IO.mapRequired(
"SymInfo", Sym.
SymInfo);
189 IO.mapOptional(
"References", Sym.
References, 0u);
190 IO.mapOptional(
"Flags", NSymbolFlag->Flag);
191 IO.mapOptional(
"Signature", Sym.
Signature);
192 IO.mapOptional(
"TemplateSpecializationArgs",
197 IO.mapOptional(
"Type", Sym.
Type);
202 template <>
struct ScalarEnumerationTraits<SymbolLanguage> {
205 IO.enumCase(Value,
"Cpp", SymbolLanguage::CXX);
206 IO.enumCase(Value,
"ObjC", SymbolLanguage::ObjC);
207 IO.enumCase(Value,
"Swift", SymbolLanguage::Swift);
213 #define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)
248 template <>
struct MappingTraits<RefBundle> {
250 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO,
252 IO.mapRequired(
"ID", NSymbolID->HexString);
253 IO.mapRequired(
"References",
Refs.second);
266 template <>
struct MappingTraits<
Ref> {
268 MappingNormalization<NormalizedRefKind, RefKind> NKind(IO, R.
Kind);
269 IO.mapRequired(
"Kind", NKind->Kind);
270 IO.mapRequired(
"Location", R.
Location);
277 Kind =
static_cast<uint8_t
>(R);
287 MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO,
ID);
288 IO.mapRequired(
"ID", NSymbolID->HexString);
294 MappingNormalization<NormalizedSymbolRole, RelationKind> NRole(
297 IO.mapRequired(
"Predicate", NRole->Kind);
305 Flag =
static_cast<uint8_t
>(O);
323 if (
HexString.size() == Digest.size() * 2 &&
324 llvm::all_of(
HexString, llvm::isHexDigit)) {
325 memcpy(Digest.data(), llvm::fromHex(
HexString).data(), Digest.size());
327 I.setError(std::string(
"Bad hex file digest: ") +
HexString);
337 IO.mapRequired(
"URI", Node.URI);
338 MappingNormalization<NormalizedSourceFlag, IncludeGraphNode::SourceFlag>
339 NSourceFlag(IO, Node.Flags);
340 IO.mapRequired(
"Flags", NSourceFlag->Flag);
341 MappingNormalization<NormalizedFileDigest, FileDigest> NDigest(IO,
343 IO.mapRequired(
"Digest", NDigest->HexString);
344 IO.mapRequired(
"DirectIncludes", Node.DirectIncludes);
348 template <>
struct MappingTraits<CompileCommandYAML> {
349 static void mapping(IO &IO, CompileCommandYAML &Cmd) {
350 IO.mapRequired(
"Directory", Cmd.Directory);
351 IO.mapRequired(
"CommandLine", Cmd.CommandLine);
355 template <>
struct MappingTraits<VariantEntry> {
356 static void mapping(IO &IO, VariantEntry &Variant) {
357 if (IO.mapTag(
"!Symbol", Variant.Symbol.hasValue())) {
358 if (!IO.outputting())
359 Variant.Symbol.emplace();
361 }
else if (IO.mapTag(
"!Refs", Variant.Refs.hasValue())) {
362 if (!IO.outputting())
363 Variant.Refs.emplace();
365 }
else if (IO.mapTag(
"!Relations", Variant.Relation.hasValue())) {
366 if (!IO.outputting())
367 Variant.Relation.emplace();
369 }
else if (IO.mapTag(
"!Source", Variant.Source.hasValue())) {
370 if (!IO.outputting())
371 Variant.Source.emplace();
373 }
else if (IO.mapTag(
"!Cmd", Variant.Cmd.hasValue())) {
374 if (!IO.outputting())
375 Variant.Cmd.emplace();
377 IO,
static_cast<CompileCommandYAML &
>(*Variant.Cmd));
390 for (
const auto &Sym : *O.
Symbols) {
396 for (
auto &Sym : *O.
Refs) {
408 for (
const auto &Source : *O.
Sources) {
410 Entry.Source = Source.getValue();
421 llvm::Expected<IndexFileIn>
readYAML(llvm::StringRef Data,
426 llvm::BumpPtrAllocator
429 llvm::yaml::Input Yin(Data, &
Strings);
431 llvm::Optional<tooling::CompileCommand> Cmd;
432 while (Yin.setCurrentDocument()) {
433 llvm::yaml::EmptyContext
Ctx;
434 VariantEntry Variant;
435 yamlize(Yin, Variant,
true,
Ctx);
437 return llvm::errorCodeToError(Yin.error());
439 if (Variant.Symbol) {
440 Variant.Symbol->Origin = Origin;
441 Symbols.
insert(*Variant.Symbol);
444 for (
const auto &
Ref : Variant.Refs->second)
445 Refs.insert(Variant.Refs->first,
Ref);
446 if (Variant.Relation)
447 Relations.
insert(*Variant.Relation);
448 if (Variant.Source) {
449 auto &IGN = Variant.Source.getValue();
450 auto Entry = Sources.try_emplace(IGN.URI).first;
451 Entry->getValue() = std::move(IGN);
454 for (
auto &Include :
Entry->getValue().DirectIncludes)
455 Include = Sources.try_emplace(Include).first->getKey();
463 Result.Symbols.emplace(std::move(Symbols).build());
464 Result.Refs.emplace(std::move(
Refs).build());
465 Result.Relations.emplace(std::move(Relations).build());
467 Result.Sources = std::move(Sources);
468 Result.Cmd = std::move(Cmd);
469 return std::move(Result);
475 llvm::raw_string_ostream
OS(Buf);
484 RefBundle
Refs = {Data.first, Data.second};
487 llvm::raw_string_ostream
OS(Buf);
497 llvm::raw_string_ostream
OS(Buf);
508 llvm::raw_string_ostream
OS(Buf);
llvm::Expected< IndexFileIn > readYAML(llvm::StringRef, SymbolOrigin Origin)
Some operations such as code completion produce a set of candidates.
SymbolID ID
The ID of the symbol.
NormalizedSourceFlag(IO &)
RelationKind denormalize(IO &IO)
RefKind
Describes the kind of a cross-reference.
NormalizedSymbolRole(IO &)
void insert(const Relation &R)
Adds a relation to the slab.
RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
NormalizedSymbolFlag(IO &)
RefKind denormalize(IO &)
#define DEFINE_ENUM(name)
NormalizedFileDigest(IO &, const FileDigest &Digest)
Represents a relation between two symbols.
RelationSlab::Builder is a mutable container that can 'freeze' to RelationSlab.
const char * denormalize(IO &IO)
NormalizedRefKind(IO &, RefKind O)
unsigned References
The number of translation units that reference this symbol from their main file.
NormalizedFileURI(IO &, const char *FileURI)
IncludeGraphNode::SourceFlag denormalize(IO &)
NormalizedSymbolRole(IO &IO, RelationKind R)
llvm::StringRef ReturnType
Type when this symbol is used in an expression.
static void mapping(IO &IO, SymbolID &ID)
SymbolLocation Location
The source location where the symbol is named.
void writeYAML(const IndexFileOut &, llvm::raw_ostream &)
std::string toYAML(const Symbol &)
The class presents a C++ symbol, e.g.
index::SymbolInfo SymInfo
The symbol information, like symbol kind.
static void mapping(IO &IO, VariantEntry &Variant)
llvm::StringRef Name
The unqualified name of the symbol, e.g. "bar" (for ns::bar).
std::array< uint8_t, 20 > SymbolID
NormalizedSourceFlag(IO &, IncludeGraphNode::SourceFlag O)
static void mapping(IO &IO, YPosition &Value)
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
SymbolLocation CanonicalDeclaration
The location of the preferred declaration of the symbol.
NormalizedPosition(IO &, const Position &Pos)
Position denormalize(IO &)
llvm::StringRef CompletionSnippetSuffix
What to insert when completing this symbol, after the symbol name.
static void mapping(IO &IO, Ref &R)
FileDigest denormalize(IO &I)
std::vector< llvm::StringRef > Strings
Represents a symbol occurrence in the source file.
static void mapping(IO &IO, Symbol &Sym)
const tooling::CompileCommand * Cmd
static void mapping(IO &IO, SymbolInfo &SymInfo)
llvm::StringRef TemplateSpecializationArgs
Argument list in human-readable format, will be displayed to help disambiguate between different spec...
std::array< uint8_t, 8 > FileDigest
const IncludeGraph * Sources
static llvm::Expected< SymbolID > fromStr(llvm::StringRef)
static void mapping(IO &IO, SymbolLocation &Value)
llvm::StringRef Scope
The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::raw_string_ostream OS
llvm::BumpPtrAllocator Arena
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
clang::find_all_symbols::SymbolInfo SymbolInfo
NormalizedSymbolFlag(IO &, Symbol::SymbolFlag F)
llvm::StringMap< IncludeGraphNode > IncludeGraph
SymbolLocation Definition
The location of the symbol's definition, if one was found.
static void mapping(IO &IO, CompileCommandYAML &Cmd)
SymbolSlab::Builder is a mutable container that can 'freeze' to SymbolSlab.
static void mapping(IO &IO, IncludeGraphNode &Node)
Symbol::SymbolFlag denormalize(IO &)
static void enumeration(IO &IO, SymbolKind &Value)
static void enumeration(IO &IO, SymbolLanguage &Value)
NormalizedSymbolID(IO &, const SymbolID &ID)
llvm::StringRef Signature
A brief description of the symbol that can be appended in the completion candidate list.
llvm::StringRef Type
Raw representation of the OpaqueType of the symbol, used for scoring purposes.
llvm::SmallVector< IncludeHeaderWithReferences, 1 > IncludeHeaders
One Symbol can potentially be included via different headers.
const SymbolSlab * Symbols
llvm::StringRef Documentation
Documentation including comment for the symbol declaration.
NormalizedFileDigest(IO &)
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
static void mapping(IO &IO, Relation &Relation)
SymbolID denormalize(IO &I)
static void mapping(IO &IO, RefBundle &Refs)
const RelationSlab * Relations