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 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/ScopedPrinter.h"
10 #include "llvm/ADT/APSInt.h"
11 #include "gtest/gtest.h"
12 #include <vector>
13
14 using namespace llvm;
15
TEST(JSONScopedPrinterTest,PrettyPrintCtor)16 TEST(JSONScopedPrinterTest, PrettyPrintCtor) {
17 auto PrintFunc = [](ScopedPrinter &W) {
18 DictScope D(W);
19 W.printString("Key", "Value");
20 };
21 std::string StreamBuffer;
22 raw_string_ostream OS(StreamBuffer);
23 JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true);
24 JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false);
25
26 const char *PrettyPrintOut = R"({
27 "Key": "Value"
28 })";
29 const char *NoPrettyPrintOut = R"({"Key":"Value"})";
30 PrintFunc(PrettyPrintWriter);
31 EXPECT_EQ(PrettyPrintOut, OS.str());
32 StreamBuffer.clear();
33 PrintFunc(NoPrettyPrintWriter);
34 EXPECT_EQ(NoPrettyPrintOut, OS.str());
35 }
36
TEST(JSONScopedPrinterTest,DelimitedScopeCtor)37 TEST(JSONScopedPrinterTest, DelimitedScopeCtor) {
38 std::string StreamBuffer;
39 raw_string_ostream OS(StreamBuffer);
40 {
41 JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false,
42 std::make_unique<DictScope>());
43 DictScopeWriter.printString("Label", "DictScope");
44 }
45 EXPECT_EQ(R"({"Label":"DictScope"})", OS.str());
46 StreamBuffer.clear();
47 {
48 JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false,
49 std::make_unique<ListScope>());
50 ListScopeWriter.printString("ListScope");
51 }
52 EXPECT_EQ(R"(["ListScope"])", OS.str());
53 StreamBuffer.clear();
54 {
55 JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false);
56 NoScopeWriter.printString("NoScope");
57 }
58 EXPECT_EQ(R"("NoScope")", OS.str());
59 }
60
61 class ScopedPrinterTest : public ::testing::Test {
62 protected:
63 std::string StreamBuffer;
64 raw_string_ostream OS;
65 ScopedPrinter Writer;
66 JSONScopedPrinter JSONWriter;
67
68 bool HasPrintedToJSON;
69
ScopedPrinterTest()70 ScopedPrinterTest()
71 : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true),
72 HasPrintedToJSON(false) {}
73
74 using PrintFunc = function_ref<void(ScopedPrinter &)>;
75
verifyScopedPrinter(StringRef Expected,PrintFunc Func)76 void verifyScopedPrinter(StringRef Expected, PrintFunc Func) {
77 Func(Writer);
78 Writer.flush();
79 EXPECT_EQ(Expected.str(), OS.str());
80 StreamBuffer.clear();
81 }
82
verifyJSONScopedPrinter(StringRef Expected,PrintFunc Func)83 void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) {
84 {
85 DictScope D(JSONWriter);
86 Func(JSONWriter);
87 }
88 JSONWriter.flush();
89 EXPECT_EQ(Expected.str(), OS.str());
90 StreamBuffer.clear();
91 HasPrintedToJSON = true;
92 }
93
verifyAll(StringRef ExpectedOut,StringRef JSONExpectedOut,PrintFunc Func)94 void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut,
95 PrintFunc Func) {
96 verifyScopedPrinter(ExpectedOut, Func);
97 verifyJSONScopedPrinter(JSONExpectedOut, Func);
98 }
99
TearDown()100 void TearDown() {
101 // JSONScopedPrinter fails an assert if nothing's been printed.
102 if (!HasPrintedToJSON)
103 JSONWriter.printString("");
104 }
105 };
106
TEST_F(ScopedPrinterTest,GetKind)107 TEST_F(ScopedPrinterTest, GetKind) {
108 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind());
109 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind());
110 }
111
TEST_F(ScopedPrinterTest,ClassOf)112 TEST_F(ScopedPrinterTest, ClassOf) {
113 EXPECT_TRUE(ScopedPrinter::classof(&Writer));
114 EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter));
115 EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter));
116 EXPECT_FALSE(JSONScopedPrinter::classof(&Writer));
117 }
118
TEST_F(ScopedPrinterTest,Indent)119 TEST_F(ScopedPrinterTest, Indent) {
120 auto PrintFunc = [](ScopedPrinter &W) {
121 W.printString("|");
122 W.indent();
123 W.printString("|");
124 W.indent(2);
125 W.printString("|");
126 };
127
128 const char *ExpectedOut = R"(|
129 |
130 |
131 )";
132 verifyScopedPrinter(ExpectedOut, PrintFunc);
133 }
134
TEST_F(ScopedPrinterTest,Unindent)135 TEST_F(ScopedPrinterTest, Unindent) {
136 auto PrintFunc = [](ScopedPrinter &W) {
137 W.indent(3);
138 W.printString("|");
139 W.unindent(2);
140 W.printString("|");
141 W.unindent();
142 W.printString("|");
143 W.unindent();
144 W.printString("|");
145 };
146
147 const char *ExpectedOut = R"( |
148 |
149 |
150 |
151 )";
152 verifyScopedPrinter(ExpectedOut, PrintFunc);
153 }
154
TEST_F(ScopedPrinterTest,ResetIndent)155 TEST_F(ScopedPrinterTest, ResetIndent) {
156 auto PrintFunc = [](ScopedPrinter &W) {
157 W.indent(4);
158 W.printString("|");
159 W.resetIndent();
160 W.printString("|");
161 };
162
163 const char *ExpectedOut = R"( |
164 |
165 )";
166 verifyScopedPrinter(ExpectedOut, PrintFunc);
167 }
168
TEST_F(ScopedPrinterTest,PrintIndent)169 TEST_F(ScopedPrinterTest, PrintIndent) {
170 auto PrintFunc = [](ScopedPrinter &W) {
171 W.printIndent();
172 W.printString("|");
173 W.indent();
174 W.printIndent();
175 W.printString("|");
176 };
177
178 const char *ExpectedOut = R"(|
179 |
180 )";
181 verifyScopedPrinter(ExpectedOut, PrintFunc);
182 }
183
TEST_F(ScopedPrinterTest,GetIndentLevel)184 TEST_F(ScopedPrinterTest, GetIndentLevel) {
185 EXPECT_EQ(Writer.getIndentLevel(), 0);
186 Writer.indent();
187 EXPECT_EQ(Writer.getIndentLevel(), 1);
188 Writer.indent();
189 EXPECT_EQ(Writer.getIndentLevel(), 2);
190 Writer.unindent();
191 EXPECT_EQ(Writer.getIndentLevel(), 1);
192 Writer.indent();
193 Writer.resetIndent();
194 EXPECT_EQ(Writer.getIndentLevel(), 0);
195 Writer.unindent();
196 EXPECT_EQ(Writer.getIndentLevel(), 0);
197 Writer.indent();
198 EXPECT_EQ(Writer.getIndentLevel(), 1);
199 }
200
TEST_F(ScopedPrinterTest,SetPrefix)201 TEST_F(ScopedPrinterTest, SetPrefix) {
202 auto PrintFunc = [](ScopedPrinter &W) {
203 W.setPrefix("Prefix1");
204 W.indent();
205 W.printIndent();
206 W.printString("|");
207 W.unindent();
208 W.printIndent();
209 W.printString("|");
210 W.setPrefix("Prefix2");
211 W.printIndent();
212 W.printString("|");
213 };
214
215 const char *ExpectedOut = R"(Prefix1 Prefix1 |
216 Prefix1Prefix1|
217 Prefix2Prefix2|
218 )";
219 verifyScopedPrinter(ExpectedOut, PrintFunc);
220 }
221
TEST_F(ScopedPrinterTest,PrintEnum)222 TEST_F(ScopedPrinterTest, PrintEnum) {
223 auto PrintFunc = [](ScopedPrinter &W) {
224 const EnumEntry<int> EnumList[] = {{"Name1", "AltName1", 1},
225 {"Name2", "AltName2", 2},
226 {"Name3", "AltName3", 3},
227 {"Name4", "AltName4", 2}};
228 EnumEntry<int> OtherEnum{"Name5", "AltName5", 5};
229 W.printEnum("Exists", EnumList[1].Value, makeArrayRef(EnumList));
230 W.printEnum("DoesNotExist", OtherEnum.Value, makeArrayRef(EnumList));
231 };
232
233 const char *ExpectedOut = R"(Exists: Name2 (0x2)
234 DoesNotExist: 0x5
235 )";
236
237 const char *JSONExpectedOut = R"({
238 "Exists": {
239 "Value": "Name2",
240 "RawValue": 2
241 },
242 "DoesNotExist": 5
243 })";
244 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
245 }
246
TEST_F(ScopedPrinterTest,PrintFlag)247 TEST_F(ScopedPrinterTest, PrintFlag) {
248 auto PrintFunc = [](ScopedPrinter &W) {
249 const EnumEntry<uint16_t> SingleBitFlags[] = {
250 {"Name0", "AltName0", 0},
251 {"Name1", "AltName1", 1},
252 {"Name2", "AltName2", 1 << 1},
253 {"Name3", "AltName3", 1 << 2}};
254 const EnumEntry<uint16_t> UnsortedFlags[] = {
255 {"C", "c", 1}, {"B", "b", 1 << 1}, {"A", "a", 1 << 2}};
256 const EnumEntry<uint16_t> EnumFlags[] = {
257 {"FirstByte1", "First1", 0x1u}, {"FirstByte2", "First2", 0x2u},
258 {"FirstByte3", "First3", 0x3u}, {"SecondByte1", "Second1", 0x10u},
259 {"SecondByte2", "Second2", 0x20u}, {"SecondByte3", "Second3", 0x30u},
260 {"ThirdByte1", "Third1", 0x100u}, {"ThirdByte2", "Third2", 0x200u},
261 {"ThirdByte3", "Third3", 0x300u}};
262 W.printFlags("ZeroFlag", 0, makeArrayRef(SingleBitFlags));
263 W.printFlags("NoFlag", 1 << 3, makeArrayRef(SingleBitFlags));
264 W.printFlags("Flag1", SingleBitFlags[1].Value,
265 makeArrayRef(SingleBitFlags));
266 W.printFlags("Flag1&3", (1 << 2) + 1, makeArrayRef(SingleBitFlags));
267
268 W.printFlags("ZeroFlagRaw", 0);
269 W.printFlags("NoFlagRaw", 1 << 3);
270 W.printFlags("Flag1Raw", SingleBitFlags[1].Value);
271 W.printFlags("Flag1&3Raw", (1 << 2) + 1);
272
273 W.printFlags("FlagSorted", (1 << 2) + (1 << 1) + 1,
274 makeArrayRef(UnsortedFlags));
275
276 uint16_t NoBitMask = 0;
277 uint16_t FirstByteMask = 0xFu;
278 uint16_t SecondByteMask = 0xF0u;
279 uint16_t ThirdByteMask = 0xF00u;
280 W.printFlags("NoBitMask", 0xFFFu, makeArrayRef(EnumFlags), NoBitMask);
281 W.printFlags("FirstByteMask", 0x3u, makeArrayRef(EnumFlags), FirstByteMask);
282 W.printFlags("SecondByteMask", 0x30u, makeArrayRef(EnumFlags),
283 SecondByteMask);
284 W.printFlags("ValueOutsideMask", 0x1u, makeArrayRef(EnumFlags),
285 SecondByteMask);
286 W.printFlags("FirstSecondByteMask", 0xFFu, makeArrayRef(EnumFlags),
287 FirstByteMask, SecondByteMask);
288 W.printFlags("FirstSecondThirdByteMask", 0x333u, makeArrayRef(EnumFlags),
289 FirstByteMask, SecondByteMask, ThirdByteMask);
290 };
291
292 const char *ExpectedOut = R"(ZeroFlag [ (0x0)
293 ]
294 NoFlag [ (0x8)
295 ]
296 Flag1 [ (0x1)
297 Name1 (0x1)
298 ]
299 Flag1&3 [ (0x5)
300 Name1 (0x1)
301 Name3 (0x4)
302 ]
303 ZeroFlagRaw [ (0x0)
304 ]
305 NoFlagRaw [ (0x8)
306 0x8
307 ]
308 Flag1Raw [ (0x1)
309 0x1
310 ]
311 Flag1&3Raw [ (0x5)
312 0x1
313 0x4
314 ]
315 FlagSorted [ (0x7)
316 A (0x4)
317 B (0x2)
318 C (0x1)
319 ]
320 NoBitMask [ (0xFFF)
321 FirstByte1 (0x1)
322 FirstByte2 (0x2)
323 FirstByte3 (0x3)
324 SecondByte1 (0x10)
325 SecondByte2 (0x20)
326 SecondByte3 (0x30)
327 ThirdByte1 (0x100)
328 ThirdByte2 (0x200)
329 ThirdByte3 (0x300)
330 ]
331 FirstByteMask [ (0x3)
332 FirstByte3 (0x3)
333 ]
334 SecondByteMask [ (0x30)
335 SecondByte3 (0x30)
336 ]
337 ValueOutsideMask [ (0x1)
338 FirstByte1 (0x1)
339 ]
340 FirstSecondByteMask [ (0xFF)
341 ]
342 FirstSecondThirdByteMask [ (0x333)
343 FirstByte3 (0x3)
344 SecondByte3 (0x30)
345 ThirdByte3 (0x300)
346 ]
347 )";
348
349 const char *JSONExpectedOut = R"({
350 "ZeroFlag": {
351 "RawFlags": 0,
352 "Flags": []
353 },
354 "NoFlag": {
355 "RawFlags": 8,
356 "Flags": []
357 },
358 "Flag1": {
359 "RawFlags": 1,
360 "Flags": [
361 {
362 "Name": "Name1",
363 "Value": 1
364 }
365 ]
366 },
367 "Flag1&3": {
368 "RawFlags": 5,
369 "Flags": [
370 {
371 "Name": "Name1",
372 "Value": 1
373 },
374 {
375 "Name": "Name3",
376 "Value": 4
377 }
378 ]
379 },
380 "ZeroFlagRaw": {
381 "RawFlags": 0,
382 "Flags": []
383 },
384 "NoFlagRaw": {
385 "RawFlags": 8,
386 "Flags": [
387 8
388 ]
389 },
390 "Flag1Raw": {
391 "RawFlags": 1,
392 "Flags": [
393 1
394 ]
395 },
396 "Flag1&3Raw": {
397 "RawFlags": 5,
398 "Flags": [
399 1,
400 4
401 ]
402 },
403 "FlagSorted": {
404 "RawFlags": 7,
405 "Flags": [
406 {
407 "Name": "A",
408 "Value": 4
409 },
410 {
411 "Name": "B",
412 "Value": 2
413 },
414 {
415 "Name": "C",
416 "Value": 1
417 }
418 ]
419 },
420 "NoBitMask": {
421 "RawFlags": 4095,
422 "Flags": [
423 {
424 "Name": "FirstByte1",
425 "Value": 1
426 },
427 {
428 "Name": "FirstByte2",
429 "Value": 2
430 },
431 {
432 "Name": "FirstByte3",
433 "Value": 3
434 },
435 {
436 "Name": "SecondByte1",
437 "Value": 16
438 },
439 {
440 "Name": "SecondByte2",
441 "Value": 32
442 },
443 {
444 "Name": "SecondByte3",
445 "Value": 48
446 },
447 {
448 "Name": "ThirdByte1",
449 "Value": 256
450 },
451 {
452 "Name": "ThirdByte2",
453 "Value": 512
454 },
455 {
456 "Name": "ThirdByte3",
457 "Value": 768
458 }
459 ]
460 },
461 "FirstByteMask": {
462 "RawFlags": 3,
463 "Flags": [
464 {
465 "Name": "FirstByte3",
466 "Value": 3
467 }
468 ]
469 },
470 "SecondByteMask": {
471 "RawFlags": 48,
472 "Flags": [
473 {
474 "Name": "SecondByte3",
475 "Value": 48
476 }
477 ]
478 },
479 "ValueOutsideMask": {
480 "RawFlags": 1,
481 "Flags": [
482 {
483 "Name": "FirstByte1",
484 "Value": 1
485 }
486 ]
487 },
488 "FirstSecondByteMask": {
489 "RawFlags": 255,
490 "Flags": []
491 },
492 "FirstSecondThirdByteMask": {
493 "RawFlags": 819,
494 "Flags": [
495 {
496 "Name": "FirstByte3",
497 "Value": 3
498 },
499 {
500 "Name": "SecondByte3",
501 "Value": 48
502 },
503 {
504 "Name": "ThirdByte3",
505 "Value": 768
506 }
507 ]
508 }
509 })";
510 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
511 }
512
TEST_F(ScopedPrinterTest,PrintNumber)513 TEST_F(ScopedPrinterTest, PrintNumber) {
514 auto PrintFunc = [](ScopedPrinter &W) {
515 uint64_t Unsigned64Max = std::numeric_limits<uint64_t>::max();
516 uint64_t Unsigned64Min = std::numeric_limits<uint64_t>::min();
517 W.printNumber("uint64_t-max", Unsigned64Max);
518 W.printNumber("uint64_t-min", Unsigned64Min);
519
520 uint32_t Unsigned32Max = std::numeric_limits<uint32_t>::max();
521 uint32_t Unsigned32Min = std::numeric_limits<uint32_t>::min();
522 W.printNumber("uint32_t-max", Unsigned32Max);
523 W.printNumber("uint32_t-min", Unsigned32Min);
524
525 uint16_t Unsigned16Max = std::numeric_limits<uint16_t>::max();
526 uint16_t Unsigned16Min = std::numeric_limits<uint16_t>::min();
527 W.printNumber("uint16_t-max", Unsigned16Max);
528 W.printNumber("uint16_t-min", Unsigned16Min);
529
530 uint8_t Unsigned8Max = std::numeric_limits<uint8_t>::max();
531 uint8_t Unsigned8Min = std::numeric_limits<uint8_t>::min();
532 W.printNumber("uint8_t-max", Unsigned8Max);
533 W.printNumber("uint8_t-min", Unsigned8Min);
534
535 int64_t Signed64Max = std::numeric_limits<int64_t>::max();
536 int64_t Signed64Min = std::numeric_limits<int64_t>::min();
537 W.printNumber("int64_t-max", Signed64Max);
538 W.printNumber("int64_t-min", Signed64Min);
539
540 int32_t Signed32Max = std::numeric_limits<int32_t>::max();
541 int32_t Signed32Min = std::numeric_limits<int32_t>::min();
542 W.printNumber("int32_t-max", Signed32Max);
543 W.printNumber("int32_t-min", Signed32Min);
544
545 int16_t Signed16Max = std::numeric_limits<int16_t>::max();
546 int16_t Signed16Min = std::numeric_limits<int16_t>::min();
547 W.printNumber("int16_t-max", Signed16Max);
548 W.printNumber("int16_t-min", Signed16Min);
549
550 int8_t Signed8Max = std::numeric_limits<int8_t>::max();
551 int8_t Signed8Min = std::numeric_limits<int8_t>::min();
552 W.printNumber("int8_t-max", Signed8Max);
553 W.printNumber("int8_t-min", Signed8Min);
554
555 APSInt LargeNum("9999999999999999999999");
556 W.printNumber("apsint", LargeNum);
557
558 W.printNumber("label", "value", 0);
559 };
560
561 const char *ExpectedOut = R"(uint64_t-max: 18446744073709551615
562 uint64_t-min: 0
563 uint32_t-max: 4294967295
564 uint32_t-min: 0
565 uint16_t-max: 65535
566 uint16_t-min: 0
567 uint8_t-max: 255
568 uint8_t-min: 0
569 int64_t-max: 9223372036854775807
570 int64_t-min: -9223372036854775808
571 int32_t-max: 2147483647
572 int32_t-min: -2147483648
573 int16_t-max: 32767
574 int16_t-min: -32768
575 int8_t-max: 127
576 int8_t-min: -128
577 apsint: 9999999999999999999999
578 label: value (0)
579 )";
580
581 const char *JSONExpectedOut = R"({
582 "uint64_t-max": 18446744073709551615,
583 "uint64_t-min": 0,
584 "uint32_t-max": 4294967295,
585 "uint32_t-min": 0,
586 "uint16_t-max": 65535,
587 "uint16_t-min": 0,
588 "uint8_t-max": 255,
589 "uint8_t-min": 0,
590 "int64_t-max": 9223372036854775807,
591 "int64_t-min": -9223372036854775808,
592 "int32_t-max": 2147483647,
593 "int32_t-min": -2147483648,
594 "int16_t-max": 32767,
595 "int16_t-min": -32768,
596 "int8_t-max": 127,
597 "int8_t-min": -128,
598 "apsint": 9999999999999999999999,
599 "label": {
600 "Value": "value",
601 "RawValue": 0
602 }
603 })";
604 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
605 }
606
TEST_F(ScopedPrinterTest,PrintBoolean)607 TEST_F(ScopedPrinterTest, PrintBoolean) {
608 auto PrintFunc = [](ScopedPrinter &W) {
609 W.printBoolean("True", true);
610 W.printBoolean("False", false);
611 };
612
613 const char *ExpectedOut = R"(True: Yes
614 False: No
615 )";
616
617 const char *JSONExpectedOut = R"({
618 "True": true,
619 "False": false
620 })";
621 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
622 }
623
TEST_F(ScopedPrinterTest,PrintVersion)624 TEST_F(ScopedPrinterTest, PrintVersion) {
625 auto PrintFunc = [](ScopedPrinter &W) {
626 W.printVersion("Version", "123", "456", "789");
627 };
628 const char *ExpectedOut = R"(Version: 123.456.789
629 )";
630 verifyScopedPrinter(ExpectedOut, PrintFunc);
631 }
632
TEST_F(ScopedPrinterTest,PrintList)633 TEST_F(ScopedPrinterTest, PrintList) {
634 auto PrintFunc = [](ScopedPrinter &W) {
635 const std::vector<uint64_t> EmptyList;
636 const std::vector<std::string> StringList = {"foo", "bar", "baz"};
637 const bool BoolList[] = {true, false};
638 const std::vector<uint64_t> Unsigned64List = {
639 std::numeric_limits<uint64_t>::max(),
640 std::numeric_limits<uint64_t>::min()};
641 const std::vector<uint32_t> Unsigned32List = {
642 std::numeric_limits<uint32_t>::max(),
643 std::numeric_limits<uint32_t>::min()};
644 const std::vector<uint16_t> Unsigned16List = {
645 std::numeric_limits<uint16_t>::max(),
646 std::numeric_limits<uint16_t>::min()};
647 const std::vector<uint8_t> Unsigned8List = {
648 std::numeric_limits<uint8_t>::max(),
649 std::numeric_limits<uint8_t>::min()};
650 const std::vector<int64_t> Signed64List = {
651 std::numeric_limits<int64_t>::max(),
652 std::numeric_limits<int64_t>::min()};
653 const std::vector<int32_t> Signed32List = {
654 std::numeric_limits<int32_t>::max(),
655 std::numeric_limits<int32_t>::min()};
656 const std::vector<int16_t> Signed16List = {
657 std::numeric_limits<int16_t>::max(),
658 std::numeric_limits<int16_t>::min()};
659 const std::vector<int8_t> Signed8List = {
660 std::numeric_limits<int8_t>::max(), std::numeric_limits<int8_t>::min()};
661 const std::vector<APSInt> APSIntList = {APSInt("9999999999999999999999"),
662 APSInt("-9999999999999999999999")};
663 W.printList("EmptyList", EmptyList);
664 W.printList("StringList", StringList);
665 W.printList("BoolList", makeArrayRef(BoolList));
666 W.printList("uint64List", Unsigned64List);
667 W.printList("uint32List", Unsigned32List);
668 W.printList("uint16List", Unsigned16List);
669 W.printList("uint8List", Unsigned8List);
670 W.printList("int64List", Signed64List);
671 W.printList("int32List", Signed32List);
672 W.printList("int16List", Signed16List);
673 W.printList("int8List", Signed8List);
674 W.printList("APSIntList", APSIntList);
675 };
676
677 const char *ExpectedOut = R"(EmptyList: []
678 StringList: [foo, bar, baz]
679 BoolList: [1, 0]
680 uint64List: [18446744073709551615, 0]
681 uint32List: [4294967295, 0]
682 uint16List: [65535, 0]
683 uint8List: [255, 0]
684 int64List: [9223372036854775807, -9223372036854775808]
685 int32List: [2147483647, -2147483648]
686 int16List: [32767, -32768]
687 int8List: [127, -128]
688 APSIntList: [9999999999999999999999, -9999999999999999999999]
689 )";
690
691 const char *JSONExpectedOut = R"({
692 "EmptyList": [],
693 "StringList": [
694 "foo",
695 "bar",
696 "baz"
697 ],
698 "BoolList": [
699 true,
700 false
701 ],
702 "uint64List": [
703 18446744073709551615,
704 0
705 ],
706 "uint32List": [
707 4294967295,
708 0
709 ],
710 "uint16List": [
711 65535,
712 0
713 ],
714 "uint8List": [
715 255,
716 0
717 ],
718 "int64List": [
719 9223372036854775807,
720 -9223372036854775808
721 ],
722 "int32List": [
723 2147483647,
724 -2147483648
725 ],
726 "int16List": [
727 32767,
728 -32768
729 ],
730 "int8List": [
731 127,
732 -128
733 ],
734 "APSIntList": [
735 9999999999999999999999,
736 -9999999999999999999999
737 ]
738 })";
739 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
740 }
741
TEST_F(ScopedPrinterTest,PrintListPrinter)742 TEST_F(ScopedPrinterTest, PrintListPrinter) {
743 auto PrintFunc = [](ScopedPrinter &W) {
744 const std::string StringList[] = {"a", "ab", "abc"};
745 W.printList("StringSizeList", StringList,
746 [](raw_ostream &OS, StringRef Item) { OS << Item.size(); });
747 };
748
749 const char *ExpectedOut = R"(StringSizeList: [1, 2, 3]
750 )";
751 verifyScopedPrinter(ExpectedOut, PrintFunc);
752 }
753
TEST_F(ScopedPrinterTest,PrintHex)754 TEST_F(ScopedPrinterTest, PrintHex) {
755 auto PrintFunc = [](ScopedPrinter &W) {
756 W.printHex("HexNumber", 0x10);
757 W.printHex("HexLabel", "Name", 0x10);
758 };
759
760 const char *ExpectedOut = R"(HexNumber: 0x10
761 HexLabel: Name (0x10)
762 )";
763
764 const char *JSONExpectedOut = R"({
765 "HexNumber": 16,
766 "HexLabel": {
767 "Value": "Name",
768 "RawValue": 16
769 }
770 })";
771 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
772 }
773
TEST_F(ScopedPrinterTest,PrintHexList)774 TEST_F(ScopedPrinterTest, PrintHexList) {
775 auto PrintFunc = [](ScopedPrinter &W) {
776 const uint64_t HexList[] = {0x1, 0x10, 0x100};
777 W.printHexList("HexList", HexList);
778 };
779 const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100]
780 )";
781
782 const char *JSONExpectedOut = R"({
783 "HexList": [
784 1,
785 16,
786 256
787 ]
788 })";
789 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
790 }
791
TEST_F(ScopedPrinterTest,PrintSymbolOffset)792 TEST_F(ScopedPrinterTest, PrintSymbolOffset) {
793 auto PrintFunc = [](ScopedPrinter &W) {
794 W.printSymbolOffset("SymbolOffset", "SymbolName", 0x10);
795 W.printSymbolOffset("NoSymbolOffset", "SymbolName", 0);
796 };
797 const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10
798 NoSymbolOffset: SymbolName+0x0
799 )";
800
801 const char *JSONExpectedOut = R"({
802 "SymbolOffset": {
803 "SymName": "SymbolName",
804 "Offset": 16
805 },
806 "NoSymbolOffset": {
807 "SymName": "SymbolName",
808 "Offset": 0
809 }
810 })";
811 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
812 }
813
TEST_F(ScopedPrinterTest,PrintString)814 TEST_F(ScopedPrinterTest, PrintString) {
815 auto PrintFunc = [](ScopedPrinter &W) {
816 const StringRef StringRefValue("Value");
817 const std::string StringValue = "Value";
818 const char *CharArrayValue = "Value";
819 W.printString("StringRef", StringRefValue);
820 W.printString("String", StringValue);
821 W.printString("CharArray", CharArrayValue);
822 ListScope L(W, "StringList");
823 W.printString(StringRefValue);
824 };
825
826 const char *ExpectedOut = R"(StringRef: Value
827 String: Value
828 CharArray: Value
829 StringList [
830 Value
831 ]
832 )";
833
834 const char *JSONExpectedOut = R"({
835 "StringRef": "Value",
836 "String": "Value",
837 "CharArray": "Value",
838 "StringList": [
839 "Value"
840 ]
841 })";
842 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
843 }
844
TEST_F(ScopedPrinterTest,PrintBinary)845 TEST_F(ScopedPrinterTest, PrintBinary) {
846 auto PrintFunc = [](ScopedPrinter &W) {
847 std::vector<uint8_t> IntArray = {70, 111, 111, 66, 97, 114};
848 std::vector<char> CharArray = {'F', 'o', 'o', 'B', 'a', 'r'};
849 std::vector<uint8_t> InvalidChars = {255, 255};
850 W.printBinary("Binary1", "FooBar", IntArray);
851 W.printBinary("Binary2", "FooBar", CharArray);
852 W.printBinary("Binary3", IntArray);
853 W.printBinary("Binary4", CharArray);
854 W.printBinary("Binary5", StringRef("FooBar"));
855 W.printBinary("Binary6", StringRef("Multiple Line FooBar"));
856 W.printBinaryBlock("Binary7", IntArray, 20);
857 W.printBinaryBlock("Binary8", IntArray);
858 W.printBinaryBlock("Binary9", "FooBar");
859 W.printBinaryBlock("Binary10", "Multiple Line FooBar");
860 W.printBinaryBlock("Binary11", InvalidChars);
861 };
862
863 const char *ExpectedOut = R"(Binary1: FooBar (46 6F 6F 42 61 72)
864 Binary2: FooBar (46 6F 6F 42 61 72)
865 Binary3: (46 6F 6F 42 61 72)
866 Binary4: (46 6F 6F 42 61 72)
867 Binary5: (46 6F 6F 42 61 72)
868 Binary6 (
869 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|
870 0010: 6F426172 |oBar|
871 )
872 Binary7 (
873 0014: 466F6F42 6172 |FooBar|
874 )
875 Binary8 (
876 0000: 466F6F42 6172 |FooBar|
877 )
878 Binary9 (
879 0000: 466F6F42 6172 |FooBar|
880 )
881 Binary10 (
882 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|
883 0010: 6F426172 |oBar|
884 )
885 Binary11 (
886 0000: FFFF |..|
887 )
888 )";
889
890 const char *JSONExpectedOut = R"({
891 "Binary1": {
892 "Value": "FooBar",
893 "Offset": 0,
894 "Bytes": [
895 70,
896 111,
897 111,
898 66,
899 97,
900 114
901 ]
902 },
903 "Binary2": {
904 "Value": "FooBar",
905 "Offset": 0,
906 "Bytes": [
907 70,
908 111,
909 111,
910 66,
911 97,
912 114
913 ]
914 },
915 "Binary3": {
916 "Offset": 0,
917 "Bytes": [
918 70,
919 111,
920 111,
921 66,
922 97,
923 114
924 ]
925 },
926 "Binary4": {
927 "Offset": 0,
928 "Bytes": [
929 70,
930 111,
931 111,
932 66,
933 97,
934 114
935 ]
936 },
937 "Binary5": {
938 "Offset": 0,
939 "Bytes": [
940 70,
941 111,
942 111,
943 66,
944 97,
945 114
946 ]
947 },
948 "Binary6": {
949 "Offset": 0,
950 "Bytes": [
951 77,
952 117,
953 108,
954 116,
955 105,
956 112,
957 108,
958 101,
959 32,
960 76,
961 105,
962 110,
963 101,
964 32,
965 70,
966 111,
967 111,
968 66,
969 97,
970 114
971 ]
972 },
973 "Binary7": {
974 "Offset": 20,
975 "Bytes": [
976 70,
977 111,
978 111,
979 66,
980 97,
981 114
982 ]
983 },
984 "Binary8": {
985 "Offset": 0,
986 "Bytes": [
987 70,
988 111,
989 111,
990 66,
991 97,
992 114
993 ]
994 },
995 "Binary9": {
996 "Offset": 0,
997 "Bytes": [
998 70,
999 111,
1000 111,
1001 66,
1002 97,
1003 114
1004 ]
1005 },
1006 "Binary10": {
1007 "Offset": 0,
1008 "Bytes": [
1009 77,
1010 117,
1011 108,
1012 116,
1013 105,
1014 112,
1015 108,
1016 101,
1017 32,
1018 76,
1019 105,
1020 110,
1021 101,
1022 32,
1023 70,
1024 111,
1025 111,
1026 66,
1027 97,
1028 114
1029 ]
1030 },
1031 "Binary11": {
1032 "Offset": 0,
1033 "Bytes": [
1034 255,
1035 255
1036 ]
1037 }
1038 })";
1039 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
1040 }
1041
TEST_F(ScopedPrinterTest,PrintObject)1042 TEST_F(ScopedPrinterTest, PrintObject) {
1043 auto PrintFunc = [](ScopedPrinter &W) { W.printObject("Object", "Value"); };
1044
1045 const char *ExpectedOut = R"(Object: Value
1046 )";
1047
1048 const char *JSONExpectedOut = R"({
1049 "Object": "Value"
1050 })";
1051 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
1052 }
1053
TEST_F(ScopedPrinterTest,StartLine)1054 TEST_F(ScopedPrinterTest, StartLine) {
1055 auto PrintFunc = [](ScopedPrinter &W) {
1056 W.startLine() << "|";
1057 W.indent(2);
1058 W.startLine() << "|";
1059 W.unindent();
1060 W.startLine() << "|";
1061 };
1062
1063 const char *ExpectedOut = "| | |";
1064 verifyScopedPrinter(ExpectedOut, PrintFunc);
1065 }
1066
TEST_F(ScopedPrinterTest,GetOStream)1067 TEST_F(ScopedPrinterTest, GetOStream) {
1068 auto PrintFunc = [](ScopedPrinter &W) { W.getOStream() << "Test"; };
1069
1070 const char *ExpectedOut = "Test";
1071 verifyScopedPrinter(ExpectedOut, PrintFunc);
1072 }
1073
TEST_F(ScopedPrinterTest,PrintScope)1074 TEST_F(ScopedPrinterTest, PrintScope) {
1075 auto PrintFunc = [](ScopedPrinter &W) {
1076 {
1077 DictScope O(W, "Object");
1078 { DictScope OO(W, "ObjectInObject"); }
1079 { ListScope LO(W, "ListInObject"); }
1080 }
1081 {
1082 ListScope L(W, "List");
1083 { DictScope OL(W, "ObjectInList"); }
1084 { ListScope LL(W, "ListInList"); }
1085 }
1086 };
1087
1088 const char *ExpectedOut = R"(Object {
1089 ObjectInObject {
1090 }
1091 ListInObject [
1092 ]
1093 }
1094 List [
1095 ObjectInList {
1096 }
1097 ListInList [
1098 ]
1099 ]
1100 )";
1101
1102 const char *JSONExpectedOut = R"({
1103 "Object": {
1104 "ObjectInObject": {},
1105 "ListInObject": []
1106 },
1107 "List": [
1108 {
1109 "ObjectInList": {}
1110 },
1111 {
1112 "ListInList": []
1113 }
1114 ]
1115 })";
1116 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);
1117 }
1118