1228 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/ScopedPrinter.h"10#include "llvm/ADT/APSInt.h"11#include "llvm/ADT/BitmaskEnum.h"12#include "llvm/Support/Format.h"13#include "gtest/gtest.h"14#include <cmath>15#include <vector>16 17namespace {18enum class BitmaskEnum : uint8_t {19 F1 = 0x1,20 F2 = 0x2,21 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/F2),22};23LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();24} // namespace25 26using namespace llvm;27 28TEST(JSONScopedPrinterTest, PrettyPrintCtor) {29 auto PrintFunc = [](ScopedPrinter &W) {30 DictScope D(W);31 W.printString("Key", "Value");32 };33 std::string StreamBuffer;34 raw_string_ostream OS(StreamBuffer);35 JSONScopedPrinter PrettyPrintWriter(OS, /*PrettyPrint=*/true);36 JSONScopedPrinter NoPrettyPrintWriter(OS, /*PrettyPrint=*/false);37 38 const char *PrettyPrintOut = R"({39 "Key": "Value"40})";41 const char *NoPrettyPrintOut = R"({"Key":"Value"})";42 PrintFunc(PrettyPrintWriter);43 EXPECT_EQ(PrettyPrintOut, StreamBuffer);44 StreamBuffer.clear();45 PrintFunc(NoPrettyPrintWriter);46 EXPECT_EQ(NoPrettyPrintOut, StreamBuffer);47}48 49TEST(JSONScopedPrinterTest, DelimitedScopeCtor) {50 std::string StreamBuffer;51 raw_string_ostream OS(StreamBuffer);52 {53 JSONScopedPrinter DictScopeWriter(OS, /*PrettyPrint=*/false,54 std::make_unique<DictScope>());55 DictScopeWriter.printString("Label", "DictScope");56 }57 EXPECT_EQ(R"({"Label":"DictScope"})", StreamBuffer);58 StreamBuffer.clear();59 {60 JSONScopedPrinter ListScopeWriter(OS, /*PrettyPrint=*/false,61 std::make_unique<ListScope>());62 ListScopeWriter.printString("ListScope");63 }64 EXPECT_EQ(R"(["ListScope"])", StreamBuffer);65 StreamBuffer.clear();66 {67 JSONScopedPrinter NoScopeWriter(OS, /*PrettyPrint=*/false);68 NoScopeWriter.printString("NoScope");69 }70 EXPECT_EQ(R"("NoScope")", StreamBuffer);71}72 73class ScopedPrinterTest : public ::testing::Test {74protected:75 std::string StreamBuffer;76 raw_string_ostream OS;77 ScopedPrinter Writer;78 JSONScopedPrinter JSONWriter;79 80 bool HasPrintedToJSON;81 82 ScopedPrinterTest()83 : OS(StreamBuffer), Writer(OS), JSONWriter(OS, /*PrettyPrint=*/true),84 HasPrintedToJSON(false) {}85 86 using PrintFunc = function_ref<void(ScopedPrinter &)>;87 88 void verifyScopedPrinter(StringRef Expected, PrintFunc Func) {89 Func(Writer);90 Writer.flush();91 EXPECT_EQ(Expected.str(), StreamBuffer);92 StreamBuffer.clear();93 }94 95 void verifyJSONScopedPrinter(StringRef Expected, PrintFunc Func) {96 {97 DictScope D(JSONWriter);98 Func(JSONWriter);99 }100 JSONWriter.flush();101 EXPECT_EQ(Expected.str(), StreamBuffer);102 StreamBuffer.clear();103 HasPrintedToJSON = true;104 }105 106 void verifyAll(StringRef ExpectedOut, StringRef JSONExpectedOut,107 PrintFunc Func) {108 verifyScopedPrinter(ExpectedOut, Func);109 verifyJSONScopedPrinter(JSONExpectedOut, Func);110 }111 112 void TearDown() override {113 // JSONScopedPrinter fails an assert if nothing's been printed.114 if (!HasPrintedToJSON)115 JSONWriter.printString("");116 }117};118 119TEST_F(ScopedPrinterTest, GetKind) {120 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::Base, Writer.getKind());121 EXPECT_EQ(ScopedPrinter::ScopedPrinterKind::JSON, JSONWriter.getKind());122}123 124TEST_F(ScopedPrinterTest, ClassOf) {125 EXPECT_TRUE(ScopedPrinter::classof(&Writer));126 EXPECT_TRUE(JSONScopedPrinter::classof(&JSONWriter));127 EXPECT_FALSE(ScopedPrinter::classof(&JSONWriter));128 EXPECT_FALSE(JSONScopedPrinter::classof(&Writer));129}130 131TEST_F(ScopedPrinterTest, Indent) {132 auto PrintFunc = [](ScopedPrinter &W) {133 W.printString("|");134 W.indent();135 W.printString("|");136 W.indent(2);137 W.printString("|");138 };139 140 const char *ExpectedOut = R"(|141 |142 |143)";144 verifyScopedPrinter(ExpectedOut, PrintFunc);145}146 147TEST_F(ScopedPrinterTest, Unindent) {148 auto PrintFunc = [](ScopedPrinter &W) {149 W.indent(3);150 W.printString("|");151 W.unindent(2);152 W.printString("|");153 W.unindent();154 W.printString("|");155 W.unindent();156 W.printString("|");157 };158 159 const char *ExpectedOut = R"( |160 |161|162|163)";164 verifyScopedPrinter(ExpectedOut, PrintFunc);165}166 167TEST_F(ScopedPrinterTest, ResetIndent) {168 auto PrintFunc = [](ScopedPrinter &W) {169 W.indent(4);170 W.printString("|");171 W.resetIndent();172 W.printString("|");173 };174 175 const char *ExpectedOut = R"( |176|177)";178 verifyScopedPrinter(ExpectedOut, PrintFunc);179}180 181TEST_F(ScopedPrinterTest, PrintIndent) {182 auto PrintFunc = [](ScopedPrinter &W) {183 W.printIndent();184 W.printString("|");185 W.indent();186 W.printIndent();187 W.printString("|");188 };189 190 const char *ExpectedOut = R"(|191 |192)";193 verifyScopedPrinter(ExpectedOut, PrintFunc);194}195 196TEST_F(ScopedPrinterTest, GetIndentLevel) {197 EXPECT_EQ(Writer.getIndentLevel(), 0);198 Writer.indent();199 EXPECT_EQ(Writer.getIndentLevel(), 1);200 Writer.indent();201 EXPECT_EQ(Writer.getIndentLevel(), 2);202 Writer.unindent();203 EXPECT_EQ(Writer.getIndentLevel(), 1);204 Writer.indent();205 Writer.resetIndent();206 EXPECT_EQ(Writer.getIndentLevel(), 0);207 Writer.unindent();208 EXPECT_EQ(Writer.getIndentLevel(), 0);209 Writer.indent();210 EXPECT_EQ(Writer.getIndentLevel(), 1);211}212 213TEST_F(ScopedPrinterTest, SetPrefix) {214 auto PrintFunc = [](ScopedPrinter &W) {215 W.setPrefix("Prefix1");216 W.indent();217 W.printIndent();218 W.printString("|");219 W.unindent();220 W.printIndent();221 W.printString("|");222 W.setPrefix("Prefix2");223 W.printIndent();224 W.printString("|");225 };226 227 const char *ExpectedOut = R"(Prefix1 Prefix1 |228Prefix1Prefix1|229Prefix2Prefix2|230)";231 verifyScopedPrinter(ExpectedOut, PrintFunc);232}233 234TEST_F(ScopedPrinterTest, PrintEnum) {235 auto PrintFunc = [](ScopedPrinter &W) {236 const EnumEntry<int> EnumList[] = {{"Name1", "AltName1", 1},237 {"Name2", "AltName2", 2},238 {"Name3", "AltName3", 3},239 {"Name4", "AltName4", 2}};240 EnumEntry<int> OtherEnum{"Name5", "AltName5", 5};241 W.printEnum("Exists", EnumList[1].Value, ArrayRef(EnumList));242 W.printEnum("DoesNotExist", OtherEnum.Value, ArrayRef(EnumList));243 };244 245 const char *ExpectedOut = R"(Exists: Name2 (0x2)246DoesNotExist: 0x5247)";248 249 const char *JSONExpectedOut = R"({250 "Exists": {251 "Name": "Name2",252 "Value": 2253 },254 "DoesNotExist": 5255})";256 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);257}258 259TEST_F(ScopedPrinterTest, PrintFlag) {260 auto PrintFunc = [](ScopedPrinter &W) {261 const EnumEntry<uint16_t> SingleBitFlags[] = {262 {"Name0", "AltName0", 0},263 {"Name1", "AltName1", 1},264 {"Name2", "AltName2", 1 << 1},265 {"Name3", "AltName3", 1 << 2}};266 const EnumEntry<uint16_t> UnsortedFlags[] = {267 {"C", "c", 1}, {"B", "b", 1 << 1}, {"A", "a", 1 << 2}};268 const EnumEntry<uint16_t> EnumFlags[] = {269 {"FirstByte1", "First1", 0x1u}, {"FirstByte2", "First2", 0x2u},270 {"FirstByte3", "First3", 0x3u}, {"SecondByte1", "Second1", 0x10u},271 {"SecondByte2", "Second2", 0x20u}, {"SecondByte3", "Second3", 0x30u},272 {"ThirdByte1", "Third1", 0x100u}, {"ThirdByte2", "Third2", 0x200u},273 {"ThirdByte3", "Third3", 0x300u}};274 275 const EnumEntry<BitmaskEnum> ScopedFlags[] = {276 {"F1", "AltF1", BitmaskEnum::F1},277 {"F2", "AltF2", BitmaskEnum::F2},278 };279 280 W.printFlags("ZeroFlag", 0, ArrayRef(SingleBitFlags));281 W.printFlags("NoFlag", 1 << 3, ArrayRef(SingleBitFlags));282 W.printFlags("Flag1", SingleBitFlags[1].Value, ArrayRef(SingleBitFlags));283 W.printFlags("Flag1&3", (1 << 2) + 1, ArrayRef(SingleBitFlags));284 285 W.printFlags("ZeroFlagRaw", 0);286 W.printFlags("NoFlagRaw", 1 << 3);287 W.printFlags("Flag1Raw", SingleBitFlags[1].Value);288 W.printFlags("Flag1&3Raw", (1 << 2) + 1);289 290 W.printFlags("FlagSorted", (1 << 2) + (1 << 1) + 1,291 ArrayRef(UnsortedFlags));292 293 uint16_t NoBitMask = 0;294 uint16_t FirstByteMask = 0xFu;295 uint16_t SecondByteMask = 0xF0u;296 uint16_t ThirdByteMask = 0xF00u;297 W.printFlags("NoBitMask", 0xFFFu, ArrayRef(EnumFlags), NoBitMask);298 W.printFlags("FirstByteMask", 0x3u, ArrayRef(EnumFlags), FirstByteMask);299 W.printFlags("SecondByteMask", 0x30u, ArrayRef(EnumFlags), SecondByteMask);300 W.printFlags("ValueOutsideMask", 0x1u, ArrayRef(EnumFlags), SecondByteMask);301 W.printFlags("FirstSecondByteMask", 0xFFu, ArrayRef(EnumFlags),302 FirstByteMask, SecondByteMask);303 W.printFlags("FirstSecondThirdByteMask", 0x333u, ArrayRef(EnumFlags),304 FirstByteMask, SecondByteMask, ThirdByteMask);305 W.printFlags("BitmaskEnum::F1", BitmaskEnum::F1, ArrayRef(ScopedFlags));306 };307 308 const char *ExpectedOut = R"(ZeroFlag [ (0x0)309]310NoFlag [ (0x8)311]312Flag1 [ (0x1)313 Name1 (0x1)314]315Flag1&3 [ (0x5)316 Name1 (0x1)317 Name3 (0x4)318]319ZeroFlagRaw [ (0x0)320]321NoFlagRaw [ (0x8)322 0x8323]324Flag1Raw [ (0x1)325 0x1326]327Flag1&3Raw [ (0x5)328 0x1329 0x4330]331FlagSorted [ (0x7)332 A (0x4)333 B (0x2)334 C (0x1)335]336NoBitMask [ (0xFFF)337 FirstByte1 (0x1)338 FirstByte2 (0x2)339 FirstByte3 (0x3)340 SecondByte1 (0x10)341 SecondByte2 (0x20)342 SecondByte3 (0x30)343 ThirdByte1 (0x100)344 ThirdByte2 (0x200)345 ThirdByte3 (0x300)346]347FirstByteMask [ (0x3)348 FirstByte3 (0x3)349]350SecondByteMask [ (0x30)351 SecondByte3 (0x30)352]353ValueOutsideMask [ (0x1)354 FirstByte1 (0x1)355]356FirstSecondByteMask [ (0xFF)357]358FirstSecondThirdByteMask [ (0x333)359 FirstByte3 (0x3)360 SecondByte3 (0x30)361 ThirdByte3 (0x300)362]363BitmaskEnum::F1 [ (0x1)364 F1 (0x1)365]366)";367 368 const char *JSONExpectedOut = R"({369 "ZeroFlag": {370 "Value": 0,371 "Flags": []372 },373 "NoFlag": {374 "Value": 8,375 "Flags": []376 },377 "Flag1": {378 "Value": 1,379 "Flags": [380 {381 "Name": "Name1",382 "Value": 1383 }384 ]385 },386 "Flag1&3": {387 "Value": 5,388 "Flags": [389 {390 "Name": "Name1",391 "Value": 1392 },393 {394 "Name": "Name3",395 "Value": 4396 }397 ]398 },399 "ZeroFlagRaw": {400 "Value": 0,401 "Flags": []402 },403 "NoFlagRaw": {404 "Value": 8,405 "Flags": [406 8407 ]408 },409 "Flag1Raw": {410 "Value": 1,411 "Flags": [412 1413 ]414 },415 "Flag1&3Raw": {416 "Value": 5,417 "Flags": [418 1,419 4420 ]421 },422 "FlagSorted": {423 "Value": 7,424 "Flags": [425 {426 "Name": "A",427 "Value": 4428 },429 {430 "Name": "B",431 "Value": 2432 },433 {434 "Name": "C",435 "Value": 1436 }437 ]438 },439 "NoBitMask": {440 "Value": 4095,441 "Flags": [442 {443 "Name": "FirstByte1",444 "Value": 1445 },446 {447 "Name": "FirstByte2",448 "Value": 2449 },450 {451 "Name": "FirstByte3",452 "Value": 3453 },454 {455 "Name": "SecondByte1",456 "Value": 16457 },458 {459 "Name": "SecondByte2",460 "Value": 32461 },462 {463 "Name": "SecondByte3",464 "Value": 48465 },466 {467 "Name": "ThirdByte1",468 "Value": 256469 },470 {471 "Name": "ThirdByte2",472 "Value": 512473 },474 {475 "Name": "ThirdByte3",476 "Value": 768477 }478 ]479 },480 "FirstByteMask": {481 "Value": 3,482 "Flags": [483 {484 "Name": "FirstByte3",485 "Value": 3486 }487 ]488 },489 "SecondByteMask": {490 "Value": 48,491 "Flags": [492 {493 "Name": "SecondByte3",494 "Value": 48495 }496 ]497 },498 "ValueOutsideMask": {499 "Value": 1,500 "Flags": [501 {502 "Name": "FirstByte1",503 "Value": 1504 }505 ]506 },507 "FirstSecondByteMask": {508 "Value": 255,509 "Flags": []510 },511 "FirstSecondThirdByteMask": {512 "Value": 819,513 "Flags": [514 {515 "Name": "FirstByte3",516 "Value": 3517 },518 {519 "Name": "SecondByte3",520 "Value": 48521 },522 {523 "Name": "ThirdByte3",524 "Value": 768525 }526 ]527 },528 "BitmaskEnum::F1": {529 "Value": 1,530 "Flags": [531 {532 "Name": "F1",533 "Value": 1534 }535 ]536 }537})";538 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);539}540 541// Format floats using the same format string as PrintNumber, so we can check542// the output on all platforms.543template <typename T,544 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>545std::string formatFloatString(T Val) {546 std::string Ret;547 raw_string_ostream OS(Ret);548 OS << format("%5.1f", Val);549 return Ret;550}551 552// Format floats using the same format string used in JSON, so we can check the553// output on all platforms.554template <typename T,555 std::enable_if_t<std::is_floating_point_v<T>, bool> = true>556std::string formatJsonFloatString(T Val) {557 std::string Ret;558 raw_string_ostream OS(Ret);559 OS << format("%.*g", std::numeric_limits<double>::max_digits10, Val);560 return Ret;561}562 563TEST_F(ScopedPrinterTest, PrintNumber) {564 constexpr float MaxFloat = std::numeric_limits<float>::max();565 constexpr float MinFloat = std::numeric_limits<float>::min();566 constexpr float InfFloat = std::numeric_limits<float>::infinity();567 const float NaNFloat = std::nanf("1");568 constexpr double MaxDouble = std::numeric_limits<double>::max();569 constexpr double MinDouble = std::numeric_limits<double>::min();570 constexpr double InfDouble = std::numeric_limits<double>::infinity();571 const double NaNDouble = std::nan("1");572 573 auto PrintFunc = [&](ScopedPrinter &W) {574 uint64_t Unsigned64Max = std::numeric_limits<uint64_t>::max();575 uint64_t Unsigned64Min = std::numeric_limits<uint64_t>::min();576 W.printNumber("uint64_t-max", Unsigned64Max);577 W.printNumber("uint64_t-min", Unsigned64Min);578 579 uint32_t Unsigned32Max = std::numeric_limits<uint32_t>::max();580 uint32_t Unsigned32Min = std::numeric_limits<uint32_t>::min();581 W.printNumber("uint32_t-max", Unsigned32Max);582 W.printNumber("uint32_t-min", Unsigned32Min);583 584 uint16_t Unsigned16Max = std::numeric_limits<uint16_t>::max();585 uint16_t Unsigned16Min = std::numeric_limits<uint16_t>::min();586 W.printNumber("uint16_t-max", Unsigned16Max);587 W.printNumber("uint16_t-min", Unsigned16Min);588 589 uint8_t Unsigned8Max = std::numeric_limits<uint8_t>::max();590 uint8_t Unsigned8Min = std::numeric_limits<uint8_t>::min();591 W.printNumber("uint8_t-max", Unsigned8Max);592 W.printNumber("uint8_t-min", Unsigned8Min);593 594 int64_t Signed64Max = std::numeric_limits<int64_t>::max();595 int64_t Signed64Min = std::numeric_limits<int64_t>::min();596 W.printNumber("int64_t-max", Signed64Max);597 W.printNumber("int64_t-min", Signed64Min);598 599 int32_t Signed32Max = std::numeric_limits<int32_t>::max();600 int32_t Signed32Min = std::numeric_limits<int32_t>::min();601 W.printNumber("int32_t-max", Signed32Max);602 W.printNumber("int32_t-min", Signed32Min);603 604 int16_t Signed16Max = std::numeric_limits<int16_t>::max();605 int16_t Signed16Min = std::numeric_limits<int16_t>::min();606 W.printNumber("int16_t-max", Signed16Max);607 W.printNumber("int16_t-min", Signed16Min);608 609 int8_t Signed8Max = std::numeric_limits<int8_t>::max();610 int8_t Signed8Min = std::numeric_limits<int8_t>::min();611 W.printNumber("int8_t-max", Signed8Max);612 W.printNumber("int8_t-min", Signed8Min);613 614 APSInt LargeNum("9999999999999999999999");615 W.printNumber("apsint", LargeNum);616 617 W.printNumber("label", "value", 0);618 619 W.printNumber("float-max", MaxFloat);620 W.printNumber("float-min", MinFloat);621 W.printNumber("float-inf", InfFloat);622 W.printNumber("float-nan", NaNFloat);623 W.printNumber("float-42.0", 42.0f);624 W.printNumber("float-42.5625", 42.5625f);625 626 W.printNumber("double-max", MaxDouble);627 W.printNumber("double-min", MinDouble);628 W.printNumber("double-inf", InfDouble);629 W.printNumber("double-nan", NaNDouble);630 W.printNumber("double-42.0", 42.0);631 W.printNumber("double-42.5625", 42.5625);632 };633 634 std::string ExpectedOut = Twine(635 R"(uint64_t-max: 18446744073709551615636uint64_t-min: 0637uint32_t-max: 4294967295638uint32_t-min: 0639uint16_t-max: 65535640uint16_t-min: 0641uint8_t-max: 255642uint8_t-min: 0643int64_t-max: 9223372036854775807644int64_t-min: -9223372036854775808645int32_t-max: 2147483647646int32_t-min: -2147483648647int16_t-max: 32767648int16_t-min: -32768649int8_t-max: 127650int8_t-min: -128651apsint: 9999999999999999999999652label: value (0)653float-max: )" + formatFloatString(MaxFloat) +654 R"(655float-min: 0.0656float-inf: )" + formatFloatString(InfFloat) +657 R"(658float-nan: )" + formatFloatString(NaNFloat) +659 R"(660float-42.0: 42.0661float-42.5625: 42.6662double-max: )" + formatFloatString(MaxDouble) +663 R"(664double-min: 0.0665double-inf: )" + formatFloatString(InfDouble) +666 R"(667double-nan: )" + formatFloatString(NaNDouble) +668 R"(669double-42.0: 42.0670double-42.5625: 42.6671)")672 .str();673 674 std::string JSONExpectedOut = Twine(R"({675 "uint64_t-max": 18446744073709551615,676 "uint64_t-min": 0,677 "uint32_t-max": 4294967295,678 "uint32_t-min": 0,679 "uint16_t-max": 65535,680 "uint16_t-min": 0,681 "uint8_t-max": 255,682 "uint8_t-min": 0,683 "int64_t-max": 9223372036854775807,684 "int64_t-min": -9223372036854775808,685 "int32_t-max": 2147483647,686 "int32_t-min": -2147483648,687 "int16_t-max": 32767,688 "int16_t-min": -32768,689 "int8_t-max": 127,690 "int8_t-min": -128,691 "apsint": 9999999999999999999999,692 "label": {693 "Name": "value",694 "Value": 0695 },696 "float-max": 3.4028234663852886e+38,697 "float-min": 1.1754943508222875e-38,698 "float-inf": )" + formatJsonFloatString(InfFloat) +699 R"(,700 "float-nan": )" + formatJsonFloatString(NaNFloat) +701 R"(,702 "float-42.0": 42,703 "float-42.5625": 42.5625,704 "double-max": 1.7976931348623157e+308,705 "double-min": 2.2250738585072014e-308,706 "double-inf": )" + formatJsonFloatString(InfDouble) +707 R"(,708 "double-nan": )" + formatJsonFloatString(NaNDouble) +709 R"(,710 "double-42.0": 42,711 "double-42.5625": 42.5625712})")713 .str();714 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);715}716 717TEST_F(ScopedPrinterTest, PrintBoolean) {718 auto PrintFunc = [](ScopedPrinter &W) {719 W.printBoolean("True", true);720 W.printBoolean("False", false);721 };722 723 const char *ExpectedOut = R"(True: Yes724False: No725)";726 727 const char *JSONExpectedOut = R"({728 "True": true,729 "False": false730})";731 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);732}733 734TEST_F(ScopedPrinterTest, PrintVersion) {735 auto PrintFunc = [](ScopedPrinter &W) {736 W.printVersion("Version", "123", "456", "789");737 };738 const char *ExpectedOut = R"(Version: 123.456.789739)";740 verifyScopedPrinter(ExpectedOut, PrintFunc);741}742 743TEST_F(ScopedPrinterTest, PrintList) {744 auto PrintFunc = [](ScopedPrinter &W) {745 const std::vector<uint64_t> EmptyList;746 const std::vector<std::string> StringList = {"foo", "bar", "baz"};747 const bool BoolList[] = {true, false};748 const std::vector<uint64_t> Unsigned64List = {749 std::numeric_limits<uint64_t>::max(),750 std::numeric_limits<uint64_t>::min()};751 const std::vector<uint32_t> Unsigned32List = {752 std::numeric_limits<uint32_t>::max(),753 std::numeric_limits<uint32_t>::min()};754 const std::vector<uint16_t> Unsigned16List = {755 std::numeric_limits<uint16_t>::max(),756 std::numeric_limits<uint16_t>::min()};757 const std::vector<uint8_t> Unsigned8List = {758 std::numeric_limits<uint8_t>::max(),759 std::numeric_limits<uint8_t>::min()};760 const std::vector<int64_t> Signed64List = {761 std::numeric_limits<int64_t>::max(),762 std::numeric_limits<int64_t>::min()};763 const std::vector<int32_t> Signed32List = {764 std::numeric_limits<int32_t>::max(),765 std::numeric_limits<int32_t>::min()};766 const std::vector<int16_t> Signed16List = {767 std::numeric_limits<int16_t>::max(),768 std::numeric_limits<int16_t>::min()};769 const std::vector<int8_t> Signed8List = {770 std::numeric_limits<int8_t>::max(), std::numeric_limits<int8_t>::min()};771 const std::vector<APSInt> APSIntList = {APSInt("9999999999999999999999"),772 APSInt("-9999999999999999999999")};773 W.printList("EmptyList", EmptyList);774 W.printList("StringList", StringList);775 W.printList("BoolList", ArrayRef(BoolList));776 W.printList("uint64List", Unsigned64List);777 W.printList("uint32List", Unsigned32List);778 W.printList("uint16List", Unsigned16List);779 W.printList("uint8List", Unsigned8List);780 W.printList("int64List", Signed64List);781 W.printList("int32List", Signed32List);782 W.printList("int16List", Signed16List);783 W.printList("int8List", Signed8List);784 W.printList("APSIntList", APSIntList);785 };786 787 const char *ExpectedOut = R"(EmptyList: []788StringList: [foo, bar, baz]789BoolList: [1, 0]790uint64List: [18446744073709551615, 0]791uint32List: [4294967295, 0]792uint16List: [65535, 0]793uint8List: [255, 0]794int64List: [9223372036854775807, -9223372036854775808]795int32List: [2147483647, -2147483648]796int16List: [32767, -32768]797int8List: [127, -128]798APSIntList: [9999999999999999999999, -9999999999999999999999]799)";800 801 const char *JSONExpectedOut = R"({802 "EmptyList": [],803 "StringList": [804 "foo",805 "bar",806 "baz"807 ],808 "BoolList": [809 true,810 false811 ],812 "uint64List": [813 18446744073709551615,814 0815 ],816 "uint32List": [817 4294967295,818 0819 ],820 "uint16List": [821 65535,822 0823 ],824 "uint8List": [825 255,826 0827 ],828 "int64List": [829 9223372036854775807,830 -9223372036854775808831 ],832 "int32List": [833 2147483647,834 -2147483648835 ],836 "int16List": [837 32767,838 -32768839 ],840 "int8List": [841 127,842 -128843 ],844 "APSIntList": [845 9999999999999999999999,846 -9999999999999999999999847 ]848})";849 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);850}851 852TEST_F(ScopedPrinterTest, PrintListPrinter) {853 auto PrintFunc = [](ScopedPrinter &W) {854 const std::string StringList[] = {"a", "ab", "abc"};855 W.printList("StringSizeList", StringList,856 [](raw_ostream &OS, StringRef Item) { OS << Item.size(); });857 };858 859 const char *ExpectedOut = R"(StringSizeList: [1, 2, 3]860)";861 verifyScopedPrinter(ExpectedOut, PrintFunc);862}863 864TEST_F(ScopedPrinterTest, PrintHex) {865 auto PrintFunc = [](ScopedPrinter &W) {866 W.printHex("HexNumber", 0x10);867 W.printHex("HexLabel", "Name", 0x10);868 };869 870 const char *ExpectedOut = R"(HexNumber: 0x10871HexLabel: Name (0x10)872)";873 874 const char *JSONExpectedOut = R"({875 "HexNumber": 16,876 "HexLabel": {877 "Name": "Name",878 "Value": 16879 }880})";881 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);882}883 884TEST_F(ScopedPrinterTest, PrintHexList) {885 auto PrintFunc = [](ScopedPrinter &W) {886 const uint64_t HexList[] = {0x1, 0x10, 0x100};887 W.printHexList("HexList", HexList);888 };889 const char *ExpectedOut = R"(HexList: [0x1, 0x10, 0x100]890)";891 892 const char *JSONExpectedOut = R"({893 "HexList": [894 1,895 16,896 256897 ]898})";899 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);900}901 902TEST_F(ScopedPrinterTest, PrintSymbolOffset) {903 auto PrintFunc = [](ScopedPrinter &W) {904 W.printSymbolOffset("SymbolOffset", "SymbolName", 0x10);905 W.printSymbolOffset("NoSymbolOffset", "SymbolName", 0);906 };907 const char *ExpectedOut = R"(SymbolOffset: SymbolName+0x10908NoSymbolOffset: SymbolName+0x0909)";910 911 const char *JSONExpectedOut = R"({912 "SymbolOffset": {913 "SymName": "SymbolName",914 "Offset": 16915 },916 "NoSymbolOffset": {917 "SymName": "SymbolName",918 "Offset": 0919 }920})";921 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);922}923 924TEST_F(ScopedPrinterTest, PrintString) {925 auto PrintFunc = [](ScopedPrinter &W) {926 const StringRef StringRefValue("Value");927 const std::string StringValue = "Value";928 const char *CharArrayValue = "Value";929 W.printString("StringRef", StringRefValue);930 W.printString("String", StringValue);931 W.printString("CharArray", CharArrayValue);932 ListScope L(W, "StringList");933 W.printString(StringRefValue);934 };935 936 const char *ExpectedOut = R"(StringRef: Value937String: Value938CharArray: Value939StringList [940 Value941]942)";943 944 const char *JSONExpectedOut = R"({945 "StringRef": "Value",946 "String": "Value",947 "CharArray": "Value",948 "StringList": [949 "Value"950 ]951})";952 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);953}954 955TEST_F(ScopedPrinterTest, PrintBinary) {956 auto PrintFunc = [](ScopedPrinter &W) {957 std::vector<uint8_t> IntArray = {70, 111, 111, 66, 97, 114};958 std::vector<char> CharArray = {'F', 'o', 'o', 'B', 'a', 'r'};959 std::vector<uint8_t> InvalidChars = {255, 255};960 W.printBinary("Binary1", "FooBar", IntArray);961 W.printBinary("Binary2", "FooBar", CharArray);962 W.printBinary("Binary3", IntArray);963 W.printBinary("Binary4", CharArray);964 W.printBinary("Binary5", StringRef("FooBar"));965 W.printBinary("Binary6", StringRef("Multiple Line FooBar"));966 W.printBinaryBlock("Binary7", IntArray, 20);967 W.printBinaryBlock("Binary8", IntArray);968 W.printBinaryBlock("Binary9", "FooBar");969 W.printBinaryBlock("Binary10", "Multiple Line FooBar");970 W.printBinaryBlock("Binary11", InvalidChars);971 };972 973 const char *ExpectedOut = R"(Binary1: FooBar (46 6F 6F 42 61 72)974Binary2: FooBar (46 6F 6F 42 61 72)975Binary3: (46 6F 6F 42 61 72)976Binary4: (46 6F 6F 42 61 72)977Binary5: (46 6F 6F 42 61 72)978Binary6 (979 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|980 0010: 6F426172 |oBar|981)982Binary7 (983 0014: 466F6F42 6172 |FooBar|984)985Binary8 (986 0000: 466F6F42 6172 |FooBar|987)988Binary9 (989 0000: 466F6F42 6172 |FooBar|990)991Binary10 (992 0000: 4D756C74 69706C65 204C696E 6520466F |Multiple Line Fo|993 0010: 6F426172 |oBar|994)995Binary11 (996 0000: FFFF |..|997)998)";999 1000 const char *JSONExpectedOut = R"({1001 "Binary1": {1002 "Value": "FooBar",1003 "Offset": 0,1004 "Bytes": [1005 70,1006 111,1007 111,1008 66,1009 97,1010 1141011 ]1012 },1013 "Binary2": {1014 "Value": "FooBar",1015 "Offset": 0,1016 "Bytes": [1017 70,1018 111,1019 111,1020 66,1021 97,1022 1141023 ]1024 },1025 "Binary3": {1026 "Offset": 0,1027 "Bytes": [1028 70,1029 111,1030 111,1031 66,1032 97,1033 1141034 ]1035 },1036 "Binary4": {1037 "Offset": 0,1038 "Bytes": [1039 70,1040 111,1041 111,1042 66,1043 97,1044 1141045 ]1046 },1047 "Binary5": {1048 "Offset": 0,1049 "Bytes": [1050 70,1051 111,1052 111,1053 66,1054 97,1055 1141056 ]1057 },1058 "Binary6": {1059 "Offset": 0,1060 "Bytes": [1061 77,1062 117,1063 108,1064 116,1065 105,1066 112,1067 108,1068 101,1069 32,1070 76,1071 105,1072 110,1073 101,1074 32,1075 70,1076 111,1077 111,1078 66,1079 97,1080 1141081 ]1082 },1083 "Binary7": {1084 "Offset": 20,1085 "Bytes": [1086 70,1087 111,1088 111,1089 66,1090 97,1091 1141092 ]1093 },1094 "Binary8": {1095 "Offset": 0,1096 "Bytes": [1097 70,1098 111,1099 111,1100 66,1101 97,1102 1141103 ]1104 },1105 "Binary9": {1106 "Offset": 0,1107 "Bytes": [1108 70,1109 111,1110 111,1111 66,1112 97,1113 1141114 ]1115 },1116 "Binary10": {1117 "Offset": 0,1118 "Bytes": [1119 77,1120 117,1121 108,1122 116,1123 105,1124 112,1125 108,1126 101,1127 32,1128 76,1129 105,1130 110,1131 101,1132 32,1133 70,1134 111,1135 111,1136 66,1137 97,1138 1141139 ]1140 },1141 "Binary11": {1142 "Offset": 0,1143 "Bytes": [1144 255,1145 2551146 ]1147 }1148})";1149 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);1150}1151 1152TEST_F(ScopedPrinterTest, PrintObject) {1153 auto PrintFunc = [](ScopedPrinter &W) { W.printObject("Object", "Value"); };1154 1155 const char *ExpectedOut = R"(Object: Value1156)";1157 1158 const char *JSONExpectedOut = R"({1159 "Object": "Value"1160})";1161 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);1162}1163 1164TEST_F(ScopedPrinterTest, StartLine) {1165 auto PrintFunc = [](ScopedPrinter &W) {1166 W.startLine() << "|";1167 W.indent(2);1168 W.startLine() << "|";1169 W.unindent();1170 W.startLine() << "|";1171 };1172 1173 const char *ExpectedOut = "| | |";1174 verifyScopedPrinter(ExpectedOut, PrintFunc);1175}1176 1177TEST_F(ScopedPrinterTest, GetOStream) {1178 auto PrintFunc = [](ScopedPrinter &W) { W.getOStream() << "Test"; };1179 1180 const char *ExpectedOut = "Test";1181 verifyScopedPrinter(ExpectedOut, PrintFunc);1182}1183 1184TEST_F(ScopedPrinterTest, PrintScope) {1185 auto PrintFunc = [](ScopedPrinter &W) {1186 {1187 DictScope O(W, "Object");1188 { DictScope OO(W, "ObjectInObject"); }1189 { ListScope LO(W, "ListInObject"); }1190 }1191 {1192 ListScope L(W, "List");1193 { DictScope OL(W, "ObjectInList"); }1194 { ListScope LL(W, "ListInList"); }1195 }1196 };1197 1198 const char *ExpectedOut = R"(Object {1199 ObjectInObject {1200 }1201 ListInObject [1202 ]1203}1204List [1205 ObjectInList {1206 }1207 ListInList [1208 ]1209]1210)";1211 1212 const char *JSONExpectedOut = R"({1213 "Object": {1214 "ObjectInObject": {},1215 "ListInObject": []1216 },1217 "List": [1218 {1219 "ObjectInList": {}1220 },1221 {1222 "ListInList": []1223 }1224 ]1225})";1226 verifyAll(ExpectedOut, JSONExpectedOut, PrintFunc);1227}1228