brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.8 KiB · 280b3ee Raw
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