Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===-- ScopedPrinter.h ----------------------------------------*- C++ -*--===//
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
#ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
10
#define LLVM_SUPPORT_SCOPEDPRINTER_H
11
 
12
#include "llvm/ADT/APSInt.h"
13
#include "llvm/ADT/ArrayRef.h"
14
#include "llvm/ADT/SmallVector.h"
15
#include "llvm/ADT/StringExtras.h"
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/Support/DataTypes.h"
18
#include "llvm/Support/Endian.h"
19
#include "llvm/Support/JSON.h"
20
#include "llvm/Support/raw_ostream.h"
21
 
22
namespace llvm {
23
 
24
template <typename T> struct EnumEntry {
25
  StringRef Name;
26
  // While Name suffices in most of the cases, in certain cases
27
  // GNU style and LLVM style of ELFDumper do not
28
  // display same string for same enum. The AltName if initialized appropriately
29
  // will hold the string that GNU style emits.
30
  // Example:
31
  // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
32
  // "Advanced Micro Devices X86-64" on GNU style
33
  StringRef AltName;
34
  T Value;
35
  constexpr EnumEntry(StringRef N, StringRef A, T V)
36
      : Name(N), AltName(A), Value(V) {}
37
  constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
38
};
39
 
40
struct HexNumber {
41
  // To avoid sign-extension we have to explicitly cast to the appropriate
42
  // unsigned type. The overloads are here so that every type that is implicitly
43
  // convertible to an integer (including enums and endian helpers) can be used
44
  // without requiring type traits or call-site changes.
45
  HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
46
  HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
47
  HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
48
  HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
49
  HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
50
  HexNumber(signed long long Value)
51
      : Value(static_cast<unsigned long long>(Value)) {}
52
  HexNumber(unsigned char Value) : Value(Value) {}
53
  HexNumber(unsigned short Value) : Value(Value) {}
54
  HexNumber(unsigned int Value) : Value(Value) {}
55
  HexNumber(unsigned long Value) : Value(Value) {}
56
  HexNumber(unsigned long long Value) : Value(Value) {}
57
  uint64_t Value;
58
};
59
 
60
struct FlagEntry {
61
  FlagEntry(StringRef Name, char Value)
62
      : Name(Name), Value(static_cast<unsigned char>(Value)) {}
63
  FlagEntry(StringRef Name, signed char Value)
64
      : Name(Name), Value(static_cast<unsigned char>(Value)) {}
65
  FlagEntry(StringRef Name, signed short Value)
66
      : Name(Name), Value(static_cast<unsigned short>(Value)) {}
67
  FlagEntry(StringRef Name, signed int Value)
68
      : Name(Name), Value(static_cast<unsigned int>(Value)) {}
69
  FlagEntry(StringRef Name, signed long Value)
70
      : Name(Name), Value(static_cast<unsigned long>(Value)) {}
71
  FlagEntry(StringRef Name, signed long long Value)
72
      : Name(Name), Value(static_cast<unsigned long long>(Value)) {}
73
  FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {}
74
  FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {}
75
  FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {}
76
  FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {}
77
  FlagEntry(StringRef Name, unsigned long long Value)
78
      : Name(Name), Value(Value) {}
79
  StringRef Name;
80
  uint64_t Value;
81
};
82
 
83
raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
84
 
85
template <class T> std::string to_string(const T &Value) {
86
  std::string number;
87
  raw_string_ostream stream(number);
88
  stream << Value;
89
  return stream.str();
90
}
91
 
92
template <typename T, typename TEnum>
93
std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
94
  for (const EnumEntry<TEnum> &EnumItem : EnumValues)
95
    if (EnumItem.Value == Value)
96
      return std::string(EnumItem.AltName);
97
  return utohexstr(Value, true);
98
}
99
 
