Author: Zeyi Xu
Date: 2026-03-20T23:55:00+08:00
New Revision: 6d45f6dfb7e139671c569e4680894609f141c3c9

URL: 
https://github.com/llvm/llvm-project/commit/6d45f6dfb7e139671c569e4680894609f141c3c9
DIFF: 
https://github.com/llvm/llvm-project/commit/6d45f6dfb7e139671c569e4680894609f141c3c9.diff

LOG: [clang-tidy] Generate valid JSON for characters that require escaping 
(#187454)

As of AI Usage: This PR is assisted by Claude
Closes #187201

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
    clang-tools-extra/docs/ReleaseNotes.rst
    
clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp 
b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
index 68b8ae0797acc..9b593367657b6 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyProfiling.cpp
@@ -9,6 +9,7 @@
 #include "ClangTidyProfiling.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/JSON.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <optional>
@@ -45,13 +46,24 @@ void 
ClangTidyProfiling::printUserFriendlyTable(llvm::raw_ostream &OS,
 void ClangTidyProfiling::printAsJSON(llvm::raw_ostream &OS,
                                      llvm::TimerGroup &TG) {
   assert(Storage && "We should have a filename.");
-  OS << "{\n";
-  OS << R"("file": ")" << Storage->SourceFilename << "\",\n";
-  OS << R"("timestamp": ")" << Storage->Timestamp << "\",\n";
-  OS << "\"profile\": {\n";
-  TG.printJSONValues(OS, "");
-  OS << "\n}\n";
-  OS << "}\n";
+  std::string TimestampStr;
+  llvm::raw_string_ostream TmpOS(TimestampStr);
+  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
+  TmpOS << Storage->Timestamp;
+
+  llvm::json::OStream JOS(OS, 2);
+  JOS.object([&] {
+    JOS.attribute("file", Storage->SourceFilename);
+    JOS.attribute("timestamp", TimestampStr);
+    JOS.attributeBegin("profile");
+    JOS.rawValue([&](llvm::raw_ostream &ROS) {
+      ROS << "{\n";
+      TG.printJSONValues(ROS, "");
+      ROS << "\n}";
+    });
+    JOS.attributeEnd();
+  });
+  OS << "\n";
   OS.flush();
 }
 

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index c5d0c617a9fd7..ef4a771d5a0f6 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -102,6 +102,9 @@ Improvements to clang-tidy
   manages the creation of temporary header files and ensures that diagnostics
   and fixes are verified for the specified headers.
 
+- Improved :program:`clang-tidy` ``-store-check-profile`` by generating valid
+  JSON when the source file path contains characters that require JSON 
escaping.
+
 New checks
 ^^^^^^^^^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
 
b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
index 192fbf546d203..9800881af9292 100644
--- 
a/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/infrastructure/clang-tidy-store-check-profile-one-tu.cpp
@@ -1,9 +1,11 @@
 // RUN: rm -rf %t.dir/out
 // RUN: clang-tidy -enable-check-profile 
-checks='-*,readability-function-size' -store-check-profile=%t.dir/out %s -- 
2>&1 | not FileCheck --match-full-lines 
-implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s
 // RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | 
FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' 
-check-prefix=CHECK-FILE %s
+// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | 
%python -c "import sys, json; json.load(sys.stdin)"
 // RUN: rm -rf %t.dir/out
 // RUN: clang-tidy -enable-check-profile 
-checks='-*,readability-function-size' -store-check-profile=%t.dir/out %s -- 
2>&1
 // RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | 
FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' 
-check-prefix=CHECK-FILE %s
+// RUN: cat %t.dir/out/*-clang-tidy-store-check-profile-one-tu.cpp.json | 
%python -c "import sys, json; json.load(sys.stdin)"
 
 // CHECK-CONSOLE-NOT: 
===-------------------------------------------------------------------------===
 // CHECK-CONSOLE-NOT: {{.*}}  --- Name ---


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to