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