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/Specifiers.h"
19#include "clang/Tooling/StandaloneExecution.h"
20#include "llvm/ADT/APSInt.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringExtras.h"
23#include <array>
24#include <optional>
25#include <string>
26
27namespace clang {
28namespace doc {
29
30// SHA1'd hash of a USR.
31using SymbolID = std::array<uint8_t, 20>;
32
33struct BaseRecordInfo;
34struct EnumInfo;
35struct FunctionInfo;
36struct Info;
37struct TypedefInfo;
38
39enum class InfoType {
40 IT_default,
41 IT_namespace,
42 IT_record,
43 IT_function,
44 IT_enum,
45 IT_typedef
46};
47
48enum class CommentKind {
49 CK_FullComment,
50 CK_ParagraphComment,
51 CK_TextComment,
52 CK_InlineCommandComment,
53 CK_HTMLStartTagComment,
54 CK_HTMLEndTagComment,
55 CK_BlockCommandComment,
56 CK_ParamCommandComment,
57 CK_TParamCommandComment,
58 CK_VerbatimBlockComment,
59 CK_VerbatimBlockLineComment,
60 CK_VerbatimLineComment,
61 CK_Unknown
62};
63
64CommentKind stringToCommentKind(llvm::StringRef KindStr);
65llvm::StringRef commentKindToString(CommentKind Kind);
66
67// A representation of a parsed comment.
68struct CommentInfo {
69 CommentInfo() = default;
70 CommentInfo(CommentInfo &Other) = delete;
71 CommentInfo(CommentInfo &&Other) = default;
72 CommentInfo &operator=(CommentInfo &&Other) = default;
73
74 bool operator==(const CommentInfo &Other) const;
75
76 // This operator is used to sort a vector of CommentInfos.
77 // No specific order (attributes more important than others) is required. Any
78 // sort is enough, the order is only needed to call std::unique after sorting
79 // the vector.
80 bool operator<(const CommentInfo &Other) const;
81
82 CommentKind Kind = CommentKind::
83 CK_Unknown; // Kind of comment (FullComment, ParagraphComment,
84 // TextComment, InlineCommandComment, HTMLStartTagComment,
85 // HTMLEndTagComment, BlockCommandComment,
86 // ParamCommandComment, TParamCommandComment,
87 // VerbatimBlockComment, VerbatimBlockLineComment,
88 // VerbatimLineComment).
89 SmallString<64> Text; // Text of the comment.
90 SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
91 SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
92 SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
93 SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
94 bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
95 bool Explicit = false; // Indicates if the direction of a param is explicit
96 // (for (T)ParamCommand).
97 llvm::SmallVector<SmallString<16>, 4>
98 AttrKeys; // List of attribute keys (for HTML).
99 llvm::SmallVector<SmallString<16>, 4>
100 AttrValues; // List of attribute values for each key (for HTML).
101 llvm::SmallVector<SmallString<16>, 4>
102 Args; // List of arguments to commands (for InlineCommand).
103 std::vector<std::unique_ptr<CommentInfo>>
104 Children; // List of child comments for this CommentInfo.
105};
106
107struct Reference {
108 // This variant (that takes no qualified name parameter) uses the Name as the
109 // QualName (very useful in unit tests to reduce verbosity). This can't use an
110 // empty string to indicate the default because we need to accept the empty
111 // string as a valid input for the global namespace (it will have
112 // "GlobalNamespace" as the name, but an empty QualName).
113 Reference(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
114 InfoType IT = InfoType::IT_default)
115 : USR(USR), Name(Name), QualName(Name), RefType(IT) {}
116 Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
117 StringRef Path = StringRef())
118 : USR(USR), Name(Name), QualName(QualName), RefType(IT), Path(Path) {}
119
120 bool operator==(const Reference &Other) const {
121 return std::tie(args: USR, args: Name, args: QualName, args: RefType) ==
122 std::tie(args: Other.USR, args: Other.Name, args: QualName, args: Other.RefType);
123 }
124
125 bool mergeable(const Reference &Other);
126 void merge(Reference &&I);
127 bool operator<(const Reference &Other) const { return Name < Other.Name; }
128
129 /// Returns the path for this Reference relative to CurrentPath.
130 llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
131
132 /// Returns the basename that should be used for this Reference.
133 llvm::SmallString<16> getFileBaseName() const;
134
135 SymbolID USR = SymbolID(); // Unique identifier for referenced decl
136
137 // Name of type (possibly unresolved). Not including namespaces or template
138 // parameters (so for a std::vector<int> this would be "vector"). See also
139 // QualName.
140 SmallString<16> Name;
141
142 // Full qualified name of this type, including namespaces and template
143 // parameter (for example this could be "std::vector<int>"). Contrast to
144 // Name.
145 SmallString<16> QualName;
146
147 InfoType RefType = InfoType::IT_default; // Indicates the type of this
148 // Reference (namespace, record,
149 // function, enum, default).
150 // Path of directory where the clang-doc generated file will be saved
151 // (possibly unresolved)
152 llvm::SmallString<128> Path;
153};
154
155// Holds the children of a record or namespace.
156struct ScopeChildren {
157 // Namespaces and Records are references because they will be properly
158 // documented in their own info, while the entirety of Functions and Enums are
159 // included here because they should not have separate documentation from
160 // their scope.
161 //
162 // Namespaces are not syntactically valid as children of records, but making
163 // this general for all possible container types reduces code complexity.
164 std::vector<Reference> Namespaces;
165 std::vector<Reference> Records;
166 std::vector<FunctionInfo> Functions;
167 std::vector<EnumInfo> Enums;
168 std::vector<TypedefInfo> Typedefs;
169
170 void sort();
171};
172
173// A base struct for TypeInfos
174struct TypeInfo {
175 TypeInfo() = default;
176 TypeInfo(const Reference &R) : Type(R) {}
177
178 // Convenience constructor for when there is no symbol ID or info type
179 // (normally used for built-in types in tests).
180 TypeInfo(StringRef Name, StringRef Path = StringRef())
181 : Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}
182
183 bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
184
185 Reference Type; // Referenced type in this info.
186
187 bool IsTemplate = false;
188 bool IsBuiltIn = false;
189};
190
191// Represents one template parameter.
192//
193// This is a very simple serialization of the text of the source code of the
194// template parameter. It is saved in a struct so there is a place to add the
195// name and default values in the future if needed.
196struct TemplateParamInfo {
197 TemplateParamInfo() = default;
198 explicit TemplateParamInfo(StringRef Contents) : Contents(Contents) {}
199
200 // The literal contents of the code for that specifies this template parameter
201 // for this declaration. Typical values will be "class T" and
202 // "typename T = int".
203 SmallString<16> Contents;
204};
205
206struct TemplateSpecializationInfo {
207 // Indicates the declaration that this specializes.
208 SymbolID SpecializationOf;
209
210 // Template parameters applying to the specialized record/function.
211 std::vector<TemplateParamInfo> Params;
212};
213
214// Records the template information for a struct or function that is a template
215// or an explicit template specialization.
216struct TemplateInfo {
217 // May be empty for non-partial specializations.
218 std::vector<TemplateParamInfo> Params;
219
220 // Set when this is a specialization of another record/function.
221 std::optional<TemplateSpecializationInfo> Specialization;
222};
223
224// Info for field types.
225struct FieldTypeInfo : public TypeInfo {
226 FieldTypeInfo() = default;
227 FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
228 StringRef DefaultValue = StringRef())
229 : TypeInfo(TI), Name(Name), DefaultValue(DefaultValue) {}
230
231 bool operator==(const FieldTypeInfo &Other) const {
232 return std::tie(args: Type, args: Name, args: DefaultValue) ==
233 std::tie(args: Other.Type, args: Other.Name, args: Other.DefaultValue);
234 }
235
236 SmallString<16> Name; // Name associated with this info.
237
238 // When used for function parameters, contains the string representing the
239 // expression of the default value, if any.
240 SmallString<16> DefaultValue;
241};
242
243// Info for member types.
244struct MemberTypeInfo : public FieldTypeInfo {
245 MemberTypeInfo() = default;
246 MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access,
247 bool IsStatic = false)
248 : FieldTypeInfo(TI, Name), Access(Access), IsStatic(IsStatic) {}
249
250 bool operator==(const MemberTypeInfo &Other) const {
251 return std::tie(args: Type, args: Name, args: Access, args: IsStatic, args: Description) ==
252 std::tie(args: Other.Type, args: Other.Name, args: Other.Access, args: Other.IsStatic,
253 args: Other.Description);
254 }
255
256 // Access level associated with this info (public, protected, private, none).
257 // AS_public is set as default because the bitcode writer requires the enum
258 // with value 0 to be used as the default.
259 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
260 AccessSpecifier Access = AccessSpecifier::AS_public;
261
262 std::vector<CommentInfo> Description; // Comment description of this field.
263 bool IsStatic = false;
264};
265
266struct Location {
267 Location(int StartLineNumber = 0, int EndLineNumber = 0,
268 StringRef Filename = StringRef(), bool IsFileInRootDir = false)
269 : StartLineNumber(StartLineNumber), EndLineNumber(EndLineNumber),
270 Filename(Filename), IsFileInRootDir(IsFileInRootDir) {}
271
272 bool operator==(const Location &Other) const {
273 return std::tie(args: StartLineNumber, args: EndLineNumber, args: Filename) ==
274 std::tie(args: Other.StartLineNumber, args: Other.EndLineNumber, args: Other.Filename);
275 }
276
277 bool operator!=(const Location &Other) const { return !(*this == Other); }
278
279 // This operator is used to sort a vector of Locations.
280 // No specific order (attributes more important than others) is required. Any
281 // sort is enough, the order is only needed to call std::unique after sorting
282 // the vector.
283 bool operator<(const Location &Other) const {
284 return std::tie(args: StartLineNumber, args: EndLineNumber, args: Filename) <
285 std::tie(args: Other.StartLineNumber, args: Other.EndLineNumber, args: Other.Filename);
286 }
287
288 int StartLineNumber = 0; // Line number of this Location.
289 int EndLineNumber = 0;
290 SmallString<32> Filename; // File for this Location.
291 bool IsFileInRootDir = false; // Indicates if file is inside root directory
292};
293
294/// A base struct for Infos.
295struct Info {
296 Info(InfoType IT = InfoType::IT_default, SymbolID USR = SymbolID(),
297 StringRef Name = StringRef(), StringRef Path = StringRef())
298 : USR(USR), IT(IT), Name(Name), Path(Path) {}
299
300 Info(const Info &Other) = delete;
301 Info(Info &&Other) = default;
302
303 virtual ~Info() = default;
304
305 Info &operator=(Info &&Other) = default;
306
307 SymbolID USR =
308 SymbolID(); // Unique identifier for the decl described by this Info.
309 InfoType IT = InfoType::IT_default; // InfoType of this particular Info.
310 SmallString<16> Name; // Unqualified name of the decl.
311 llvm::SmallVector<Reference, 4>
312 Namespace; // List of parent namespaces for this decl.
313 std::vector<CommentInfo> Description; // Comment description of this decl.
314 llvm::SmallString<128> Path; // Path of directory where the clang-doc
315 // generated file will be saved
316
317 void mergeBase(Info &&I);
318 bool mergeable(const Info &Other);
319
320 llvm::SmallString<16> extractName() const;
321
322 /// Returns the file path for this Info relative to CurrentPath.
323 llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
324
325 /// Returns the basename that should be used for this Info.
326 llvm::SmallString<16> getFileBaseName() const;
327};
328
329// Info for namespaces.
330struct NamespaceInfo : public Info {
331 NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
332 StringRef Path = StringRef());
333
334 void merge(NamespaceInfo &&I);
335
336 ScopeChildren Children;
337};
338
339// Info for symbols.
340struct SymbolInfo : public Info {
341 SymbolInfo(InfoType IT, SymbolID USR = SymbolID(),
342 StringRef Name = StringRef(), StringRef Path = StringRef())
343 : Info(IT, USR, Name, Path) {}
344
345 void merge(SymbolInfo &&I);
346
347 bool operator<(const SymbolInfo &Other) const {
348 // Sort by declaration location since we want the doc to be
349 // generated in the order of the source code.
350 // If the declaration location is the same, or not present
351 // we sort by defined location otherwise fallback to the extracted name
352 if (Loc.size() > 0 && Other.Loc.size() > 0 && Loc[0] != Other.Loc[0])
353 return Loc[0] < Other.Loc[0];
354
355 if (DefLoc && Other.DefLoc && *DefLoc != *Other.DefLoc)
356 return *DefLoc < *Other.DefLoc;
357
358 return extractName() < Other.extractName();
359 }
360
361 std::optional<Location> DefLoc; // Location where this decl is defined.
362 llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
363 bool IsStatic = false;
364};
365
366// TODO: Expand to allow for documenting templating and default args.
367// Info for functions.
368struct FunctionInfo : public SymbolInfo {
369 FunctionInfo(SymbolID USR = SymbolID())
370 : SymbolInfo(InfoType::IT_function, USR) {}
371
372 void merge(FunctionInfo &&I);
373
374 bool IsMethod = false; // Indicates whether this function is a class method.
375 Reference Parent; // Reference to the parent class decl for this method.
376 TypeInfo ReturnType; // Info about the return type of this function.
377 llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
378 // Access level for this method (public, private, protected, none).
379 // AS_public is set as default because the bitcode writer requires the enum
380 // with value 0 to be used as the default.
381 // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
382 AccessSpecifier Access = AccessSpecifier::AS_public;
383
384 // Full qualified name of this function, including namespaces and template
385 // specializations.
386 SmallString<16> FullName;
387
388 // Function Prototype
389 SmallString<256> Prototype;
390
391 // When present, this function is a template or specialization.
392 std::optional<TemplateInfo> Template;
393};
394
395// TODO: Expand to allow for documenting templating, inheritance access,
396// friend classes
397// Info for types.
398struct RecordInfo : public SymbolInfo {
399 RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
400 StringRef Path = StringRef());
401
402 void merge(RecordInfo &&I);
403
404 // Type of this record (struct, class, union, interface).
405 TagTypeKind TagType = TagTypeKind::Struct;
406
407 // Full qualified name of this record, including namespaces and template
408 // specializations.
409 SmallString<16> FullName;
410
411 // When present, this record is a template or specialization.
412 std::optional<TemplateInfo> Template;
413
414 // Indicates if the record was declared using a typedef. Things like anonymous
415 // structs in a typedef:
416 // typedef struct { ... } foo_t;
417 // are converted into records with the typedef as the Name + this flag set.
418 bool IsTypeDef = false;
419
420 llvm::SmallVector<MemberTypeInfo, 4>
421 Members; // List of info about record members.
422 llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
423 // (does not include virtual
424 // parents).
425 llvm::SmallVector<Reference, 4>
426 VirtualParents; // List of virtual base/parent records.
427
428 std::vector<BaseRecordInfo>
429 Bases; // List of base/parent records; this includes inherited methods and
430 // attributes
431
432 ScopeChildren Children;
433};
434
435// Info for typedef and using statements.
436struct TypedefInfo : public SymbolInfo {
437 TypedefInfo(SymbolID USR = SymbolID())
438 : SymbolInfo(InfoType::IT_typedef, USR) {}
439
440 void merge(TypedefInfo &&I);
441
442 TypeInfo Underlying;
443
444 // Underlying type declaration
445 SmallString<16> TypeDeclaration;
446
447 /// Comment description for the typedef.
448 std::vector<CommentInfo> Description;
449
450 // Indicates if this is a new C++ "using"-style typedef:
451 // using MyVector = std::vector<int>
452 // False means it's a C-style typedef:
453 // typedef std::vector<int> MyVector;
454 bool IsUsing = false;
455};
456
457struct BaseRecordInfo : public RecordInfo {
458 BaseRecordInfo();
459 BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
460 AccessSpecifier Access, bool IsParent);
461
462 // Indicates if base corresponds to a virtual inheritance
463 bool IsVirtual = false;
464 // Access level associated with this inherited info (public, protected,
465 // private).
466 AccessSpecifier Access = AccessSpecifier::AS_public;
467 bool IsParent = false; // Indicates if this base is a direct parent
468};
469
470// Information for a single possible value of an enumeration.
471struct EnumValueInfo {
472 explicit EnumValueInfo(StringRef Name = StringRef(),
473 StringRef Value = StringRef("0"),
474 StringRef ValueExpr = StringRef())
475 : Name(Name), Value(Value), ValueExpr(ValueExpr) {}
476
477 bool operator==(const EnumValueInfo &Other) const {
478 return std::tie(args: Name, args: Value, args: ValueExpr) ==
479 std::tie(args: Other.Name, args: Other.Value, args: Other.ValueExpr);
480 }
481
482 SmallString<16> Name;
483
484 // The computed value of the enumeration constant. This could be the result of
485 // evaluating the ValueExpr, or it could be automatically generated according
486 // to C rules.
487 SmallString<16> Value;
488
489 // Stores the user-supplied initialization expression for this enumeration
490 // constant. This will be empty for implicit enumeration values.
491 SmallString<16> ValueExpr;
492
493 /// Comment description of this field.
494 std::vector<CommentInfo> Description;
495};
496
497// TODO: Expand to allow for documenting templating.
498// Info for types.
499struct EnumInfo : public SymbolInfo {
500 EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
501 EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}
502
503 void merge(EnumInfo &&I);
504
505 // Indicates whether this enum is scoped (e.g. enum class).
506 bool Scoped = false;
507
508 // Set to nonempty to the type when this is an explicitly typed enum. For
509 // enum Foo : short { ... };
510 // this will be "short".
511 std::optional<TypeInfo> BaseType;
512
513 llvm::SmallVector<EnumValueInfo, 4> Members; // List of enum members.
514};
515
516struct Index : public Reference {
517 Index() = default;
518 Index(StringRef Name) : Reference(SymbolID(), Name) {}
519 Index(StringRef Name, StringRef JumpToSection)
520 : Reference(SymbolID(), Name), JumpToSection(JumpToSection) {}
521 Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
522 : Reference(USR, Name, IT, Name, Path) {}
523 // This is used to look for a USR in a vector of Indexes using std::find
524 bool operator==(const SymbolID &Other) const { return USR == Other; }
525 bool operator<(const Index &Other) const;
526
527 std::optional<SmallString<16>> JumpToSection;
528 std::vector<Index> Children;
529
530 void sort();
531};
532
533// TODO: Add functionality to include separate markdown pages.
534
535// A standalone function to call to merge a vector of infos into one.
536// This assumes that all infos in the vector are of the same type, and will fail
537// if they are different.
538llvm::Expected<std::unique_ptr<Info>>
539mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
540
541struct ClangDocContext {
542 ClangDocContext() = default;
543 ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
544 bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
545 StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
546 StringRef Base, std::vector<std::string> UserStylesheets,
547 bool FTimeTrace = false);
548 tooling::ExecutionContext *ECtx;
549 std::string ProjectName; // Name of project clang-doc is documenting.
550 bool PublicOnly; // Indicates if only public declarations are documented.
551 bool FTimeTrace; // Indicates if ftime trace is turned on
552 int Granularity; // Granularity of ftime trace
553 std::string OutDirectory; // Directory for outputting generated files.
554 std::string SourceRoot; // Directory where processed files are stored. Links
555 // to definition locations will only be generated if
556 // the file is in this dir.
557 // URL of repository that hosts code used for links to definition locations.
558 std::optional<std::string> RepositoryUrl;
559 // Prefix of line code for repository.
560 std::optional<std::string> RepositoryLinePrefix;
561 // Path of CSS stylesheets that will be copied to OutDirectory and used to
562 // style all HTML files.
563 std::vector<std::string> UserStylesheets;
564 // JavaScript files that will be imported in all HTML files.
565 std::vector<std::string> JsScripts;
566 // Base directory for remote repositories.
567 StringRef Base;
568 // Maps mustache template types to specific mustache template files.
569 // Ex. comment-template -> /path/to/comment-template.mustache
570 llvm::StringMap<std::string> MustacheTemplates;
571 Index Idx;
572};
573
574} // namespace doc
575} // namespace clang
576
577#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
578

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/clang-doc/Representation.h