100
class ScopedPrinter {
101
public:
102
  enum class ScopedPrinterKind {
103
    Base,
104
    JSON,
105
  };
106
 
107
  ScopedPrinter(raw_ostream &OS,
108
                ScopedPrinterKind Kind = ScopedPrinterKind::Base)
109
      : OS(OS), Kind(Kind) {}
110
 
111
  ScopedPrinterKind getKind() const { return Kind; }
112
 
113
  static bool classof(const ScopedPrinter *SP) {
114
    return SP->getKind() == ScopedPrinterKind::Base;
115
  }
116
 
117
  virtual ~ScopedPrinter() = default;
118
 
119
  void flush() { OS.flush(); }
120
 
121
  void indent(int Levels = 1) { IndentLevel += Levels; }
122
 
123
  void unindent(int Levels = 1) {
124
    IndentLevel = IndentLevel > Levels ? IndentLevel - Levels : 0;
125
  }
126
 
127
  void resetIndent() { IndentLevel = 0; }
128
 
129
  int getIndentLevel() { return IndentLevel; }
130
 
131
  void setPrefix(StringRef P) { Prefix = P; }
132
 
133
  void printIndent() {
134
    OS << Prefix;
135
    for (int i = 0; i < IndentLevel; ++i)
136
      OS << "  ";
137
  }
138
 
139
  template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
140
 
141
  template <typename T, typename TEnum>
142
  void printEnum(StringRef Label, T Value,
143
                 ArrayRef<EnumEntry<TEnum>> EnumValues) {
144
    StringRef Name;
145
    bool Found = false;
146
    for (const auto &EnumItem : EnumValues) {
147
      if (EnumItem.Value == Value) {
148
        Name = EnumItem.Name;
149
        Found = true;
150
        break;
151
      }
152
    }
153
 
154
    if (Found)
155
      printHex(Label, Name, Value);
156
    else
157
      printHex(Label, Value);
158
  }
159
 
160
  template <typename T, typename TFlag>
161
  void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
162
                  TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
163
                  TFlag EnumMask3 = {}) {
164
    SmallVector<FlagEntry, 10> SetFlags;
165
 
166
    for (const auto &Flag : Flags) {
167
      if (Flag.Value == 0)
168
        continue;
169
 
170
      TFlag EnumMask{};
171
      if (Flag.Value & EnumMask1)
172
        EnumMask = EnumMask1;
173
      else if (Flag.Value & EnumMask2)
174
        EnumMask = EnumMask2;
175
      else if (Flag.Value & EnumMask3)
176
        EnumMask = EnumMask3;
177
      bool IsEnum = (Flag.Value & EnumMask) != 0;
178
      if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
179
          (IsEnum && (Value & EnumMask) == Flag.Value)) {
180
        SetFlags.emplace_back(Flag.Name, Flag.Value);
181
      }
182
    }
183
 
184
    llvm::sort(SetFlags, &flagName);
185
    printFlagsImpl(Label, hex(Value), SetFlags);
186
  }
187
 
188
  template <typename T> void printFlags(StringRef Label, T Value) {
189
    SmallVector<HexNumber, 10> SetFlags;
190
    uint64_t Flag = 1;
191
    uint64_t Curr = Value;
192
    while (Curr > 0) {
193
      if (Curr & 1)
194
        SetFlags.emplace_back(Flag);
195
      Curr >>= 1;
196
      Flag <<= 1;
197
    }
198
    printFlagsImpl(Label, hex(Value), SetFlags);
199
  }
200
 
201
  virtual void printNumber(StringRef Label, uint64_t Value) {
202
    startLine() << Label << ": " << Value << "\n";
203
  }
204
 
205
  virtual void printNumber(StringRef Label, uint32_t Value) {
206
    startLine() << Label << ": " << Value << "\n";
207
  }
208
 
209
  virtual void printNumber(StringRef Label, uint16_t Value) {
210
    startLine() << Label << ": " << Value << "\n";
211
  }
212
 
213
  virtual void printNumber(StringRef Label, uint8_t Value) {
214
    startLine() << Label << ": " << unsigned(Value) << "\n";
215
  }
216
 
217
  virtual void printNumber(StringRef Label, int64_t Value) {
218
    startLine() << Label << ": " << Value << "\n";
219
  }
220
 
