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