https://github.com/YLChenZ updated 
https://github.com/llvm/llvm-project/pull/134089

>From 319c55aef5c458ae4ac6c7f3f186d338f6fe2e37 Mon Sep 17 00:00:00 2001
From: YLChenZ <chentongyon...@gmail.com>
Date: Wed, 2 Apr 2025 22:03:53 +0800
Subject: [PATCH 1/3] [llvm][doc]: Merge the contents of identical entries.

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 68 +++++++++++++++++------
 1 file changed, 50 insertions(+), 18 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 06f6b073240ba..6a2cdcd4ebc8e 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -5144,6 +5144,14 @@ class SpellingList {
 
     Spellings[(size_t)Kind].push_back(Name);
   }
+
+  void merge(const SpellingList &Other) {
+    for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) {
+      Spellings[Kind].insert(Spellings[Kind].end(),
+                             Other.Spellings[Kind].begin(),
+                             Other.Spellings[Kind].end());
+    }
+  }
 };
 
 class DocumentationData {
@@ -5301,44 +5309,68 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
       return L->getValueAsString("Name") < R->getValueAsString("Name");
     }
   };
-  std::map<const Record *, std::vector<DocumentationData>, CategoryLess>
+
+  std::map<const Record *, std::map<std::string, DocumentationData>,
+           CategoryLess>
       SplitDocs;
+
+  // Collect documentation data, grouping by category and heading.
   for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     const Record &Attr = *A;
     std::vector<const Record *> Docs =
         Attr.getValueAsListOfDefs("Documentation");
+
     for (const auto *D : Docs) {
       const Record &Doc = *D;
       const Record *Category = Doc.getValueAsDef("Category");
       // If the category is "InternalOnly", then there cannot be any other
       // documentation categories (otherwise, the attribute would be
       // emitted into the docs).
-      const StringRef Cat = Category->getValueAsString("Name");
-      bool InternalOnly = Cat == "InternalOnly";
-      if (InternalOnly && Docs.size() > 1)
+      StringRef Cat = Category->getValueAsString("Name");
+      if (Cat == "InternalOnly" && Docs.size() > 1)
         PrintFatalError(Doc.getLoc(),
                         "Attribute is \"InternalOnly\", but has multiple "
                         "documentation categories");
 
-      if (!InternalOnly)
-        SplitDocs[Category].push_back(DocumentationData(
-            Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr, Cat)));
+      if (Cat == "InternalOnly")
+        continue;
+
+      // Generate Heading and Spellings.
+      auto HeadingAndSpellings =
+          GetAttributeHeadingAndSpellings(Doc, Attr, Cat);
+
+      auto &CategoryDocs = SplitDocs[Category];
+
+      // If the heading already exists, merge the documentation.
+      auto It = CategoryDocs.find(HeadingAndSpellings.first);
+      if (It != CategoryDocs.end()) {
+        // Merge spellings
+        It->second.SupportedSpellings.merge(HeadingAndSpellings.second);
+        // Merge content
+        It->second.Documentation = &Doc; // Update reference
+      } else {
+        // Otherwise, add a new entry.
+        CategoryDocs.emplace(HeadingAndSpellings.first,
+                             DocumentationData(Doc, Attr, 
HeadingAndSpellings));
+      }
     }
   }
 
-  // Having split the attributes out based on what documentation goes where,
-  // we can begin to generate sections of documentation.
-  for (auto &I : SplitDocs) {
-    WriteCategoryHeader(I.first, OS);
+  // Write out documentation, merging attributes with the same heading.
+  for (auto &CategoryPair : SplitDocs) {
+    WriteCategoryHeader(CategoryPair.first, OS);
+
+    std::vector<DocumentationData> MergedDocs;
+    for (auto &DocPair : CategoryPair.second)
+      MergedDocs.push_back(std::move(DocPair.second));
 
-    sort(I.second,
-         [](const DocumentationData &D1, const DocumentationData &D2) {
-           return D1.Heading < D2.Heading;
-         });
+    std::sort(MergedDocs.begin(), MergedDocs.end(),
+              [](const DocumentationData &D1, const DocumentationData &D2) {
+                return D1.Heading < D2.Heading;
+              });
 
-    // Walk over each of the attributes in the category and write out their
-    // documentation.
-    for (const auto &Doc : I.second)
+    // Output each documentation entry.
+    for (const auto &Doc : MergedDocs)
       WriteDocumentation(Records, Doc, OS);
   }
 }

>From 24307e5587a9f71c05fb03b9ea4c8f7e539876c3 Mon Sep 17 00:00:00 2001
From: YLChenZ <chentongyon...@gmail.com>
Date: Fri, 4 Apr 2025 09:29:59 +0800
Subject: [PATCH 2/3] merge with same content

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 36 +++++++++++------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 6a2cdcd4ebc8e..3d119f6be4131 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -5144,12 +5144,11 @@ class SpellingList {
 
     Spellings[(size_t)Kind].push_back(Name);
   }
-
+  
   void merge(const SpellingList &Other) {
     for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) {
       Spellings[Kind].insert(Spellings[Kind].end(),
-                             Other.Spellings[Kind].begin(),
-                             Other.Spellings[Kind].end());
+                 Other.Spellings[Kind].begin(), Other.Spellings[Kind].end());
     }
   }
 };
@@ -5309,16 +5308,13 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
       return L->getValueAsString("Name") < R->getValueAsString("Name");
     }
   };
