[clang-tools-extra] [clang-doc] Flatten repeated @return and @brief comment arrays (PR #188739)

via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 26 06:15:37 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Zohaib (syedzohaibshah)

<details>
<summary>Changes</summary>

Multiple occurrences of \return or \brief in a doc comment were emitted
as nested arrays in the JSON output instead of a single flat array.

Also handles \returns, \result (aliases for \return) and \short (alias
for \brief).

Fixes #<!-- -->169006


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


2 Files Affected:

- (modified) clang-tools-extra/clang-doc/JSONGenerator.cpp (+26-8) 
- (added) clang-tools-extra/test/clang-doc/json/multiple-return-comments.cpp (+30) 


``````````diff
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index a9223cb9c3e8a..ef0d4d614a070 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -133,8 +133,11 @@ json::Object JSONGenerator::serializeLocation(const Location &Loc) {
 ///
 /// \param Comment Either an Object or Array, depending on the comment type
 /// \param Key     The type (Brief, Code, etc.) of comment to be inserted
+/// \param FlattenArray If true and Comment is an array, merge its elements
+///                     instead of nesting. Used for BriefComments and
+///                     ReturnComments to avoid double-nested arrays.
 static void insertComment(Object &Description, json::Value &Comment,
-                          StringRef Key) {
+                          StringRef Key, bool FlattenArray = false) {
   // The comment has a Children array for the actual text, with meta attributes
   // alongside it in the Object.
   if (auto *Obj = Comment.getAsObject()) {
@@ -150,11 +153,26 @@ static void insertComment(Object &Description, json::Value &Comment,
   auto DescriptionIt = Description.find(Key);
 
   if (DescriptionIt == Description.end()) {
-    auto CommentsArray = json::Array();
-    CommentsArray.push_back(Comment);
-    Description[Key] = std::move(CommentsArray);
+    // For FlattenArray mode, if Comment is an array, use it directly
+    if (FlattenArray && Comment.getAsArray()) {
+      Description[Key] = Comment;
+    } else {
+      auto CommentsArray = json::Array();
+      CommentsArray.push_back(Comment);
+      Description[Key] = std::move(CommentsArray);
+    }
     Description["Has" + Key.str()] = true;
   } else {
+    // For FlattenArray mode, if Comment is an array, merge its elements
+    if (FlattenArray) {
+      if (auto *CommentArray = Comment.getAsArray()) {
+        auto *DestArray = DescriptionIt->getSecond().getAsArray();
+        for (auto &Element : *CommentArray) {
+          DestArray->push_back(Element);
+        }
+        return;
+      }
+    }
     DescriptionIt->getSecond().getAsArray()->push_back(Comment);
   }
 }
@@ -217,10 +235,10 @@ static Object serializeComment(const CommentInfo &I, Object &Description) {
 
   case CommentKind::CK_BlockCommandComment: {
     auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
-    if (I.Name == "brief")
-      insertComment(Description, TextCommentsArray, "BriefComments");
-    else if (I.Name == "return")
-      insertComment(Description, TextCommentsArray, "ReturnComments");
+    if (I.Name == "brief" || I.Name == "short")
+      insertComment(Description, TextCommentsArray, "BriefComments", true);
+    else if (I.Name == "return" || I.Name == "returns" || I.Name == "result")
+      insertComment(Description, TextCommentsArray, "ReturnComments", true);
     else if (I.Name == "throws" || I.Name == "throw") {
       json::Value ThrowsVal = Object();
       auto &ThrowsObj = *ThrowsVal.getAsObject();
diff --git a/clang-tools-extra/test/clang-doc/json/multiple-return-comments.cpp b/clang-tools-extra/test/clang-doc/json/multiple-return-comments.cpp
new file mode 100644
index 0000000000000..e1203a4115e78
--- /dev/null
+++ b/clang-tools-extra/test/clang-doc/json/multiple-return-comments.cpp
@@ -0,0 +1,30 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: clang-doc --output=%t --format=json --executor=standalone %s
+// RUN: FileCheck %s < %t/json/GlobalNamespace/index.json
+
+/// @brief Test function for multiple return comments
+///
+/// @return First return value description
+/// @return Second return value description
+int testMultipleReturns() {
+  return 42;
+}
+
+// CHECK:      "Functions": [
+// CHECK-NEXT:   {
+// CHECK:        "Description": {
+// CHECK:          "BriefComments": [
+// CHECK-NEXT:       {
+// CHECK-NEXT:         "TextComment": "Test function for multiple return comments"
+// CHECK-NEXT:       }
+// CHECK-NEXT:     ],
+// CHECK:          "HasReturnComments": true,
+// CHECK:          "ReturnComments": [
+// CHECK-NEXT:       {
+// CHECK-NEXT:         "TextComment": "First return value description"
+// CHECK-NEXT:       },
+// CHECK-NEXT:       {
+// CHECK-NEXT:         "TextComment": "Second return value description"
+// CHECK-NEXT:       }
+// CHECK-NEXT:     ]
+// CHECK:        }

``````````

</details>


https://github.com/llvm/llvm-project/pull/188739


More information about the cfe-commits mailing list