llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Samarth Narang (snarang181) <details> <summary>Changes</summary> Implements https://github.com/llvm/llvm-project/issues/142272 --- Patch is 51.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/142273.diff 17 Files Affected: - (modified) clang-tools-extra/clang-doc/BitcodeReader.cpp (+7-2) - (modified) clang-tools-extra/clang-doc/BitcodeWriter.cpp (+2-1) - (modified) clang-tools-extra/clang-doc/HTMLGenerator.cpp (+12-6) - (modified) clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp (+7-5) - (modified) clang-tools-extra/clang-doc/MDGenerator.cpp (+38-20) - (modified) clang-tools-extra/clang-doc/Representation.cpp (+60) - (modified) clang-tools-extra/clang-doc/Representation.h (+26-7) - (modified) clang-tools-extra/clang-doc/Serialize.cpp (+1-1) - (modified) clang-tools-extra/clang-doc/YAMLGenerator.cpp (+30-1) - (added) clang-tools-extra/test/clang-doc/Inputs/html-tag-comment.yaml (+12) - (added) clang-tools-extra/test/clang-doc/html-tag-comment.cpp (+17) - (modified) clang-tools-extra/test/clang-doc/templates.cpp (+8-8) - (modified) clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp (+35-33) - (modified) clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp (+10-10) - (modified) clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp (+29-27) - (modified) clang-tools-extra/unittests/clang-doc/MergeTest.cpp (+9-9) - (modified) clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp (+62-60) ``````````diff diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: - return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { + llvm::SmallString<16> KindStr; + if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; + I->Kind = stringToCommentKind(KindStr); + return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..708ce09d9e5b2 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..8a36fbf99c857 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,7 +635,8 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { + switch (I.Kind) { + case CommentKind::CK_FullComment: { auto FullComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV); for (const auto &Child : I.Children) { std::unique_ptr<HTMLNode> Node = genHTML(*Child); @@ -645,7 +646,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) { return std::move(FullComment); } - if (I.Kind == "ParagraphComment") { + case CommentKind::CK_ParagraphComment: { auto ParagraphComment = std::make_unique<TagNode>(HTMLTag::TAG_P); for (const auto &Child : I.Children) { std::unique_ptr<HTMLNode> Node = genHTML(*Child); @@ -657,7 +658,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) { return std::move(ParagraphComment); } - if (I.Kind == "BlockCommandComment") { + case CommentKind::CK_BlockCommandComment: { auto BlockComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV); BlockComment->Children.emplace_back( std::make_unique<TagNode>(HTMLTag::TAG_DIV, I.Name)); @@ -670,12 +671,17 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) { return nullptr; return std::move(BlockComment); } - if (I.Kind == "TextComment") { - if (I.Text == "") + + case CommentKind::CK_TextComment: { + if (I.Text.empty()) return nullptr; return std::make_unique<TextNode>(I.Text); } - return nullptr; + + // For now, no handling — fallthrough. + default: + return nullptr; + } } static std::unique_ptr<TagNode> genHTML(const std::vector<CommentInfo> &C) { diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 65dc2e93582e8..95306eee12f31 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -198,21 +198,23 @@ static json::Value extractValue(const TypedefInfo &I) { } static json::Value extractValue(const CommentInfo &I) { - assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" || - I.Kind == "ParagraphComment" || I.Kind == "TextComment") && + assert((I.Kind == CommentKind::CK_BlockCommandComment || + I.Kind == CommentKind::CK_FullComment || + I.Kind == CommentKind::CK_ParagraphComment || + I.Kind == CommentKind::CK_TextComment) && "Unknown Comment type in CommentInfo."); Object Obj = Object(); json::Value Child = Object(); // TextComment has no children, so return it. - if (I.Kind == "TextComment") { + if (I.Kind == CommentKind::CK_TextComment) { Obj.insert({"TextComment", I.Text}); return Obj; } // BlockCommandComment needs to generate a Command key. - if (I.Kind == "BlockCommandComment") + if (I.Kind == CommentKind::CK_BlockCommandComment) Child.getAsObject()->insert({"Command", I.Name}); // Use the same handling for everything else. @@ -226,7 +228,7 @@ static json::Value extractValue(const CommentInfo &I) { for (const auto &C : I.Children) CARef.emplace_back(extractValue(*C)); Child.getAsObject()->insert({"Children", ChildArr}); - Obj.insert({I.Kind, Child}); + Obj.insert({commentKindToString(I.Kind), Child}); return Obj; } diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index ccd6175c96cb8..2becccf8b07da 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -75,39 +75,49 @@ static void maybeWriteSourceFileRef(llvm::raw_ostream &OS, } static void writeDescription(const CommentInfo &I, raw_ostream &OS) { - if (I.Kind == "FullComment") { + switch (I.Kind) { + case CommentKind::CK_FullComment: for (const auto &Child : I.Children) writeDescription(*Child, OS); - } else if (I.Kind == "ParagraphComment") { + break; + + case CommentKind::CK_ParagraphComment: for (const auto &Child : I.Children) writeDescription(*Child, OS); writeNewLine(OS); - } else if (I.Kind == "BlockCommandComment") { + break; + + case CommentKind::CK_BlockCommandComment: OS << genEmphasis(I.Name); for (const auto &Child : I.Children) writeDescription(*Child, OS); - } else if (I.Kind == "InlineCommandComment") { + break; + + case CommentKind::CK_InlineCommandComment: OS << genEmphasis(I.Name) << " " << I.Text; - } else if (I.Kind == "ParamCommandComment") { - std::string Direction = I.Explicit ? (" " + I.Direction).str() : ""; - OS << genEmphasis(I.ParamName) << I.Text << Direction; - for (const auto &Child : I.Children) - writeDescription(*Child, OS); - } else if (I.Kind == "TParamCommandComment") { + break; + + case CommentKind::CK_ParamCommandComment: + case CommentKind::CK_TParamCommandComment: { std::string Direction = I.Explicit ? (" " + I.Direction).str() : ""; OS << genEmphasis(I.ParamName) << I.Text << Direction; for (const auto &Child : I.Children) writeDescription(*Child, OS); - } else if (I.Kind == "VerbatimBlockComment") { + break; + } + + case CommentKind::CK_VerbatimBlockComment: for (const auto &Child : I.Children) writeDescription(*Child, OS); - } else if (I.Kind == "VerbatimBlockLineComment") { - OS << I.Text; - writeNewLine(OS); - } else if (I.Kind == "VerbatimLineComment") { + break; + + case CommentKind::CK_VerbatimBlockLineComment: + case CommentKind::CK_VerbatimLineComment: OS << I.Text; writeNewLine(OS); - } else if (I.Kind == "HTMLStartTagComment") { + break; + + case CommentKind::CK_HTMLStartTagComment: { if (I.AttrKeys.size() != I.AttrValues.size()) return; std::string Buffer; @@ -117,12 +127,20 @@ static void writeDescription(const CommentInfo &I, raw_ostream &OS) { std::string CloseTag = I.SelfClosing ? "/>" : ">"; writeLine("<" + I.Name + Attrs.str() + CloseTag, OS); - } else if (I.Kind == "HTMLEndTagComment") { + break; + } + + case CommentKind::CK_HTMLEndTagComment: writeLine("</" + I.Name + ">", OS); - } else if (I.Kind == "TextComment") { + break; + + case CommentKind::CK_TextComment: OS << I.Text; - } else { - OS << "Unknown comment kind: " << I.Kind << ".\n\n"; + break; + + case CommentKind::CK_Unknown: + OS << "Unknown comment kind: " << static_cast<int>(I.Kind) << ".\n\n"; + break; } } diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 9ab2f342d969a..9fb3839419731 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -26,6 +26,66 @@ namespace clang { namespace doc { +CommentKind stringToCommentKind(llvm::StringRef KindStr) { + if (KindStr == "FullComment") + return CommentKind::CK_FullComment; + if (KindStr == "ParagraphComment") + return CommentKind::CK_ParagraphComment; + if (KindStr == "TextComment") + return CommentKind::CK_TextComment; + if (KindStr == "InlineCommandComment") + return CommentKind::CK_InlineCommandComment; + if (KindStr == "HTMLStartTagComment") + return CommentKind::CK_HTMLStartTagComment; + if (KindStr == "HTMLEndTagComment") + return CommentKind::CK_HTMLEndTagComment; + if (KindStr == "BlockCommandComment") + return CommentKind::CK_BlockCommandComment; + if (KindStr == "ParamCommandComment") + return CommentKind::CK_ParamCommandComment; + if (KindStr == "TParamCommandComment") + return CommentKind::CK_TParamCommandComment; + if (KindStr == "VerbatimBlockComment") + return CommentKind::CK_VerbatimBlockComment; + if (KindStr == "VerbatimBlockLineComment") + return CommentKind::CK_VerbatimBlockLineComment; + if (KindStr == "VerbatimLineComment") + return CommentKind::CK_VerbatimLineComment; + return CommentKind::CK_Unknown; +} + +llvm::StringRef commentKindToString(CommentKind Kind) { + switch (Kind) { + case CommentKind::CK_FullComment: + return "FullComment"; + case CommentKind::CK_ParagraphComment: + return "ParagraphComment"; + case CommentKind::CK_TextComment: + return "TextComment"; + case CommentKind::CK_InlineCommandComment: + return "InlineCommandComment"; + case CommentKind::CK_HTMLStartTagComment: + return "HTMLStartTagComment"; + case CommentKind::CK_HTMLEndTagComment: + return "HTMLEndTagComment"; + case CommentKind::CK_BlockCommandComment: + return "BlockCommandComment"; + case CommentKind::CK_ParamCommandComment: + return "ParamCommandComment"; + case CommentKind::CK_TParamCommandComment: + return "TParamCommandComment"; + case CommentKind::CK_VerbatimBlockComment: + return "VerbatimBlockComment"; + case CommentKind::CK_VerbatimBlockLineComment: + return "VerbatimBlockLineComment"; + case CommentKind::CK_VerbatimLineComment: + return "VerbatimLineComment"; + case CommentKind::CK_Unknown: + return "Unknown"; + } + llvm_unreachable("Unhandled CommentKind"); +} + namespace { const SymbolID EmptySID = SymbolID(); diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index a3a6217f76bbd..15f5638a80803 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -45,6 +45,25 @@ enum class InfoType { IT_typedef }; +enum class CommentKind { + CK_FullComment, + CK_ParagraphComment, + CK_TextComment, + CK_InlineCommandComment, + CK_HTMLStartTagComment, + CK_HTMLEndTagComment, + CK_BlockCommandComment, + CK_ParamCommandComment, + CK_TParamCommandComment, + CK_VerbatimBlockComment, + CK_VerbatimBlockLineComment, + CK_VerbatimLineComment, + CK_Unknown +}; + +CommentKind stringToCommentKind(llvm::StringRef KindStr); +llvm::StringRef commentKindToString(CommentKind Kind); + // A representation of a parsed comment. struct CommentInfo { CommentInfo() = default; @@ -60,13 +79,13 @@ struct CommentInfo { // the vector. bool operator<(const CommentInfo &Other) const; - // TODO: The Kind field should be an enum, so we can switch on it easily. - SmallString<16> - Kind; // Kind of comment (FullComment, ParagraphComment, TextComment, - // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment, - // BlockCommandComment, ParamCommandComment, - // TParamCommandComment, VerbatimBlockComment, - // VerbatimBlockLineComment, VerbatimLineComment). + CommentKind Kind = CommentKind:: + CK_Unknown; // Kind of comment (FullComment, ParagraphComment, + // TextComment, InlineCommandComment, HTMLStartTagComment, + // HTMLEndTagComment, BlockCommandComment, + // ParamCommandComment, TParamCommandComment, + // VerbatimBlockComment, VerbatimBlockLineComment, + // VerbatimLineComment). SmallString<64> Text; // Text of the comment. SmallString<16> Name; // Name of the comment (for Verbatim and HTML). SmallString<8> Direction; // Parameter direction (for (T)ParamCommand). diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 3932a939de973..462001b3f3027 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -270,7 +270,7 @@ class ClangDocCommentVisitor }; void ClangDocCommentVisitor::parseComment(const comments::Comment *C) { - CurrentCI.Kind = C->getCommentKindName(); + CurrentCI.Kind = stringToCommentKind(C->getCommentKindName()); ConstCommentVisitor<ClangDocCommentVisitor>::visit(C); for (comments::Comment *Child : llvm::make_range(C->child_begin(), C->child_end())) { diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp index 8c110b34e8e20..09fadcbc1e742 100644 --- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -65,6 +65,35 @@ template <> struct ScalarEnumerationTraits<InfoType> { } }; +template <> +struct llvm::yaml::ScalarEnumerationTraits<clang::doc::CommentKind> { + static void enumeration(IO &IO, clang::doc::CommentKind &Value) { + IO.enumCase(Value, "FullComment", clang::doc::CommentKind::CK_FullComment); + IO.enumCase(Value, "ParagraphComment", + clang::doc::CommentKind::CK_ParagraphComment); + IO.enumCase(Value, "TextComment", clang::doc::CommentKind::CK_TextComment); + IO.enumCase(Value, "InlineCommandComment", + clang::doc::CommentKind::CK_InlineCommandComment); + IO.enumCase(Value, "HTMLStartTagComment", + clang::doc::CommentKind::CK_HTMLStartTagComment); + IO.enumCase(Value, "HTMLEndTagComment", + clang::doc::CommentKind::CK_HTMLEndTagComment); + IO.enumCase(Value, "BlockCommandComment", + clang::doc::CommentKind::CK_BlockCommandComment); + IO.enumCase(Value, "ParamCommandComment", + clang::doc::CommentKind::CK_ParamCommandComment); + IO.enumCase(Value, "TParamCommandComment", + clang::doc::CommentKind::CK_TParamCommandComment); + IO.enumCase(Value, "VerbatimBlockComment", + clang::doc::CommentKind::CK_VerbatimBlockComment); + IO.enumCase(Value, "VerbatimBlockLineComment", + clang::doc::CommentKind::CK_VerbatimBlockLineComment); + IO.enumCase(Value, "VerbatimLineComment", + clang::doc::CommentKind::CK_VerbatimLineComment); + IO.enumCase(Value, "Unknown", clang::doc::CommentKind::CK_Unknown); + } +}; + // Scalars to YAML output. template <unsigned U> struct ScalarTraits<SmallString<U>> { @@ -149,7 +178,7 @@ static void recordInfoMapping(IO &IO, RecordInfo &I) { } static void commentInfoMapping(IO &IO, CommentInfo &I) { - IO.mapOptional("Kind", I.Kind, SmallString<16>()); + IO.mapOptional("Kind", I.Kind, CommentKind::CK_Unknown); IO.mapOptional("Text", I.Text, SmallString<64>()); IO.mapOptional("Name", I.Name, SmallString<16>()); IO.mapOptional("Direction", I.Direction, SmallString<8>()); diff --git a/clang-tools-extra/test/clang-doc/Inputs/html-tag-comment.yaml b/clang-tools-extra/test/clang-doc/Inputs/html-tag-comment.yaml new file mode 100644 index 0000000000000..875e9b5947f47 --- /dev/null +++ b/clang-tools-extra/test/clang-doc/Inputs/html-tag-comment.yaml @@ -0,0 +1,12 @@ +--- +Name: 'withHtmlTag' +Description: + - Kind: FullComment + Children: + - Kind: VerbatimBlockComment + Name: 'verbatim' + CloseName: 'endverbatim' + Children: + - Kind: VerbatimBlockLineComment + Text: '<ul class="test"><li> Testing. </li></ul>' +... diff --git a/clang-tools-extra/test/clang-doc/html-tag-comment.cpp b/clang-tools-extra/test/clang-doc/html-tag-comment.cpp new file mode 100644 index 0000000000000..97e2e3b22e368 --- /dev/null +++ b/clang-tools-extra/test/clang-doc/html-tag-comment.cpp @@ -0,0 +1,17 @@ +// RUN: clang-doc --public --format=yaml -p %T %s -output=%t +// RUN: FileCheck --input-file=%S/Inputs/html-tag-comment.yaml %s + +/// \verbatim <ul class="test"><li> Testing. </li></ul> \endverbatim +void withHtmlTag() {} +// CHECK: --- +// CHECK: Name: 'withHtmlTag' +// CHECK: Description: +// CHECK: - Kind: FullComment +// CHECK: Children: +// CHECK: - Kind: VerbatimBlockComment +// CHECK: Name: 'verbatim' +// CHECK: CloseName: 'endverbatim' +// CHECK: Children: +// CHECK: - Kind: VerbatimBlockLineComment +// CHECK: Text: '<ul class="test"><li> Testing. </li></ul>' +// CHECK: ... diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp index 426a0b16befd4..abe03a7d2d0ea 100644 --- a/clang-tools-extra/test/clang-doc/templates.cpp +++ b/clang-tools-extra/test/clang-doc/templates.cpp @@ -112,22 +112,22 @@ tuple<int, int, bool> func_with_tuple_param(tuple<int, int, bool> t) { return t; // YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' // YAML-NEXT: Name: 'func_with_tuple_param' // YAML-NEXT: Description: -// YAML-NEXT: - Kind: 'FullComment' +// YAML-NEXT: - Kind: FullComment // YAML-NEXT: Children: -// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: - Kind: ParagraphComment // YAML-NEXT: Children: -// YAML-NEXT: - Kind: 'TextComment' +// YAML-NEXT: - Kind: TextComment // YAML-NEXT: Text: ' A function with a tuple parameter' -// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: - Kind: ParagraphComment // YAML-NEXT: Children: -// YAML-NEXT: - Kind: 'TextComment' -// YAML-NEXT: - Kind: 'ParamCommandComment' +// YAML-NEXT: - Kind: TextComment +// YAML-NEXT: - Kind: ParamCommandComment // YAML-NEXT: Direction: '[in]' // YAML-NEXT: ParamName: 't' // YAML-NEXT: Children: -// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: - Kind: ParagraphComment // YAML-NEXT: Children: -// YAML-NEXT: - Kind: 'TextComment' +// YAML-NEXT: - Kind: TextComment // YAML-NEXT: Text: ' The input to func_with_tuple_param' // YAML-NEXT: DefLocation: // YAML-NEXT: LineNumber: [[# @LINE - 23]] diff --git a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp index 4f2466af9a6bd..bbe158ed50e28 100644 --- a/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp +++ b/clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp @@ -93,12 +93,12 @@ TEST(BitcodeTest, emitRecordInfoBitcode) { // Documentation for the data member. CommentInfo TopComment; - TopComment.Kind = "FullComment"; + TopComment.Kind = CommentKind::CK_FullComment; TopComment.Children.emplace_back(std::make_unique<CommentInfo>()); CommentInfo *Brief = TopComment.Children.... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/142273 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits