[llvm] [Support] ScopedPrinter: support pretty-printing JSON (PR #214806)
Dan McGregor via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 10:55:50 PDT 2026
https://github.com/dankm created https://github.com/llvm/llvm-project/pull/214806
Add a specific printObject implementation for JSON values. For the default ScopedPrinter this supports printing with the existing indentation level. For JSONScopedPrinter it prints a raw attribute with no special handling.
I intend to use this for forthcoming support for FDO packakaging metadata support in readobj.
This is split from #214375 at the request of @jh7370.
>From f63d07db90fb6c17129200fa33d9fb4d03c5dc5c Mon Sep 17 00:00:00 2001
From: Dan McGregor <danmcgr at protonmail.com>
Date: Fri, 17 Jul 2026 13:40:40 -0600
Subject: [PATCH] [Support] ScopedPrinter: support pretty-printing JSON
Add a specific printObject implementation for JSON values.
For the default ScopedPrinter this supports printing with the
existing indentation level. For JSONScopedPrinter it prints a
raw attribute with no special handling.
I intend to use this for forthcoming support for FDO packakaging
metadata support in readobj.
---
llvm/include/llvm/Support/JSON.h | 7 +++--
llvm/include/llvm/Support/ScopedPrinter.h | 13 ++++++++
llvm/unittests/Support/ScopedPrinterTest.cpp | 32 ++++++++++++++++++++
3 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h
index 3b145a69c74cb..a0118ca883ce6 100644
--- a/llvm/include/llvm/Support/JSON.h
+++ b/llvm/include/llvm/Support/JSON.h
@@ -984,8 +984,9 @@ class OStream {
public:
using Block = llvm::function_ref<void()>;
// If IndentSize is nonzero, output is pretty-printed.
- explicit OStream(llvm::raw_ostream &OS, unsigned IndentSize = 0)
- : OS(OS), IndentSize(IndentSize) {
+ explicit OStream(llvm::raw_ostream &OS, unsigned IndentSize = 0,
+ unsigned IndentLevel = 0)
+ : OS(OS), IndentSize(IndentSize), Indent(IndentSize * IndentLevel) {
Stack.emplace_back();
}
~OStream() {
@@ -1084,7 +1085,7 @@ class OStream {
llvm::StringRef PendingComment;
llvm::raw_ostream &OS;
unsigned IndentSize;
- unsigned Indent = 0;
+ unsigned Indent;
};
/// Serializes this Value to JSON, writing it to the provided stream.
diff --git a/llvm/include/llvm/Support/ScopedPrinter.h b/llvm/include/llvm/Support/ScopedPrinter.h
index f6fd2671e812f..134ce1af80673 100644
--- a/llvm/include/llvm/Support/ScopedPrinter.h
+++ b/llvm/include/llvm/Support/ScopedPrinter.h
@@ -399,6 +399,15 @@ class LLVM_ABI ScopedPrinter {
printString(Label, to_string(Value));
}
+ virtual void printObject(StringRef Label, const json::Value &Value) {
+ std::string PrettyValue;
+ raw_string_ostream PrettyStream(PrettyValue);
+ json::OStream(PrettyStream, 2, getIndentLevel()).value(Value);
+ startLine() << Label << ": "
+ << PrettyValue.substr(PrettyValue.find_first_not_of(" "))
+ << "\n";
+ }
+
virtual void objectBegin() { scopedBegin('{'); }
virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
@@ -672,6 +681,10 @@ class JSONScopedPrinter : public ScopedPrinter {
JOS.attribute(Label, Value);
}
+ void printObject(StringRef Label, const json::Value &Value) override {
+ JOS.attribute(Label, Value);
+ }
+
void objectBegin() override {
scopedBegin({Scope::Object, ScopeKind::NoAttribute});
}
diff --git a/llvm/unittests/Support/ScopedPrinterTest.cpp b/llvm/unittests/Support/ScopedPrinterTest.cpp
index d2b0d643a0be9..e38b07a5ff72b 100644
--- a/llvm/unittests/Support/ScopedPrinterTest.cpp
+++ b/llvm/unittests/Support/ScopedPrinterTest.cpp
@@ -1174,6 +1174,38 @@ TEST_F(ScopedPrinterTest, PrintObject) {
verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
+TEST_F(ScopedPrinterTest, PrintJSONObject) {
+ auto PrintFunc = [](ScopedPrinter &W) {
+ W.printObject("Object",
+ json::Value(json::Object(
+ {{"Key", "Value"}, {"Key2", json::Array{1, 1, 2, 3}}})));
+ };
+
+ const char *ExpectedOut = R"(Object: {
+ "Key": "Value",
+ "Key2": [
+ 1,
+ 1,
+ 2,
+ 3
+ ]
+}
+)";
+
+ const char *JSONExpectedOut = R"({
+ "Object": {
+ "Key": "Value",
+ "Key2": [
+ 1,
+ 1,
+ 2,
+ 3
+ ]
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
+}
+
TEST_F(ScopedPrinterTest, StartLine) {
auto PrintFunc = [](ScopedPrinter &W) {
W.startLine() << "|";
More information about the llvm-commits
mailing list