diff options
author | Erich Keane <erich.keane@intel.com> | 2017-10-16 20:31:05 +0000 |
---|---|---|
committer | Erich Keane <erich.keane@intel.com> | 2017-10-16 20:31:05 +0000 |
commit | a98a2be8695bc56c64a66a681954b86afa2227a9 (patch) | |
tree | de912b1bfd8f08615e07294b5352faf072249a0a /clang | |
parent | 46e0918f83bb360a9cacc9e56027e93a02ace0e4 (diff) | |
download | bcm5719-llvm-a98a2be8695bc56c64a66a681954b86afa2227a9.tar.gz bcm5719-llvm-a98a2be8695bc56c64a66a681954b86afa2227a9.zip |
Sort Attributes by "HeaderName"
Attributes in the docs were previously sorted (apparently)
by the attribute name, so AnyX86Interrupt ended up being the
first one, rather than in a meaningful place. This resulted in the
4 'interrupt' titled sections being all in different places.
This replaces it with a naive alphabetical sort (case sensitive, underscore
and special characters first, etc).
Differential Revision: https://reviews.llvm.org/D38969
llvm-svn: 315931
Diffstat (limited to 'clang')
-rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 015cc4dd1fc..6e19fc87d11 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3663,9 +3663,14 @@ class DocumentationData { public: const Record *Documentation; const Record *Attribute; - - DocumentationData(const Record &Documentation, const Record &Attribute) - : Documentation(&Documentation), Attribute(&Attribute) {} + std::string Heading; + unsigned SupportedSpellings; + + DocumentationData(const Record &Documentation, const Record &Attribute, + const std::pair<std::string, unsigned> HeadingAndKinds) + : Documentation(&Documentation), Attribute(&Attribute), + Heading(std::move(HeadingAndKinds.first)), + SupportedSpellings(HeadingAndKinds.second) {} }; static void WriteCategoryHeader(const Record *DocCategory, @@ -3691,16 +3696,17 @@ enum SpellingKind { Pragma = 1 << 6 }; -static void WriteDocumentation(RecordKeeper &Records, - const DocumentationData &Doc, raw_ostream &OS) { +static std::pair<std::string, unsigned> +GetAttributeHeadingAndSpellingKinds(const Record &Documentation, + const Record &Attribute) { // FIXME: there is no way to have a per-spelling category for the attribute // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. - std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Doc.Attribute); + std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute); // Determine the heading to be used for this attribute. - std::string Heading = Doc.Documentation->getValueAsString("Heading"); + std::string Heading = Documentation.getValueAsString("Heading"); bool CustomHeading = !Heading.empty(); if (Heading.empty()) { // If there's only one spelling, we can simply use that. @@ -3722,7 +3728,7 @@ static void WriteDocumentation(RecordKeeper &Records, // If the heading is still empty, it is an error. if (Heading.empty()) - PrintFatalError(Doc.Attribute->getLoc(), + PrintFatalError(Attribute.getLoc(), "This attribute requires a heading to be specified"); // Gather a list of unique spellings; this is not the same as the semantic @@ -3765,29 +3771,33 @@ static void WriteDocumentation(RecordKeeper &Records, } Heading += ")"; } - OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n"; - if (!SupportedSpellings) - PrintFatalError(Doc.Attribute->getLoc(), + PrintFatalError(Attribute.getLoc(), "Attribute has no supported spellings; cannot be " "documented"); + return std::make_pair(std::move(Heading), SupportedSpellings); +} + +static void WriteDocumentation(RecordKeeper &Records, + const DocumentationData &Doc, raw_ostream &OS) { + OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\","; OS << " \"Pragma\", \"Pragma clang attribute\"\n\n"; OS << " \""; - if (SupportedSpellings & GNU) OS << "X"; + if (Doc.SupportedSpellings & GNU) OS << "X"; OS << "\",\""; - if (SupportedSpellings & CXX11) OS << "X"; + if (Doc.SupportedSpellings & CXX11) OS << "X"; OS << "\",\""; - if (SupportedSpellings & C2x) OS << "X"; + if (Doc.SupportedSpellings & C2x) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Declspec) OS << "X"; + if (Doc.SupportedSpellings & Declspec) OS << "X"; OS << "\",\""; - if (SupportedSpellings & Keyword) OS << "X"; + if (Doc.SupportedSpellings & Keyword) OS << "X"; OS << "\", \""; - if (SupportedSpellings & Pragma) OS << "X"; + if (Doc.SupportedSpellings & Pragma) OS << "X"; OS << "\", \""; if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute)) OS << "X"; @@ -3842,18 +3852,24 @@ void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) { if (Undocumented && Docs.size() > 1) PrintFatalError(Doc.getLoc(), "Attribute is \"Undocumented\", but has multiple " - "documentation categories"); + "documentation categories"); if (!Undocumented) - SplitDocs[Category].push_back(DocumentationData(Doc, Attr)); + SplitDocs[Category].push_back(DocumentationData( + Doc, Attr, GetAttributeHeadingAndSpellingKinds(Doc, Attr))); } } // Having split the attributes out based on what documentation goes where, // we can begin to generate sections of documentation. - for (const auto &I : SplitDocs) { + for (auto &I : SplitDocs) { WriteCategoryHeader(I.first, OS); + std::sort(I.second.begin(), I.second.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) |