Representation.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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. #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
  14. #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
  15. #include "clang/AST/Type.h"
  16. #include "clang/Basic/Specifiers.h"
  17. #include "clang/Tooling/StandaloneExecution.h"
  18. #include "llvm/ADT/APSInt.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringExtras.h"
  21. #include <array>
  22. #include <optional>
  23. #include <string>
  24. namespace clang {
  25. namespace doc {
  26. // SHA1'd hash of a USR.
  27. using SymbolID = std::array<uint8_t, 20>;
  28. struct BaseRecordInfo;
  29. struct EnumInfo;
  30. struct FunctionInfo;
  31. struct Info;
  32. struct TypedefInfo;
  33. enum class InfoType {
  34. IT_default,
  35. IT_namespace,
  36. IT_record,
  37. IT_function,
  38. IT_enum,
  39. IT_typedef
  40. };
  41. // A representation of a parsed comment.
  42. struct CommentInfo {
  43. CommentInfo() = default;
  44. CommentInfo(CommentInfo &Other) = delete;
  45. CommentInfo(CommentInfo &&Other) = default;
  46. CommentInfo &operator=(CommentInfo &&Other) = default;
  47. bool operator==(const CommentInfo &Other) const;
  48. // This operator is used to sort a vector of CommentInfos.
  49. // No specific order (attributes more important than others) is required. Any
  50. // sort is enough, the order is only needed to call std::unique after sorting
  51. // the vector.
  52. bool operator<(const CommentInfo &Other) const;
  53. SmallString<16>
  54. Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
  55. // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
  56. // BlockCommandComment, ParamCommandComment,
  57. // TParamCommandComment, VerbatimBlockComment,
  58. // VerbatimBlockLineComment, VerbatimLineComment).
  59. SmallString<64> Text; // Text of the comment.
  60. SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
  61. SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
  62. SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
  63. SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
  64. bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
  65. bool Explicit = false; // Indicates if the direction of a param is explicit
  66. // (for (T)ParamCommand).
  67. llvm::SmallVector<SmallString<16>, 4>
  68. AttrKeys; // List of attribute keys (for HTML).
  69. llvm::SmallVector<SmallString<16>, 4>
  70. AttrValues; // List of attribute values for each key (for HTML).
  71. llvm::SmallVector<SmallString<16>, 4>
  72. Args; // List of arguments to commands (for InlineCommand).
  73. std::vector<std::unique_ptr<CommentInfo>>
  74. Children; // List of child comments for this CommentInfo.
  75. };
  76. struct Reference {
  77. // This variant (that takes no qualified name parameter) uses the Name as the
  78. // QualName (very useful in unit tests to reduce verbosity). This can't use an
  79. // empty string to indicate the default because we need to accept the empty
  80. // string as a valid input for the global namespace (it will have
  81. // "GlobalNamespace" as the name, but an empty QualName).
  82. Reference(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
  83. InfoType IT = InfoType::IT_default)
  84. : USR(USR), Name(Name), QualName(Name), RefType(IT) {}
  85. Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
  86. StringRef Path = StringRef())
  87. : USR(USR), Name(Name), QualName(QualName), RefType(IT), Path(Path) {}
  88. bool operator==(const Reference &Other) const {
  89. return std::tie(USR, Name, QualName, RefType) ==
  90. std::tie(Other.USR, Other.Name, QualName, Other.RefType);
  91. }
  92. bool mergeable(const Reference &Other);
  93. void merge(Reference &&I);
  94. /// Returns the path for this Reference relative to CurrentPath.
  95. llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
  96. /// Returns the basename that should be used for this Reference.
  97. llvm::SmallString<16> getFileBaseName() const;
  98. SymbolID USR = SymbolID(); // Unique identifier for referenced decl
  99. // Name of type (possibly unresolved). Not including namespaces or template
  100. // parameters (so for a std::vector<int> this would be "vector"). See also
  101. // QualName.
  102. SmallString<16> Name;
  103. // Full qualified name of this type, including namespaces and template
  104. // parameter (for example this could be "std::vector<int>"). Contrast to
  105. // Name.
  106. SmallString<16> QualName;
  107. InfoType RefType = InfoType::IT_default; // Indicates the type of this
  108. // Reference (namespace, record,
  109. // function, enum, default).
  110. // Path of directory where the clang-doc generated file will be saved
  111. // (possibly unresolved)
  112. llvm::SmallString<128> Path;
  113. };
  114. // Holds the children of a record or namespace.
  115. struct ScopeChildren {
  116. // Namespaces and Records are references because they will be properly
  117. // documented in their own info, while the entirety of Functions and Enums are
  118. // included here because they should not have separate documentation from
  119. // their scope.
  120. //
  121. // Namespaces are not syntactically valid as children of records, but making
  122. // this general for all possible container types reduces code complexity.
  123. std::vector<Reference> Namespaces;
  124. std::vector<Reference> Records;
  125. std::vector<FunctionInfo> Functions;
  126. std::vector<EnumInfo> Enums;
  127. std::vector<TypedefInfo> Typedefs;
  128. };
  129. // A base struct for TypeInfos
  130. struct TypeInfo {
  131. TypeInfo() = default;
  132. TypeInfo(const Reference &R) : Type(R) {}
  133. // Convenience constructor for when there is no symbol ID or info type
  134. // (normally used for built-in types in tests).
  135. TypeInfo(StringRef Name, StringRef Path = StringRef())
  136. : Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}
  137. bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
  138. Reference Type; // Referenced type in this info.
  139. };
  140. // Represents one template parameter.
  141. //
  142. // This is a very simple serialization of the text of the source code of the
  143. // template parameter. It is saved in a struct so there is a place to add the
  144. // name and default values in the future if needed.
  145. struct TemplateParamInfo {
  146. TemplateParamInfo() = default;
  147. explicit TemplateParamInfo(StringRef Contents) : Contents(Contents) {}
  148. // The literal contents of the code for that specifies this template parameter
  149. // for this declaration. Typical values will be "class T" and
  150. // "typename T = int".
  151. SmallString<16> Contents;
  152. };
  153. struct TemplateSpecializationInfo {
  154. // Indicates the declaration that this specializes.
  155. SymbolID SpecializationOf;
  156. // Template parameters applying to the specialized record/function.
  157. std::vector<TemplateParamInfo> Params;
  158. };
  159. // Records the template information for a struct or function that is a template
  160. // or an explicit template specialization.
  161. struct TemplateInfo {
  162. // May be empty for non-partial specializations.
  163. std::vector<TemplateParamInfo> Params;
  164. // Set when this is a specialization of another record/function.
  165. std::optional<TemplateSpecializationInfo> Specialization;
  166. };
  167. // Info for field types.
  168. struct FieldTypeInfo : public TypeInfo {
  169. FieldTypeInfo() = default;
  170. FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
  171. StringRef DefaultValue = StringRef())
  172. : TypeInfo(TI), Name(Name), DefaultValue(DefaultValue) {}
  173. bool operator==(const FieldTypeInfo &Other) const {
  174. return std::tie(Type, Name, DefaultValue) ==
  175. std::tie(Other.Type, Other.Name, Other.DefaultValue);
  176. }
  177. SmallString<16> Name; // Name associated with this info.
  178. // When used for function parameters, contains the string representing the
  179. // expression of the default value, if any.
  180. SmallString<16> DefaultValue;
  181. };
  182. // Info for member types.
  183. struct MemberTypeInfo : public FieldTypeInfo {
  184. MemberTypeInfo() = default;
  185. MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access)
  186. : FieldTypeInfo(TI, Name), Access(Access) {}
  187. bool operator==(const MemberTypeInfo &Other) const {
  188. return std::tie(Type, Name, Access, Description) ==
  189. std::tie(Other.Type, Other.Name, Other.Access, Other.Description);
  190. }
  191. // Access level associated with this info (public, protected, private, none).
  192. // AS_public is set as default because the bitcode writer requires the enum
  193. // with value 0 to be used as the default.
  194. // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
  195. AccessSpecifier Access = AccessSpecifier::AS_public;
  196. std::vector<CommentInfo> Description; // Comment description of this field.
  197. };
  198. struct Location {
  199. Location(int LineNumber = 0, StringRef Filename = StringRef(),
  200. bool IsFileInRootDir = false)
  201. : LineNumber(LineNumber), Filename(Filename),
  202. IsFileInRootDir(IsFileInRootDir) {}
  203. bool operator==(const Location &Other) const {
  204. return std::tie(LineNumber, Filename) ==
  205. std::tie(Other.LineNumber, Other.Filename);
  206. }
  207. // This operator is used to sort a vector of Locations.
  208. // No specific order (attributes more important than others) is required. Any
  209. // sort is enough, the order is only needed to call std::unique after sorting
  210. // the vector.
  211. bool operator<(const Location &Other) const {
  212. return std::tie(LineNumber, Filename) <
  213. std::tie(Other.LineNumber, Other.Filename);
  214. }
  215. int LineNumber = 0; // Line number of this Location.
  216. SmallString<32> Filename; // File for this Location.
  217. bool IsFileInRootDir = false; // Indicates if file is inside root directory
  218. };
  219. /// A base struct for Infos.
  220. struct Info {
  221. Info(InfoType IT = InfoType::IT_default, SymbolID USR = SymbolID(),
  222. StringRef Name = StringRef(), StringRef Path = StringRef())
  223. : USR(USR), IT(IT), Name(Name), Path(Path) {}
  224. Info(const Info &Other) = delete;
  225. Info(Info &&Other) = default;
  226. virtual ~Info() = default;
  227. SymbolID USR =
  228. SymbolID(); // Unique identifier for the decl described by this Info.
  229. const InfoType IT = InfoType::IT_default; // InfoType of this particular Info.
  230. SmallString<16> Name; // Unqualified name of the decl.
  231. llvm::SmallVector<Reference, 4>
  232. Namespace; // List of parent namespaces for this decl.
  233. std::vector<CommentInfo> Description; // Comment description of this decl.
  234. llvm::SmallString<128> Path; // Path of directory where the clang-doc
  235. // generated file will be saved
  236. void mergeBase(Info &&I);
  237. bool mergeable(const Info &Other);
  238. llvm::SmallString<16> extractName() const;
  239. /// Returns the file path for this Info relative to CurrentPath.
  240. llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
  241. /// Returns the basename that should be used for this Info.
  242. llvm::SmallString<16> getFileBaseName() const;
  243. // Returns a reference to the parent scope (that is, the immediate parent
  244. // namespace or class in which this decl resides).
  245. llvm::Expected<Reference> getEnclosingScope();
  246. };
  247. // Info for namespaces.
  248. struct NamespaceInfo : public Info {
  249. NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
  250. StringRef Path = StringRef());
  251. void merge(NamespaceInfo &&I);
  252. ScopeChildren Children;
  253. };
  254. // Info for symbols.
  255. struct SymbolInfo : public Info {
  256. SymbolInfo(InfoType IT, SymbolID USR = SymbolID(),
  257. StringRef Name = StringRef(), StringRef Path = StringRef())
  258. : Info(IT, USR, Name, Path) {}
  259. void merge(SymbolInfo &&I);
  260. std::optional<Location> DefLoc; // Location where this decl is defined.
  261. llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
  262. };
  263. // TODO: Expand to allow for documenting templating and default args.
  264. // Info for functions.
  265. struct FunctionInfo : public SymbolInfo {
  266. FunctionInfo(SymbolID USR = SymbolID())
  267. : SymbolInfo(InfoType::IT_function, USR) {}
  268. void merge(FunctionInfo &&I);
  269. bool IsMethod = false; // Indicates whether this function is a class method.
  270. Reference Parent; // Reference to the parent class decl for this method.
  271. TypeInfo ReturnType; // Info about the return type of this function.
  272. llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
  273. // Access level for this method (public, private, protected, none).
  274. // AS_public is set as default because the bitcode writer requires the enum
  275. // with value 0 to be used as the default.
  276. // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
  277. AccessSpecifier Access = AccessSpecifier::AS_public;
  278. // Full qualified name of this function, including namespaces and template
  279. // specializations.
  280. SmallString<16> FullName;
  281. // When present, this function is a template or specialization.
  282. std::optional<TemplateInfo> Template;
  283. };
  284. // TODO: Expand to allow for documenting templating, inheritance access,
  285. // friend classes
  286. // Info for types.
  287. struct RecordInfo : public SymbolInfo {
  288. RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
  289. StringRef Path = StringRef());
  290. void merge(RecordInfo &&I);
  291. // Type of this record (struct, class, union, interface).
  292. TagTypeKind TagType = TagTypeKind::TTK_Struct;
  293. // Full qualified name of this record, including namespaces and template
  294. // specializations.
  295. SmallString<16> FullName;
  296. // When present, this record is a template or specialization.
  297. std::optional<TemplateInfo> Template;
  298. // Indicates if the record was declared using a typedef. Things like anonymous
  299. // structs in a typedef:
  300. // typedef struct { ... } foo_t;
  301. // are converted into records with the typedef as the Name + this flag set.
  302. bool IsTypeDef = false;
  303. llvm::SmallVector<MemberTypeInfo, 4>
  304. Members; // List of info about record members.
  305. llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
  306. // (does not include virtual
  307. // parents).
  308. llvm::SmallVector<Reference, 4>
  309. VirtualParents; // List of virtual base/parent records.
  310. std::vector<BaseRecordInfo>
  311. Bases; // List of base/parent records; this includes inherited methods and
  312. // attributes
  313. ScopeChildren Children;
  314. };
  315. // Info for typedef and using statements.
  316. struct TypedefInfo : public SymbolInfo {
  317. TypedefInfo(SymbolID USR = SymbolID())
  318. : SymbolInfo(InfoType::IT_typedef, USR) {}
  319. void merge(TypedefInfo &&I);
  320. TypeInfo Underlying;
  321. // Inidicates if this is a new C++ "using"-style typedef:
  322. // using MyVector = std::vector<int>
  323. // False means it's a C-style typedef:
  324. // typedef std::vector<int> MyVector;
  325. bool IsUsing = false;
  326. };
  327. struct BaseRecordInfo : public RecordInfo {
  328. BaseRecordInfo();
  329. BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
  330. AccessSpecifier Access, bool IsParent);
  331. // Indicates if base corresponds to a virtual inheritance
  332. bool IsVirtual = false;
  333. // Access level associated with this inherited info (public, protected,
  334. // private).
  335. AccessSpecifier Access = AccessSpecifier::AS_public;
  336. bool IsParent = false; // Indicates if this base is a direct parent
  337. };
  338. // Information for a single possible value of an enumeration.
  339. struct EnumValueInfo {
  340. explicit EnumValueInfo(StringRef Name = StringRef(),
  341. StringRef Value = StringRef("0"),
  342. StringRef ValueExpr = StringRef())
  343. : Name(Name), Value(Value), ValueExpr(ValueExpr) {}
  344. bool operator==(const EnumValueInfo &Other) const {
  345. return std::tie(Name, Value, ValueExpr) ==
  346. std::tie(Other.Name, Other.Value, Other.ValueExpr);
  347. }
  348. SmallString<16> Name;
  349. // The computed value of the enumeration constant. This could be the result of
  350. // evaluating the ValueExpr, or it could be automatically generated according
  351. // to C rules.
  352. SmallString<16> Value;
  353. // Stores the user-supplied initialization expression for this enumeration
  354. // constant. This will be empty for implicit enumeration values.
  355. SmallString<16> ValueExpr;
  356. };
  357. // TODO: Expand to allow for documenting templating.
  358. // Info for types.
  359. struct EnumInfo : public SymbolInfo {
  360. EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
  361. EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}
  362. void merge(EnumInfo &&I);
  363. // Indicates whether this enum is scoped (e.g. enum class).
  364. bool Scoped = false;
  365. // Set to nonempty to the type when this is an explicitly typed enum. For
  366. // enum Foo : short { ... };
  367. // this will be "short".
  368. std::optional<TypeInfo> BaseType;
  369. llvm::SmallVector<EnumValueInfo, 4> Members; // List of enum members.
  370. };
  371. struct Index : public Reference {
  372. Index() = default;
  373. Index(StringRef Name) : Reference(SymbolID(), Name) {}
  374. Index(StringRef Name, StringRef JumpToSection)
  375. : Reference(SymbolID(), Name), JumpToSection(JumpToSection) {}
  376. Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
  377. : Reference(USR, Name, IT, Name, Path) {}
  378. // This is used to look for a USR in a vector of Indexes using std::find
  379. bool operator==(const SymbolID &Other) const { return USR == Other; }
  380. bool operator<(const Index &Other) const;
  381. std::optional<SmallString<16>> JumpToSection;
  382. std::vector<Index> Children;
  383. void sort();
  384. };
  385. // TODO: Add functionality to include separate markdown pages.
  386. // A standalone function to call to merge a vector of infos into one.
  387. // This assumes that all infos in the vector are of the same type, and will fail
  388. // if they are different.
  389. llvm::Expected<std::unique_ptr<Info>>
  390. mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
  391. struct ClangDocContext {
  392. ClangDocContext() = default;
  393. ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
  394. bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
  395. StringRef RepositoryUrl,
  396. std::vector<std::string> UserStylesheets,
  397. std::vector<std::string> JsScripts);
  398. tooling::ExecutionContext *ECtx;
  399. std::string ProjectName; // Name of project clang-doc is documenting.
  400. bool PublicOnly; // Indicates if only public declarations are documented.
  401. std::string OutDirectory; // Directory for outputting generated files.
  402. std::string SourceRoot; // Directory where processed files are stored. Links
  403. // to definition locations will only be generated if
  404. // the file is in this dir.
  405. // URL of repository that hosts code used for links to definition locations.
  406. std::optional<std::string> RepositoryUrl;
  407. // Path of CSS stylesheets that will be copied to OutDirectory and used to
  408. // style all HTML files.
  409. std::vector<std::string> UserStylesheets;
  410. // JavaScript files that will be imported in allHTML file.
  411. std::vector<std::string> JsScripts;
  412. // Other files that should be copied to OutDirectory, besides UserStylesheets.
  413. std::vector<std::string> FilesToCopy;
  414. Index Idx;
  415. };
  416. } // namespace doc
  417. } // namespace clang
  418. #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H