[PATCH] D114052: Add JSONScopedPrinter as a subclass to ScopedPrinter with history stack
Jayson Yan via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 16 20:54:13 PST 2021
Jaysonyan created this revision.
Jaysonyan added reviewers: leonardchan, phosek, jhenderson.
Herald added subscribers: dexonsmith, rupprecht, mgrang.
Jaysonyan requested review of this revision.
Herald added subscribers: llvm-commits, MaskRay.
Herald added a project: LLVM.
This is an alternative approach to the following diff: D111658: Add JSON output skeleton to llvm-readelf <https://reviews.llvm.org/D111658>
The major difference is that in this change `JSONScoperPrinter` inherits from `ScopedPrinter` rather
than creating a `ScopedPrinterBase` base class which both `JSONScopedPrinter` and `ScopedPrinter`
inherit from.
In comment {D111658#3121940 <https://reviews.llvm.org/D111658#3121940>} I cited 3 reasons for why I didn't think this was possible. I'll go over
how this change address each problem:
**Problem 1:** `ScopedPrinter` has template methods which are not able to be virtual.
**Solution:** Add private internal non-template methods which can be virtual. The
public template method then transforms all template parameters into concrete types
and then used to call the internal non-template method. This enables `JSONScopedPrinter`
to override the functionality of all of `ScopedPrinter`'s methods.
**Problem 2:** `ScopedPrinter` provides a method `startLine()` which returns the underlying
`raw_ostream`. It would be impossible to ensure printing directly to `raw_ostream` results
in valid JSON.
**Solution:** There is still no easy solution to the problem. Though since this change is to
enable json output for `llvm-readelf`. The planned solution to this problem is to have a
`JSONELFDumper` class similar to D111658: Add JSON output skeleton to llvm-readelf <https://reviews.llvm.org/D111658> and override
methods which call `startLine()` to use another interface.
**Problem 3:** A common usage pattern inside `llvm-readelf` (calling `ListScope(W, "attr1")`
and then `DictScope(W, "attr2")`) produces invalid json since you can't have attributes inside
of lists. (The example would product the following json output)
ListScope(W, "attr1");
DictScope(W, "attr2");
"attr1" : [
"attr2" : { ... }
]
**Solution:** Add a "history" stack similar to the one inside `json::OStream` conditionally
output an encompassing `{}` if inside the context of a list. The following are code examples
and their respective outputs:
ListScope(W, "attr1");
DictScope(W, "attr2");
W.printString("attr3", "val");
"attr1" : [
{
"attr2" : {
"attr3" : "val"
}
}
]
DictScope(W, "attr1");
DictScope(W, "attr2");
W.printString("attr3", "val");
"attr1" : {
"attr2" : {
"attr3" : "val"
}
}
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114052
Files:
llvm/include/llvm/Support/ScopedPrinter.h
llvm/tools/llvm-readobj/llvm-readobj.cpp
llvm/tools/llvm-readobj/llvm-readobj.h
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114052.387806.patch
Type: text/x-patch
Size: 20548 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211117/3f58b4b5/attachment.bin>
More information about the llvm-commits
mailing list