diff tools/llvm-readobj/StreamWriter.h @ 0:95c75e76d11b LLVM3.4

LLVM 3.4
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Thu, 12 Dec 2013 13:56:28 +0900
parents
children 54457678186b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/llvm-readobj/StreamWriter.h	Thu Dec 12 13:56:28 2013 +0900
@@ -0,0 +1,282 @@
+//===-- StreamWriter.h ----------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_READOBJ_STREAMWRITER_H
+#define LLVM_READOBJ_STREAMWRITER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+using namespace llvm;
+using namespace llvm::support;
+
+namespace llvm {
+
+template<typename T>
+struct EnumEntry {
+  StringRef Name;
+  T Value;
+};
+
+struct HexNumber {
+  // To avoid sign-extension we have to explicitly cast to the appropriate
+  // unsigned type. The overloads are here so that every type that is implicitly
+  // convertible to an integer (including enums and endian helpers) can be used
+  // without requiring type traits or call-site changes.
+  HexNumber(int8_t   Value) : Value(static_cast<uint8_t >(Value)) { }
+  HexNumber(int16_t  Value) : Value(static_cast<uint16_t>(Value)) { }
+  HexNumber(int32_t  Value) : Value(static_cast<uint32_t>(Value)) { }
+  HexNumber(int64_t  Value) : Value(static_cast<uint64_t>(Value)) { }
+  HexNumber(uint8_t  Value) : Value(Value) { }
+  HexNumber(uint16_t Value) : Value(Value) { }
+  HexNumber(uint32_t Value) : Value(Value) { }
+  HexNumber(uint64_t Value) : Value(Value) { }
+  uint64_t Value;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);
+
+class StreamWriter {
+public:
+  StreamWriter(raw_ostream &OS)
+    : OS(OS)
+    , IndentLevel(0) {
+  }
+
+  void flush() {
+    OS.flush();
+  }
+
+  void indent(int Levels = 1) {
+    IndentLevel += Levels;
+  }
+
+  void unindent(int Levels = 1) {
+    IndentLevel = std::max(0, IndentLevel - Levels);
+  }
+
+  void printIndent() {
+    for (int i = 0; i < IndentLevel; ++i)
+      OS << "  ";
+  }
+
+  template<typename T>
+  HexNumber hex(T Value) {
+    return HexNumber(Value);
+  }
+
+  template<typename T, typename TEnum>
+  void printEnum(StringRef Label, T Value,
+                 ArrayRef<EnumEntry<TEnum> > EnumValues) {
+    StringRef Name;
+    bool Found = false;
+    for (size_t i = 0; i < EnumValues.size(); ++i) {
+      if (EnumValues[i].Value == Value) {
+        Name = EnumValues[i].Name;
+        Found = true;
+        break;
+      }
+    }
+
+    if (Found) {
+      startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
+    } else {
+      startLine() << Label << ": " << hex(Value) << "\n";
+    }
+  }
+
+  template<typename T, typename TFlag>
+  void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag> > Flags,
+                  TFlag EnumMask = TFlag(0)) {
+    typedef EnumEntry<TFlag> FlagEntry;
+    typedef SmallVector<FlagEntry, 10> FlagVector;
+    FlagVector SetFlags;
+
+    for (typename ArrayRef<FlagEntry>::const_iterator I = Flags.begin(),
+                                                 E = Flags.end(); I != E; ++I) {
+      if (I->Value == 0)
+        continue;
+
+      bool IsEnum = (I->Value & EnumMask) != 0;
+      if ((!IsEnum && (Value & I->Value) == I->Value) ||
+          (IsEnum  && (Value & EnumMask) == I->Value)) {
+        SetFlags.push_back(*I);
+      }
+    }
+
+    std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
+
+    startLine() << Label << " [ (" << hex(Value) << ")\n";
+    for (typename FlagVector::const_iterator I = SetFlags.begin(),
+                                             E = SetFlags.end();
+                                             I != E; ++I) {
+      startLine() << "  " << I->Name << " (" << hex(I->Value) << ")\n";
+    }
+    startLine() << "]\n";
+  }
+
+  template<typename T>
+  void printFlags(StringRef Label, T Value) {
+    startLine() << Label << " [ (" << hex(Value) << ")\n";
+    uint64_t Flag = 1;
+    uint64_t Curr = Value;
+    while (Curr > 0) {
+      if (Curr & 1)
+        startLine() << "  " << hex(Flag) << "\n";
+      Curr >>= 1;
+      Flag <<= 1;
+    }
+    startLine() << "]\n";
+  }
+
+  void printNumber(StringRef Label, uint64_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, uint32_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, uint16_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, uint8_t Value) {
+    startLine() << Label << ": " << unsigned(Value) << "\n";
+  }
+
+  void printNumber(StringRef Label, int64_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, int32_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, int16_t Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printNumber(StringRef Label, int8_t Value) {
+    startLine() << Label << ": " << int(Value) << "\n";
+  }
+
+  template<typename T>
+  void printHex(StringRef Label, T Value) {
+    startLine() << Label << ": " << hex(Value) << "\n";
+  }
+
+  template<typename T>
+  void printHex(StringRef Label, StringRef Str, T Value) {
+    startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
+  }
+
+  void printString(StringRef Label, StringRef Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  void printString(StringRef Label, const std::string &Value) {
+    startLine() << Label << ": " << Value << "\n";
+  }
+
+  template<typename T>
+  void printNumber(StringRef Label, StringRef Str, T Value) {
+    startLine() << Label << ": " << Str << " (" << Value << ")\n";
+  }
+
+  void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
+    printBinaryImpl(Label, Str, Value, false);
+  }
+
+  void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
+    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
+                        Value.size());
+    printBinaryImpl(Label, Str, V, false);
+  }
+
+  void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
+    printBinaryImpl(Label, StringRef(), Value, false);
+  }
+
+  void printBinary(StringRef Label, ArrayRef<char> Value) {
+    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
+                        Value.size());
+    printBinaryImpl(Label, StringRef(), V, false);
+  }
+
+  void printBinary(StringRef Label, StringRef Value) {
+    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
+                        Value.size());
+    printBinaryImpl(Label, StringRef(), V, false);
+  }
+
+  void printBinaryBlock(StringRef Label, StringRef Value) {
+    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
+                        Value.size());
+    printBinaryImpl(Label, StringRef(), V, true);
+  }
+
+  raw_ostream& startLine() {
+    printIndent();
+    return OS;
+  }
+
+  raw_ostream& getOStream() {
+    return OS;
+  }
+
+private:
+  template<typename T>
+  static bool flagName(const EnumEntry<T>& lhs, const EnumEntry<T>& rhs) {
+    return lhs.Name < rhs.Name;
+  }
+
+  void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
+                       bool Block);
+
+  raw_ostream &OS;
+  int IndentLevel;
+};
+
+struct DictScope {
+  DictScope(StreamWriter& W, StringRef N) : W(W) {
+    W.startLine() << N << " {\n";
+    W.indent();
+  }
+
+  ~DictScope() {
+    W.unindent();
+    W.startLine() << "}\n";
+  }
+
+  StreamWriter& W;
+};
+
+struct ListScope {
+  ListScope(StreamWriter& W, StringRef N) : W(W) {
+    W.startLine() << N << " [\n";
+    W.indent();
+  }
+
+  ~ListScope() {
+    W.unindent();
+    W.startLine() << "]\n";
+  }
+
+  StreamWriter& W;
+};
+
+} // namespace llvm
+
+#endif