[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang-tools-extra / clang-doc / Representation.h
blob2738b6f5ca63a6b8afe8ebe023afd48f676f5b45
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.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
15 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
17 #include "clang/AST/Type.h"
18 #include "clang/Basic/Specifiers.h"
19 #include "clang/Tooling/StandaloneExecution.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include <array>
24 #include <string>
26 namespace clang {
27 namespace doc {
29 // SHA1'd hash of a USR.
30 using SymbolID = std::array<uint8_t, 20>;
32 struct Info;
33 struct FunctionInfo;
34 struct EnumInfo;
35 struct BaseRecordInfo;
37 enum class InfoType {
38 IT_default,
39 IT_namespace,
40 IT_record,
41 IT_function,
42 IT_enum
45 // A representation of a parsed comment.
46 struct CommentInfo {
47 CommentInfo() = default;
48 CommentInfo(CommentInfo &Other) = delete;
49 CommentInfo(CommentInfo &&Other) = default;
50 CommentInfo &operator=(CommentInfo &&Other) = default;
52 bool operator==(const CommentInfo &Other) const {
53 auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName,
54 SelfClosing, Explicit, AttrKeys, AttrValues, Args);
55 auto SecondCI =
56 std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction,
57 Other.ParamName, Other.CloseName, Other.SelfClosing,
58 Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args);
60 if (FirstCI != SecondCI || Children.size() != Other.Children.size())
61 return false;
63 return std::equal(Children.begin(), Children.end(), Other.Children.begin(),
64 llvm::deref<std::equal_to<>>{});
67 // This operator is used to sort a vector of CommentInfos.
68 // No specific order (attributes more important than others) is required. Any
69 // sort is enough, the order is only needed to call std::unique after sorting
70 // the vector.
71 bool operator<(const CommentInfo &Other) const {
72 auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName,
73 SelfClosing, Explicit, AttrKeys, AttrValues, Args);
74 auto SecondCI =
75 std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction,
76 Other.ParamName, Other.CloseName, Other.SelfClosing,
77 Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args);
79 if (FirstCI < SecondCI)
80 return true;
82 if (FirstCI == SecondCI) {
83 return std::lexicographical_compare(
84 Children.begin(), Children.end(), Other.Children.begin(),
85 Other.Children.end(), llvm::deref<std::less<>>());
88 return false;
91 SmallString<16>
92 Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
93 // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
94 // BlockCommandComment, ParamCommandComment,
95 // TParamCommandComment, VerbatimBlockComment,
96 // VerbatimBlockLineComment, VerbatimLineComment).
97 SmallString<64> Text; // Text of the comment.
98 SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
99 SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
100 SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
101 SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
102 bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
103 bool Explicit = false; // Indicates if the direction of a param is explicit
104 // (for (T)ParamCommand).
105 llvm::SmallVector<SmallString<16>, 4>
106 AttrKeys; // List of attribute keys (for HTML).
107 llvm::SmallVector<SmallString<16>, 4>
108 AttrValues; // List of attribute values for each key (for HTML).
109 llvm::SmallVector<SmallString<16>, 4>
110 Args; // List of arguments to commands (for InlineCommand).
111 std::vector<std::unique_ptr<CommentInfo>>
112 Children; // List of child comments for this CommentInfo.
115 struct Reference {
116 Reference() = default;
117 Reference(llvm::StringRef Name) : Name(Name) {}
118 // An empty path means the info is in the global namespace because the path is
119 // a composite of the parent namespaces.
120 Reference(llvm::StringRef Name, StringRef Path)
121 : Name(Name), Path(Path), IsInGlobalNamespace(Path.empty()) {}
122 Reference(SymbolID USR, StringRef Name, InfoType IT)
123 : USR(USR), Name(Name), RefType(IT) {}
124 // An empty path means the info is in the global namespace because the path is
125 // a composite of the parent namespaces.
126 Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
127 : USR(USR), Name(Name), RefType(IT), Path(Path),
128 IsInGlobalNamespace(Path.empty()) {}
130 bool operator==(const Reference &Other) const {
131 return std::tie(USR, Name, RefType) ==
132 std::tie(Other.USR, Other.Name, Other.RefType);
135 bool mergeable(const Reference &Other);
136 void merge(Reference &&I);
138 /// Returns the path for this Reference relative to CurrentPath.
139 llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
141 /// Returns the basename that should be used for this Reference.
142 llvm::SmallString<16> getFileBaseName() const;
144 SymbolID USR = SymbolID(); // Unique identifier for referenced decl
145 SmallString<16> Name; // Name of type (possibly unresolved).
146 InfoType RefType = InfoType::IT_default; // Indicates the type of this
147 // Reference (namespace, record,
148 // function, enum, default).
149 // Path of directory where the clang-doc generated file will be saved
150 // (possibly unresolved)
151 llvm::SmallString<128> Path;
152 // Indicates if the info's parent is the global namespace, or if the info is
153 // the global namespace
154 bool IsInGlobalNamespace = false;
157 // A base struct for TypeInfos
158 struct TypeInfo {
159 TypeInfo() = default;
160 TypeInfo(SymbolID Type, StringRef Field, InfoType IT)
161 : Type(Type, Field, IT) {}
162 TypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path)
163 : Type(Type, Field, IT, Path) {}
164 TypeInfo(llvm::StringRef RefName) : Type(RefName) {}
165 TypeInfo(llvm::StringRef RefName, StringRef Path) : Type(RefName, Path) {}
167 bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
169 Reference Type; // Referenced type in this info.
172 // Info for field types.
173 struct FieldTypeInfo : public TypeInfo {
174 FieldTypeInfo() = default;
175 FieldTypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path,
176 llvm::StringRef Name)
177 : TypeInfo(Type, Field, IT, Path), Name(Name) {}
178 FieldTypeInfo(llvm::StringRef RefName, llvm::StringRef Name)
179 : TypeInfo(RefName), Name(Name) {}
180 FieldTypeInfo(llvm::StringRef RefName, StringRef Path, llvm::StringRef Name)
181 : TypeInfo(RefName, Path), Name(Name) {}
183 bool operator==(const FieldTypeInfo &Other) const {
184 return std::tie(Type, Name) == std::tie(Other.Type, Other.Name);
187 SmallString<16> Name; // Name associated with this info.
190 // Info for member types.
191 struct MemberTypeInfo : public FieldTypeInfo {
192 MemberTypeInfo() = default;
193 MemberTypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path,
194 llvm::StringRef Name, AccessSpecifier Access)
195 : FieldTypeInfo(Type, Field, IT, Path, Name), Access(Access) {}
196 MemberTypeInfo(llvm::StringRef RefName, llvm::StringRef Name,
197 AccessSpecifier Access)
198 : FieldTypeInfo(RefName, Name), Access(Access) {}
199 MemberTypeInfo(llvm::StringRef RefName, StringRef Path, llvm::StringRef Name,
200 AccessSpecifier Access)
201 : FieldTypeInfo(RefName, Path, Name), Access(Access) {}
203 bool operator==(const MemberTypeInfo &Other) const {
204 return std::tie(Type, Name, Access, Description) ==
205 std::tie(Other.Type, Other.Name, Other.Access, Other.Description);
208 // Access level associated with this info (public, protected, private, none).
209 // AS_public is set as default because the bitcode writer requires the enum
210 // with value 0 to be used as the default.
211 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
212 AccessSpecifier Access = AccessSpecifier::AS_public;
214 std::vector<CommentInfo> Description; // Comment description of this field.
217 struct Location {
218 Location() = default;
219 Location(int LineNumber, SmallString<16> Filename)
220 : LineNumber(LineNumber), Filename(std::move(Filename)) {}
221 Location(int LineNumber, SmallString<16> Filename, bool IsFileInRootDir)
222 : LineNumber(LineNumber), Filename(std::move(Filename)),
223 IsFileInRootDir(IsFileInRootDir) {}
225 bool operator==(const Location &Other) const {
226 return std::tie(LineNumber, Filename) ==
227 std::tie(Other.LineNumber, Other.Filename);
230 // This operator is used to sort a vector of Locations.
231 // No specific order (attributes more important than others) is required. Any
232 // sort is enough, the order is only needed to call std::unique after sorting
233 // the vector.
234 bool operator<(const Location &Other) const {
235 return std::tie(LineNumber, Filename) <
236 std::tie(Other.LineNumber, Other.Filename);
239 int LineNumber; // Line number of this Location.
240 SmallString<32> Filename; // File for this Location.
241 bool IsFileInRootDir = false; // Indicates if file is inside root directory
244 /// A base struct for Infos.
245 struct Info {
246 Info() = default;
247 Info(InfoType IT) : IT(IT) {}
248 Info(InfoType IT, SymbolID USR) : USR(USR), IT(IT) {}
249 Info(InfoType IT, SymbolID USR, StringRef Name)
250 : USR(USR), IT(IT), Name(Name) {}
251 Info(InfoType IT, SymbolID USR, StringRef Name, StringRef Path)
252 : USR(USR), IT(IT), Name(Name), Path(Path) {}
253 Info(const Info &Other) = delete;
254 Info(Info &&Other) = default;
256 virtual ~Info() = default;
258 SymbolID USR =
259 SymbolID(); // Unique identifier for the decl described by this Info.
260 const InfoType IT = InfoType::IT_default; // InfoType of this particular Info.
261 SmallString<16> Name; // Unqualified name of the decl.
262 llvm::SmallVector<Reference, 4>
263 Namespace; // List of parent namespaces for this decl.
264 std::vector<CommentInfo> Description; // Comment description of this decl.
265 llvm::SmallString<128> Path; // Path of directory where the clang-doc
266 // generated file will be saved
268 void mergeBase(Info &&I);
269 bool mergeable(const Info &Other);
271 llvm::SmallString<16> extractName() const;
273 /// Returns the file path for this Info relative to CurrentPath.
274 llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
276 /// Returns the basename that should be used for this Info.
277 llvm::SmallString<16> getFileBaseName() const;
279 // Returns a reference to the parent scope (that is, the immediate parent
280 // namespace or class in which this decl resides).
281 llvm::Expected<Reference> getEnclosingScope();
284 // Info for namespaces.
285 struct NamespaceInfo : public Info {
286 NamespaceInfo() : Info(InfoType::IT_namespace) {}
287 NamespaceInfo(SymbolID USR) : Info(InfoType::IT_namespace, USR) {}
288 NamespaceInfo(SymbolID USR, StringRef Name)
289 : Info(InfoType::IT_namespace, USR, Name) {}
290 NamespaceInfo(SymbolID USR, StringRef Name, StringRef Path)
291 : Info(InfoType::IT_namespace, USR, Name, Path) {}
293 void merge(NamespaceInfo &&I);
295 // Namespaces and Records are references because they will be properly
296 // documented in their own info, while the entirety of Functions and Enums are
297 // included here because they should not have separate documentation from
298 // their scope.
299 std::vector<Reference> ChildNamespaces;
300 std::vector<Reference> ChildRecords;
301 std::vector<FunctionInfo> ChildFunctions;
302 std::vector<EnumInfo> ChildEnums;
305 // Info for symbols.
306 struct SymbolInfo : public Info {
307 SymbolInfo(InfoType IT) : Info(IT) {}
308 SymbolInfo(InfoType IT, SymbolID USR) : Info(IT, USR) {}
309 SymbolInfo(InfoType IT, SymbolID USR, StringRef Name) : Info(IT, USR, Name) {}
310 SymbolInfo(InfoType IT, SymbolID USR, StringRef Name, StringRef Path)
311 : Info(IT, USR, Name, Path) {}
313 void merge(SymbolInfo &&I);
315 llvm::Optional<Location> DefLoc; // Location where this decl is defined.
316 llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
319 // TODO: Expand to allow for documenting templating and default args.
320 // Info for functions.
321 struct FunctionInfo : public SymbolInfo {
322 FunctionInfo() : SymbolInfo(InfoType::IT_function) {}
323 FunctionInfo(SymbolID USR) : SymbolInfo(InfoType::IT_function, USR) {}
325 void merge(FunctionInfo &&I);
327 bool IsMethod = false; // Indicates whether this function is a class method.
328 Reference Parent; // Reference to the parent class decl for this method.
329 TypeInfo ReturnType; // Info about the return type of this function.
330 llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
331 // Access level for this method (public, private, protected, none).
332 // AS_public is set as default because the bitcode writer requires the enum
333 // with value 0 to be used as the default.
334 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
335 AccessSpecifier Access = AccessSpecifier::AS_public;
338 // TODO: Expand to allow for documenting templating, inheritance access,
339 // friend classes
340 // Info for types.
341 struct RecordInfo : public SymbolInfo {
342 RecordInfo() : SymbolInfo(InfoType::IT_record) {}
343 RecordInfo(SymbolID USR) : SymbolInfo(InfoType::IT_record, USR) {}
344 RecordInfo(SymbolID USR, StringRef Name)
345 : SymbolInfo(InfoType::IT_record, USR, Name) {}
346 RecordInfo(SymbolID USR, StringRef Name, StringRef Path)
347 : SymbolInfo(InfoType::IT_record, USR, Name, Path) {}
349 void merge(RecordInfo &&I);
351 // Type of this record (struct, class, union, interface).
352 TagTypeKind TagType = TagTypeKind::TTK_Struct;
354 // Indicates if the record was declared using a typedef. Things like anonymous
355 // structs in a typedef:
356 // typedef struct { ... } foo_t;
357 // are converted into records with the typedef as the Name + this flag set.
358 bool IsTypeDef = false;
360 llvm::SmallVector<MemberTypeInfo, 4>
361 Members; // List of info about record members.
362 llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
363 // (does not include virtual
364 // parents).
365 llvm::SmallVector<Reference, 4>
366 VirtualParents; // List of virtual base/parent records.
368 std::vector<BaseRecordInfo>
369 Bases; // List of base/parent records; this includes inherited methods and
370 // attributes
372 // Records are references because they will be properly documented in their
373 // own info, while the entirety of Functions and Enums are included here
374 // because they should not have separate documentation from their scope.
375 std::vector<Reference> ChildRecords;
376 std::vector<FunctionInfo> ChildFunctions;
377 std::vector<EnumInfo> ChildEnums;
380 struct BaseRecordInfo : public RecordInfo {
381 BaseRecordInfo() : RecordInfo() {}
382 BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
383 AccessSpecifier Access, bool IsParent)
384 : RecordInfo(USR, Name, Path), IsVirtual(IsVirtual), Access(Access),
385 IsParent(IsParent) {}
387 // Indicates if base corresponds to a virtual inheritance
388 bool IsVirtual = false;
389 // Access level associated with this inherited info (public, protected,
390 // private).
391 AccessSpecifier Access = AccessSpecifier::AS_public;
392 bool IsParent = false; // Indicates if this base is a direct parent
395 // TODO: Expand to allow for documenting templating.
396 // Info for types.
397 struct EnumInfo : public SymbolInfo {
398 EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
399 EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}
401 void merge(EnumInfo &&I);
403 bool Scoped =
404 false; // Indicates whether this enum is scoped (e.g. enum class).
405 llvm::SmallVector<SmallString<16>, 4> Members; // List of enum members.
408 struct Index : public Reference {
409 Index() = default;
410 Index(StringRef Name) : Reference(Name) {}
411 Index(StringRef Name, StringRef JumpToSection)
412 : Reference(Name), JumpToSection(JumpToSection) {}
413 Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
414 : Reference(USR, Name, IT, Path) {}
415 // This is used to look for a USR in a vector of Indexes using std::find
416 bool operator==(const SymbolID &Other) const { return USR == Other; }
417 bool operator<(const Index &Other) const;
419 llvm::Optional<SmallString<16>> JumpToSection;
420 std::vector<Index> Children;
422 void sort();
425 // TODO: Add functionality to include separate markdown pages.
427 // A standalone function to call to merge a vector of infos into one.
428 // This assumes that all infos in the vector are of the same type, and will fail
429 // if they are different.
430 llvm::Expected<std::unique_ptr<Info>>
431 mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
433 struct ClangDocContext {
434 ClangDocContext() = default;
435 ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
436 bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
437 StringRef RepositoryUrl,
438 std::vector<std::string> UserStylesheets,
439 std::vector<std::string> JsScripts);
440 tooling::ExecutionContext *ECtx;
441 std::string ProjectName; // Name of project clang-doc is documenting.
442 bool PublicOnly; // Indicates if only public declarations are documented.
443 std::string OutDirectory; // Directory for outputting generated files.
444 std::string SourceRoot; // Directory where processed files are stored. Links
445 // to definition locations will only be generated if
446 // the file is in this dir.
447 // URL of repository that hosts code used for links to definition locations.
448 llvm::Optional<std::string> RepositoryUrl;
449 // Path of CSS stylesheets that will be copied to OutDirectory and used to
450 // style all HTML files.
451 std::vector<std::string> UserStylesheets;
452 // JavaScript files that will be imported in allHTML file.
453 std::vector<std::string> JsScripts;
454 // Other files that should be copied to OutDirectory, besides UserStylesheets.
455 std::vector<std::string> FilesToCopy;
456 Index Idx;
459 } // namespace doc
460 } // namespace clang
462 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H