-
-  std::map<const Record *, std::map<std::string, DocumentationData>,
-           CategoryLess>
-      SplitDocs;
+ 
+  std::map<const Record *, std::map<uint32_t, DocumentationData>, 
CategoryLess> SplitDocs;
 
   // Collect documentation data, grouping by category and heading.
   for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     const Record &Attr = *A;
-    std::vector<const Record *> Docs =
-        Attr.getValueAsListOfDefs("Documentation");
+    std::vector<const Record *> Docs = 
Attr.getValueAsListOfDefs("Documentation");
 
     for (const auto *D : Docs) {
       const Record &Doc = *D;
@@ -5336,27 +5332,31 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
         continue;
 
       // Generate Heading and Spellings.
-      auto HeadingAndSpellings =
-          GetAttributeHeadingAndSpellings(Doc, Attr, Cat);
+      auto HeadingAndSpellings = GetAttributeHeadingAndSpellings(Doc, Attr, 
Cat);
 
       auto &CategoryDocs = SplitDocs[Category];
 
-      // If the heading already exists, merge the documentation.
-      auto It = CategoryDocs.find(HeadingAndSpellings.first);
+      std::string key = Doc.getValueAsString("Content").str();
+      uint32_t keyHash = llvm::hash_value(key);
+      // If the content already exists, merge the documentation.
+      auto It = CategoryDocs.find(keyHash);
       if (It != CategoryDocs.end()) {
+        //Merge heading
+        if (It->second.Heading != HeadingAndSpellings.first)
+          It->second.Heading += ", " + HeadingAndSpellings.first;
         // Merge spellings
         It->second.SupportedSpellings.merge(HeadingAndSpellings.second);
         // Merge content
         It->second.Documentation = &Doc; // Update reference
-      } else {
-        // Otherwise, add a new entry.
-        CategoryDocs.emplace(HeadingAndSpellings.first,
-                             DocumentationData(Doc, Attr, 
HeadingAndSpellings));
+      }
+      else {
+         // Otherwise, add a new entry.
+         CategoryDocs.emplace(keyHash, DocumentationData(Doc, Attr, 
HeadingAndSpellings));
       }
     }
   }
 
-  // Write out documentation, merging attributes with the same heading.
+  // Write out documentation, merging attributes with the same content.
   for (auto &CategoryPair : SplitDocs) {
     WriteCategoryHeader(CategoryPair.first, OS);
 

>From 324d4064c8c27521d9d3043b3040ce7c781e6386 Mon Sep 17 00:00:00 2001
From: YLChenZ <chentongyon...@gmail.com>
Date: Fri, 4 Apr 2025 09:30:57 +0800
Subject: [PATCH 3/3] merge with same content

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 26 +++++++++++++----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 3d119f6be4131..0ea12eeba1d5d 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -5144,11 +5144,12 @@ class SpellingList {
 
     Spellings[(size_t)Kind].push_back(Name);
   }
-  
+
   void merge(const SpellingList &Other) {
     for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) {
       Spellings[Kind].insert(Spellings[Kind].end(),
-                 Other.Spellings[Kind].begin(), Other.Spellings[Kind].end());
+                             Other.Spellings[Kind].begin(),
+                             Other.Spellings[Kind].end());
     }
   }
 };
@@ -5308,13 +5309,15 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
       return L->getValueAsString("Name") < R->getValueAsString("Name");
     }
   };
- 
-  std::map<const Record *, std::map<uint32_t, DocumentationData>, 
CategoryLess> SplitDocs;
+
+  std::map<const Record *, std::map<uint32_t, DocumentationData>, CategoryLess>
+      SplitDocs;
 
   // Collect documentation data, grouping by category and heading.
   for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     const Record &Attr = *A;
-    std::vector<const Record *> Docs = 
Attr.getValueAsListOfDefs("Documentation");
+    std::vector<const Record *> Docs =
+        Attr.getValueAsListOfDefs("Documentation");
 
     for (const auto *D : Docs) {
       const Record &Doc = *D;
@@ -5332,7 +5335,8 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
         continue;
 
       // Generate Heading and Spellings.
-      auto HeadingAndSpellings = GetAttributeHeadingAndSpellings(Doc, Attr, 
Cat);
+      auto HeadingAndSpellings =
+          GetAttributeHeadingAndSpellings(Doc, Attr, Cat);
 
       auto &CategoryDocs = SplitDocs[Category];
 
@@ -5341,17 +5345,17 @@ void EmitClangAttrDocs(const RecordKeeper &Records, 
raw_ostream &OS) {
       // If the content already exists, merge the documentation.
       auto It = CategoryDocs.find(keyHash);
       if (It != CategoryDocs.end()) {
-        //Merge heading
+        // Merge heading
         if (It->second.Heading != HeadingAndSpellings.first)
           It->second.Heading += ", " + HeadingAndSpellings.first;
         // Merge spellings
         It->second.SupportedSpellings.merge(HeadingAndSpellings.second);
         // Merge content
         It->second.Documentation = &Doc; // Update reference
-      }
-      else {
-         // Otherwise, add a new entry.
-         CategoryDocs.emplace(keyHash, DocumentationData(Doc, Attr, 
HeadingAndSpellings));
+      } else {
+        // Otherwise, add a new entry.
+        CategoryDocs.emplace(keyHash,
+                             DocumentationData(Doc, Attr, 
HeadingAndSpellings));
       }
     }
   }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to