clang-tools 23.0.0git
Representation.h
Go to the documentation of this file.
1///===-- Representation.h - ClangDoc Representation -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the internal representations of different declaration
10// types for the clang-doc tool.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
15#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
16
17#include "clang/AST/Type.h"
18#include "clang/Basic/Diagnostic.h"
19#include "clang/Basic/Specifiers.h"
20#include "clang/Tooling/Execution.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/ilist_node.h"
24#include "llvm/ADT/simple_ilist.h"
25#include "llvm/Support/Allocator.h"
26#include "llvm/Support/Mutex.h"
27#include "llvm/Support/StringSaver.h"
28#include <array>
29#include <memory>
30#include <optional>
31#include <string>
32
33namespace clang {
34namespace doc {
35
37public:
38 StringRef intern(StringRef Name) {
39 if (Name.empty())
40 return StringRef();
41
42 llvm::sys::SmartScopedLock<true> Lock(PoolMutex);
43 return Saver.save(Name);
44 }
45
46private:
47 llvm::sys::SmartMutex<true> PoolMutex;
48 llvm::BumpPtrAllocator Alloc;
49 llvm::UniqueStringSaver Saver{Alloc};
50};
51
52ConcurrentStringPool &getGlobalStringPool();
53
54extern thread_local llvm::BumpPtrAllocator TransientArena;
55extern thread_local llvm::BumpPtrAllocator PersistentArena;
56
57inline StringRef internString(const Twine &T) {
58 if (T.isTriviallyEmpty())
59 return StringRef();
60
61 if (T.isSingleStringRef()) {
62 StringRef S = T.getSingleStringRef();
63 if (S.empty())
64 return StringRef();
65 return getGlobalStringPool().intern(S);
66 }
67
68 SmallString<128> Buffer;
69 StringRef S = T.toStringRef(Buffer);
70 if (S.empty())
71 return StringRef();
72 return getGlobalStringPool().intern(S);
73}
74
75template <typename T>
77 llvm::BumpPtrAllocator &Alloc) {
78 if (V.empty())
79 return llvm::ArrayRef<T>();
80 T *Allocated = static_cast<T *>(Alloc.Allocate<T>(V.size()));
81 std::uninitialized_move(V.begin(), V.end(), Allocated);
82 return llvm::ArrayRef<T>(Allocated, V.size());
83}
84
85template <typename T>
86llvm::ArrayRef<T> allocateArray(llvm::ArrayRef<T> V,
87 llvm::BumpPtrAllocator &Alloc) {
88 if (V.empty())
89 return llvm::ArrayRef<T>();
90 T *Allocated = static_cast<T *>(Alloc.Allocate<T>(V.size()));
91 std::uninitialized_move(V.begin(), V.end(), Allocated);
92 return llvm::ArrayRef<T>(Allocated, V.size());
93}
94
95template <typename T>
96llvm::ArrayRef<T> deepCopyArray(llvm::ArrayRef<T> V,
97 llvm::BumpPtrAllocator &Alloc) {
98 if (V.empty())
99 return llvm::ArrayRef<T>();
100 T *Allocated = static_cast<T *>(Alloc.Allocate<T>(V.size()));
101 for (size_t Idx = 0; Idx < V.size(); ++Idx) {
102 new (Allocated + Idx) T(V[Idx], Alloc);
103 }
104 return llvm::ArrayRef<T>(Allocated, V.size());
105}
106
107// A helper function to create an owned pointer, abstracting away the memory
108// allocation mechanism.
109template <typename T, typename... Args> T *allocateTransient(Args &&...args) {
110 return new (TransientArena.Allocate<T>()) T(std::forward<Args>(args)...);
111}
112
113// A helper function to create memory allocated in the TransientArena.
114template <typename T, typename... Args> T *allocatePersistent(Args &&...args) {
115 return new (PersistentArena.Allocate<T>()) T(std::forward<Args>(args)...);
116}
117
118// An overload to explicitly allocate on an arena, returning a bare pointer.
119template <typename T, typename... Args>
120T *allocatePtr(llvm::BumpPtrAllocator &Alloc, Args &&...args) {
121 return new (Alloc.Allocate<T>()) T(std::forward<Args>(args)...);
122}
123
124template <typename T> struct InfoNode : public llvm::ilist_node<InfoNode<T>> {
125 InfoNode(T *P) : Ptr(P) {}
126 T *Ptr = nullptr;
127
128 operator T &() { return *Ptr; }
129 operator const T &() const { return *Ptr; }
130
131 T &operator*() { return *Ptr; }
132 const T &operator*() const { return *Ptr; }
133 T *operator->() { return Ptr; }
134 const T *operator->() const { return Ptr; }
135
136 bool operator==(const InfoNode<T> &Other) const {
137 if (!Ptr || !Other.Ptr)
138 return Ptr == Other.Ptr;
139 return *Ptr == *Other.Ptr;
140 }
141
142 bool operator!=(const InfoNode<T> &Other) const { return !(*this == Other); }
143
144 bool operator<(const InfoNode<T> &Other) const {
145 if (!Ptr || !Other.Ptr)
146 return Ptr < Other.Ptr;
147 return *Ptr < *Other.Ptr;
148 }
149};
150
151template <typename T, typename... Args>
152InfoNode<T> *allocateListNode(llvm::BumpPtrAllocator &Alloc, Args &&...args) {
153 T *Item = allocatePtr<T>(Alloc, std::forward<Args>(args)...);
154 return allocatePtr<InfoNode<T>>(Alloc, Item);
155}
156
157template <typename T, typename... Args>
159 return allocateListNode<T>(TransientArena, std::forward<Args>(args)...);
160}
161
162template <typename T>
163InfoNode<T> *allocateListNode(llvm::BumpPtrAllocator &Alloc, T *Item) {
164 return allocatePtr<InfoNode<T>>(Alloc, Item);
165}
166
167template <typename T> InfoNode<T> *allocateListNodeTransient(T *Item) {
169}
170
171template <typename T, typename... Args>
173 return allocateListNode<T>(PersistentArena, std::forward<Args>(args)...);
174}
175
176template <typename T> InfoNode<T> *allocateListNodePersistent(T *Item) {
178}
179
180// An abstraction for lists that are dynamically managed (inserted/removed).
181// To be eventually transitioned to llvm::simple_ilist.
182template <typename T> using DocList = llvm::simple_ilist<InfoNode<T>>;
183
184// SHA1'd hash of a USR.
185using SymbolID = std::array<uint8_t, 20>;
186
187constexpr SymbolID GlobalNamespaceID = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
189
190struct BaseRecordInfo;
191struct EnumInfo;
192struct FunctionInfo;
193struct Info;
194struct TypedefInfo;
195struct ConceptInfo;
196struct VarInfo;
197
209
225
227
228CommentKind stringToCommentKind(llvm::StringRef KindStr);
229llvm::StringRef commentKindToString(CommentKind Kind);
230
231struct CommentInfo;
232
233// A representation of a parsed comment.
235 CommentInfo() = default;
236 CommentInfo(const CommentInfo &Other) = default;
237 CommentInfo &operator=(const CommentInfo &Other) = default;
238 CommentInfo(const CommentInfo &Other, llvm::BumpPtrAllocator &Arena);
239 CommentInfo(CommentInfo &&Other) = default;
240 CommentInfo &operator=(CommentInfo &&Other) = default;
241
242 CommentInfo(CommentKind Kind, llvm::ArrayRef<CommentInfo> Children = {},
243 StringRef Text = StringRef(), StringRef Name = StringRef(),
244 StringRef CloseName = StringRef(),
245 StringRef Direction = StringRef(),
246 StringRef ParamName = StringRef(), bool Explicit = false,
247 bool SelfClosing = false, llvm::ArrayRef<StringRef> AttrKeys = {},
248 llvm::ArrayRef<StringRef> AttrValues = {})
251 AttrKeys(AttrKeys), AttrValues(AttrValues), Kind(Kind),
253
254 bool operator==(const CommentInfo &Other) const;
255
256 // This operator is used to sort a vector of CommentInfos.
257 // No specific order (attributes more important than others) is required. Any
258 // sort is enough, the order is only needed to call std::unique after sorting
259 // the vector.
260 bool operator<(const CommentInfo &Other) const;
261
262 // List of child comments for this CommentInfo.
263 ArrayRef<CommentInfo> Children = {};
264
265 // Parameter direction (for (T)ParamCommand).
266 StringRef Direction = {};
267
268 // Name of the comment (for Verbatim and HTML).
269 StringRef Name = {};
270
271 // Parameter name (for (T)ParamCommand).
272 StringRef ParamName = {};
273
274 // Closing tag name (for VerbatimBlock).
275 StringRef CloseName = {};
276
277 // Text of the comment.
278 StringRef Text = {};
279
280 // List of attribute keys (for HTML).
281 ArrayRef<StringRef> AttrKeys = {};
282
283 // List of attribute values for each key (for HTML).
284 ArrayRef<StringRef> AttrValues = {};
285
286 // List of arguments to commands (for InlineCommand).
287 ArrayRef<StringRef> Args = {};
288
289 // Type of comment. Unknown by default.
291
292 // Indicates if tag is self-closing (for HTML).
293 bool SelfClosing = false;
294
295 // Indicates if the direction of a param is explicit (for (T)ParamCommand).
296 bool Explicit = false;
297};
298
299struct Reference {
300 // This variant (that takes no qualified name parameter) uses the Name as the
301 // QualName (very useful in unit tests to reduce verbosity). This can't use an
302 // empty string to indicate the default because we need to accept the empty
303 // string as a valid input for the global namespace (it will have
304 // "GlobalNamespace" as the name, but an empty QualName).
305 Reference(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
307 : USR(USR), RefType(IT), Name(internString(Name)),
309 Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
310 StringRef Path = StringRef())
311 : USR(USR), RefType(IT), Name(internString(Name)),
318
319 bool operator==(const Reference &Other) const {
320 return std::tie(USR, Name, QualName, RefType) ==
321 std::tie(Other.USR, Other.Name, Other.QualName, Other.RefType);
322 }
323
324 bool mergeable(const Reference &Other);
325 void merge(Reference &&I);
326 bool operator<(const Reference &Other) const { return Name < Other.Name; }
327
328 /// Returns the path for this Reference relative to CurrentPath.
329 StringRef getRelativeFilePath(const StringRef &CurrentPath) const;
330
331 /// Returns the basename that should be used for this Reference.
332 StringRef getFileBaseName() const;
333
334 SymbolID USR = SymbolID(); // Unique identifier for referenced decl
335
336 InfoType RefType = InfoType::IT_default; // Indicates the type of this
337 // Reference (namespace, record,
338 // function, enum, default).
339
340 // Name of type (possibly unresolved). Not including namespaces or template
341 // parameters (so for a std::vector<int> this would be "vector"). See also
342 // QualName.
343 StringRef Name = {};
344
345 // Full qualified name of this type, including namespaces and template
346 // parameter (for example this could be "std::vector<int>"). Contrast to
347 // Name.
348 StringRef QualName = {};
349
350 // Path of directory where the clang-doc generated file will be saved
351 // (possibly unresolved)
352 StringRef Path = {};
353 StringRef DocumentationFileName = {};
354};
355
356// A Context is a reference that holds a relative path from a certain Info's
357// location.
358struct Context : public Reference {
359 Context(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
360 StringRef Path, StringRef DocumentationFileName)
362 explicit Context(const Info &I);
363 StringRef RelativePath = {};
364};
365
366// Holds the children of a record or namespace.
368 // Namespaces and Records are references because they will be properly
369 // documented in their own info, while the entirety of Functions and Enums are
370 // included here because they should not have separate documentation from
371 // their scope.
372 //
373 // Namespaces are not syntactically valid as children of records, but making
374 // this general for all possible container types reduces code complexity.
382
383 void sort();
384};
385
386// A base struct for TypeInfos
387struct TypeInfo {
388 TypeInfo() = default;
389 TypeInfo(const Reference &R) : Type(R) {}
390
391 // Convenience constructor for when there is no symbol ID or info type
392 // (normally used for built-in types in tests).
393 TypeInfo(StringRef Name, StringRef Path = StringRef())
394 : Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}
395
396 bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
397
398 Reference Type; // Referenced type in this info.
399
400 bool IsTemplate = false;
401 bool IsBuiltIn = false;
402};
403
404// Represents one template parameter.
405//
406// This is a very simple serialization of the text of the source code of the
407// template parameter. It is saved in a struct so there is a place to add the
408// name and default values in the future if needed.
410 TemplateParamInfo() = default;
413
414 // The literal contents of the code for that specifies this template parameter
415 // for this declaration. Typical values will be "class T" and
416 // "typename T = int".
417 StringRef Contents = {};
418};
419
423 llvm::BumpPtrAllocator &Arena);
424
425 // Indicates the declaration that this specializes.
427
428 // Template parameters applying to the specialized record/function.
429 llvm::ArrayRef<TemplateParamInfo> Params = {};
430};
431
433 ConstraintInfo() = default;
434 ConstraintInfo(SymbolID USR, StringRef Name)
435 : ConceptRef(USR, Name, InfoType::IT_concept) {}
437
438 StringRef ConstraintExpr = {};
439};
440
441// Records the template information for a struct or function that is a template
442// or an explicit template specialization.
444 TemplateInfo() = default;
445 TemplateInfo(const TemplateInfo &Other, llvm::BumpPtrAllocator &Arena);
446
447 // May be empty for non-partial specializations.
448 llvm::ArrayRef<TemplateParamInfo> Params = {};
449
450 // Set when this is a specialization of another record/function.
451 std::optional<TemplateSpecializationInfo> Specialization;
452 llvm::ArrayRef<ConstraintInfo> Constraints = {};
453};
454
455// Info for field types.
456struct FieldTypeInfo : public TypeInfo {
457 FieldTypeInfo() = default;
458 FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
459 StringRef DefaultValue = StringRef())
462
463 bool operator==(const FieldTypeInfo &Other) const {
464 return std::tie(Type, Name, DefaultValue) ==
465 std::tie(Other.Type, Other.Name, Other.DefaultValue);
466 }
467
468 StringRef Name = {}; // Name associated with this info.
469
470 // When used for function parameters, contains the string representing the
471 // expression of the default value, if any.
472 StringRef DefaultValue = {};
473};
474
475// Info for member types.
477 MemberTypeInfo() = default;
478 MemberTypeInfo(const MemberTypeInfo &Other, llvm::BumpPtrAllocator &Arena);
479 MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access,
480 bool IsStatic = false)
482
483 bool operator==(const MemberTypeInfo &Other) const {
484 if (std::tie(Type, Name, Access, IsStatic) !=
485 std::tie(Other.Type, Other.Name, Other.Access, Other.IsStatic))
486 return false;
487 return std::equal(Description.begin(), Description.end(),
488 Other.Description.begin(), Other.Description.end());
489 }
490
492
493 // Access level associated with this info (public, protected, private, none).
494 // AS_public is set as default because the bitcode writer requires the enum
495 // with value 0 to be used as the default.
496 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
497 AccessSpecifier Access = AccessSpecifier::AS_public;
498 bool IsStatic = false;
499};
500
501struct Location {
506
507 bool operator==(const Location &Other) const {
508 return std::tie(StartLineNumber, EndLineNumber, Filename) ==
509 std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
510 }
511
512 bool operator!=(const Location &Other) const { return !(*this == Other); }
513
514 // This operator is used to sort a vector of Locations.
515 // No specific order (attributes more important than others) is required. Any
516 // sort is enough, the order is only needed to call std::unique after sorting
517 // the vector.
518 bool operator<(const Location &Other) const {
519 return std::tie(StartLineNumber, EndLineNumber, Filename) <
520 std::tie(Other.StartLineNumber, Other.EndLineNumber, Other.Filename);
521 }
522
523 StringRef Filename = {};
526 bool IsFileInRootDir = false;
527};
528
529/// A base struct for Infos.
530struct Info {
532 StringRef Name = StringRef(), StringRef Path = StringRef())
534
535 Info(const Info &Other, llvm::BumpPtrAllocator &Arena);
536 Info(const Info &Other) = delete;
537 Info(Info &&Other) = default;
538
539 Info &operator=(Info &&Other) = default;
540
541 void mergeBase(Info &&I);
542 bool mergeable(const Info &Other);
543
544 StringRef extractName() const;
545
546 /// Returns the file path for this Info relative to CurrentPath.
547 StringRef getRelativeFilePath(const StringRef &CurrentPath) const;
548
549 /// Returns the basename that should be used for this Info.
550 StringRef getFileBaseName() const;
551
552 // Path of directory where the clang-doc generated file will be saved.
553 StringRef Path = {};
554
555 // Unqualified name of the decl.
556 StringRef Name = {};
557
558 // The name used for the file that this info is documented in.
559 // In the JSON generator, infos are documented in files with mangled names.
560 // Thus, we keep track of the physical filename for linking purposes.
561 StringRef DocumentationFileName = {};
562
563 // List of parent namespaces for this decl.
564 llvm::ArrayRef<Reference> Namespace;
565
566 // Unique identifier for the decl described by this Info.
568
569 // Currently only used for namespaces and records.
571
572 // InfoType of this particular Info.
574
575 // Comment description of this decl.
577};
578
579inline Context::Context(const Info &I)
580 : Reference(I.USR, I.Name, I.IT, I.Name, I.Path, I.DocumentationFileName) {}
581
582// Info for namespaces.
583struct NamespaceInfo : public Info {
584 NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
585 StringRef Path = StringRef());
586
587 void merge(NamespaceInfo &&I);
588
590};
591
592// Info for symbols.
593struct SymbolInfo : public Info {
595 StringRef Name = StringRef(), StringRef Path = StringRef())
596 : Info(IT, USR, Name, Path) {}
597
598 SymbolInfo(const SymbolInfo &Other, llvm::BumpPtrAllocator &Arena);
599
600 void merge(SymbolInfo &&I);
601
602 bool operator<(const SymbolInfo &Other) const {
603 // Sort by declaration location since we want the doc to be
604 // generated in the order of the source code.
605 // If the declaration location is the same, or not present
606 // we sort by defined location otherwise fallback to the extracted name
607 if (!Loc.empty() && !Other.Loc.empty() && Loc.front() != Other.Loc.front())
608 return Loc.front() < Other.Loc.front();
609
610 if (DefLoc && Other.DefLoc && *DefLoc != *Other.DefLoc)
611 return *DefLoc < *Other.DefLoc;
612
613 return extractName() < Other.extractName();
614 }
615
616 std::optional<Location> DefLoc; // Location where this decl is defined.
617 DocList<Location> Loc = {}; // Locations where this decl is declared.
618 StringRef MangledName = {};
619 bool IsStatic = false;
620};
621
622struct FriendInfo : public SymbolInfo {
626 const StringRef Name = StringRef())
627 : SymbolInfo(IT, USR, Name) {}
628 FriendInfo(const FriendInfo &Other, llvm::BumpPtrAllocator &Arena);
629 bool mergeable(const FriendInfo &Other);
630 void merge(FriendInfo &&Other);
631
633 std::optional<TemplateInfo> Template;
634 std::optional<TypeInfo> ReturnType;
635 llvm::ArrayRef<FieldTypeInfo> Params = {};
636 bool IsClass = false;
637};
638
647
648// TODO: Expand to allow for documenting templating and default args.
649// Info for functions.
650struct FunctionInfo : public SymbolInfo {
653
654 void merge(FunctionInfo &&I);
655
658 llvm::ArrayRef<FieldTypeInfo> Params = {};
659 StringRef Prototype = {};
660
661 // When present, this function is a template or specialization.
662 std::optional<TemplateInfo> Template;
663
664 // Access level for this method (public, private, protected, none).
665 // AS_public is set as default because the bitcode writer requires the enum
666 // with value 0 to be used as the default.
667 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
668 AccessSpecifier Access = AccessSpecifier::AS_public;
669
670 bool IsMethod = false;
671};
672
673// TODO: Expand to allow for documenting templating, inheritance access,
674// friend classes
675// Info for types.
676struct RecordInfo : public SymbolInfo {
677 RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
678 StringRef Path = StringRef());
679
680 RecordInfo(const RecordInfo &Other, llvm::BumpPtrAllocator &Arena);
681
682 void merge(RecordInfo &&I);
683
684 // Type of this record (struct, class, union, interface).
685 TagTypeKind TagType = TagTypeKind::Struct;
686
687 // Indicates if the record was declared using a typedef. Things like anonymous
688 // structs in a typedef:
689 // typedef struct { ... } foo_t;
690 // are converted into records with the typedef as the Name + this flag set.
691 bool IsTypeDef = false;
692
693 // When present, this record is a template or specialization.
694 std::optional<TemplateInfo> Template;
695
696 llvm::ArrayRef<MemberTypeInfo> Members =
697 {}; // List of info about record members.
698 llvm::ArrayRef<Reference> Parents =
699 {}; // List of base/parent records (does not include virtual parents).
700 llvm::ArrayRef<Reference> VirtualParents =
701 {}; // List of virtual base/parent records.
702
703 llvm::ArrayRef<BaseRecordInfo> Bases =
704 {}; // List of base/parent records; this includes inherited methods and
705 // attributes
706
707 llvm::ArrayRef<FriendInfo> Friends = {};
708
710};
711
712// Info for typedef and using statements.
713struct TypedefInfo : public SymbolInfo {
716
717 void merge(TypedefInfo &&I);
718
720
721 // Only type aliases can be templates.
722 std::optional<TemplateInfo> Template;
723
724 // Underlying type declaration
725 StringRef TypeDeclaration = {};
726
727 // Indicates if this is a new C++ "using"-style typedef:
728 // using MyVector = std::vector<int>
729 // False means it's a C-style typedef:
730 // typedef std::vector<int> MyVector;
731 bool IsUsing = false;
732};
733
734struct BaseRecordInfo : public RecordInfo {
736 BaseRecordInfo(const BaseRecordInfo &Other, llvm::BumpPtrAllocator &Arena);
737 BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
738 AccessSpecifier Access, bool IsParent);
739
740 // Access level associated with this inherited info (public, protected,
741 // private).
742 AccessSpecifier Access = AccessSpecifier::AS_public;
743 // Indicates if base corresponds to a virtual inheritance
744 bool IsVirtual = false;
745 bool IsParent = false; // Indicates if this base is a direct parent
746};
747
748// Information for a single possible value of an enumeration.
750 explicit EnumValueInfo(StringRef Name = StringRef(),
751 StringRef Value = StringRef("0"),
752 StringRef ValueExpr = StringRef())
755
756 EnumValueInfo(const EnumValueInfo &Other, llvm::BumpPtrAllocator &Arena);
757
758 bool operator==(const EnumValueInfo &Other) const {
759 return std::tie(Name, Value, ValueExpr) ==
760 std::tie(Other.Name, Other.Value, Other.ValueExpr);
761 }
762
763 StringRef Name = {};
764
765 // The computed value of the enumeration constant. This could be the result of
766 // evaluating the ValueExpr, or it could be automatically generated according
767 // to C rules.
768 StringRef Value = {};
769
770 // Stores the user-supplied initialization expression for this enumeration
771 // constant. This will be empty for implicit enumeration values.
772 StringRef ValueExpr = {};
773
774 /// Comment description of this field.
776};
777
778// TODO: Expand to allow for documenting templating.
779// Info for types.
780struct EnumInfo : public SymbolInfo {
783
784 void merge(EnumInfo &&I);
785
786 // Indicates whether this enum is scoped (e.g. enum class).
787 bool Scoped = false;
788
789 // Set to nonempty to the type when this is an explicitly typed enum. For
790 // enum Foo : short { ... };
791 // this will be "short".
792 std::optional<TypeInfo> BaseType;
793
794 llvm::ArrayRef<EnumValueInfo> Members = {}; // List of enum members.
795};
796
807
808struct Index : public Reference {
809 Index() = default;
810 Index(StringRef Name) : Reference(SymbolID(), Name) {}
813 Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
814 : Reference(USR, Name, IT, Name, Path) {}
815 // This is used to look for a USR in a vector of Indexes using std::find
816 bool operator==(const SymbolID &Other) const { return USR == Other; }
817 bool operator<(const Index &Other) const;
818
819 std::optional<StringRef> JumpToSection;
820 llvm::StringMap<Index> Children;
821
822 std::vector<const Index *> getSortedChildren() const;
823 void sort();
824};
825
826// TODO: Add functionality to include separate markdown pages.
827
828// A standalone function to call to merge a vector of infos into one.
829// This assumes that all infos in the vector are of the same type, and will fail
830// if they are different.
831llvm::Expected<Info *> mergeInfos(SmallVectorImpl<Info *> &Values);
832
833// Merges a single new Info into an existing Reduced Info (allocating it if
834// needed).
835llvm::Error mergeSingleInfo(doc::Info *&Reduced, doc::Info *NewInfo,
836 llvm::BumpPtrAllocator &Arena);
837
839 ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
840 bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
841 StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
842 StringRef Base, std::vector<std::string> UserStylesheets,
843 clang::DiagnosticsEngine &Diags, OutputFormatTy Format,
844 bool FTimeTrace = false, bool Pretty = false);
845 tooling::ExecutionContext *ECtx;
846 std::string ProjectName; // Name of project clang-doc is documenting.
847 std::string OutDirectory; // Directory for outputting generated files.
848 std::string SourceRoot; // Directory where processed files are stored. Links
849 // to definition locations will only be generated if
850 // the file is in this dir.
851 // URL of repository that hosts code used for links to definition locations.
852 std::optional<std::string> RepositoryUrl;
853 // Prefix of line code for repository.
854 std::optional<std::string> RepositoryLinePrefix;
855 // Path of CSS stylesheets that will be copied to OutDirectory and used to
856 // style all HTML files.
857 std::vector<std::string> UserStylesheets;
858 // JavaScript files that will be imported in all HTML files.
859 std::vector<std::string> JsScripts;
860 // Base directory for remote repositories.
861 StringRef Base;
862 // Maps mustache template types to specific mustache template files.
863 // Ex. comment-template -> /path/to/comment-template.mustache
864 llvm::StringMap<std::string> MustacheTemplates;
865 // A pointer to a DiagnosticsEngine for error reporting.
866 clang::DiagnosticsEngine &Diags;
869 int Granularity; // Granularity of ftime trace
870 bool PublicOnly; // Indicates if only public declarations are documented.
871 bool FTimeTrace; // Indicates if ftime trace is turned on
872 bool Pretty; // Indicates if JSON is emitted with whitespace.
873};
874
875// Ensure arena allocated types remain safe to allocate in the arena.
876// Only trivially destructible types are safe, so enforce that at compile-time.
877static_assert(std::is_trivially_destructible_v<CommentInfo>);
878static_assert(std::is_trivially_destructible_v<ConceptInfo>);
879static_assert(std::is_trivially_destructible_v<ConstraintInfo>);
880static_assert(std::is_trivially_destructible_v<EnumInfo>);
881static_assert(std::is_trivially_destructible_v<FieldTypeInfo>);
882static_assert(std::is_trivially_destructible_v<FriendInfo>);
883static_assert(std::is_trivially_destructible_v<FunctionInfo>);
884static_assert(std::is_trivially_destructible_v<Info>);
885static_assert(std::is_trivially_destructible_v<Location>);
886static_assert(std::is_trivially_destructible_v<MemberTypeInfo>);
887static_assert(std::is_trivially_destructible_v<NamespaceInfo>);
888static_assert(std::is_trivially_destructible_v<RecordInfo>);
889static_assert(std::is_trivially_destructible_v<Reference>);
890static_assert(std::is_trivially_destructible_v<ScopeChildren>);
891static_assert(std::is_trivially_destructible_v<SymbolInfo>);
892static_assert(std::is_trivially_destructible_v<TemplateInfo>);
893static_assert(std::is_trivially_destructible_v<TemplateParamInfo>);
894static_assert(std::is_trivially_destructible_v<TemplateSpecializationInfo>);
895static_assert(std::is_trivially_destructible_v<TypeInfo>);
896static_assert(std::is_trivially_destructible_v<TypedefInfo>);
897static_assert(std::is_trivially_destructible_v<VarInfo>);
898
899} // namespace doc
900} // namespace clang
901
902#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
static llvm::cl::opt< std::string > RepositoryCodeLinePrefix("repository-line-prefix", llvm::cl::desc("Prefix of line code for repository."), llvm::cl::cat(ClangDocCategory))
clang::find_all_symbols::SymbolInfo SymbolInfo
StringRef intern(StringRef Name)
T * allocatePtr(llvm::BumpPtrAllocator &Alloc, Args &&...args)
llvm::simple_ilist< InfoNode< T > > DocList
thread_local llvm::BumpPtrAllocator PersistentArena
T * allocatePersistent(Args &&...args)
T * allocateTransient(Args &&...args)
ConcurrentStringPool & getGlobalStringPool()
CommentKind stringToCommentKind(llvm::StringRef KindStr)
llvm::ArrayRef< T > deepCopyArray(llvm::ArrayRef< T > V, llvm::BumpPtrAllocator &Alloc)
InfoNode< T > * allocateListNodePersistent(Args &&...args)
InfoNode< T > * allocateListNode(llvm::BumpPtrAllocator &Alloc, Args &&...args)
thread_local llvm::BumpPtrAllocator TransientArena
StringRef internString(const Twine &T)
llvm::ArrayRef< T > allocateArray(llvm::SmallVectorImpl< T > &V, llvm::BumpPtrAllocator &Alloc)
llvm::Expected< Info * > mergeInfos(SmallVectorImpl< Info * > &Values)
InfoNode< T > * allocateListNodeTransient(Args &&...args)
constexpr SymbolID GlobalNamespaceID
std::array< uint8_t, 20 > SymbolID
llvm::StringRef commentKindToString(CommentKind Kind)
llvm::Error mergeSingleInfo(doc::Info *&Reduced, doc::Info *NewInfo, llvm::BumpPtrAllocator &Arena)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::optional< std::string > RepositoryUrl
std::vector< std::string > UserStylesheets
llvm::StringMap< std::string > MustacheTemplates
std::vector< std::string > JsScripts
tooling::ExecutionContext * ECtx
clang::DiagnosticsEngine & Diags
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName, bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot, StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix, StringRef Base, std::vector< std::string > UserStylesheets, clang::DiagnosticsEngine &Diags, OutputFormatTy Format, bool FTimeTrace=false, bool Pretty=false)
std::optional< std::string > RepositoryLinePrefix
ArrayRef< StringRef > Args
CommentInfo & operator=(CommentInfo &&Other)=default
CommentInfo(CommentKind Kind, llvm::ArrayRef< CommentInfo > Children={}, StringRef Text=StringRef(), StringRef Name=StringRef(), StringRef CloseName=StringRef(), StringRef Direction=StringRef(), StringRef ParamName=StringRef(), bool Explicit=false, bool SelfClosing=false, llvm::ArrayRef< StringRef > AttrKeys={}, llvm::ArrayRef< StringRef > AttrValues={})
bool operator<(const CommentInfo &Other) const
CommentInfo(CommentInfo &&Other)=default
bool operator==(const CommentInfo &Other) const
CommentInfo(const CommentInfo &Other)=default
ArrayRef< CommentInfo > Children
CommentInfo & operator=(const CommentInfo &Other)=default
ArrayRef< StringRef > AttrKeys
ArrayRef< StringRef > AttrValues
void merge(ConceptInfo &&I)
ConstraintInfo(SymbolID USR, StringRef Name)
Context(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName, StringRef Path, StringRef DocumentationFileName)
llvm::ArrayRef< EnumValueInfo > Members
void merge(EnumInfo &&I)
std::optional< TypeInfo > BaseType
DocList< CommentInfo > Description
Comment description of this field.
bool operator==(const EnumValueInfo &Other) const
EnumValueInfo(StringRef Name=StringRef(), StringRef Value=StringRef("0"), StringRef ValueExpr=StringRef())
FieldTypeInfo(const TypeInfo &TI, StringRef Name=StringRef(), StringRef DefaultValue=StringRef())
bool operator==(const FieldTypeInfo &Other) const
FriendInfo(const InfoType IT, const SymbolID &USR, const StringRef Name=StringRef())
std::optional< TypeInfo > ReturnType
void merge(FriendInfo &&Other)
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
bool mergeable(const FriendInfo &Other)
FunctionInfo(SymbolID USR=SymbolID())
llvm::ArrayRef< FieldTypeInfo > Params
void merge(FunctionInfo &&I)
std::optional< TemplateInfo > Template
Index(StringRef Name, StringRef JumpToSection)
bool operator<(const Index &Other) const
std::optional< StringRef > JumpToSection
bool operator==(const SymbolID &Other) const
Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
Index(StringRef Name)
llvm::StringMap< Index > Children
std::vector< const Index * > getSortedChildren() const
bool operator<(const InfoNode< T > &Other) const
bool operator!=(const InfoNode< T > &Other) const
const T * operator->() const
const T & operator*() const
bool operator==(const InfoNode< T > &Other) const
A base struct for Infos.
StringRef getRelativeFilePath(const StringRef &CurrentPath) const
Returns the file path for this Info relative to CurrentPath.
Info & operator=(Info &&Other)=default
Info(InfoType IT=InfoType::IT_default, SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
bool mergeable(const Info &Other)
DocList< CommentInfo > Description
llvm::ArrayRef< Reference > Namespace
StringRef extractName() const
StringRef DocumentationFileName
void mergeBase(Info &&I)
Info(Info &&Other)=default
Info(const Info &Other)=delete
StringRef getFileBaseName() const
Returns the basename that should be used for this Info.
bool operator==(const Location &Other) const
Location(int StartLineNumber=0, int EndLineNumber=0, StringRef Filename=StringRef(), bool IsFileInRootDir=false)
bool operator<(const Location &Other) const
bool operator!=(const Location &Other) const
MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access, bool IsStatic=false)
DocList< CommentInfo > Description
bool operator==(const MemberTypeInfo &Other) const
NamespaceInfo(SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
void merge(NamespaceInfo &&I)
llvm::ArrayRef< BaseRecordInfo > Bases
llvm::ArrayRef< FriendInfo > Friends
RecordInfo(SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
llvm::ArrayRef< Reference > VirtualParents
std::optional< TemplateInfo > Template
llvm::ArrayRef< Reference > Parents
llvm::ArrayRef< MemberTypeInfo > Members
void merge(RecordInfo &&I)
Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName, StringRef Path, StringRef DocumentationFileName)
void merge(Reference &&I)
Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName, StringRef Path=StringRef())
Reference(SymbolID USR=SymbolID(), StringRef Name=StringRef(), InfoType IT=InfoType::IT_default)
bool mergeable(const Reference &Other)
StringRef getFileBaseName() const
Returns the basename that should be used for this Reference.
StringRef getRelativeFilePath(const StringRef &CurrentPath) const
Returns the path for this Reference relative to CurrentPath.
bool operator<(const Reference &Other) const
bool operator==(const Reference &Other) const
DocList< Reference > Records
DocList< EnumInfo > Enums
DocList< ConceptInfo > Concepts
DocList< VarInfo > Variables
DocList< FunctionInfo > Functions
DocList< Reference > Namespaces
DocList< TypedefInfo > Typedefs
SymbolInfo(InfoType IT, SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
DocList< Location > Loc
bool operator<(const SymbolInfo &Other) const
std::optional< Location > DefLoc
void merge(SymbolInfo &&I)
llvm::ArrayRef< TemplateParamInfo > Params
llvm::ArrayRef< ConstraintInfo > Constraints
std::optional< TemplateSpecializationInfo > Specialization
TemplateParamInfo(StringRef Contents)
llvm::ArrayRef< TemplateParamInfo > Params
TypeInfo(StringRef Name, StringRef Path=StringRef())
TypeInfo(const Reference &R)
bool operator==(const TypeInfo &Other) const
void merge(TypedefInfo &&I)
std::optional< TemplateInfo > Template
TypedefInfo(SymbolID USR=SymbolID())
VarInfo(SymbolID USR)
void merge(VarInfo &&I)