176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//===-- StreamWriter.h ----------------------------------------------------===//
276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//                     The LLVM Compiler Infrastructure
476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher// This file is distributed under the University of Illinois Open Source
676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher// License. See LICENSE.TXT for details.
776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//
876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher//===----------------------------------------------------------------------===//
976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
1276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
1376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/ADT/ArrayRef.h"
1476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/ADT/SmallVector.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringRef.h"
1676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/DataTypes.h"
1776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/Endian.h"
1876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include "llvm/Support/raw_ostream.h"
1976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#include <algorithm>
2076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
2176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherusing namespace llvm;
2276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherusing namespace llvm::support;
2376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
2476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophernamespace llvm {
2576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
2676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christophertemplate<typename T>
2776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstruct EnumEntry {
2876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StringRef Name;
2976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  T Value;
3076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
3176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
3276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstruct HexNumber {
3376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // To avoid sign-extension we have to explicitly cast to the appropriate
3476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // unsigned type. The overloads are here so that every type that is implicitly
3576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // convertible to an integer (including enums and endian helpers) can be used
3676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  // without requiring type traits or call-site changes.
3776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(int8_t   Value) : Value(static_cast<uint8_t >(Value)) { }
3876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(int16_t  Value) : Value(static_cast<uint16_t>(Value)) { }
3976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(int32_t  Value) : Value(static_cast<uint32_t>(Value)) { }
4076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(int64_t  Value) : Value(static_cast<uint64_t>(Value)) { }
4176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(uint8_t  Value) : Value(Value) { }
4276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(uint16_t Value) : Value(Value) { }
4376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(uint32_t Value) : Value(Value) { }
4476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber(uint64_t Value) : Value(Value) { }
4576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  uint64_t Value;
4676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
4776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
4876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherraw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);
4976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
5076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherclass StreamWriter {
5176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherpublic:
5276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StreamWriter(raw_ostream &OS)
5376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    : OS(OS)
5476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    , IndentLevel(0) {
5576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
5676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
5776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void flush() {
5876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    OS.flush();
5976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
6076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void indent(int Levels = 1) {
6276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    IndentLevel += Levels;
6376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
6476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void unindent(int Levels = 1) {
6676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    IndentLevel = std::max(0, IndentLevel - Levels);
6776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
6876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
6976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printIndent() {
7076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    for (int i = 0; i < IndentLevel; ++i)
7176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      OS << "  ";
7276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
7376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
7476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
7576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  HexNumber hex(T Value) {
7676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return HexNumber(Value);
7776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
7876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
7976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T, typename TEnum>
8076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printEnum(StringRef Label, T Value,
8176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                 ArrayRef<EnumEntry<TEnum> > EnumValues) {
8276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    StringRef Name;
8376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    bool Found = false;
84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &EnumItem : EnumValues) {
85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (EnumItem.Value == Value) {
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Name = EnumItem.Name;
8776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher        Found = true;
8876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher        break;
8976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      }
9076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
9176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
9276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    if (Found) {
9376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
9476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    } else {
9576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      startLine() << Label << ": " << hex(Value) << "\n";
9676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
9776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
9876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
9976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T, typename TFlag>
10076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag> > Flags,
10176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                  TFlag EnumMask = TFlag(0)) {
10276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    typedef EnumEntry<TFlag> FlagEntry;
10376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    typedef SmallVector<FlagEntry, 10> FlagVector;
10476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    FlagVector SetFlags;
10576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Flag : Flags) {
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Flag.Value == 0)
10876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher        continue;
10976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      bool IsEnum = (Flag.Value & EnumMask) != 0;
111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          (IsEnum  && (Value & EnumMask) == Flag.Value)) {
113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        SetFlags.push_back(Flag);
11476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      }
11576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
11676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
11776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
11876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
11976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << " [ (" << hex(Value) << ")\n";
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Flag : SetFlags) {
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
12276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
12376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << "]\n";
12476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
12576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
12676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
12776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printFlags(StringRef Label, T Value) {
12876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << " [ (" << hex(Value) << ")\n";
12976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    uint64_t Flag = 1;
13076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    uint64_t Curr = Value;
13176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    while (Curr > 0) {
13276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      if (Curr & 1)
13376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher        startLine() << "  " << hex(Flag) << "\n";
13476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      Curr >>= 1;
13576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher      Flag <<= 1;
13676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    }
13776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << "]\n";
13876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
13976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
14076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, uint64_t Value) {
14176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
14276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
14376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
14476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, uint32_t Value) {
14576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
14676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
14776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
14876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, uint16_t Value) {
14976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
15076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
15176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
15276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, uint8_t Value) {
15376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << unsigned(Value) << "\n";
15476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
15576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
15676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, int64_t Value) {
15776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
15876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
15976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
16076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, int32_t Value) {
16176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
16276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
16376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
16476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, int16_t Value) {
16576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
16676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
16776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
16876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, int8_t Value) {
16976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << int(Value) << "\n";
17076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
17176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
172c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  void printBoolean(StringRef Label, bool Value) {
173c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
174c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  template <typename T_>
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void printList(StringRef Label, const SmallVectorImpl<T_> &List) {
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    startLine() << Label << ": [";
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool Comma = false;
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (const auto &Item : List) {
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (Comma)
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << ", ";
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      OS << Item;
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Comma = true;
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "]\n";
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
19076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printHex(StringRef Label, T Value) {
19176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << hex(Value) << "\n";
19276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
19376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
19476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
19576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printHex(StringRef Label, StringRef Str, T Value) {
19676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
19776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
19876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
19976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printString(StringRef Label, StringRef Value) {
20076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
20176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
20276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
20376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printString(StringRef Label, const std::string &Value) {
20476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Value << "\n";
20576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
20676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
20776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
20876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printNumber(StringRef Label, StringRef Str, T Value) {
20976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    startLine() << Label << ": " << Str << " (" << Value << ")\n";
21076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
21176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
21276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
21376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, Str, Value, false);
21476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
21576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
21676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          Value.size());
21976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, Str, V, false);
22076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
22176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
22276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
22376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, StringRef(), Value, false);
22476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
22576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
22676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinary(StringRef Label, ArrayRef<char> Value) {
22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          Value.size());
22976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, StringRef(), V, false);
23076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
23176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
23276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinary(StringRef Label, StringRef Value) {
23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          Value.size());
23576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, StringRef(), V, false);
23676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
23776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
23876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinaryBlock(StringRef Label, StringRef Value) {
23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto V = makeArrayRef(reinterpret_cast<const uint8_t*>(Value.data()),
24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          Value.size());
24176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printBinaryImpl(Label, StringRef(), V, true);
24276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
24376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
24476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  raw_ostream& startLine() {
24576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    printIndent();
24676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return OS;
24776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
24876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
24976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  raw_ostream& getOStream() {
25076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return OS;
25176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
25276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
25376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherprivate:
25476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  template<typename T>
25576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  static bool flagName(const EnumEntry<T>& lhs, const EnumEntry<T>& rhs) {
25676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    return lhs.Name < rhs.Name;
25776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
25876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
25976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
26076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher                       bool Block);
26176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
26276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  raw_ostream &OS;
26376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  int IndentLevel;
26476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
26576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
26676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstruct DictScope {
26776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  DictScope(StreamWriter& W, StringRef N) : W(W) {
26876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine() << N << " {\n";
26976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.indent();
27076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
27176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
27276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ~DictScope() {
27376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.unindent();
27476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine() << "}\n";
27576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
27676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
27776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StreamWriter& W;
27876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
27976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
28076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopherstruct ListScope {
28176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ListScope(StreamWriter& W, StringRef N) : W(W) {
28276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine() << N << " [\n";
28376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.indent();
28476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
28576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
28676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  ~ListScope() {
28776e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.unindent();
28876e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher    W.startLine() << "]\n";
28976e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  }
29076e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
29176e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher  StreamWriter& W;
29276e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher};
29376e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
29476e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher} // namespace llvm
29576e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher
29676e70f340c09ba759ad96d8dfe416b64f24bc287Eric Christopher#endif
297