llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (YLChenZ)

<details>
<summary>Changes</summary>

Closes #<!-- -->133706.

before the patch:


![docb4](https://github.com/user-attachments/assets/6db1000f-d555-48b8-8a19-85c41b043fd8)
after the patch:


![doc-after](https://github.com/user-attachments/assets/1cff64b6-db2e-48d8-b0a9-a403fd61f8af)


---
Full diff: https://github.com/llvm/llvm-project/pull/134089.diff


1 Files Affected:

- (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+50-18) 


``````````diff
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);
   }
 }

``````````

</details>


https://github.com/llvm/llvm-project/pull/134089
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to