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

Reply via email to