Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / Support / ScopedPrinterTest.cpp
blob895e04c2c024af3d79151e7fe24c0d299a0c7a65
1 //===- llvm/unittest/Support/ScopedPrinterTest.cpp - ScopedPrinter tests --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/ScopedPrinter.h"
10 #include "llvm/ADT/APSInt.h"
11 #include "llvm/Support/Format.h"
12 #include "gtest/gtest.h"
13 #include <cmath>
14 #include <vector>
16 using namespace llvm;
18 TEST(JSONScopedPrinterTest, PrettyPrintCtor) {
19 auto PrintFunc = [](ScopedPrinter &W) {
20 DictScope D(W);
21 W.printString("Key", "Value");
23 std::string StreamBuffer;
24 raw_string_ostream OS(StreamBuffer);
25 JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true);
26 JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false);
28 const char *PrettyPrintOut = R"({
29 "Key": "Value"
30 })";
31 const char *NoPrettyPrintOut = R"({"Key":"Value"})";
32 PrintFunc(PrettyPrintWriter);
33 EXPECT_EQ(PrettyPrintOut, OS.str());
34 StreamBuffer.clear();
35 PrintFunc(NoPrettyPrintWriter);
36 EXPECT_EQ(NoPrettyPrintOut, OS.str());
39 TEST(JSONScopedPrinterTest, DelimitedScopeCtor) {
40 std::string StreamBuffer;
41 raw_string_ostream OS(StreamBuffer);
43 JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false,
44 std::make_unique<DictScope>());
45 DictScopeWriter.printString("Label", "DictScope");
47 EXPECT_EQ(R"({"Label":"DictScope"})", OS.str());
48 StreamBuffer.clear();
50 JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false,
51 std::make_unique<ListScope>());
52 ListScopeWriter.printString("ListScope");
54 EXPECT_EQ(R"(["ListScope"])", OS.str());
55 StreamBuffer.clear();
57 JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false);
58 NoScopeWriter.printString("NoScope");
60 EXPECT_EQ(R"("NoScope")", OS.str());
63 class ScopedPrinterTest : public ::testing::Test {
64 protected:
65 std::string StreamBuffer;
66 raw_string_ostream OS;
67 ScopedPrinter Writer;
68 JSONScopedPrinter JSONWriter;
70 bool HasPrintedToJSON;
72 ScopedPrinterTest()
73 : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true),
74 HasPrintedToJSON(false) {}
76 using PrintFunc = function_ref<void(ScopedPrinter &)>;
78 void verifyScopedPrinter(StringRef Expected, PrintFunc Func) {
79 Func(Writer);
80 Writer.flush();
81 EXPECT_EQ(Expected.str(), OS.str());
82 StreamBuffer.clear();
85 void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) {
87 DictScope D(JSONWriter);
88 Func(JSONWriter);
90 JSONWriter.flush();
91 EXPECT_EQ(Expected.str(), OS.str());
92 StreamBuffer.clear();
93 HasPrintedToJSON = true;
96 void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut,
97 PrintFunc Func) {
98 verifyScopedPrinter(ExpectedOut, Func);
99 verifyJSONScopedPrinter(JSONExpectedOut, Func);
102 void TearDown() {
103 // JSONScopedPrinter fails an assert if nothing's been printed.
104 if (!HasPrintedToJSON)
105 JSONWriter.printString("");
109 TEST_F(ScopedPrinterTest, GetKind) {
110 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind());
111 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind());
114 TEST_F(ScopedPrinterTest, ClassOf) {
115 EXPECT_TRUE(ScopedPrinter::classof(&Writer));
116 EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter));
117 EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter));
118 EXPECT_FALSE(JSONScopedPrinter::classof(&Writer));
121 TEST_F(ScopedPrinterTest, Indent) {
122 auto PrintFunc = [](ScopedPrinter &W) {
123 W.printString("|");
124 W.indent();
125 W.printString("|");
126 W.indent(2);
127 W.printString("|");
130 const char *ExpectedOut = R"(|
134 verifyScopedPrinter(ExpectedOut, PrintFunc);
137 TEST_F(ScopedPrinterTest, Unindent) {
138 auto PrintFunc = [](ScopedPrinter &W) {
139 W.indent(3);
140 W.printString("|");
141 W.unindent(2);
142 W.printString("|");
143 W.unindent();
144 W.printString("|");
145 W.unindent();
146 W.printString("|");
149 const char *ExpectedOut = R"( |
154 verifyScopedPrinter(ExpectedOut, PrintFunc);
157 TEST_F(ScopedPrinterTest, ResetIndent) {
158 auto PrintFunc = [](ScopedPrinter &W) {
159 W.indent(4);
160 W.printString("|");
161 W.resetIndent();
162 W.printString("|");
165 const char *ExpectedOut = R"( |
168 verifyScopedPrinter(ExpectedOut, PrintFunc);
171 TEST_F(ScopedPrinterTest, PrintIndent) {
172 auto PrintFunc = [](ScopedPrinter &W) {
173 W.printIndent();
174 W.printString("|");
175 W.indent();
176 W.printIndent();
177 W.printString("|");
180 const char *ExpectedOut = R"(|
183 verifyScopedPrinter(ExpectedOut, PrintFunc);
186 TEST_F(ScopedPrinterTest, GetIndentLevel) {
187 EXPECT_EQ(Writer.getIndentLevel(), 0);
188 Writer.indent();
189 EXPECT_EQ(Writer.getIndentLevel(), 1);
190 Writer.indent();
191 EXPECT_EQ(Writer.getIndentLevel(), 2);
192 Writer.unindent();
193 EXPECT_EQ(Writer.getIndentLevel(), 1);
194 Writer.indent();
195 Writer.resetIndent();
196 EXPECT_EQ(Writer.getIndentLevel(), 0);
197 Writer.unindent();
198 EXPECT_EQ(Writer.getIndentLevel(), 0);
199 Writer.indent();
200 EXPECT_EQ(Writer.getIndentLevel(), 1);
203 TEST_F(ScopedPrinterTest, SetPrefix) {
204 auto PrintFunc = [](ScopedPrinter &W) {
205 W.setPrefix("Prefix1");
206 W.indent();
207 W.printIndent();
208 W.printString("|");
209 W.unindent();
210 W.printIndent();
211 W.printString("|");
212 W.setPrefix("Prefix2");
213 W.printIndent();
214 W.printString("|");
217 const char *ExpectedOut = R"(Prefix1 Prefix1 |
218 Prefix1Prefix1|
219 Prefix2Prefix2|
221 verifyScopedPrinter(ExpectedOut, PrintFunc);
224 TEST_F(ScopedPrinterTest, PrintEnum) {
225 auto PrintFunc = [](ScopedPrinter &W) {
226 const EnumEntry<int> EnumList[] = {{"Name1", "AltName1", 1},
227 {"Name2", "AltName2", 2},
228 {"Name3", "AltName3", 3},
229 {"Name4", "AltName4", 2}};
230 EnumEntry<int> OtherEnum{"Name5", "AltName5", 5};
231 W.printEnum("Exists", EnumList[1].Value, ArrayRef(EnumList));
232 W.printEnum("DoesNotExist", OtherEnum.Value, ArrayRef(EnumList));
235 const char *ExpectedOut = R"(Exists: Name2 (0x2)
236 DoesNotExist: 0x5
239 const char *JSONExpectedOut = R"({
240 "Exists": {
241 "Name": "Name2",
242 "Value": 2
244 "DoesNotExist": 5
245 })";
246 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
249 TEST_F(ScopedPrinterTest, PrintFlag) {
250 auto PrintFunc = [](ScopedPrinter &W) {
251 const EnumEntry<uint16_t> SingleBitFlags[] = {
252 {"Name0", "AltName0", 0},
253 {"Name1", "AltName1", 1},
254 {"Name2", "AltName2", 1 << 1},
255 {"Name3", "AltName3", 1 << 2}};
256 const EnumEntry<uint16_t> UnsortedFlags[] = {
257 {"C", "c", 1}, {"B", "b", 1 << 1}, {"A", "a", 1 << 2}};
258 const EnumEntry<uint16_t> EnumFlags[] = {
259 {"FirstByte1", "First1", 0x1u}, {"FirstByte2", "First2", 0x2u},
260 {"FirstByte3", "First3", 0x3u}, {"SecondByte1", "Second1", 0x10u},
261 {"SecondByte2", "Second2", 0x20u}, {"SecondByte3", "Second3", 0x30u},
262 {"ThirdByte1", "Third1", 0x100u}, {"ThirdByte2", "Third2", 0x200u},
263 {"ThirdByte3", "Third3", 0x300u}};
264 W.printFlags("ZeroFlag", 0, ArrayRef(SingleBitFlags));
265 W.printFlags("NoFlag", 1 << 3, ArrayRef(SingleBitFlags));
266 W.printFlags("Flag1", SingleBitFlags[1].Value, ArrayRef(SingleBitFlags));
267 W.printFlags("Flag1&3", (1 << 2) + 1, ArrayRef(SingleBitFlags));
269 W.printFlags("ZeroFlagRaw", 0);
270 W.printFlags("NoFlagRaw", 1 << 3);
271 W.printFlags("Flag1Raw", SingleBitFlags[1].Value);
272 W.printFlags("Flag1&3Raw", (1 << 2) + 1);
274 W.printFlags("FlagSorted", (1 << 2) + (1 << 1) + 1,
275 ArrayRef(UnsortedFlags));
277 uint16_t NoBitMask = 0;
278 uint16_t FirstByteMask = 0xFu;
279 uint16_t SecondByteMask = 0xF0u;
280 uint16_t ThirdByteMask = 0xF00u;
281 W.printFlags("NoBitMask", 0xFFFu, ArrayRef(EnumFlags), NoBitMask);
282 W.printFlags("FirstByteMask", 0x3u, ArrayRef(EnumFlags), FirstByteMask);
283 W.printFlags("SecondByteMask", 0x30u, ArrayRef(EnumFlags), SecondByteMask);
284 W.printFlags("ValueOutsideMask", 0x1u, ArrayRef(EnumFlags), SecondByteMask);
285 W.printFlags("FirstSecondByteMask", 0xFFu, ArrayRef(EnumFlags),
286 FirstByteMask, SecondByteMask);
287 W.printFlags("FirstSecondThirdByteMask", 0x333u, ArrayRef(EnumFlags),
288 FirstByteMask, SecondByteMask, ThirdByteMask);
291 const char *ExpectedOut = R"(ZeroFlag [ (0x0)
293 NoFlag [ (0x8)
295 Flag1 [ (0x1)
296 Name1 (0x1)
298 Flag1&3 [ (0x5)
299 Name1 (0x1)
300 Name3 (0x4)
302 ZeroFlagRaw [ (0x0)
304 NoFlagRaw [ (0x8)
307 Flag1Raw [ (0x1)
310 Flag1&3Raw [ (0x5)
314 FlagSorted [ (0x7)
315 A (0x4)
316 B (0x2)
317 C (0x1)
319 NoBitMask [ (0xFFF)
320 FirstByte1 (0x1)
321 FirstByte2 (0x2)
322 FirstByte3 (0x3)
323 SecondByte1 (0x10)
324 SecondByte2 (0x20)
325 SecondByte3 (0x30)
326 ThirdByte1 (0x100)
327 ThirdByte2 (0x200)
328 ThirdByte3 (0x300)
330 FirstByteMask [ (0x3)
331 FirstByte3 (0x3)
333 SecondByteMask [ (0x30)
334 SecondByte3 (0x30)
336 ValueOutsideMask [ (0x1)
337 FirstByte1 (0x1)
339 FirstSecondByteMask [ (0xFF)
341 FirstSecondThirdByteMask [ (0x333)
342 FirstByte3 (0x3)
343 SecondByte3 (0x30)
344 ThirdByte3 (0x300)
348 const char *JSONExpectedOut = R"({
349 "ZeroFlag": {
350 "Value": 0,
351 "Flags": []
353 "NoFlag": {
354 "Value": 8,
355 "Flags": []
357 "Flag1": {
358 "Value": 1,
359 "Flags": [
361 "Name": "Name1",
362 "Value": 1
366 "Flag1&3": {
367 "Value": 5,
368 "Flags": [
370 "Name": "Name1",
371 "Value": 1
374 "Name": "Name3",
375 "Value": 4
379 "ZeroFlagRaw": {
380 "Value": 0,
381 "Flags": []
383 "NoFlagRaw": {
384 "Value": 8,
385 "Flags": [
389 "Flag1Raw": {
390 "Value": 1,
391 "Flags": [
395 "Flag1&3Raw": {
396 "Value": 5,
397 "Flags": [
402 "FlagSorted": {
403 "Value": 7,
404 "Flags": [
406 "Name": "A",
407 "Value": 4
410 "Name": "B",
411 "Value": 2
414 "Name": "C",
415 "Value": 1
419 "NoBitMask": {
420 "Value": 4095,
421 "Flags": [
423 "Name": "FirstByte1",
424 "Value": 1
427 "Name": "FirstByte2",
428 "Value": 2
431 "Name": "FirstByte3",
432 "Value": 3
435 "Name": "SecondByte1",
436 "Value": 16
439 "Name": "SecondByte2",
440 "Value": 32
443 "Name": "SecondByte3",
444 "Value": 48
447 "Name": "ThirdByte1",
448 "Value": 256
451 "Name": "ThirdByte2",
452 "Value": 512
455 "Name": "ThirdByte3",
456 "Value": 768
460 "FirstByteMask": {
461 "Value": 3,
462 "Flags": [
464 "Name": "FirstByte3",
465 "Value": 3
469 "SecondByteMask": {
470 "Value": 48,
471 "Flags": [
473 "Name": "SecondByte3",
474 "Value": 48
478 "ValueOutsideMask": {
479 "Value": 1,
480 "Flags": [
482 "Name": "FirstByte1",
483 "Value": 1
487 "FirstSecondByteMask": {
488 "Value": 255,
489 "Flags": []
491 "FirstSecondThirdByteMask": {
492 "Value": 819,
493 "Flags": [
495 "Name": "FirstByte3",
496 "Value": 3
499 "Name": "SecondByte3",
500 "Value": 48
503 "Name": "ThirdByte3",
504 "Value": 768
508 })";
509 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
512 // Format floats using the same format string as PrintNumber, so we can check
513 // the output on all platforms.
514 template <typename T,
515 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
516 std::string formatFloatString(T Val) {
517 std::string Ret;
518 raw_string_ostream OS(Ret);
519 OS << format("%5.1f", Val);
520 return Ret;
523 // Format floats using the same format string used in JSON, so we can check the
524 // output on all platforms.
525 template <typename T,
526 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
527 std::string formatJsonFloatString(T Val) {
528 std::string Ret;
529 raw_string_ostream OS(Ret);
530 OS << format("%.*g", std::numeric_limits<double>::max_digits10, Val);
531 return Ret;
534 TEST_F(ScopedPrinterTest, PrintNumber) {
535 constexpr float MaxFloat = std::numeric_limits<float>::max();
536 constexpr float MinFloat = std::numeric_limits<float>::min();
537 constexpr float InfFloat = std::numeric_limits<float>::infinity();
538 const float NaNFloat = std::nanf("1");
539 constexpr double MaxDouble = std::numeric_limits<double>::max();
540 constexpr double MinDouble = std::numeric_limits<double>::min();
541 constexpr double InfDouble = std::numeric_limits<double>::infinity();
542 const double NaNDouble = std::nan("1");
544 auto PrintFunc = [&](ScopedPrinter &W) {
545 uint64_t Unsigned64Max = std::numeric_limits<uint64_t>::max();
546 uint64_t Unsigned64Min = std::numeric_limits<uint64_t>::min();
547 W.printNumber("uint64_t-max", Unsigned64Max);
548 W.printNumber("uint64_t-min", Unsigned64Min);
550 uint32_t Unsigned32Max = std::numeric_limits<uint32_t>::max();
551 uint32_t Unsigned32Min = std::numeric_limits<uint32_t>::min();
552 W.printNumber("uint32_t-max", Unsigned32Max);
553 W.printNumber("uint32_t-min", Unsigned32Min);
555 uint16_t Unsigned16Max = std::numeric_limits<uint16_t>::max();
556 uint16_t Unsigned16Min = std::numeric_limits<uint16_t>::min();
557 W.printNumber("uint16_t-max", Unsigned16Max);
558 W.printNumber("uint16_t-min", Unsigned16Min);
560 uint8_t Unsigned8Max = std::numeric_limits<uint8_t>::max();
561 uint8_t Unsigned8Min = std::numeric_limits<uint8_t>::min();
562 W.printNumber("uint8_t-max", Unsigned8Max);
563 W.printNumber("uint8_t-min", Unsigned8Min);
565 int64_t Signed64Max = std::numeric_limits<int64_t>::max();
566 int64_t Signed64Min = std::numeric_limits<int64_t>::min();
567 W.printNumber("int64_t-max", Signed64Max);
568 W.printNumber("int64_t-min", Signed64Min);
570 int32_t Signed32Max = std::numeric_limits<int32_t>::max();
571 int32_t Signed32Min = std::numeric_limits<int32_t>::min();
572 W.printNumber("int32_t-max", Signed32Max);
573 W.printNumber("int32_t-min", Signed32Min);
575 int16_t Signed16Max = std::numeric_limits<int16_t>::max();
576 int16_t Signed16Min = std::numeric_limits<int16_t>::min();
577 W.printNumber("int16_t-max", Signed16Max);
578 W.printNumber("int16_t-min", Signed16Min);
580 int8_t Signed8Max = std::numeric_limits<int8_t>::max();
581 int8_t Signed8Min = std::numeric_limits<int8_t>::min();
582 W.printNumber("int8_t-max", Signed8Max);
583 W.printNumber("int8_t-min", Signed8Min);
585 APSInt LargeNum("9999999999999999999999");
586 W.printNumber("apsint", LargeNum);
588 W.printNumber("label", "value", 0);
590 W.printNumber("float-max", MaxFloat);
591 W.printNumber("float-min", MinFloat);
592 W.printNumber("float-inf", InfFloat);
593 W.printNumber("float-nan", NaNFloat);
594 W.printNumber("float-42.0", 42.0f);
595 W.printNumber("float-42.5625", 42.5625f);
597 W.printNumber("double-max", MaxDouble);
598 W.printNumber("double-min", MinDouble);
599 W.printNumber("double-inf", InfDouble);
600 W.printNumber("double-nan", NaNDouble);
601 W.printNumber("double-42.0", 42.0);
602 W.printNumber("double-42.5625", 42.5625);
605 std::string ExpectedOut = Twine(
606 R"(uint64_t-max: 18446744073709551615
607 uint64_t-min: 0
608 uint32_t-max: 4294967295
609 uint32_t-min: 0
610 uint16_t-max: 65535
611 uint16_t-min: 0
612 uint8_t-max: 255
613 uint8_t-min: 0
614 int64_t-max: 9223372036854775807
615 int64_t-min: -9223372036854775808
616 int32_t-max: 2147483647
617 int32_t-min: -2147483648
618 int16_t-max: 32767
619 int16_t-min: -32768
620 int8_t-max: 127
621 int8_t-min: -128
622 apsint: 9999999999999999999999
623 label: value (0)
624 float-max: )" + formatFloatString(MaxFloat) +
626 float-min: 0.0
627 float-inf: )" + formatFloatString(InfFloat) +
629 float-nan: )" + formatFloatString(NaNFloat) +
631 float-42.0: 42.0
632 float-42.5625: 42.6
633 double-max: )" + formatFloatString(MaxDouble) +
635 double-min: 0.0
636 double-inf: )" + formatFloatString(InfDouble) +
638 double-nan: )" + formatFloatString(NaNDouble) +
640 double-42.0: 42.0
641 double-42.5625: 42.6
643 .str();
645 std::string JSONExpectedOut = Twine(R"({
646 "uint64_t-max": 18446744073709551615,
647 "uint64_t-min": 0,
648 "uint32_t-max": 4294967295,
649 "uint32_t-min": 0,
650 "uint16_t-max": 65535,
651 "uint16_t-min": 0,
652 "uint8_t-max": 255,
653 "uint8_t-min": 0,
654 "int64_t-max": 9223372036854775807,
655 "int64_t-min": -9223372036854775808,
656 "int32_t-max": 2147483647,
657 "int32_t-min": -2147483648,
658 "int16_t-max": 32767,
659 "int16_t-min": -32768,
660 "int8_t-max": 127,
661 "int8_t-min": -128,
662 "apsint": 9999999999999999999999,
663 "label": {
664 "Name": "value",
665 "Value": 0
667 "float-max": 3.4028234663852886e+38,
668 "float-min": 1.1754943508222875e-38,
669 "float-inf": )" + formatJsonFloatString(InfFloat) +
670 R"(,
671 "float-nan": )" + formatJsonFloatString(NaNFloat) +
672 R"(,
673 "float-42.0": 42,
674 "float-42.5625": 42.5625,
675 "double-max": 1.7976931348623157e+308,
676 "double-min": 2.2250738585072014e-308,
677 "double-inf": )" + formatJsonFloatString(InfDouble) +
678 R"(,
679 "double-nan": )" + formatJsonFloatString(NaNDouble) +
680 R"(,
681 "double-42.0": 42,
682 "double-42.5625": 42.5625
683 })")
684 .str();
685 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
688 TEST_F(ScopedPrinterTest, PrintBoolean) {
689 auto PrintFunc = [](ScopedPrinter &W) {
690 W.printBoolean("True", true);
691 W.printBoolean("False", false);
694 const char *ExpectedOut = R"(True: Yes
695 False: No
698 const char *JSONExpectedOut = R"({
699 "True": true,
700 "False": false
701 })";
702 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
705 TEST_F(ScopedPrinterTest, PrintVersion) {
706 auto PrintFunc = [](ScopedPrinter &W) {
707 W.printVersion("Version", "123", "456", "789");
709 const char *ExpectedOut = R"(Version: 123.456.789
711 verifyScopedPrinter(ExpectedOut, PrintFunc);
714 TEST_F(ScopedPrinterTest, PrintList) {
715 auto PrintFunc = [](ScopedPrinter &W) {
716 const std::vector<uint64_t> EmptyList;
717 const std::vector<std::string> StringList = {"foo", "bar", "baz"};
718 const bool BoolList[] = {true, false};
719 const std::vector<uint64_t> Unsigned64List = {
720 std::numeric_limits<uint64_t>::max(),
721 std::numeric_limits<uint64_t>::min()};
722 const std::vector<uint32_t> Unsigned32List = {
723 std::numeric_limits<uint32_t>::max(),
724 std::numeric_limits<uint32_t>::min()};
725 const std::vector<uint16_t> Unsigned16List = {
726 std::numeric_limits<uint16_t>::max(),
727 std::numeric_limits<uint16_t>::min()};
728 const std::vector<uint8_t> Unsigned8List = {
729 std::numeric_limits<uint8_t>::max(),
730 std::numeric_limits<uint8_t>::min()};
731 const std::vector<int64_t> Signed64List = {
732 std::numeric_limits<int64_t>::max(),
733 std::numeric_limits<int64_t>::min()};
734 const std::vector<int32_t> Signed32List = {
735 std::numeric_limits<int32_t>::max(),
736 std::numeric_limits<int32_t>::min()};
737 const std::vector<int16_t> Signed16List = {
738 std::numeric_limits<int16_t>::max(),
739 std::numeric_limits<int16_t>::min()};
740 const std::vector<int8_t> Signed8List = {
741 std::numeric_limits<int8_t>::max(), std::numeric_limits<int8_t>::min()};
742 const std::vector<APSInt> APSIntList = {APSInt("9999999999999999999999"),
743 APSInt("-9999999999999999999999")};
744 W.printList("EmptyList", EmptyList);
745 W.printList("StringList", StringList);
746 W.printList("BoolList", ArrayRef(BoolList));
747 W.printList("uint64List", Unsigned64List);
748 W.printList("uint32List", Unsigned32List);
749 W.printList("uint16List", Unsigned16List);
750 W.printList("uint8List", Unsigned8List);
751 W.printList("int64List", Signed64List);
752 W.printList("int32List", Signed32List);
753 W.printList("int16List", Signed16List);
754 W.printList("int8List", Signed8List);
755 W.printList("APSIntList", APSIntList);
758 const char *ExpectedOut = R"(EmptyList: []
759 StringList: [foo, bar, baz]
760 BoolList: [1, 0]
761 uint64List: [18446744073709551615, 0]
762 uint32List: [4294967295, 0]
763 uint16List: [65535, 0]
764 uint8List: [255, 0]
765 int64List: [9223372036854775807, -9223372036854775808]
766 int32List: [2147483647, -2147483648]
767 int16List: [32767, -32768]
768 int8List: [127, -128]
769 APSIntList: [9999999999999999999999, -9999999999999999999999]
772 const char *JSONExpectedOut = R"({
773 "EmptyList": [],
774 "StringList": [
775 "foo",
776 "bar",
777 "baz"
779 "BoolList": [
780 true,
781 false
783 "uint64List": [
784 18446744073709551615,
787 "uint32List": [
788 4294967295,
791 "uint16List": [
792 65535,
795 "uint8List": [
796 255,
799 "int64List": [
800 9223372036854775807,
801 -9223372036854775808
803 "int32List": [
804 2147483647,
805 -2147483648
807 "int16List": [
808 32767,
809 -32768
811 "int8List": [
812 127,
813 -128
815 "APSIntList": [
816 9999999999999999999999,
817 -9999999999999999999999
819 })";
820 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
823 TEST_F(ScopedPrinterTest, PrintListPrinter) {
824 auto PrintFunc = [](ScopedPrinter &W) {
825 const std::string StringList[] = {"a", "ab", "abc"};
826 W.printList("StringSizeList", StringList,
827 [](raw_ostream &OS, StringRef Item) { OS << Item.size(); });
830 const char *ExpectedOut = R"(StringSizeList: [1, 2, 3]
832 verifyScopedPrinter(ExpectedOut, PrintFunc);
835 TEST_F(ScopedPrinterTest, PrintHex) {
836 auto PrintFunc = [](ScopedPrinter &W) {
837 W.printHex("HexNumber", 0x10);
838 W.printHex("HexLabel", "Name", 0x10);
841 const char *ExpectedOut = R"(HexNumber: 0x10
842 HexLabel: Name (0x10)
845 const char *JSONExpectedOut = R"({
846 "HexNumber": 16,
847 "HexLabel": {
848 "Name": "Name",
849 "Value": 16
851 })";
852 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
855 TEST_F(ScopedPrinterTest, PrintHexList) {
856 auto PrintFunc = [](ScopedPrinter &W) {
857 const uint64_t HexList[] = {0x1, 0x10, 0x100};
858 W.printHexList("HexList", HexList);
860 const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100]
863 const char *JSONExpectedOut = R"({
864 "HexList": [
869 })";
870 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
873 TEST_F(ScopedPrinterTest, PrintSymbolOffset) {
874 auto PrintFunc = [](ScopedPrinter &W) {
875 W.printSymbolOffset("SymbolOffset", "SymbolName", 0x10);
876 W.printSymbolOffset("NoSymbolOffset", "SymbolName", 0);
878 const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10
879 NoSymbolOffset: SymbolName+0x0
882 const char *JSONExpectedOut = R"({
883 "SymbolOffset": {
884 "SymName": "SymbolName",
885 "Offset": 16
887 "NoSymbolOffset": {
888 "SymName": "SymbolName",
889 "Offset": 0
891 })";
892 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
895 TEST_F(ScopedPrinterTest, PrintString) {
896 auto PrintFunc = [](ScopedPrinter &W) {
897 const StringRef StringRefValue("Value");
898 const std::string StringValue = "Value";
899 const char *CharArrayValue = "Value";
900 W.printString("StringRef", StringRefValue);
901 W.printString("String", StringValue);
902 W.printString("CharArray", CharArrayValue);
903 ListScope L(W, "StringList");
904 W.printString(StringRefValue);
907 const char *ExpectedOut = R"(StringRef: Value
908 String: Value
909 CharArray: Value
910 StringList [
911 Value
915 const char *JSONExpectedOut = R"({
916 "StringRef": "Value",
917 "String": "Value",
918 "CharArray": "Value",
919 "StringList": [
920 "Value"
922 })";
923 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
926 TEST_F(ScopedPrinterTest, PrintBinary) {
927 auto PrintFunc = [](ScopedPrinter &W) {
928 std::vector<uint8_t> IntArray = {70, 111, 111, 66, 97, 114};
929 std::vector<char> CharArray = {'F', 'o', 'o', 'B', 'a', 'r'};
930 std::vector<uint8_t> InvalidChars = {255, 255};
931 W.printBinary("Binary1", "FooBar", IntArray);
932 W.printBinary("Binary2", "FooBar", CharArray);
933 W.printBinary("Binary3", IntArray);
934 W.printBinary("Binary4", CharArray);
935 W.printBinary("Binary5", StringRef("FooBar"));
936 W.printBinary("Binary6", StringRef("Multiple Line FooBar"));
937 W.printBinaryBlock("Binary7", IntArray, 20);
938 W.printBinaryBlock("Binary8", IntArray);
939 W.printBinaryBlock("Binary9", "FooBar");
940 W.printBinaryBlock("Binary10", "Multiple Line FooBar");
941 W.printBinaryBlock("Binary11", InvalidChars);
944 const char *ExpectedOut = R"(Binary1: FooBar (46 6F 6F 42 61 72)
945 Binary2: FooBar (46 6F 6F 42 61 72)
946 Binary3: (46 6F 6F 42 61 72)
947 Binary4: (46 6F 6F 42 61 72)
948 Binary5: (46 6F 6F 42 61 72)
949 Binary6 (
950 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|
951 0010: 6F426172 |oBar|
953 Binary7 (
954 0014: 466F6F42 6172 |FooBar|
956 Binary8 (
957 0000: 466F6F42 6172 |FooBar|
959 Binary9 (
960 0000: 466F6F42 6172 |FooBar|
962 Binary10 (
963 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|
964 0010: 6F426172 |oBar|
966 Binary11 (
967 0000: FFFF |..|
971 const char *JSONExpectedOut = R"({
972 "Binary1": {
973 "Value": "FooBar",
974 "Offset": 0,
975 "Bytes": [
977 111,
978 111,
984 "Binary2": {
985 "Value": "FooBar",
986 "Offset": 0,
987 "Bytes": [
989 111,
990 111,
996 "Binary3": {
997 "Offset": 0,
998 "Bytes": [
1000 111,
1001 111,
1007 "Binary4": {
1008 "Offset": 0,
1009 "Bytes": [
1011 111,
1012 111,
1018 "Binary5": {
1019 "Offset": 0,
1020 "Bytes": [
1022 111,
1023 111,
1029 "Binary6": {
1030 "Offset": 0,
1031 "Bytes": [
1033 117,
1034 108,
1035 116,
1036 105,
1037 112,
1038 108,
1039 101,
1042 105,
1043 110,
1044 101,
1047 111,
1048 111,
1054 "Binary7": {
1055 "Offset": 20,
1056 "Bytes": [
1058 111,
1059 111,
1065 "Binary8": {
1066 "Offset": 0,
1067 "Bytes": [
1069 111,
1070 111,
1076 "Binary9": {
1077 "Offset": 0,
1078 "Bytes": [
1080 111,
1081 111,
1087 "Binary10": {
1088 "Offset": 0,
1089 "Bytes": [
1091 117,
1092 108,
1093 116,
1094 105,
1095 112,
1096 108,
1097 101,
1100 105,
1101 110,
1102 101,
1105 111,
1106 111,
1112 "Binary11": {
1113 "Offset": 0,
1114 "Bytes": [
1115 255,
1119 })";
1120 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
1123 TEST_F(ScopedPrinterTest, PrintObject) {
1124 auto PrintFunc = [](ScopedPrinter &W) { W.printObject("Object", "Value"); };
1126 const char *ExpectedOut = R"(Object: Value
1129 const char *JSONExpectedOut = R"({
1130 "Object": "Value"
1131 })";
1132 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
1135 TEST_F(ScopedPrinterTest, StartLine) {
1136 auto PrintFunc = [](ScopedPrinter &W) {
1137 W.startLine() << "|";
1138 W.indent(2);
1139 W.startLine() << "|";
1140 W.unindent();
1141 W.startLine() << "|";
1144 const char *ExpectedOut = "| | |";
1145 verifyScopedPrinter(ExpectedOut, PrintFunc);
1148 TEST_F(ScopedPrinterTest, GetOStream) {
1149 auto PrintFunc = [](ScopedPrinter &W) { W.getOStream() << "Test"; };
1151 const char *ExpectedOut = "Test";
1152 verifyScopedPrinter(ExpectedOut, PrintFunc);
1155 TEST_F(ScopedPrinterTest, PrintScope) {
1156 auto PrintFunc = [](ScopedPrinter &W) {
1158 DictScope O(W, "Object");
1159 { DictScope OO(W, "ObjectInObject"); }
1160 { ListScope LO(W, "ListInObject"); }
1163 ListScope L(W, "List");
1164 { DictScope OL(W, "ObjectInList"); }
1165 { ListScope LL(W, "ListInList"); }
1169 const char *ExpectedOut = R"(Object {
1170 ObjectInObject {
1172 ListInObject [
1175 List [
1176 ObjectInList {
1178 ListInList [
1183 const char *JSONExpectedOut = R"({
1184 "Object": {
1185 "ObjectInObject": {},
1186 "ListInObject": []
1188 "List": [
1190 "ObjectInList": {}
1193 "ListInList": []
1196 })";
1197 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);