221
  virtual void printNumber(StringRef Label, int32_t Value) {
222
    startLine() << Label << ": " << Value << "\n";
223
  }
224
 
225
  virtual void printNumber(StringRef Label, int16_t Value) {
226
    startLine() << Label << ": " << Value << "\n";
227
  }
228
 
229
  virtual void printNumber(StringRef Label, int8_t Value) {
230
    startLine() << Label << ": " << int(Value) << "\n";
231
  }
232
 
233
  virtual void printNumber(StringRef Label, const APSInt &Value) {
234
    startLine() << Label << ": " << Value << "\n";
235
  }
236
 
237
  template <typename T>
238
  void printNumber(StringRef Label, StringRef Str, T Value) {
239
    printNumberImpl(Label, Str, to_string(Value));
240
  }
241
 
242
  virtual void printBoolean(StringRef Label, bool Value) {
243
    startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
244
  }
245
 
246
  template <typename... T> void printVersion(StringRef Label, T... Version) {
247
    startLine() << Label << ": ";
248
    printVersionInternal(Version...);
249
    getOStream() << "\n";
250
  }
251
 
252
  template <typename T>
253
  void printList(StringRef Label, const ArrayRef<T> List) {
254
    SmallVector<std::string, 10> StringList;
255
    for (const auto &Item : List)
256
      StringList.emplace_back(to_string(Item));
257
    printList(Label, StringList);
258
  }
259
 
260
  virtual void printList(StringRef Label, const ArrayRef<bool> List) {
261
    printListImpl(Label, List);
262
  }
263
 
264
  virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
265
    printListImpl(Label, List);
266
  }
267
 
268
  virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
269
    printListImpl(Label, List);
270
  }
271
 
272
  virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
273
    printListImpl(Label, List);
274
  }
275
 
276
  virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
277
    printListImpl(Label, List);
278
  }
279
 
280
  virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) {
281
    SmallVector<unsigned> NumberList;
282
    for (const uint8_t &Item : List)
283
      NumberList.emplace_back(Item);
284
    printListImpl(Label, NumberList);
285
  }
286
 
287
  virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
288
    printListImpl(Label, List);
289
  }
290
 
291
  virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
292
    printListImpl(Label, List);
293
  }
294
 
295
  virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
296
    printListImpl(Label, List);
297
  }
298
 
299
  virtual void printList(StringRef Label, const ArrayRef<int8_t> List) {
300
    SmallVector<int> NumberList;
301
    for (const int8_t &Item : List)
302
      NumberList.emplace_back(Item);
303
    printListImpl(Label, NumberList);
304
  }
305
 
306
  virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
307
    printListImpl(Label, List);
308
  }
309
 
310
  template <typename T, typename U>
311
  void printList(StringRef Label, const T &List, const U &Printer) {
312
    startLine() << Label << ": [";
313
    ListSeparator LS;
314
    for (const auto &Item : List) {
315
      OS << LS;
316
      Printer(OS, Item);
317
    }
318
    OS << "]\n";
319
  }
320
 
321
  template <typename T> void printHexList(StringRef Label, const T &List) {
322
    SmallVector<HexNumber> HexList;
323
    for (const auto &Item : List)
324
      HexList.emplace_back(Item);
325
    printHexListImpl(Label, HexList);
326
  }
327
 
328
  template <typename T> void printHex(StringRef Label, T Value) {
329
    printHexImpl(Label, hex(Value));
330
  }
331
 
332
  template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
333
    printHexImpl(Label, Str, hex(Value));
334
  }
335
 
336
  template <typename T>
337
  void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
338
    printSymbolOffsetImpl(Label, Symbol, hex(Value));
339
  }
340
 
341
  virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
342
 
343
  virtual void printString(StringRef Label, StringRef Value) {
344
    startLine() << Label << ": " << Value << "\n";
345
  }
346
 
347
  void printStringEscaped(StringRef Label, StringRef Value) {
348
    printStringEscapedImpl(Label, Value);
349
  }
350
 
351
  void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
