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