clang-tools 22.0.0git
JSONGenerator.cpp
Go to the documentation of this file.
1#include "Generators.h"
2#include "clang/Basic/Specifiers.h"
3#include "llvm/Support/JSON.h"
4
5using namespace llvm;
6using namespace llvm::json;
7
8namespace clang {
9namespace doc {
10
11class JSONGenerator : public Generator {
12public:
13 static const char *Format;
14
15 Error generateDocs(StringRef RootDir,
16 llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
17 const ClangDocContext &CDCtx) override;
18 Error createResources(ClangDocContext &CDCtx) override;
19 Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
20 const ClangDocContext &CDCtx) override;
21};
22
23const char *JSONGenerator::Format = "json";
24
25static void serializeInfo(const ConstraintInfo &I, Object &Obj);
26static void serializeInfo(const RecordInfo &I, Object &Obj,
27 const std::optional<StringRef> &RepositoryUrl);
28
29static void serializeReference(const Reference &Ref, Object &ReferenceObj);
30
31template <typename Container, typename SerializationFunc>
32static void serializeArray(const Container &Records, Object &Obj,
33 const std::string &Key,
34 SerializationFunc SerializeInfo);
35
36// Convenience lambda to pass to serializeArray.
37// If a serializeInfo needs a RepositoryUrl, create a local lambda that captures
38// the optional.
39static auto SerializeInfoLambda = [](const auto &Info, Object &Object) {
40 serializeInfo(Info, Object);
41};
42static auto SerializeReferenceLambda = [](const auto &Ref, Object &Object) {
43 serializeReference(Ref, Object);
44};
45
46static std::string infoTypeToString(InfoType IT) {
47 switch (IT) {
49 return "default";
51 return "namespace";
53 return "record";
55 return "function";
57 return "enum";
59 return "typedef";
61 return "concept";
63 return "variable";
65 return "friend";
66 }
67 llvm_unreachable("Unknown InfoType encountered.");
68}
69
70static json::Object
72 const std::optional<StringRef> RepositoryUrl) {
73 Object LocationObj = Object();
74 LocationObj["LineNumber"] = Loc.StartLineNumber;
75 LocationObj["Filename"] = Loc.Filename;
76
77 if (!Loc.IsFileInRootDir || !RepositoryUrl)
78 return LocationObj;
79 SmallString<128> FileURL(*RepositoryUrl);
80 sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
81 FileURL += "#" + std::to_string(Loc.StartLineNumber);
82 LocationObj["FileURL"] = FileURL;
83 return LocationObj;
84}
85
86static void insertComment(Object &Description, json::Value &Comment,
87 StringRef Key) {
88 auto DescriptionIt = Description.find(Key);
89
90 if (DescriptionIt == Description.end()) {
91 auto CommentsArray = json::Array();
92 CommentsArray.push_back(Comment);
93 Description[Key] = std::move(CommentsArray);
94 Description["Has" + Key.str()] = true;
95 } else {
96 DescriptionIt->getSecond().getAsArray()->push_back(Comment);
97 }
98}
99
100static json::Value extractTextComments(Object *ParagraphComment) {
101 if (!ParagraphComment)
102 return json::Object();
103 return *ParagraphComment->get("Children");
104}
105
106static json::Value extractVerbatimComments(json::Array VerbatimLines) {
107 json::Value TextArray = json::Array();
108 auto &TextArrayRef = *TextArray.getAsArray();
109 for (auto &Line : VerbatimLines)
110 TextArrayRef.push_back(*Line.getAsObject()
111 ->get("VerbatimBlockLineComment")
112 ->getAsObject()
113 ->get("Text"));
114
115 return TextArray;
116}
117
118static Object serializeComment(const CommentInfo &I, Object &Description) {
119 // taken from PR #142273
120 Object Obj = Object();
121
122 json::Value ChildVal = Object();
123 Object &Child = *ChildVal.getAsObject();
124
125 json::Value ChildArr = Array();
126 auto &CARef = *ChildArr.getAsArray();
127 CARef.reserve(I.Children.size());
128 for (const auto &C : I.Children)
129 CARef.emplace_back(serializeComment(*C, Description));
130
131 switch (I.Kind) {
133 Obj.insert({commentKindToString(I.Kind), I.Text});
134 return Obj;
135 }
136
138 auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
139 if (I.Name == "brief")
140 insertComment(Description, TextCommentsArray, "BriefComments");
141 else if (I.Name == "return")
142 insertComment(Description, TextCommentsArray, "ReturnComments");
143 return Obj;
144 }
145
147 json::Value ArgsArr = Array();
148 auto &ARef = *ArgsArr.getAsArray();
149 ARef.reserve(I.Args.size());
150 for (const auto &Arg : I.Args)
151 ARef.emplace_back(Arg);
152 Child.insert({"Command", I.Name});
153 Child.insert({"Args", ArgsArr});
154 Child.insert({"Children", ChildArr});
155 Obj.insert({commentKindToString(I.Kind), ChildVal});
156 return Obj;
157 }
158
161 Child.insert({"ParamName", I.ParamName});
162 Child.insert({"Direction", I.Direction});
163 Child.insert({"Explicit", I.Explicit});
164 auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
165 Child.insert({"Children", TextCommentsArray});
167 insertComment(Description, ChildVal, "ParamComments");
168 return Obj;
169 }
170
172 if (I.CloseName == "endcode") {
173 // We don't support \code language specification
174 auto TextCommentsArray = extractVerbatimComments(CARef);
175 insertComment(Description, TextCommentsArray, "CodeComments");
176 } else if (I.CloseName == "endverbatim")
177 insertComment(Description, ChildVal, "VerbatimComments");
178 return Obj;
179 }
180
183 Child.insert({"Text", I.Text});
184 Child.insert({"Children", ChildArr});
185 Obj.insert({commentKindToString(I.Kind), ChildVal});
186 return Obj;
187 }
188
190 json::Value AttrKeysArray = json::Array();
191 json::Value AttrValuesArray = json::Array();
192 auto &KeyArr = *AttrKeysArray.getAsArray();
193 auto &ValArr = *AttrValuesArray.getAsArray();
194 KeyArr.reserve(I.AttrKeys.size());
195 ValArr.reserve(I.AttrValues.size());
196 for (const auto &K : I.AttrKeys)
197 KeyArr.emplace_back(K);
198 for (const auto &V : I.AttrValues)
199 ValArr.emplace_back(V);
200 Child.insert({"Name", I.Name});
201 Child.insert({"SelfClosing", I.SelfClosing});
202 Child.insert({"AttrKeys", AttrKeysArray});
203 Child.insert({"AttrValues", AttrValuesArray});
204 Child.insert({"Children", ChildArr});
205 Obj.insert({commentKindToString(I.Kind), ChildVal});
206 return Obj;
207 }
208
210 Child.insert({"Name", I.Name});
211 Child.insert({"Children", ChildArr});
212 Obj.insert({commentKindToString(I.Kind), ChildVal});
213 return Obj;
214 }
215
218 Child.insert({"Children", ChildArr});
219 Child["ParagraphComment"] = true;
220 return Child;
221 }
222
224 Obj.insert({commentKindToString(I.Kind), I.Text});
225 return Obj;
226 }
227 }
228 llvm_unreachable("Unknown comment kind encountered.");
229}
230
231static void
232serializeCommonAttributes(const Info &I, json::Object &Obj,
233 const std::optional<StringRef> RepositoryUrl) {
234 Obj["Name"] = I.Name;
235 Obj["USR"] = toHex(toStringRef(I.USR));
236 Obj["InfoType"] = infoTypeToString(I.IT);
237 if (!I.DocumentationFileName.empty())
238 Obj["DocumentationFileName"] = I.DocumentationFileName;
239
240 if (!I.Path.empty())
241 Obj["Path"] = I.Path;
242
243 if (!I.Namespace.empty()) {
244 Obj["Namespace"] = json::Array();
245 for (const auto &NS : I.Namespace)
246 Obj["Namespace"].getAsArray()->push_back(NS.Name);
247 }
248
249 if (!I.Description.empty()) {
250 Object Description = Object();
251 // Skip straight to the FullComment's children
252 auto &Comments = I.Description.at(0).Children;
253 for (const auto &CommentInfo : Comments) {
254 json::Value Comment = serializeComment(*CommentInfo, Description);
255 // if a ParagraphComment is returned, then it is a top-level comment that
256 // needs to be inserted manually.
257 if (auto *ParagraphComment = Comment.getAsObject();
258 ParagraphComment->get("ParagraphComment")) {
259 auto TextCommentsArray = extractTextComments(ParagraphComment);
260 insertComment(Description, TextCommentsArray, "ParagraphComments");
261 }
262 }
263 Obj["Description"] = std::move(Description);
264 }
265
266 // Namespaces aren't SymbolInfos, so they dont have a DefLoc
267 if (I.IT != InfoType::IT_namespace) {
268 const auto *Symbol = static_cast<const SymbolInfo *>(&I);
269 if (Symbol->DefLoc)
270 Obj["Location"] =
271 serializeLocation(Symbol->DefLoc.value(), RepositoryUrl);
272 }
273}
274
275static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
276 ReferenceObj["Path"] = Ref.Path;
277 ReferenceObj["Name"] = Ref.Name;
278 ReferenceObj["QualName"] = Ref.QualName;
279 ReferenceObj["USR"] = toHex(toStringRef(Ref.USR));
280 if (!Ref.DocumentationFileName.empty())
281 ReferenceObj["DocumentationFileName"] = Ref.DocumentationFileName;
282}
283
284// Although namespaces and records both have ScopeChildren, they serialize them
285// differently. Only enums, records, and typedefs are handled here.
286static void
288 const std::optional<StringRef> RepositoryUrl) {
289 static auto SerializeInfo = [RepositoryUrl](const auto &Info,
290 Object &Object) {
292 };
293
294 if (!Children.Enums.empty()) {
295 serializeArray(Children.Enums, Obj, "Enums", SerializeInfo);
296 Obj["HasEnums"] = true;
297 }
298
299 if (!Children.Typedefs.empty())
300 serializeArray(Children.Typedefs, Obj, "Typedefs", SerializeInfo);
301
302 if (!Children.Records.empty()) {
303 serializeArray(Children.Records, Obj, "Records", SerializeReferenceLambda);
304 Obj["HasRecords"] = true;
305 }
306}
307
308template <typename Container, typename SerializationFunc>
309static void serializeArray(const Container &Records, Object &Obj,
310 const std::string &Key,
311 SerializationFunc SerializeInfo) {
312 json::Value RecordsArray = Array();
313 auto &RecordsArrayRef = *RecordsArray.getAsArray();
314 RecordsArrayRef.reserve(Records.size());
315 for (size_t Index = 0; Index < Records.size(); ++Index) {
316 json::Value ItemVal = Object();
317 auto &ItemObj = *ItemVal.getAsObject();
318 SerializeInfo(Records[Index], ItemObj);
319 if (Index == Records.size() - 1)
320 ItemObj["End"] = true;
321 RecordsArrayRef.push_back(ItemVal);
322 }
323 Obj[Key] = RecordsArray;
324}
325
326static void serializeInfo(const ConstraintInfo &I, Object &Obj) {
328 Obj["Expression"] = I.ConstraintExpr;
329}
330
331static void serializeInfo(const ArrayRef<TemplateParamInfo> &Params,
332 Object &Obj) {
333 json::Value ParamsArray = Array();
334 auto &ParamsArrayRef = *ParamsArray.getAsArray();
335 ParamsArrayRef.reserve(Params.size());
336 for (const auto &Param : Params)
337 ParamsArrayRef.push_back(Param.Contents);
338 Obj["Parameters"] = ParamsArray;
339}
340
341static void serializeInfo(const TemplateInfo &Template, Object &Obj) {
342 json::Value TemplateVal = Object();
343 auto &TemplateObj = *TemplateVal.getAsObject();
344
345 if (Template.Specialization) {
346 json::Value TemplateSpecializationVal = Object();
347 auto &TemplateSpecializationObj = *TemplateSpecializationVal.getAsObject();
348 TemplateSpecializationObj["SpecializationOf"] =
349 toHex(toStringRef(Template.Specialization->SpecializationOf));
350 if (!Template.Specialization->Params.empty())
351 serializeInfo(Template.Specialization->Params, TemplateSpecializationObj);
352 TemplateObj["Specialization"] = TemplateSpecializationVal;
353 }
354
355 if (!Template.Params.empty())
356 serializeInfo(Template.Params, TemplateObj);
357
358 if (!Template.Constraints.empty())
359 serializeArray(Template.Constraints, TemplateObj, "Constraints",
361
362 Obj["Template"] = TemplateVal;
363}
364
365static void serializeInfo(const ConceptInfo &I, Object &Obj,
366 const std::optional<StringRef> &RepositoryUrl) {
368 Obj["IsType"] = I.IsType;
369 Obj["ConstraintExpression"] = I.ConstraintExpression;
370 serializeInfo(I.Template, Obj);
371}
372
373static void serializeInfo(const TypeInfo &I, Object &Obj) {
374 Obj["Name"] = I.Type.Name;
375 Obj["QualName"] = I.Type.QualName;
376 Obj["USR"] = toHex(toStringRef(I.Type.USR));
377 Obj["IsTemplate"] = I.IsTemplate;
378 Obj["IsBuiltIn"] = I.IsBuiltIn;
379}
380
381static void serializeInfo(const FieldTypeInfo &I, Object &Obj) {
382 Obj["Name"] = I.Name;
383 Obj["Type"] = I.Type.Name;
384}
385
386static void serializeInfo(const FunctionInfo &F, json::Object &Obj,
387 const std::optional<StringRef> RepositoryURL) {
388 serializeCommonAttributes(F, Obj, RepositoryURL);
389 Obj["IsStatic"] = F.IsStatic;
390
391 auto ReturnTypeObj = Object();
392 serializeInfo(F.ReturnType, ReturnTypeObj);
393 Obj["ReturnType"] = std::move(ReturnTypeObj);
394
395 if (!F.Params.empty())
396 serializeArray(F.Params, Obj, "Params", SerializeInfoLambda);
397
398 if (F.Template)
399 serializeInfo(F.Template.value(), Obj);
400}
401
402static void serializeInfo(const EnumValueInfo &I, Object &Obj) {
403 Obj["Name"] = I.Name;
404 if (!I.ValueExpr.empty())
405 Obj["ValueExpr"] = I.ValueExpr;
406 else
407 Obj["Value"] = I.Value;
408}
409
410static void serializeInfo(const EnumInfo &I, json::Object &Obj,
411 const std::optional<StringRef> &RepositoryUrl) {
413 Obj["Scoped"] = I.Scoped;
414
415 if (I.BaseType) {
416 json::Value BaseTypeVal = Object();
417 auto &BaseTypeObj = *BaseTypeVal.getAsObject();
418 BaseTypeObj["Name"] = I.BaseType->Type.Name;
419 BaseTypeObj["QualName"] = I.BaseType->Type.QualName;
420 BaseTypeObj["USR"] = toHex(toStringRef(I.BaseType->Type.USR));
421 Obj["BaseType"] = BaseTypeVal;
422 }
423
424 if (!I.Members.empty())
425 serializeArray(I.Members, Obj, "Members", SerializeInfoLambda);
426}
427
428static void serializeInfo(const TypedefInfo &I, json::Object &Obj,
429 const std::optional<StringRef> &RepositoryUrl) {
431 Obj["TypeDeclaration"] = I.TypeDeclaration;
432 Obj["IsUsing"] = I.IsUsing;
433 json::Value TypeVal = Object();
434 auto &TypeObj = *TypeVal.getAsObject();
435 serializeInfo(I.Underlying, TypeObj);
436 Obj["Underlying"] = TypeVal;
437}
438
439static void serializeInfo(const BaseRecordInfo &I, Object &Obj,
440 const std::optional<StringRef> &RepositoryUrl) {
441 serializeInfo(static_cast<const RecordInfo &>(I), Obj, RepositoryUrl);
442 Obj["IsVirtual"] = I.IsVirtual;
443 Obj["Access"] = getAccessSpelling(I.Access);
444 Obj["IsParent"] = I.IsParent;
445}
446
447static void serializeInfo(const FriendInfo &I, Object &Obj) {
448 auto FriendRef = Object();
449 serializeReference(I.Ref, FriendRef);
450 Obj["Reference"] = std::move(FriendRef);
451 Obj["IsClass"] = I.IsClass;
452 if (I.Template)
453 serializeInfo(I.Template.value(), Obj);
454 if (I.Params)
455 serializeArray(I.Params.value(), Obj, "Params", SerializeInfoLambda);
456 if (I.ReturnType) {
457 auto ReturnTypeObj = Object();
458 serializeInfo(I.ReturnType.value(), ReturnTypeObj);
459 Obj["ReturnType"] = std::move(ReturnTypeObj);
460 }
461}
462
463static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
464 Obj[Key] = Array;
465 Obj["Has" + Key.str()] = true;
466}
467
468static void serializeInfo(const RecordInfo &I, json::Object &Obj,
469 const std::optional<StringRef> &RepositoryUrl) {
471 Obj["FullName"] = I.FullName;
472 Obj["TagType"] = getTagType(I.TagType);
473 Obj["IsTypedef"] = I.IsTypeDef;
474 Obj["MangledName"] = I.MangledName;
475
476 if (!I.Children.Functions.empty()) {
477 json::Value PubFunctionsArray = Array();
478 json::Array &PubFunctionsArrayRef = *PubFunctionsArray.getAsArray();
479 json::Value ProtFunctionsArray = Array();
480 json::Array &ProtFunctionsArrayRef = *ProtFunctionsArray.getAsArray();
481
482 for (const auto &Function : I.Children.Functions) {
483 json::Value FunctionVal = Object();
484 auto &FunctionObj = *FunctionVal.getAsObject();
485 serializeInfo(Function, FunctionObj, RepositoryUrl);
486 AccessSpecifier Access = Function.Access;
487 if (Access == AccessSpecifier::AS_public)
488 PubFunctionsArrayRef.push_back(FunctionVal);
489 else if (Access == AccessSpecifier::AS_protected)
490 ProtFunctionsArrayRef.push_back(FunctionVal);
491 }
492
493 if (!PubFunctionsArrayRef.empty())
494 insertArray(Obj, PubFunctionsArray, "PublicFunctions");
495 if (!ProtFunctionsArrayRef.empty())
496 Obj["ProtectedFunctions"] = ProtFunctionsArray;
497 }
498
499 if (!I.Members.empty()) {
500 json::Value PublicMembersArray = Array();
501 json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
502 json::Value ProtectedMembersArray = Array();
503 json::Array &ProtMembersArrayRef = *ProtectedMembersArray.getAsArray();
504
505 for (const MemberTypeInfo &Member : I.Members) {
506 json::Value MemberVal = Object();
507 auto &MemberObj = *MemberVal.getAsObject();
508 MemberObj["Name"] = Member.Name;
509 MemberObj["Type"] = Member.Type.Name;
510
511 if (Member.Access == AccessSpecifier::AS_public)
512 PubMembersArrayRef.push_back(MemberVal);
513 else if (Member.Access == AccessSpecifier::AS_protected)
514 ProtMembersArrayRef.push_back(MemberVal);
515 }
516
517 if (!PubMembersArrayRef.empty())
518 insertArray(Obj, PublicMembersArray, "PublicMembers");
519 if (!ProtMembersArrayRef.empty())
520 Obj["ProtectedMembers"] = ProtectedMembersArray;
521 }
522
523 if (!I.Bases.empty())
525 I.Bases, Obj, "Bases",
526 [&RepositoryUrl](const BaseRecordInfo &Base, Object &BaseObj) {
527 serializeInfo(Base, BaseObj, RepositoryUrl);
528 });
529
530 if (!I.Parents.empty())
532
533 if (!I.VirtualParents.empty())
534 serializeArray(I.VirtualParents, Obj, "VirtualParents",
536
537 if (I.Template)
538 serializeInfo(I.Template.value(), Obj);
539
540 if (!I.Friends.empty())
541 serializeArray(I.Friends, Obj, "Friends", SerializeInfoLambda);
542
544}
545
546static void serializeInfo(const VarInfo &I, json::Object &Obj,
547 const std::optional<StringRef> RepositoryUrl) {
549 Obj["IsStatic"] = I.IsStatic;
550 auto TypeObj = Object();
551 serializeInfo(I.Type, TypeObj);
552 Obj["Type"] = std::move(TypeObj);
553}
554
555static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
556 const std::optional<StringRef> RepositoryUrl) {
558
559 if (!I.Children.Namespaces.empty())
560 serializeArray(I.Children.Namespaces, Obj, "Namespaces",
562
563 static auto SerializeInfo = [RepositoryUrl](const auto &Info,
564 Object &Object) {
566 };
567
568 if (!I.Children.Functions.empty())
569 serializeArray(I.Children.Functions, Obj, "Functions", SerializeInfo);
570
571 if (!I.Children.Concepts.empty())
572 serializeArray(I.Children.Concepts, Obj, "Concepts", SerializeInfo);
573
574 if (!I.Children.Variables.empty())
575 serializeArray(I.Children.Variables, Obj, "Variables", SerializeInfo);
576
578}
579
580static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
581 SmallString<16> FileName;
582 if (I->IT == InfoType::IT_record) {
583 auto *RecordSymbolInfo = static_cast<SymbolInfo *>(I);
584 FileName = RecordSymbolInfo->MangledName;
585 } else if (I->IT == InfoType::IT_namespace && I->Name != "")
586 // Serialize the global namespace as index.json
587 FileName = I->Name;
588 else
590 sys::path::append(Path, FileName + ".json");
591 return FileName;
592}
593
595 StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
596 const ClangDocContext &CDCtx) {
597 StringSet<> CreatedDirs;
598 StringMap<std::vector<doc::Info *>> FileToInfos;
599 for (const auto &Group : Infos) {
600 Info *Info = Group.getValue().get();
601
602 SmallString<128> Path;
603 auto RootDirStr = RootDir.str() + "/json";
604 StringRef JSONDir = StringRef(RootDirStr);
605 sys::path::native(JSONDir, Path);
606 if (!CreatedDirs.contains(Path)) {
607 if (std::error_code Err = sys::fs::create_directories(Path);
608 Err != std::error_code())
609 return createFileError(Twine(Path), Err);
610 CreatedDirs.insert(Path);
611 }
612
613 SmallString<16> FileName = determineFileName(Info, Path);
614 if (FileToInfos.contains(Path))
615 continue;
616 FileToInfos[Path].push_back(Info);
618 }
619
620 for (const auto &Group : FileToInfos) {
621 std::error_code FileErr;
622 raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
623 if (FileErr)
624 return createFileError("cannot open file " + Group.getKey(), FileErr);
625
626 for (const auto &Info : Group.getValue())
627 if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
628 return Err;
629 }
630
631 return Error::success();
632}
633
635 const ClangDocContext &CDCtx) {
636 json::Object Obj = Object();
637
638 switch (I->IT) {
640 serializeInfo(*static_cast<NamespaceInfo *>(I), Obj, CDCtx.RepositoryUrl);
641 break;
643 serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl);
644 break;
651 break;
653 return createStringError(inconvertibleErrorCode(), "unexpected info type");
654 }
655 OS << llvm::formatv("{0:2}", llvm::json::Value(std::move(Obj)));
656 return Error::success();
657}
658
660 return Error::success();
661}
662
663static GeneratorRegistry::Add<JSONGenerator> JSON(JSONGenerator::Format,
664 "Generator for JSON output.");
666} // namespace doc
667} // namespace clang
unsigned Line
Definition: Bracket.cpp:77
static llvm::cl::opt< std::string > RepositoryUrl("repository", llvm::cl::desc(R"( URL of repository that hosts code. Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory))
static constexpr llvm::SourceMgr::DiagKind Error
llvm::raw_ostream & OS
const Criteria C
std::vector< std::unique_ptr< HTMLNode > > Children
StringRef FileName
SourceLocation Loc
llvm::StringMap< llvm::TimeRecord > Records
Definition: Query.cpp:97
Kind K
Definition: Rename.cpp:481
static const char * Format
Error generateDocs(StringRef RootDir, llvm::StringMap< std::unique_ptr< doc::Info > > Infos, const ClangDocContext &CDCtx) override
Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, const ClangDocContext &CDCtx) override
Error createResources(ClangDocContext &CDCtx) override
static std::string infoTypeToString(InfoType IT)
static json::Value extractTextComments(Object *ParagraphComment)
static Object serializeComment(const CommentInfo &I, Object &Description)
std::string getTagType(TagTypeKind AS)
Definition: Generators.cpp:29
static void insertComment(Object &Description, json::Value &Comment, StringRef Key)
static void serializeArray(const Container &Records, Object &Obj, const std::string &Key, SerializationFunc SerializeInfo)
volatile int JSONGeneratorAnchorSource
static auto SerializeReferenceLambda
static void serializeReference(const Reference &Ref, Object &ReferenceObj)
static void serializeInfo(const ConstraintInfo &I, Object &Obj)
static void serializeCommonAttributes(const Info &I, json::Object &Obj, const std::optional< StringRef > RepositoryUrl)
static GeneratorRegistry::Add< JSONGenerator > JSON(JSONGenerator::Format, "Generator for JSON output.")
static void serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj, const std::optional< StringRef > RepositoryUrl)
static auto SerializeInfoLambda
static SmallString< 16 > determineFileName(Info *I, SmallString< 128 > &Path)
static json::Value extractVerbatimComments(json::Array VerbatimLines)
static json::Object serializeLocation(const Location &Loc, const std::optional< StringRef > RepositoryUrl)
llvm::StringRef commentKindToString(CommentKind Kind)
static void insertArray(Object &Obj, json::Value &Array, StringRef Key)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
Definition: Generators.h:66
std::optional< std::string > RepositoryUrl
SmallString< 8 > Direction
std::vector< std::unique_ptr< CommentInfo > > Children
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
SmallString< 16 > CloseName
SmallString< 16 > Name
SmallString< 64 > Text
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
llvm::SmallVector< SmallString< 16 >, 4 > Args
SmallString< 16 > ParamName
SmallString< 16 > ConstraintExpression
SmallString< 16 > ConstraintExpr
llvm::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
SmallString< 16 > Value
SmallString< 16 > Name
SmallString< 16 > ValueExpr
SmallString< 16 > Name
std::optional< TypeInfo > ReturnType
std::optional< SmallVector< FieldTypeInfo, 4 > > Params
std::optional< TemplateInfo > Template
A base struct for Infos.
SmallString< 16 > DocumentationFileName
SmallString< 16 > Name
llvm::SmallString< 16 > getFileBaseName() const
Returns the basename that should be used for this Info.
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Namespace
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
SmallString< 16 > FullName
std::vector< FriendInfo > Friends
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
SmallString< 16 > QualName
llvm::SmallString< 128 > Path
SmallString< 16 > DocumentationFileName
SmallString< 16 > Name
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< ConceptInfo > Concepts
SmallString< 16 > MangledName
SmallString< 16 > TypeDeclaration