352
    printBinaryImpl(Label, Str, Value, false);
353
  }
354
 
355
  void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
356
    auto V =
357
        ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
358
    printBinaryImpl(Label, Str, V, false);
359
  }
360
 
361
  void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
362
    printBinaryImpl(Label, StringRef(), Value, false);
363
  }
364
 
365
  void printBinary(StringRef Label, ArrayRef<char> Value) {
366
    auto V =
367
        ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
368
    printBinaryImpl(Label, StringRef(), V, false);
369
  }
370
 
371
  void printBinary(StringRef Label, StringRef Value) {
372
    auto V =
373
        ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
374
    printBinaryImpl(Label, StringRef(), V, false);
375
  }
376
 
377
  void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
378
                        uint32_t StartOffset) {
379
    printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
380
  }
381
 
382
  void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
383
    printBinaryImpl(Label, StringRef(), Value, true);
384
  }
385
 
386
  void printBinaryBlock(StringRef Label, StringRef Value) {
387
    auto V =
388
        ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
389
    printBinaryImpl(Label, StringRef(), V, true);
390
  }
391
 
392
  template <typename T> void printObject(StringRef Label, const T &Value) {
393
    printString(Label, to_string(Value));
394
  }
395
 
396
  virtual void objectBegin() { scopedBegin('{'); }
397
 
398
  virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
399
 
400
  virtual void objectEnd() { scopedEnd('}'); }
401
 
402
  virtual void arrayBegin() { scopedBegin('['); }
403
 
404
  virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
405
 
406
  virtual void arrayEnd() { scopedEnd(']'); }
407
 
408
  virtual raw_ostream &startLine() {
409
    printIndent();
410
    return OS;
411
  }
412
 
413
  virtual raw_ostream &getOStream() { return OS; }
414
 
415
private:
416
  template <typename T> void printVersionInternal(T Value) {
417
    getOStream() << Value;
418
  }
419
 
420
  template <typename S, typename T, typename... TArgs>
421
  void printVersionInternal(S Value, T Value2, TArgs... Args) {
422
    getOStream() << Value << ".";
423
    printVersionInternal(Value2, Args...);
424
  }
425
 
426
  static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
427
    return LHS.Name < RHS.Name;
428
  }
429
 
430
  virtual void printBinaryImpl(StringRef Label, StringRef Str,
431
                               ArrayRef<uint8_t> Value, bool Block,
432
                               uint32_t StartOffset = 0);
433
 
434
  virtual void printFlagsImpl(StringRef Label, HexNumber Value,
435
                              ArrayRef<FlagEntry> Flags) {
436
    startLine() << Label << " [ (" << Value << ")\n";
437
    for (const auto &Flag : Flags)
438
      startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
439
    startLine() << "]\n";
440
  }
441
 
442
  virtual void printFlagsImpl(StringRef Label, HexNumber Value,
443
                              ArrayRef<HexNumber> Flags) {
444
    startLine() << Label << " [ (" << Value << ")\n";
445
    for (const auto &Flag : Flags)
446
      startLine() << "  " << Flag << '\n';
447
    startLine() << "]\n";
448
  }
449
 
450
  template <typename T> void printListImpl(StringRef Label, const T List) {
451
    startLine() << Label << ": [";
452
    ListSeparator LS;
453
    for (const auto &Item : List)
454
      OS << LS << Item;
455
    OS << "]\n";
456
  }
457
 
458
  virtual void printHexListImpl(StringRef Label,
459
                                const ArrayRef<HexNumber> List) {
460
    startLine() << Label << ": [";
461
    ListSeparator LS;
462
    for (const auto &Item : List)
463
      OS << LS << hex(Item);
464
    OS << "]\n";
465
  }
466
 
467
  virtual void printHexImpl(StringRef Label, HexNumber Value) {
468
    startLine() << Label << ": " << Value << "\n";
469
  }
470
 
471
  virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
472
    startLine() << Label << ": " << Str << " (" << Value << ")\n";
473
  }
474
 
475
  virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
