Line data Source code
1 : ///===-- Representation.h - ClangDoc Representation -------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the internal representations of different declaration
11 : // types for the clang-doc tool.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
16 : #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
17 :
18 : #include "clang/AST/Type.h"
19 : #include "clang/Basic/Specifiers.h"
20 : #include "clang/Tooling/StandaloneExecution.h"
21 : #include "llvm/ADT/Optional.h"
22 : #include "llvm/ADT/SmallVector.h"
23 : #include "llvm/ADT/StringExtras.h"
24 : #include <array>
25 : #include <string>
26 :
27 : namespace clang {
28 : namespace doc {
29 :
30 : // SHA1'd hash of a USR.
31 : using SymbolID = std::array<uint8_t, 20>;
32 :
33 : struct Info;
34 : struct FunctionInfo;
35 : struct EnumInfo;
36 :
37 : enum class InfoType {
38 : IT_default,
39 : IT_namespace,
40 : IT_record,
41 : IT_function,
42 : IT_enum
43 : };
44 :
45 : // A representation of a parsed comment.
46 : struct CommentInfo {
47 3 : CommentInfo() = default;
48 : CommentInfo(CommentInfo &Other) = delete;
49 6 : CommentInfo(CommentInfo &&Other) = default;
50 :
51 : SmallString<16>
52 : Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
53 : // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
54 : // BlockCommandComment, ParamCommandComment,
55 : // TParamCommandComment, VerbatimBlockComment,
56 : // VerbatimBlockLineComment, VerbatimLineComment).
57 : SmallString<64> Text; // Text of the comment.
58 : SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
59 : SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
60 : SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
61 : SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
62 : bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
63 : bool Explicit = false; // Indicates if the direction of a param is explicit
64 : // (for (T)ParamCommand).
65 : llvm::SmallVector<SmallString<16>, 4>
66 : AttrKeys; // List of attribute keys (for HTML).
67 : llvm::SmallVector<SmallString<16>, 4>
68 : AttrValues; // List of attribute values for each key (for HTML).
69 : llvm::SmallVector<SmallString<16>, 4>
70 : Args; // List of arguments to commands (for InlineCommand).
71 : std::vector<std::unique_ptr<CommentInfo>>
72 : Children; // List of child comments for this CommentInfo.
73 : };
74 :
75 192 : struct Reference {
76 93 : Reference() = default;
77 20 : Reference(llvm::StringRef Name) : Name(Name) {}
78 : Reference(SymbolID USR, StringRef Name, InfoType IT)
79 50 : : USR(USR), Name(Name), RefType(IT) {}
80 :
81 : bool operator==(const Reference &Other) const {
82 19 : return std::tie(USR, Name, RefType) ==
83 38 : std::tie(Other.USR, Other.Name, Other.RefType);
84 : }
85 :
86 : SymbolID USR = SymbolID(); // Unique identifer for referenced decl
87 : SmallString<16> Name; // Name of type (possibly unresolved).
88 : InfoType RefType = InfoType::IT_default; // Indicates the type of this
89 : // Reference (namespace, record,
90 : // function, enum, default).
91 : };
92 :
93 : // A base struct for TypeInfos
94 : struct TypeInfo {
95 : TypeInfo() = default;
96 16 : TypeInfo(SymbolID Type, StringRef Field, InfoType IT)
97 16 : : Type(Type, Field, IT) {}
98 20 : TypeInfo(llvm::StringRef RefName) : Type(RefName) {}
99 :
100 : bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
101 :
102 : Reference Type; // Referenced type in this info.
103 : };
104 :
105 : // Info for field types.
106 : struct FieldTypeInfo : public TypeInfo {
107 : FieldTypeInfo() = default;
108 : FieldTypeInfo(SymbolID Type, StringRef Field, InfoType IT,
109 : llvm::StringRef Name)
110 : : TypeInfo(Type, Field, IT), Name(Name) {}
111 20 : FieldTypeInfo(llvm::StringRef RefName, llvm::StringRef Name)
112 20 : : TypeInfo(RefName), Name(Name) {}
113 :
114 : bool operator==(const FieldTypeInfo &Other) const {
115 14 : return std::tie(Type, Name) == std::tie(Other.Type, Other.Name);
116 : }
117 :
118 : SmallString<16> Name; // Name associated with this info.
119 : };
120 :
121 : // Info for member types.
122 12 : struct MemberTypeInfo : public FieldTypeInfo {
123 : MemberTypeInfo() = default;
124 : MemberTypeInfo(SymbolID Type, StringRef Field, InfoType IT,
125 : llvm::StringRef Name, AccessSpecifier Access)
126 : : FieldTypeInfo(Type, Field, IT, Name), Access(Access) {}
127 : MemberTypeInfo(llvm::StringRef RefName, llvm::StringRef Name,
128 : AccessSpecifier Access)
129 6 : : FieldTypeInfo(RefName, Name), Access(Access) {}
130 :
131 : bool operator==(const MemberTypeInfo &Other) const {
132 3 : return std::tie(Type, Name, Access) ==
133 3 : std::tie(Other.Type, Other.Name, Other.Access);
134 : }
135 :
136 : AccessSpecifier Access = AccessSpecifier::AS_none; // Access level associated
137 : // with this info (public,
138 : // protected, private,
139 : // none).
140 : };
141 :
142 106 : struct Location {
143 : Location() = default;
144 : Location(int LineNumber, SmallString<16> Filename)
145 56 : : LineNumber(LineNumber), Filename(std::move(Filename)) {}
146 :
147 : bool operator==(const Location &Other) const {
148 13 : return std::tie(LineNumber, Filename) ==
149 26 : std::tie(Other.LineNumber, Other.Filename);
150 : }
151 :
152 : int LineNumber; // Line number of this Location.
153 : SmallString<32> Filename; // File for this Location.
154 : };
155 :
156 : /// A base struct for Infos.
157 : struct Info {
158 : Info() = default;
159 77 : Info(InfoType IT) : IT(IT) {}
160 10 : Info(InfoType IT, SymbolID USR) : USR(USR), IT(IT) {}
161 : Info(InfoType IT, SymbolID USR, StringRef Name)
162 10 : : USR(USR), IT(IT), Name(Name) {}
163 : Info(const Info &Other) = delete;
164 46 : Info(Info &&Other) = default;
165 :
166 174 : virtual ~Info() = default;
167 :
168 : SymbolID USR =
169 : SymbolID(); // Unique identifier for the decl described by this Info.
170 : const InfoType IT = InfoType::IT_default; // InfoType of this particular Info.
171 : SmallString<16> Name; // Unqualified name of the decl.
172 : llvm::SmallVector<Reference, 4>
173 : Namespace; // List of parent namespaces for this decl.
174 : std::vector<CommentInfo> Description; // Comment description of this decl.
175 :
176 : void mergeBase(Info &&I);
177 : bool mergeable(const Info &Other);
178 :
179 : // Returns a reference to the parent scope (that is, the immediate parent
180 : // namespace or class in which this decl resides).
181 : llvm::Expected<Reference> getEnclosingScope();
182 : };
183 :
184 : // Info for namespaces.
185 : struct NamespaceInfo : public Info {
186 10 : NamespaceInfo() : Info(InfoType::IT_namespace) {}
187 24 : NamespaceInfo(SymbolID USR) : Info(InfoType::IT_namespace, USR) {}
188 2 : NamespaceInfo(SymbolID USR, StringRef Name)
189 2 : : Info(InfoType::IT_namespace, USR, Name) {}
190 :
191 : void merge(NamespaceInfo &&I);
192 :
193 : // Namespaces and Records are references because they will be properly
194 : // documented in their own info, while the entirety of Functions and Enums are
195 : // included here because they should not have separate documentation from
196 : // their scope.
197 : std::vector<Reference> ChildNamespaces;
198 : std::vector<Reference> ChildRecords;
199 : std::vector<FunctionInfo> ChildFunctions;
200 : std::vector<EnumInfo> ChildEnums;
201 : };
202 :
203 : // Info for symbols.
204 : struct SymbolInfo : public Info {
205 60 : SymbolInfo(InfoType IT) : Info(IT) {}
206 4 : SymbolInfo(InfoType IT, SymbolID USR) : Info(IT, USR) {}
207 8 : SymbolInfo(InfoType IT, SymbolID USR, StringRef Name) : Info(IT, USR, Name) {}
208 :
209 : void merge(SymbolInfo &&I);
210 :
211 : llvm::Optional<Location> DefLoc; // Location where this decl is defined.
212 : llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
213 : };
214 :
215 : // TODO: Expand to allow for documenting templating and default args.
216 : // Info for functions.
217 : struct FunctionInfo : public SymbolInfo {
218 93 : FunctionInfo() : SymbolInfo(InfoType::IT_function) {}
219 : FunctionInfo(SymbolID USR) : SymbolInfo(InfoType::IT_function, USR) {}
220 :
221 : void merge(FunctionInfo &&I);
222 :
223 : bool IsMethod = false; // Indicates whether this function is a class method.
224 : Reference Parent; // Reference to the parent class decl for this method.
225 : TypeInfo ReturnType; // Info about the return type of this function.
226 : llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
227 : // Access level for this method (public, private, protected, none).
228 : AccessSpecifier Access = AccessSpecifier::AS_none;
229 : };
230 :
231 : // TODO: Expand to allow for documenting templating, inheritance access,
232 : // friend classes
233 : // Info for types.
234 : struct RecordInfo : public SymbolInfo {
235 18 : RecordInfo() : SymbolInfo(InfoType::IT_record) {}
236 6 : RecordInfo(SymbolID USR) : SymbolInfo(InfoType::IT_record, USR) {}
237 8 : RecordInfo(SymbolID USR, StringRef Name)
238 8 : : SymbolInfo(InfoType::IT_record, USR, Name) {}
239 :
240 : void merge(RecordInfo &&I);
241 :
242 : TagTypeKind TagType = TagTypeKind::TTK_Struct; // Type of this record
243 : // (struct, class, union,
244 : // interface).
245 : llvm::SmallVector<MemberTypeInfo, 4>
246 : Members; // List of info about record members.
247 : llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
248 : // (does not include virtual
249 : // parents).
250 : llvm::SmallVector<Reference, 4>
251 : VirtualParents; // List of virtual base/parent records.
252 :
253 : // Records are references because they will be properly
254 : // documented in their own info, while the entirety of Functions and Enums are
255 : // included here because they should not have separate documentation from
256 : // their scope.
257 : std::vector<Reference> ChildRecords;
258 : std::vector<FunctionInfo> ChildFunctions;
259 : std::vector<EnumInfo> ChildEnums;
260 : };
261 :
262 : // TODO: Expand to allow for documenting templating.
263 : // Info for types.
264 5 : struct EnumInfo : public SymbolInfo {
265 42 : EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
266 : EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}
267 :
268 : void merge(EnumInfo &&I);
269 :
270 : bool Scoped =
271 : false; // Indicates whether this enum is scoped (e.g. enum class).
272 : llvm::SmallVector<SmallString<16>, 4> Members; // List of enum members.
273 : };
274 :
275 : // TODO: Add functionality to include separate markdown pages.
276 :
277 : // A standalone function to call to merge a vector of infos into one.
278 : // This assumes that all infos in the vector are of the same type, and will fail
279 : // if they are different.
280 : llvm::Expected<std::unique_ptr<Info>>
281 : mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
282 :
283 : struct ClangDocContext {
284 : tooling::ExecutionContext *ECtx;
285 : bool PublicOnly;
286 : };
287 :
288 : } // namespace doc
289 : } // namespace clang
290 :
291 : #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
|