[llvm] 928d172 - [llvm] Add JSONScopedPrinter class
Jayson Yan via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 10 10:58:08 PST 2021
Author: Jayson Yan
Date: 2021-12-10T18:57:33Z
New Revision: 928d17254ba214749dbd58f6d5604c11057a60bc
URL: https://github.com/llvm/llvm-project/commit/928d17254ba214749dbd58f6d5604c11057a60bc
DIFF: https://github.com/llvm/llvm-project/commit/928d17254ba214749dbd58f6d5604c11057a60bc.diff
LOG: [llvm] Add JSONScopedPrinter class
This change adds a JSONScopedPrinter as a subclass to ScopedPrinter.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D114224
Added:
Modified:
llvm/include/llvm/Support/ScopedPrinter.h
llvm/lib/Support/ScopedPrinter.cpp
llvm/tools/llvm-readobj/ARMEHABIPrinter.h
llvm/unittests/Support/ScopedPrinterTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/ScopedPrinter.h b/llvm/include/llvm/Support/ScopedPrinter.h
index 7c4eb2051a70..865337e3cc7f 100644
--- a/llvm/include/llvm/Support/ScopedPrinter.h
+++ b/llvm/include/llvm/Support/ScopedPrinter.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -100,7 +101,20 @@ std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
class ScopedPrinter {
public:
- ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
+ enum class ScopedPrinterKind {
+ Base,
+ JSON,
+ };
+
+ ScopedPrinter(raw_ostream &OS,
+ ScopedPrinterKind Kind = ScopedPrinterKind::Base)
+ : OS(OS), IndentLevel(0), Kind(Kind) {}
+
+ ScopedPrinterKind getKind() const { return Kind; }
+
+ static bool classof(const ScopedPrinter *SP) {
+ return SP->getKind() == ScopedPrinterKind::Base;
+ }
virtual ~ScopedPrinter() {}
@@ -487,6 +501,7 @@ class ScopedPrinter {
raw_ostream &OS;
int IndentLevel;
StringRef Prefix;
+ ScopedPrinterKind Kind;
};
template <>
@@ -496,30 +511,329 @@ ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
startLine() << Label << ": " << hex(Value) << "\n";
}
+struct DelimitedScope;
+
+class JSONScopedPrinter : public ScopedPrinter {
+private:
+ enum class Scope {
+ Array,
+ Object,
+ };
+
+ enum class ScopeKind {
+ NoAttribute,
+ Attribute,
+ NestedAttribute,
+ };
+
+ struct ScopeContext {
+ Scope Context;
+ ScopeKind Kind;
+ ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
+ : Context(Context), Kind(Kind) {}
+ };
+
+ SmallVector<ScopeContext, 8> ScopeHistory;
+ json::OStream JOS;
+ std::unique_ptr<DelimitedScope> OuterScope;
+
+public:
+ JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
+ std::unique_ptr<DelimitedScope> &&OuterScope =
+ std::unique_ptr<DelimitedScope>{});
+
+ static bool classof(const ScopedPrinter *SP) {
+ return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
+ }
+
+ void printNumber(StringRef Label, uint64_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, uint32_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, uint16_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, uint8_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, int64_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, int32_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, int16_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, int8_t Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printNumber(StringRef Label, const APSInt &Value) override {
+ JOS.attributeBegin(Label);
+ printAPSInt(Value);
+ JOS.attributeEnd();
+ }
+
+ void printBoolean(StringRef Label, bool Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void printList(StringRef Label, const ArrayRef<bool> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<std::string> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<int64_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<int32_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<int16_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<int8_t> List) override {
+ printListImpl(Label, List);
+ }
+
+ void printList(StringRef Label, const ArrayRef<APSInt> List) override {
+ JOS.attributeArray(Label, [&]() {
+ for (const APSInt &Item : List) {
+ printAPSInt(Item);
+ }
+ });
+ }
+
+ void printString(StringRef Value) override { JOS.value(Value); }
+
+ void printString(StringRef Label, StringRef Value) override {
+ JOS.attribute(Label, Value);
+ }
+
+ void objectBegin() override {
+ scopedBegin({Scope::Object, ScopeKind::NoAttribute});
+ }
+
+ void objectBegin(StringRef Label) override {
+ scopedBegin(Label, Scope::Object);
+ }
+
+ void objectEnd() override { scopedEnd(); }
+
+ void arrayBegin() override {
+ scopedBegin({Scope::Array, ScopeKind::NoAttribute});
+ }
+
+ void arrayBegin(StringRef Label) override {
+ scopedBegin(Label, Scope::Array);
+ }
+
+ void arrayEnd() override { scopedEnd(); }
+
+private:
+ // Output HexNumbers as decimals so that they're easier to parse.
+ uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
+
+ void printAPSInt(const APSInt &Value) {
+ JOS.rawValueBegin() << Value;
+ JOS.rawValueEnd();
+ }
+
+ void printFlagsImpl(StringRef Label, HexNumber Value,
+ ArrayRef<FlagEntry> Flags) override {
+ JOS.attributeObject(Label, [&]() {
+ JOS.attribute("RawFlags", hexNumberToInt(Value));
+ JOS.attributeArray("Flags", [&]() {
+ for (const FlagEntry &Flag : Flags) {
+ JOS.objectBegin();
+ JOS.attribute("Name", Flag.Name);
+ JOS.attribute("Value", Flag.Value);
+ JOS.objectEnd();
+ }
+ });
+ });
+ }
+
+ void printFlagsImpl(StringRef Label, HexNumber Value,
+ ArrayRef<HexNumber> Flags) override {
+ JOS.attributeObject(Label, [&]() {
+ JOS.attribute("RawFlags", hexNumberToInt(Value));
+ JOS.attributeArray("Flags", [&]() {
+ for (const HexNumber &Flag : Flags) {
+ JOS.value(Flag.Value);
+ }
+ });
+ });
+ }
+
+ template <typename T> void printListImpl(StringRef Label, const T &List) {
+ JOS.attributeArray(Label, [&]() {
+ for (const auto &Item : List)
+ JOS.value(Item);
+ });
+ }
+
+ void printHexListImpl(StringRef Label,
+ const ArrayRef<HexNumber> List) override {
+ JOS.attributeArray(Label, [&]() {
+ for (const HexNumber &Item : List) {
+ JOS.value(hexNumberToInt(Item));
+ }
+ });
+ }
+
+ void printHexImpl(StringRef Label, HexNumber Value) override {
+ JOS.attribute(Label, hexNumberToInt(Value));
+ }
+
+ void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
+ JOS.attributeObject(Label, [&]() {
+ JOS.attribute("Value", Str);
+ JOS.attribute("RawValue", hexNumberToInt(Value));
+ });
+ }
+
+ void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
+ HexNumber Value) override {
+ JOS.attributeObject(Label, [&]() {
+ JOS.attribute("SymName", Symbol);
+ JOS.attribute("Offset", hexNumberToInt(Value));
+ });
+ }
+
+ void printNumberImpl(StringRef Label, StringRef Str,
+ StringRef Value) override {
+ JOS.attributeObject(Label, [&]() {
+ JOS.attribute("Value", Str);
+ JOS.attributeBegin("RawValue");
+ JOS.rawValueBegin() << Value;
+ JOS.rawValueEnd();
+ JOS.attributeEnd();
+ });
+ }
+
+ void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
+ bool Block, uint32_t StartOffset = 0) override {
+ JOS.attributeObject(Label, [&]() {
+ if (!Str.empty())
+ JOS.attribute("Value", Str);
+ JOS.attribute("Offset", StartOffset);
+ JOS.attributeArray("Bytes", [&]() {
+ for (uint8_t Val : Value)
+ JOS.value(Val);
+ });
+ });
+ }
+
+ void scopedBegin(ScopeContext ScopeCtx) {
+ if (ScopeCtx.Context == Scope::Object)
+ JOS.objectBegin();
+ else if (ScopeCtx.Context == Scope::Array)
+ JOS.arrayBegin();
+ ScopeHistory.push_back(ScopeCtx);
+ }
+
+ void scopedBegin(StringRef Label, Scope Ctx) {
+ ScopeKind Kind = ScopeKind::Attribute;
+ if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
+ JOS.objectBegin();
+ Kind = ScopeKind::NestedAttribute;
+ }
+ JOS.attributeBegin(Label);
+ scopedBegin({Ctx, Kind});
+ }
+
+ void scopedEnd() {
+ ScopeContext ScopeCtx = ScopeHistory.back();
+ if (ScopeCtx.Context == Scope::Object)
+ JOS.objectEnd();
+ else if (ScopeCtx.Context == Scope::Array)
+ JOS.arrayEnd();
+ if (ScopeCtx.Kind == ScopeKind::Attribute ||
+ ScopeCtx.Kind == ScopeKind::NestedAttribute)
+ JOS.attributeEnd();
+ if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
+ JOS.objectEnd();
+ ScopeHistory.pop_back();
+ }
+};
+
struct DelimitedScope {
- DelimitedScope(ScopedPrinter &W) : W(W) {}
+ DelimitedScope(ScopedPrinter &W) : W(&W) {}
+ DelimitedScope() : W(nullptr) {}
virtual ~DelimitedScope(){};
- ScopedPrinter &W;
+ virtual void setPrinter(ScopedPrinter &W) = 0;
+ ScopedPrinter *W;
};
struct DictScope : DelimitedScope {
+ explicit DictScope() : DelimitedScope() {}
explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
W.objectBegin(N);
}
- ~DictScope() { W.objectEnd(); }
+ void setPrinter(ScopedPrinter &W) override {
+ this->W = &W;
+ W.objectBegin();
+ }
+
+ ~DictScope() {
+ if (W)
+ W->objectEnd();
+ }
};
struct ListScope : DelimitedScope {
+ explicit ListScope() : DelimitedScope() {}
explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
W.arrayBegin(N);
}
- ~ListScope() { W.arrayEnd(); }
+ void setPrinter(ScopedPrinter &W) override {
+ this->W = &W;
+ W.arrayBegin();
+ }
+
+ ~ListScope() {
+ if (W)
+ W->arrayEnd();
+ }
};
} // namespace llvm
diff --git a/llvm/lib/Support/ScopedPrinter.cpp b/llvm/lib/Support/ScopedPrinter.cpp
index 779c6c45257d..ea90a24eaced 100644
--- a/llvm/lib/Support/ScopedPrinter.cpp
+++ b/llvm/lib/Support/ScopedPrinter.cpp
@@ -43,4 +43,14 @@ void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
}
}
+JSONScopedPrinter::JSONScopedPrinter(
+ raw_ostream &OS, bool PrettyPrint,
+ std::unique_ptr<DelimitedScope> &&OuterScope)
+ : ScopedPrinter(OS, ScopedPrinter::ScopedPrinterKind::JSON),
+ JOS(OS, /*Indent=*/PrettyPrint ? 2 : 0),
+ OuterScope(std::move(OuterScope)) {
+ if (this->OuterScope)
+ this->OuterScope->setPrinter(*this);
+}
+
} // namespace llvm
diff --git a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h
index 94f1672c6342..d641b172eb91 100644
--- a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h
+++ b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h
@@ -512,7 +512,7 @@ template <typename ET>
void PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry,
size_t Length, off_t Offset) const {
ListScope OCC(SW, "Opcodes");
- OpcodeDecoder(OCC.W).Decode(Entry, Offset, Length);
+ OpcodeDecoder(SW).Decode(Entry, Offset, Length);
}
template <typename ET>
diff --git a/llvm/unittests/Support/ScopedPrinterTest.cpp b/llvm/unittests/Support/ScopedPrinterTest.cpp
index 772ef6d9e591..d959720b2329 100644
--- a/llvm/unittests/Support/ScopedPrinterTest.cpp
+++ b/llvm/unittests/Support/ScopedPrinterTest.cpp
@@ -13,13 +13,63 @@
using namespace llvm;
+TEST(JSONScopedPrinterTest, PrettyPrintCtor) {
+ auto PrintFunc = [](ScopedPrinter &W) {
+ DictScope D(W);
+ W.printString("Key", "Value");
+ };
+ std::string StreamBuffer;
+ raw_string_ostream OS(StreamBuffer);
+ JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true);
+ JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false);
+
+ const char *PrettyPrintOut = R"({
+ "Key": "Value"
+})";
+ const char *NoPrettyPrintOut = R"({"Key":"Value"})";
+ PrintFunc(PrettyPrintWriter);
+ EXPECT_EQ(PrettyPrintOut, OS.str());
+ StreamBuffer.clear();
+ PrintFunc(NoPrettyPrintWriter);
+ EXPECT_EQ(NoPrettyPrintOut, OS.str());
+}
+
+TEST(JSONScopedPrinterTest, DelimitedScopeCtor) {
+ std::string StreamBuffer;
+ raw_string_ostream OS(StreamBuffer);
+ {
+ JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false,
+ std::make_unique<DictScope>());
+ DictScopeWriter.printString("Label", "DictScope");
+ }
+ EXPECT_EQ(R"({"Label":"DictScope"})", OS.str());
+ StreamBuffer.clear();
+ {
+ JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false,
+ std::make_unique<ListScope>());
+ ListScopeWriter.printString("ListScope");
+ }
+ EXPECT_EQ(R"(["ListScope"])", OS.str());
+ StreamBuffer.clear();
+ {
+ JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false);
+ NoScopeWriter.printString("NoScope");
+ }
+ EXPECT_EQ(R"("NoScope")", OS.str());
+}
+
class ScopedPrinterTest : public ::testing::Test {
protected:
std::string StreamBuffer;
raw_string_ostream OS;
ScopedPrinter Writer;
+ JSONScopedPrinter JSONWriter;
- ScopedPrinterTest() : OS(StreamBuffer), Writer(OS) {}
+ bool HasPrintedToJSON;
+
+ ScopedPrinterTest()
+ : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true),
+ HasPrintedToJSON(false) {}
using PrintFunc = function_ref<void(ScopedPrinter &)>;
@@ -27,9 +77,45 @@ class ScopedPrinterTest : public ::testing::Test {
Func(Writer);
Writer.flush();
EXPECT_EQ(Expected.str(), OS.str());
+ StreamBuffer.clear();
+ }
+
+ void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) {
+ {
+ DictScope D(JSONWriter);
+ Func(JSONWriter);
+ }
+ JSONWriter.flush();
+ EXPECT_EQ(Expected.str(), OS.str());
+ StreamBuffer.clear();
+ HasPrintedToJSON = true;
+ }
+
+ void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut,
+ PrintFunc Func) {
+ verifyScopedPrinter(ExpectedOut, Func);
+ verifyJSONScopedPrinter(JSONExpectedOut, Func);
+ }
+
+ void TearDown() {
+ // JSONScopedPrinter fails an assert if nothing's been printed.
+ if (!HasPrintedToJSON)
+ JSONWriter.printString("");
}
};
+TEST_F(ScopedPrinterTest, GetKind) {
+ EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind());
+ EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind());
+}
+
+TEST_F(ScopedPrinterTest, ClassOf) {
+ EXPECT_TRUE(ScopedPrinter::classof(&Writer));
+ EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter));
+ EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter));
+ EXPECT_FALSE(JSONScopedPrinter::classof(&Writer));
+}
+
TEST_F(ScopedPrinterTest, Indent) {
auto PrintFunc = [](ScopedPrinter &W) {
W.printString("|");
@@ -147,7 +233,15 @@ TEST_F(ScopedPrinterTest, PrintEnum) {
const char *ExpectedOut = R"(Exists: Name2 (0x2)
DoesNotExist: 0x5
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "Exists": {
+ "Value": "Name2",
+ "RawValue": 2
+ },
+ "DoesNotExist": 5
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintFlag) {
@@ -251,7 +345,169 @@ FirstSecondThirdByteMask [ (0x333)
ThirdByte3 (0x300)
]
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "ZeroFlag": {
+ "RawFlags": 0,
+ "Flags": []
+ },
+ "NoFlag": {
+ "RawFlags": 8,
+ "Flags": []
+ },
+ "Flag1": {
+ "RawFlags": 1,
+ "Flags": [
+ {
+ "Name": "Name1",
+ "Value": 1
+ }
+ ]
+ },
+ "Flag1&3": {
+ "RawFlags": 5,
+ "Flags": [
+ {
+ "Name": "Name1",
+ "Value": 1
+ },
+ {
+ "Name": "Name3",
+ "Value": 4
+ }
+ ]
+ },
+ "ZeroFlagRaw": {
+ "RawFlags": 0,
+ "Flags": []
+ },
+ "NoFlagRaw": {
+ "RawFlags": 8,
+ "Flags": [
+ 8
+ ]
+ },
+ "Flag1Raw": {
+ "RawFlags": 1,
+ "Flags": [
+ 1
+ ]
+ },
+ "Flag1&3Raw": {
+ "RawFlags": 5,
+ "Flags": [
+ 1,
+ 4
+ ]
+ },
+ "FlagSorted": {
+ "RawFlags": 7,
+ "Flags": [
+ {
+ "Name": "A",
+ "Value": 4
+ },
+ {
+ "Name": "B",
+ "Value": 2
+ },
+ {
+ "Name": "C",
+ "Value": 1
+ }
+ ]
+ },
+ "NoBitMask": {
+ "RawFlags": 4095,
+ "Flags": [
+ {
+ "Name": "FirstByte1",
+ "Value": 1
+ },
+ {
+ "Name": "FirstByte2",
+ "Value": 2
+ },
+ {
+ "Name": "FirstByte3",
+ "Value": 3
+ },
+ {
+ "Name": "SecondByte1",
+ "Value": 16
+ },
+ {
+ "Name": "SecondByte2",
+ "Value": 32
+ },
+ {
+ "Name": "SecondByte3",
+ "Value": 48
+ },
+ {
+ "Name": "ThirdByte1",
+ "Value": 256
+ },
+ {
+ "Name": "ThirdByte2",
+ "Value": 512
+ },
+ {
+ "Name": "ThirdByte3",
+ "Value": 768
+ }
+ ]
+ },
+ "FirstByteMask": {
+ "RawFlags": 3,
+ "Flags": [
+ {
+ "Name": "FirstByte3",
+ "Value": 3
+ }
+ ]
+ },
+ "SecondByteMask": {
+ "RawFlags": 48,
+ "Flags": [
+ {
+ "Name": "SecondByte3",
+ "Value": 48
+ }
+ ]
+ },
+ "ValueOutsideMask": {
+ "RawFlags": 1,
+ "Flags": [
+ {
+ "Name": "FirstByte1",
+ "Value": 1
+ }
+ ]
+ },
+ "FirstSecondByteMask": {
+ "RawFlags": 255,
+ "Flags": []
+ },
+ "FirstSecondThirdByteMask": {
+ "RawFlags": 819,
+ "Flags": [
+ {
+ "Name": "FirstByte3",
+ "Value": 3
+ },
+ {
+ "Name": "SecondByte3",
+ "Value": 48
+ },
+ {
+ "Name": "ThirdByte3",
+ "Value": 768
+ }
+ ]
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintNumber) {
@@ -321,7 +577,31 @@ int8_t-min: -128
apsint: 9999999999999999999999
label: value (0)
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "uint64_t-max": 18446744073709551615,
+ "uint64_t-min": 0,
+ "uint32_t-max": 4294967295,
+ "uint32_t-min": 0,
+ "uint16_t-max": 65535,
+ "uint16_t-min": 0,
+ "uint8_t-max": 255,
+ "uint8_t-min": 0,
+ "int64_t-max": 9223372036854775807,
+ "int64_t-min": -9223372036854775808,
+ "int32_t-max": 2147483647,
+ "int32_t-min": -2147483648,
+ "int16_t-max": 32767,
+ "int16_t-min": -32768,
+ "int8_t-max": 127,
+ "int8_t-min": -128,
+ "apsint": 9999999999999999999999,
+ "label": {
+ "Value": "value",
+ "RawValue": 0
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintBoolean) {
@@ -333,7 +613,12 @@ TEST_F(ScopedPrinterTest, PrintBoolean) {
const char *ExpectedOut = R"(True: Yes
False: No
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "True": true,
+ "False": false
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintVersion) {
@@ -402,7 +687,56 @@ int16List: [32767, -32768]
int8List: [127, -128]
APSIntList: [9999999999999999999999, -9999999999999999999999]
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "EmptyList": [],
+ "StringList": [
+ "foo",
+ "bar",
+ "baz"
+ ],
+ "BoolList": [
+ true,
+ false
+ ],
+ "uint64List": [
+ 18446744073709551615,
+ 0
+ ],
+ "uint32List": [
+ 4294967295,
+ 0
+ ],
+ "uint16List": [
+ 65535,
+ 0
+ ],
+ "uint8List": [
+ 255,
+ 0
+ ],
+ "int64List": [
+ 9223372036854775807,
+ -9223372036854775808
+ ],
+ "int32List": [
+ 2147483647,
+ -2147483648
+ ],
+ "int16List": [
+ 32767,
+ -32768
+ ],
+ "int8List": [
+ 127,
+ -128
+ ],
+ "APSIntList": [
+ 9999999999999999999999,
+ -9999999999999999999999
+ ]
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintListPrinter) {
@@ -426,7 +760,15 @@ TEST_F(ScopedPrinterTest, PrintHex) {
const char *ExpectedOut = R"(HexNumber: 0x10
HexLabel: Name (0x10)
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "HexNumber": 16,
+ "HexLabel": {
+ "Value": "Name",
+ "RawValue": 16
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintHexList) {
@@ -436,7 +778,15 @@ TEST_F(ScopedPrinterTest, PrintHexList) {
};
const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100]
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "HexList": [
+ 1,
+ 16,
+ 256
+ ]
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintSymbolOffset) {
@@ -447,7 +797,18 @@ TEST_F(ScopedPrinterTest, PrintSymbolOffset) {
const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10
NoSymbolOffset: SymbolName+0x0
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "SymbolOffset": {
+ "SymName": "SymbolName",
+ "Offset": 16
+ },
+ "NoSymbolOffset": {
+ "SymName": "SymbolName",
+ "Offset": 0
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintString) {
@@ -469,7 +830,16 @@ StringList [
Value
]
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "StringRef": "Value",
+ "String": "Value",
+ "CharArray": "Value",
+ "StringList": [
+ "Value"
+ ]
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintBinary) {
@@ -516,7 +886,157 @@ Binary11 (
0000: FFFF |..|
)
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "Binary1": {
+ "Value": "FooBar",
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary2": {
+ "Value": "FooBar",
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary3": {
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary4": {
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary5": {
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary6": {
+ "Offset": 0,
+ "Bytes": [
+ 77,
+ 117,
+ 108,
+ 116,
+ 105,
+ 112,
+ 108,
+ 101,
+ 32,
+ 76,
+ 105,
+ 110,
+ 101,
+ 32,
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary7": {
+ "Offset": 20,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary8": {
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary9": {
+ "Offset": 0,
+ "Bytes": [
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary10": {
+ "Offset": 0,
+ "Bytes": [
+ 77,
+ 117,
+ 108,
+ 116,
+ 105,
+ 112,
+ 108,
+ 101,
+ 32,
+ 76,
+ 105,
+ 110,
+ 101,
+ 32,
+ 70,
+ 111,
+ 111,
+ 66,
+ 97,
+ 114
+ ]
+ },
+ "Binary11": {
+ "Offset": 0,
+ "Bytes": [
+ 255,
+ 255
+ ]
+ }
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, PrintObject) {
@@ -524,7 +1044,11 @@ TEST_F(ScopedPrinterTest, PrintObject) {
const char *ExpectedOut = R"(Object: Value
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "Object": "Value"
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
TEST_F(ScopedPrinterTest, StartLine) {
@@ -574,5 +1098,20 @@ List [
]
]
)";
- verifyScopedPrinter(ExpectedOut, PrintFunc);
+
+ const char *JSONExpectedOut = R"({
+ "Object": {
+ "ObjectInObject": {},
+ "ListInObject": []
+ },
+ "List": [
+ {
+ "ObjectInList": {}
+ },
+ {
+ "ListInList": []
+ }
+ ]
+})";
+ verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
}
More information about the llvm-commits
mailing list