massberg created this revision. massberg added a reviewer: ilya-biryukov. Herald added a project: All. massberg requested review of this revision. Herald added a project: clang-tools-extra. Herald added a subscriber: cfe-commits.
C++20 is more strict when erroring out due to incomplete types. Thus the code required some restructoring so that it complies in C++20. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D141671 Files: clang-tools-extra/clang-doc/Representation.cpp clang-tools-extra/clang-doc/Representation.h
Index: clang-tools-extra/clang-doc/Representation.h =================================================================== --- clang-tools-extra/clang-doc/Representation.h +++ clang-tools-extra/clang-doc/Representation.h @@ -31,10 +31,6 @@ using SymbolID = std::array<uint8_t, 20>; struct BaseRecordInfo; -struct EnumInfo; -struct FunctionInfo; -struct Info; -struct TypedefInfo; enum class InfoType { IT_default, @@ -52,44 +48,13 @@ CommentInfo(CommentInfo &&Other) = default; CommentInfo &operator=(CommentInfo &&Other) = default; - bool operator==(const CommentInfo &Other) const { - auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName, - SelfClosing, Explicit, AttrKeys, AttrValues, Args); - auto SecondCI = - std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction, - Other.ParamName, Other.CloseName, Other.SelfClosing, - Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args); - - if (FirstCI != SecondCI || Children.size() != Other.Children.size()) - return false; - - return std::equal(Children.begin(), Children.end(), Other.Children.begin(), - llvm::deref<std::equal_to<>>{}); - } + 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 { - auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName, - SelfClosing, Explicit, AttrKeys, AttrValues, Args); - auto SecondCI = - std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction, - Other.ParamName, Other.CloseName, Other.SelfClosing, - Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args); - - if (FirstCI < SecondCI) - return true; - - if (FirstCI == SecondCI) { - return std::lexicographical_compare( - Children.begin(), Children.end(), Other.Children.begin(), - Other.Children.end(), llvm::deref<std::less<>>()); - } - - return false; - } + bool operator<(const CommentInfo &Other) const; SmallString<16> Kind; // Kind of comment (FullComment, ParagraphComment, TextComment, @@ -162,22 +127,6 @@ 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; @@ -327,16 +276,6 @@ llvm::Expected<Reference> getEnclosingScope(); }; -// Info for namespaces. -struct NamespaceInfo : public Info { - NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(), - StringRef Path = StringRef()) - : Info(InfoType::IT_namespace, USR, Name, Path) {} - - void merge(NamespaceInfo &&I); - - ScopeChildren Children; -}; // Info for symbols. struct SymbolInfo : public Info { @@ -376,13 +315,99 @@ std::optional<TemplateInfo> Template; }; +// 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. +}; + +// 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; +}; + +// 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; +}; + + +// Info for namespaces. +struct NamespaceInfo : public Info { + NamespaceInfo(SymbolID USR = SymbolID(), StringRef Name = StringRef(), + StringRef Path = StringRef()) + : Info(InfoType::IT_namespace, USR, Name, Path) {} + + void merge(NamespaceInfo &&I); + + ScopeChildren Children; +}; + // 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()) - : SymbolInfo(InfoType::IT_record, USR, Name, Path) {} + StringRef Path = StringRef()); void merge(RecordInfo &&I); @@ -417,28 +442,10 @@ 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() : RecordInfo() {} + BaseRecordInfo(); BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, bool IsVirtual, - AccessSpecifier Access, bool IsParent) - : RecordInfo(USR, Name, Path), IsVirtual(IsVirtual), Access(Access), - IsParent(IsParent) {} + AccessSpecifier Access, bool IsParent); // Indicates if base corresponds to a virtual inheritance bool IsVirtual = false; @@ -448,49 +455,6 @@ 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: clang-tools-extra/clang-doc/Representation.cpp =================================================================== --- clang-tools-extra/clang-doc/Representation.cpp +++ clang-tools-extra/clang-doc/Representation.cpp @@ -128,6 +128,49 @@ } } +bool CommentInfo::operator==(const CommentInfo &Other) const { + auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName, + SelfClosing, Explicit, AttrKeys, AttrValues, Args); + auto SecondCI = + std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction, + Other.ParamName, Other.CloseName, Other.SelfClosing, + Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args); + + if (FirstCI != SecondCI || Children.size() != Other.Children.size()) + return false; + + return std::equal(Children.begin(), Children.end(), Other.Children.begin(), + llvm::deref<std::equal_to<>>{}); +} + +bool CommentInfo::operator<(const CommentInfo &Other) const { + auto FirstCI = std::tie(Kind, Text, Name, Direction, ParamName, CloseName, + SelfClosing, Explicit, AttrKeys, AttrValues, Args); + auto SecondCI = + std::tie(Other.Kind, Other.Text, Other.Name, Other.Direction, + Other.ParamName, Other.CloseName, Other.SelfClosing, + Other.Explicit, Other.AttrKeys, Other.AttrValues, Other.Args); + + if (FirstCI < SecondCI) + return true; + + if (FirstCI == SecondCI) { + return std::lexicographical_compare( + Children.begin(), Children.end(), Other.Children.begin(), + Other.Children.end(), llvm::deref<std::less<>>()); + } + + return false; +} + +BaseRecordInfo::BaseRecordInfo() : RecordInfo() {} + +BaseRecordInfo::BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path, + bool IsVirtual, AccessSpecifier Access, + bool IsParent) + : RecordInfo(USR, Name, Path), IsVirtual(IsVirtual), Access(Access), + IsParent(IsParent) {} + static llvm::SmallString<64> calculateRelativeFilePath(const InfoType &Type, const StringRef &Path, const StringRef &Name, const StringRef &CurrentPath) { @@ -231,6 +274,9 @@ mergeBase(std::move(Other)); } +RecordInfo::RecordInfo(SymbolID USR, StringRef Name, StringRef Path) + : SymbolInfo(InfoType::IT_record, USR, Name, Path) {} + void RecordInfo::merge(RecordInfo &&Other) { assert(mergeable(Other)); if (!TagType)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits