123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- ///===-- Representation.h - ClangDoc Representation -------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the internal representations of different declaration
- // types for the clang-doc tool.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
- #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
- #include "clang/AST/Type.h"
- #include "clang/Basic/Specifiers.h"
- #include "clang/Tooling/StandaloneExecution.h"
- #include "llvm/ADT/APSInt.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringExtras.h"
- #include <array>
- #include <optional>
- #include <string>
- namespace clang {
- namespace doc {
- // SHA1'd hash of a USR.
- using SymbolID = std::array<uint8_t, 20>;
- struct BaseRecordInfo;
- struct EnumInfo;
- struct FunctionInfo;
- struct Info;
- struct TypedefInfo;
- enum class InfoType {
- IT_default,
- IT_namespace,
- IT_record,
- IT_function,
- IT_enum,
- IT_typedef
- };
- // A representation of a parsed comment.
- struct CommentInfo {
- CommentInfo() = default;
- CommentInfo(CommentInfo &Other) = delete;
- CommentInfo(CommentInfo &&Other) = default;
- CommentInfo &operator=(CommentInfo &&Other) = default;
- bool operator==(const CommentInfo &Other) const;
- // This operator is used to sort a vector of CommentInfos.
- // No specific order (attributes more important than others) is required. Any
- // sort is enough, the order is only needed to call std::unique after sorting
- // the vector.
- bool operator<(const CommentInfo &Other) const;
- SmallString<16>
- Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
- // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
- // BlockCommandComment, ParamCommandComment,
- // TParamCommandComment, VerbatimBlockComment,
- // VerbatimBlockLineComment, VerbatimLineComment).
- SmallString<64> Text; // Text of the comment.
- SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
- SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
- SmallString<16> ParamName; // Parameter name (for (T)ParamCommand).
- SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
- bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
- bool Explicit = false; // Indicates if the direction of a param is explicit
- // (for (T)ParamCommand).
- llvm::SmallVector<SmallString<16>, 4>
- AttrKeys; // List of attribute keys (for HTML).
- llvm::SmallVector<SmallString<16>, 4>
- AttrValues; // List of attribute values for each key (for HTML).
- llvm::SmallVector<SmallString<16>, 4>
- Args; // List of arguments to commands (for InlineCommand).
- std::vector<std::unique_ptr<CommentInfo>>
- Children; // List of child comments for this CommentInfo.
- };
- struct Reference {
- // This variant (that takes no qualified name parameter) uses the Name as the
- // QualName (very useful in unit tests to reduce verbosity). This can't use an
- // empty string to indicate the default because we need to accept the empty
- // string as a valid input for the global namespace (it will have
- // "GlobalNamespace" as the name, but an empty QualName).
- Reference(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
- InfoType IT = InfoType::IT_default)
- : USR(USR), Name(Name), QualName(Name), RefType(IT) {}
- Reference(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName,
- StringRef Path = StringRef())
- : USR(USR), Name(Name), QualName(QualName), RefType(IT), Path(Path) {}
- bool operator==(const Reference &Other) const {
- return std::tie(USR, Name, QualName, RefType) ==
- std::tie(Other.USR, Other.Name, QualName, Other.RefType);
- }
- bool mergeable(const Reference &Other);
- void merge(Reference &&I);
- /// Returns the path for this Reference relative to CurrentPath.
- llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
- /// Returns the basename that should be used for this Reference.
- llvm::SmallString<16> getFileBaseName() const;
- SymbolID USR = SymbolID(); // Unique identifier for referenced decl
- // Name of type (possibly unresolved). Not including namespaces or template
- // parameters (so for a std::vector<int> this would be "vector"). See also
- // QualName.
- SmallString<16> Name;
- // Full qualified name of this type, including namespaces and template
- // parameter (for example this could be "std::vector<int>"). Contrast to
- // Name.
- SmallString<16> QualName;
- InfoType RefType = InfoType::IT_default; // Indicates the type of this
- // Reference (namespace, record,
- // function, enum, default).
- // Path of directory where the clang-doc generated file will be saved
- // (possibly unresolved)
- llvm::SmallString<128> Path;
- };
- // Holds the children of a record or namespace.
- struct ScopeChildren {
- // Namespaces and Records are references because they will be properly
- // documented in their own info, while the entirety of Functions and Enums are
- // included here because they should not have separate documentation from
- // their scope.
- //
- // Namespaces are not syntactically valid as children of records, but making
- // this general for all possible container types reduces code complexity.
- std::vector<Reference> Namespaces;
- std::vector<Reference> Records;
- std::vector<FunctionInfo> Functions;
- std::vector<EnumInfo> Enums;
- std::vector<TypedefInfo> Typedefs;
- };
- // A base struct for TypeInfos
- struct TypeInfo {
- TypeInfo() = default;
- TypeInfo(const Reference &R) : Type(R) {}
- // Convenience constructor for when there is no symbol ID or info type
- // (normally used for built-in types in tests).
- TypeInfo(StringRef Name, StringRef Path = StringRef())
- : Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}
- bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
- Reference Type; // Referenced type in this info.
- };
- // Represents one template parameter.
- //
- // This is a very simple serialization of the text of the source code of the
- // template parameter. It is saved in a struct so there is a place to add the
- // name and default values in the future if needed.
- struct TemplateParamInfo {
- TemplateParamInfo() = default;
- explicit TemplateParamInfo(StringRef Contents) : Contents(Contents) {}
- // The literal contents of the code for that specifies this template parameter
- // for this declaration. Typical values will be "class T" and
- // "typename T = int".
- SmallString<16> Contents;
- };
- struct TemplateSpecializationInfo {
- // Indicates the declaration that this specializes.
- SymbolID SpecializationOf;
- // Template parameters applying to the specialized record/function.
- std::vector<TemplateParamInfo> Params;
- };
- // Records the template information for a struct or function that is a template
- // or an explicit template specialization.
- struct TemplateInfo {
- // May be empty for non-partial specializations.
- std::vector<TemplateParamInfo> Params;
- // Set when this is a specialization of another record/function.
- std::optional<TemplateSpecializationInfo> Specialization;
- };
- // Info for field types.
- struct FieldTypeInfo : public TypeInfo {
- FieldTypeInfo() = default;
- FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
- StringRef DefaultValue = StringRef())
- : TypeInfo(TI), Name(Name), DefaultValue(DefaultValue) {}
- bool operator==(const FieldTypeInfo &Other) const {
- return std::tie(Type, Name, DefaultValue) ==
- std::tie(Other.Type, Other.Name, Other.DefaultValue);
- }
- SmallString<16> Name; // Name associated with this info.
- // When used for function parameters, contains the string representing the
- // expression of the default value, if any.
- SmallString<16> DefaultValue;
- };
- // Info for member types.
- struct MemberTypeInfo : public FieldTypeInfo {
- MemberTypeInfo() = default;
- MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access)
- : FieldTypeInfo(TI, Name), Access(Access) {}
- bool operator==(const MemberTypeInfo &Other) const {
- return std::tie(Type, Name, Access, Description) ==
- std::tie(Other.Type, Other.Name, Other.Access, Other.Description);
- }
- // Access level associated with this info (public, protected, private, none).
- // AS_public is set as default because the bitcode writer requires the enum
- // with value 0 to be used as the default.
- // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
- AccessSpecifier Access = AccessSpecifier::AS_public;
- std::vector<CommentInfo> Description; // Comment description of this field.
- };
- struct Location {
- Location(int LineNumber = 0, StringRef Filename = StringRef(),
- bool IsFileInRootDir = false)
- : LineNumber(LineNumber), Filename(Filename),
- IsFileInRootDir(IsFileInRootDir) {}
- bool operator==(const Location &Other) const {
- return std::tie(LineNumber, Filename) ==
- std::tie(Other.LineNumber, Other.Filename);
- }
- // This operator is used to sort a vector of Locations.
- // No specific order (attributes more important than others) is required. Any
- // sort is enough, the order is only needed to call std::unique after sorting
- // the vector.
- bool operator<(const Location &Other) const {
- return std::tie(LineNumber, Filename) <
- std::tie(Other.LineNumber, Other.Filename);
- }
- int LineNumber = 0; // Line number of this Location.
- SmallString<32> Filename; // File for this Location.
- bool IsFileInRootDir = false; // Indicates if file is inside root directory
- };
- /// A base struct for Infos.
- struct Info {
- Info(InfoType IT = InfoType::IT_default, SymbolID USR = SymbolID(),
- StringRef Name = StringRef(), StringRef Path = StringRef())
- : USR(USR), IT(IT), Name(Name), Path(Path) {}
- Info(const Info &Other) = delete;
- Info(Info &&Other) = default;
- virtual ~Info() = default;
- SymbolID USR =
- SymbolID(); // Unique identifier for the decl described by this Info.
- const InfoType IT = InfoType::IT_default; // InfoType of this particular Info.
- SmallString<16> Name; // Unqualified name of the decl.
- llvm::SmallVector<Reference, 4>
- Namespace; // List of parent namespaces for this decl.
- std::vector<CommentInfo> Description; // Comment description of this decl.
- llvm::SmallString<128> Path; // Path of directory where the clang-doc
- // generated file will be saved
- void mergeBase(Info &&I);
- bool mergeable(const Info &Other);
- llvm::SmallString<16> extractName() const;
- /// Returns the file path for this Info relative to CurrentPath.
- llvm::SmallString<64> getRelativeFilePath(const StringRef &CurrentPath) const;
- /// Returns the basename that should be used for this Info.
- llvm::SmallString<16> getFileBaseName() const;
- // Returns a reference to the parent scope (that is, the immediate parent
- // namespace or class in which this decl resides).
- llvm::Expected<Reference> getEnclosingScope();
- };
- // Info for namespaces.
- struct NamespaceInfo : public Info {
- NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
- StringRef Path = StringRef());
- void merge(NamespaceInfo &&I);
- ScopeChildren Children;
- };
- // Info for symbols.
- struct SymbolInfo : public Info {
- SymbolInfo(InfoType IT, SymbolID USR = SymbolID(),
- StringRef Name = StringRef(), StringRef Path = StringRef())
- : Info(IT, USR, Name, Path) {}
- void merge(SymbolInfo &&I);
- std::optional<Location> DefLoc; // Location where this decl is defined.
- llvm::SmallVector<Location, 2> Loc; // Locations where this decl is declared.
- };
- // TODO: Expand to allow for documenting templating and default args.
- // Info for functions.
- struct FunctionInfo : public SymbolInfo {
- FunctionInfo(SymbolID USR = SymbolID())
- : SymbolInfo(InfoType::IT_function, USR) {}
- void merge(FunctionInfo &&I);
- bool IsMethod = false; // Indicates whether this function is a class method.
- Reference Parent; // Reference to the parent class decl for this method.
- TypeInfo ReturnType; // Info about the return type of this function.
- llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
- // Access level for this method (public, private, protected, none).
- // AS_public is set as default because the bitcode writer requires the enum
- // with value 0 to be used as the default.
- // (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
- AccessSpecifier Access = AccessSpecifier::AS_public;
- // Full qualified name of this function, including namespaces and template
- // specializations.
- SmallString<16> FullName;
- // When present, this function is a template or specialization.
- std::optional<TemplateInfo> Template;
- };
- // TODO: Expand to allow for documenting templating, inheritance access,
- // friend classes
- // Info for types.
- struct RecordInfo : public SymbolInfo {
- RecordInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(),
- StringRef Path = StringRef());
- void merge(RecordInfo &&I);
- // Type of this record (struct, class, union, interface).
- TagTypeKind TagType = TagTypeKind::TTK_Struct;
- // Full qualified name of this record, including namespaces and template
- // specializations.
- SmallString<16> FullName;
- // When present, this record is a template or specialization.
- std::optional<TemplateInfo> Template;
- // Indicates if the record was declared using a typedef. Things like anonymous
- // structs in a typedef:
- // typedef struct { ... } foo_t;
- // are converted into records with the typedef as the Name + this flag set.
- bool IsTypeDef = false;
- llvm::SmallVector<MemberTypeInfo, 4>
- Members; // List of info about record members.
- llvm::SmallVector<Reference, 4> Parents; // List of base/parent records
- // (does not include virtual
- // parents).
- llvm::SmallVector<Reference, 4>
- VirtualParents; // List of virtual base/parent records.
- std::vector<BaseRecordInfo>
- Bases; // List of base/parent records; this includes inherited methods and
- // attributes
- ScopeChildren Children;
- };
- // Info for typedef and using statements.
- struct TypedefInfo : public SymbolInfo {
- TypedefInfo(SymbolID USR = SymbolID())
- : SymbolInfo(InfoType::IT_typedef, USR) {}
- void merge(TypedefInfo &&I);
- TypeInfo Underlying;
- // Inidicates if this is a new C++ "using"-style typedef:
- // using MyVector = std::vector<int>
- // False means it's a C-style typedef:
- // typedef std::vector<int> MyVector;
- bool IsUsing = false;
- };
- struct BaseRecordInfo : public RecordInfo {
- BaseRecordInfo();
- BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual,
- AccessSpecifier Access, bool IsParent);
- // Indicates if base corresponds to a virtual inheritance
- bool IsVirtual = false;
- // Access level associated with this inherited info (public, protected,
- // private).
- AccessSpecifier Access = AccessSpecifier::AS_public;
- bool IsParent = false; // Indicates if this base is a direct parent
- };
- // Information for a single possible value of an enumeration.
- struct EnumValueInfo {
- explicit EnumValueInfo(StringRef Name = StringRef(),
- StringRef Value = StringRef("0"),
- StringRef ValueExpr = StringRef())
- : Name(Name), Value(Value), ValueExpr(ValueExpr) {}
- bool operator==(const EnumValueInfo &Other) const {
- return std::tie(Name, Value, ValueExpr) ==
- std::tie(Other.Name, Other.Value, Other.ValueExpr);
- }
- SmallString<16> Name;
- // The computed value of the enumeration constant. This could be the result of
- // evaluating the ValueExpr, or it could be automatically generated according
- // to C rules.
- SmallString<16> Value;
- // Stores the user-supplied initialization expression for this enumeration
- // constant. This will be empty for implicit enumeration values.
- SmallString<16> ValueExpr;
- };
- // TODO: Expand to allow for documenting templating.
- // Info for types.
- struct EnumInfo : public SymbolInfo {
- EnumInfo() : SymbolInfo(InfoType::IT_enum) {}
- EnumInfo(SymbolID USR) : SymbolInfo(InfoType::IT_enum, USR) {}
- void merge(EnumInfo &&I);
- // Indicates whether this enum is scoped (e.g. enum class).
- bool Scoped = false;
- // Set to nonempty to the type when this is an explicitly typed enum. For
- // enum Foo : short { ... };
- // this will be "short".
- std::optional<TypeInfo> BaseType;
- llvm::SmallVector<EnumValueInfo, 4> Members; // List of enum members.
- };
- struct Index : public Reference {
- Index() = default;
- Index(StringRef Name) : Reference(SymbolID(), Name) {}
- Index(StringRef Name, StringRef JumpToSection)
- : Reference(SymbolID(), Name), JumpToSection(JumpToSection) {}
- Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path)
- : Reference(USR, Name, IT, Name, Path) {}
- // This is used to look for a USR in a vector of Indexes using std::find
- bool operator==(const SymbolID &Other) const { return USR == Other; }
- bool operator<(const Index &Other) const;
- std::optional<SmallString<16>> JumpToSection;
- std::vector<Index> Children;
- void sort();
- };
- // TODO: Add functionality to include separate markdown pages.
- // A standalone function to call to merge a vector of infos into one.
- // This assumes that all infos in the vector are of the same type, and will fail
- // if they are different.
- llvm::Expected<std::unique_ptr<Info>>
- mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
- struct ClangDocContext {
- ClangDocContext() = default;
- ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
- bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
- StringRef RepositoryUrl,
- std::vector<std::string> UserStylesheets,
- std::vector<std::string> JsScripts);
- tooling::ExecutionContext *ECtx;
- std::string ProjectName; // Name of project clang-doc is documenting.
- bool PublicOnly; // Indicates if only public declarations are documented.
- std::string OutDirectory; // Directory for outputting generated files.
- std::string SourceRoot; // Directory where processed files are stored. Links
- // to definition locations will only be generated if
- // the file is in this dir.
- // URL of repository that hosts code used for links to definition locations.
- std::optional<std::string> RepositoryUrl;
- // Path of CSS stylesheets that will be copied to OutDirectory and used to
- // style all HTML files.
- std::vector<std::string> UserStylesheets;
- // JavaScript files that will be imported in allHTML file.
- std::vector<std::string> JsScripts;
- // Other files that should be copied to OutDirectory, besides UserStylesheets.
- std::vector<std::string> FilesToCopy;
- Index Idx;
- };
- } // namespace doc
- } // namespace clang
- #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_REPRESENTATION_H
|