476
                                     HexNumber Value) {
477
    startLine() << Label << ": " << Symbol << '+' << Value << '\n';
478
  }
479
 
480
  virtual void printNumberImpl(StringRef Label, StringRef Str,
481
                               StringRef Value) {
482
    startLine() << Label << ": " << Str << " (" << Value << ")\n";
483
  }
484
 
485
  virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
486
    startLine() << Label << ": ";
487
    OS.write_escaped(Value);
488
    OS << '\n';
489
  }
490
 
491
  void scopedBegin(char Symbol) {
492
    startLine() << Symbol << '\n';
493
    indent();
494
  }
495
 
496
  void scopedBegin(StringRef Label, char Symbol) {
497
    startLine() << Label;
498
    if (!Label.empty())
499
      OS << ' ';
500
    OS << Symbol << '\n';
501
    indent();
502
  }
503
 
504
  void scopedEnd(char Symbol) {
505
    unindent();
506
    startLine() << Symbol << '\n';
507
  }
508
 
509
  raw_ostream &OS;
510
  int IndentLevel = 0;
511
  StringRef Prefix;
512
  ScopedPrinterKind Kind;
513
};
514
 
515
template <>
516
inline void
517
ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
518
                                              support::ulittle16_t Value) {
519
  startLine() << Label << ": " << hex(Value) << "\n";
520
}
521
 
522
struct DelimitedScope;
523
 
524
class JSONScopedPrinter : public ScopedPrinter {
525
private:
526
  enum class Scope {
527
    Array,
528
    Object,
529
  };
530
 
531
  enum class ScopeKind {
532
    NoAttribute,
533
    Attribute,
534
    NestedAttribute,
535
  };
536
 
537
  struct ScopeContext {
538
    Scope Context;
539
    ScopeKind Kind;
540
    ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
541
        : Context(Context), Kind(Kind) {}
542
  };
543
 
544
  SmallVector<ScopeContext, 8> ScopeHistory;
545
  json::OStream JOS;
546
  std::unique_ptr<DelimitedScope> OuterScope;
547
 
548
public:
549
  JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
550
                    std::unique_ptr<DelimitedScope> &&OuterScope =
551
                        std::unique_ptr<DelimitedScope>{});
552
 
553
  static bool classof(const ScopedPrinter *SP) {
554
    return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
555
  }
556
 
557
  void printNumber(StringRef Label, uint64_t Value) override {
558
    JOS.attribute(Label, Value);
559
  }
560
 
561
  void printNumber(StringRef Label, uint32_t Value) override {
562
    JOS.attribute(Label, Value);
563
  }
564
 
565
  void printNumber(StringRef Label, uint16_t Value) override {
566
    JOS.attribute(Label, Value);
567
  }
568
 
569
  void printNumber(StringRef Label, uint8_t Value) override {
570
    JOS.attribute(Label, Value);
571
  }
572
 
573
  void printNumber(StringRef Label, int64_t Value) override {
574
    JOS.attribute(Label, Value);
575
  }
576
 
577
  void printNumber(StringRef Label, int32_t Value) override {
578
    JOS.attribute(Label, Value);
579
  }
580
 
581
  void printNumber(StringRef Label, int16_t Value) override {
582
    JOS.attribute(Label, Value);
583
  }
584
 
585
  void printNumber(StringRef Label, int8_t Value) override {
586
    JOS.attribute(Label, Value);
587
  }
588
 
589
  void printNumber(StringRef Label, const APSInt &Value) override {
590
    JOS.attributeBegin(Label);
591
    printAPSInt(Value);
592
    JOS.attributeEnd();
593
  }
594
 
595
  void printBoolean(StringRef Label, bool Value) override {
596
    JOS.attribute(Label, Value);
597
  }
598
 
599
  void printList(StringRef Label, const ArrayRef<bool> List) override {
600
    printListImpl(Label, List);
601
  }
602
 
603
  void printList(StringRef Label, const ArrayRef<std::string> List) override {
604
    printListImpl(Label, List);
605
  }
606
 
607
  void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
608
    printListImpl(Label, List);
609
  }
610
 
611
  void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
612
    printListImpl(Label, List);
613
  }
614
 
615
  void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
616
    printListImpl(Label, List);
617
  }
618
 
619
  void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
620
    printListImpl(Label, List);
621
  }
622
 
623
  void printList(StringRef Label, const ArrayRef<int64_t> List) override {
624
    printListImpl(Label, List);
625
  }
626
 
627
  void printList(StringRef Label, const ArrayRef<int32_t> List) override {
628
    printListImpl(Label, List);
629
  }
630
 
631
  void printList(StringRef Label, const ArrayRef<int16_t> List) override {
632
    printListImpl(Label, List);
633
  }
634
 
635
  void printList(StringRef Label, const ArrayRef<int8_t> List) override {
636
    printListImpl(Label, List);
637
  }
638
 
639
  void printList(StringRef Label, const ArrayRef<APSInt> List) override {
640
    JOS.attributeArray(Label, [&]() {
641
      for (const APSInt &Item : List) {
642
        printAPSInt(Item);
643
      }
644
    });
645
  }
646
 
647
  void printString(StringRef Value) override { JOS.value(Value); }
648
 
649
  void printString(StringRef Label, StringRef Value) override {
650
    JOS.attribute(Label, Value);
651
  }
652
 
653
  void objectBegin() override {
654
    scopedBegin({Scope::Object, ScopeKind::NoAttribute});
655
  }
656
 
657
  void objectBegin(StringRef Label) override {
658
    scopedBegin(Label, Scope::Object);
659
  }
660
 
661
  void objectEnd() override { scopedEnd(); }
662
 
663
  void arrayBegin() override {
664
    scopedBegin({Scope::Array, ScopeKind::NoAttribute});
665
  }
666
 
667
  void arrayBegin(StringRef Label) override {
668
    scopedBegin(Label, Scope::Array);
669
  }
670
 
671
  void arrayEnd() override { scopedEnd(); }
672
 
673
private:
674
  // Output HexNumbers as decimals so that they're easier to parse.
675
  uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
676
 
677
  void printAPSInt(const APSInt &Value) {
678
    JOS.rawValueBegin() << Value;
679
    JOS.rawValueEnd();
680
  }
681
 
682
  void printFlagsImpl(StringRef Label, HexNumber Value,
683
                      ArrayRef<FlagEntry> Flags) override {
684
    JOS.attributeObject(Label, [&]() {
685
      JOS.attribute("RawFlags", hexNumberToInt(Value));
686
      JOS.attributeArray("Flags", [&]() {
687
        for (const FlagEntry &Flag : Flags) {
688
          JOS.objectBegin();
689
          JOS.attribute("Name", Flag.Name);
690
          JOS.attribute("Value", Flag.Value);
691
          JOS.objectEnd();
692
        }
693
      });
694
    });
695
  }
696
 
697
  void printFlagsImpl(StringRef Label, HexNumber Value,
698
                      ArrayRef<HexNumber> Flags) override {
699
    JOS.attributeObject(Label, [&]() {
700
      JOS.attribute("RawFlags", hexNumberToInt(Value));
701
      JOS.attributeArray("Flags", [&]() {
702
        for (const HexNumber &Flag : Flags) {
703
          JOS.value(Flag.Value);
704
        }
705
      });
706
    });
707
  }
708
 
709
  template <typename T> void printListImpl(StringRef Label, const T &List) {
710
    JOS.attributeArray(Label, [&]() {
711
      for (const auto &Item : List)
712
        JOS.value(Item);
713
    });
714
  }
715
 
716
  void printHexListImpl(StringRef Label,
717
                        const ArrayRef<HexNumber> List) override {
718
    JOS.attributeArray(Label, [&]() {
719
      for (const HexNumber &Item : List) {
720
        JOS.value(hexNumberToInt(Item));
721
      }
722
    });
723
  }
724
 
725
  void printHexImpl(StringRef Label, HexNumber Value) override {
726
    JOS.attribute(Label, hexNumberToInt(Value));
727
  }
728
 
729
  void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
730
    JOS.attributeObject(Label, [&]() {
731
      JOS.attribute("Value", Str);
732
      JOS.attribute("RawValue", hexNumberToInt(Value));
733
    });
734
  }
735
 
736
  void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
737
                             HexNumber Value) override {
738
    JOS.attributeObject(Label, [&]() {
739
      JOS.attribute("SymName", Symbol);
740
      JOS.attribute("Offset", hexNumberToInt(Value));
741
    });
742
  }
743
 
744
  void printNumberImpl(StringRef Label, StringRef Str,
745
                       StringRef Value) override {
746
    JOS.attributeObject(Label, [&]() {
747
      JOS.attribute("Value", Str);
748
      JOS.attributeBegin("RawValue");
749
      JOS.rawValueBegin() << Value;
750
      JOS.rawValueEnd();
751
      JOS.attributeEnd();
752
    });
753
  }
754
 
755
  void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
756
                       bool Block, uint32_t StartOffset = 0) override {
757
    JOS.attributeObject(Label, [&]() {
758
      if (!Str.empty())
759
        JOS.attribute("Value", Str);
760
      JOS.attribute("Offset", StartOffset);
761
      JOS.attributeArray("Bytes", [&]() {
762
        for (uint8_t Val : Value)
763
          JOS.value(Val);
764
      });
765
    });
766
  }
767
 
768
  void scopedBegin(ScopeContext ScopeCtx) {
769
    if (ScopeCtx.Context == Scope::Object)
770
      JOS.objectBegin();
771
    else if (ScopeCtx.Context == Scope::Array)
772
      JOS.arrayBegin();
773
    ScopeHistory.push_back(ScopeCtx);
774
  }
775
 
776
  void scopedBegin(StringRef Label, Scope Ctx) {
777
    ScopeKind Kind = ScopeKind::Attribute;
778
    if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
779
      JOS.objectBegin();
780
      Kind = ScopeKind::NestedAttribute;
781
    }
782
    JOS.attributeBegin(Label);
783
    scopedBegin({Ctx, Kind});
784
  }
785
 
786
  void scopedEnd() {
787
    ScopeContext ScopeCtx = ScopeHistory.back();
788
    if (ScopeCtx.Context == Scope::Object)
789
      JOS.objectEnd();
790
    else if (ScopeCtx.Context == Scope::Array)
791
      JOS.arrayEnd();
792
    if (ScopeCtx.Kind == ScopeKind::Attribute ||
793
        ScopeCtx.Kind == ScopeKind::NestedAttribute)
794
      JOS.attributeEnd();
795
    if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
796
      JOS.objectEnd();
797
    ScopeHistory.pop_back();
798
  }
799
};
800
 
801
struct DelimitedScope {
802
  DelimitedScope(ScopedPrinter &W) : W(&W) {}
803
  DelimitedScope() : W(nullptr) {}
804
  virtual ~DelimitedScope() = default;
805
  virtual void setPrinter(ScopedPrinter &W) = 0;
806
  ScopedPrinter *W;
807
};
808
 
809
struct DictScope : DelimitedScope {
810
  explicit DictScope() = default;
811
  explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
812
 
813
  DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
814
    W.objectBegin(N);
815
  }
816
 
817
  void setPrinter(ScopedPrinter &W) override {
818
    this->W = &W;
819
    W.objectBegin();
820
  }
821
 
822
  ~DictScope() {
823
    if (W)
824
      W->objectEnd();
825
  }
826
};
827
 
828
struct ListScope : DelimitedScope {
829
  explicit ListScope() = default;
830
  explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
831
 
832
  ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
833
    W.arrayBegin(N);
834
  }
835
 
836
  void setPrinter(ScopedPrinter &W) override {
837
    this->W = &W;
838
    W.arrayBegin();
839
  }
840
 
841
  ~ListScope() {
842
    if (W)
843
      W->arrayEnd();
844
  }
845
};
846
 
847
} // namespace llvm
848
 
849
#endif