LCOV - code coverage report
Current view: top level - include/llvm/Support - ScopedPrinter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 152 152 100.0 %
Date: 2017-09-14 15:23:50 Functions: 120 130 92.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ScopedPrinter.h ---------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
      11             : #define LLVM_SUPPORT_SCOPEDPRINTER_H
      12             : 
      13             : #include "llvm/ADT/APSInt.h"
      14             : #include "llvm/ADT/ArrayRef.h"
      15             : #include "llvm/ADT/SmallVector.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/Support/DataTypes.h"
      18             : #include "llvm/Support/Endian.h"
      19             : #include "llvm/Support/raw_ostream.h"
      20             : #include <algorithm>
      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      472950 :   EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
      36    65904512 :   EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
      37             : };
      38             : 
      39             : struct HexNumber {
      40             :   // To avoid sign-extension we have to explicitly cast to the appropriate
      41             :   // unsigned type. The overloads are here so that every type that is implicitly
      42             :   // convertible to an integer (including enums and endian helpers) can be used
      43             :   // without requiring type traits or call-site changes.
      44             :   HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
      45             :   HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
      46             :   HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
      47        1434 :   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
      48           5 :   HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
      49             :   HexNumber(signed long long Value)
      50             :       : Value(static_cast<unsigned long long>(Value)) {}
      51       15293 :   HexNumber(unsigned char Value) : Value(Value) {}
      52        3338 :   HexNumber(unsigned short Value) : Value(Value) {}
      53      181607 :   HexNumber(unsigned int Value) : Value(Value) {}
      54             :   HexNumber(unsigned long Value) : Value(Value) {}
      55             :   HexNumber(unsigned long long Value) : Value(Value) {}
      56             :   uint64_t Value;
      57             : };
      58             : 
      59             : raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
      60             : const std::string to_hexString(uint64_t Value, bool UpperCase = true);
      61             : 
      62      102993 : template <class T> const std::string to_string(const T &Value) {
      63      205986 :   std::string number;
      64      205986 :   llvm::raw_string_ostream stream(number);
      65      110655 :   stream << Value;
      66      308979 :   return stream.str();
      67             : }
      68             : 
      69             : class ScopedPrinter {
      70             : public:
      71        4526 :   ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
      72             : 
      73        1916 :   void flush() { OS.flush(); }
      74             : 
      75      158060 :   void indent(int Levels = 1) { IndentLevel += Levels; }
      76             : 
      77             :   void unindent(int Levels = 1) {
      78      316082 :     IndentLevel = std::max(0, IndentLevel - Levels);
      79             :   }
      80             : 
      81             :   void resetIndent() { IndentLevel = 0; }
      82             : 
      83         212 :   void setPrefix(StringRef P) { Prefix = P; }
      84             : 
      85     2060750 :   void printIndent() {
      86     2060750 :     OS << Prefix;
      87     5927540 :     for (int i = 0; i < IndentLevel; ++i)
      88     3866790 :       OS << "  ";
      89     2060750 :   }
      90             : 
      91      777760 :   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
      92             : 
      93             :   template <typename T, typename TEnum>
      94       26377 :   void printEnum(StringRef Label, T Value,
      95             :                  ArrayRef<EnumEntry<TEnum>> EnumValues) {
      96             :     StringRef Name;
      97       26377 :     bool Found = false;
      98      449421 :     for (const auto &EnumItem : EnumValues) {
      99      429144 :       if (EnumItem.Value == Value) {
     100       25793 :         Name = EnumItem.Name;
     101       25793 :         Found = true;
     102             :         break;
     103             :       }
     104             :     }
     105             : 
     106             :     if (Found) {
     107       51586 :       startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
     108             :     } else {
     109        1168 :       startLine() << Label << ": " << hex(Value) << "\n";
     110             :     }
     111       26377 :   }
     112             : 
     113             :   template <typename T, typename TFlag>
     114      138320 :   void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
     115             :                   TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
     116             :                   TFlag EnumMask3 = {}) {
     117             :     typedef EnumEntry<TFlag> FlagEntry;
     118             :     typedef SmallVector<FlagEntry, 10> FlagVector;
     119      276640 :     FlagVector SetFlags;
     120             : 
     121     2348489 :     for (const auto &Flag : Flags) {
     122     2071849 :       if (Flag.Value == 0)
     123         113 :         continue;
     124             : 
     125     2071736 :       TFlag EnumMask{};
     126     2071736 :       if (Flag.Value & EnumMask1)
     127             :         EnumMask = EnumMask1;
     128     2064428 :       else if (Flag.Value & EnumMask2)
     129             :         EnumMask = EnumMask2;
     130     2063976 :       else if (Flag.Value & EnumMask3)
     131        2034 :         EnumMask = EnumMask3;
     132     2071736 :       bool IsEnum = (Flag.Value & EnumMask) != 0;
     133     4115806 :       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
     134        9794 :           (IsEnum && (Value & EnumMask) == Flag.Value)) {
     135        8695 :         SetFlags.push_back(Flag);
     136             :       }
     137             :     }
     138             : 
     139      414960 :     std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
     140             : 
     141      276640 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     142      423655 :     for (const auto &Flag : SetFlags) {
     143       17390 :       startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
     144             :     }
     145      138320 :     startLine() << "]\n";
     146      138320 :   }
     147             : 
     148          77 :   template <typename T> void printFlags(StringRef Label, T Value) {
     149         154 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     150          77 :     uint64_t Flag = 1;
     151          77 :     uint64_t Curr = Value;
     152         215 :     while (Curr > 0) {
     153          69 :       if (Curr & 1)
     154          20 :         startLine() << "  " << hex(Flag) << "\n";
     155          69 :       Curr >>= 1;
     156          69 :       Flag <<= 1;
     157             :     }
     158          77 :     startLine() << "]\n";
     159          77 :   }
     160             : 
     161      403743 :   void printNumber(StringRef Label, uint64_t Value) {
     162      403743 :     startLine() << Label << ": " << Value << "\n";
     163      403743 :   }
     164             : 
     165      283711 :   void printNumber(StringRef Label, uint32_t Value) {
     166      567422 :     startLine() << Label << ": " << Value << "\n";
     167      283711 :   }
     168             : 
     169        5734 :   void printNumber(StringRef Label, uint16_t Value) {
     170       11468 :     startLine() << Label << ": " << Value << "\n";
     171        5734 :   }
     172             : 
     173        1321 :   void printNumber(StringRef Label, uint8_t Value) {
     174        2642 :     startLine() << Label << ": " << unsigned(Value) << "\n";
     175        1321 :   }
     176             : 
     177         162 :   void printNumber(StringRef Label, int64_t Value) {
     178         162 :     startLine() << Label << ": " << Value << "\n";
     179         162 :   }
     180             : 
     181      139536 :   void printNumber(StringRef Label, int32_t Value) {
     182      279072 :     startLine() << Label << ": " << Value << "\n";
     183      139536 :   }
     184             : 
     185             :   void printNumber(StringRef Label, int16_t Value) {
     186             :     startLine() << Label << ": " << Value << "\n";
     187             :   }
     188             : 
     189             :   void printNumber(StringRef Label, int8_t Value) {
     190             :     startLine() << Label << ": " << int(Value) << "\n";
     191             :   }
     192             : 
     193        6036 :   void printNumber(StringRef Label, const APSInt &Value) {
     194       12072 :     startLine() << Label << ": " << Value << "\n";
     195        6036 :   }
     196             : 
     197         474 :   void printBoolean(StringRef Label, bool Value) {
     198         948 :     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
     199         474 :   }
     200             : 
     201             :   template <typename... T> void printVersion(StringRef Label, T... Version) {
     202             :     startLine() << Label << ": ";
     203             :     printVersionInternal(Version...);
     204             :     getOStream() << "\n";
     205             :   }
     206             : 
     207          12 :   template <typename T> void printList(StringRef Label, const T &List) {
     208          12 :     startLine() << Label << ": [";
     209          12 :     bool Comma = false;
     210          63 :     for (const auto &Item : List) {
     211          39 :       if (Comma)
     212          28 :         OS << ", ";
     213         117 :       OS << Item;
     214          39 :       Comma = true;
     215             :     }
     216          12 :     OS << "]\n";
     217          12 :   }
     218             : 
     219             :   template <typename T, typename U>
     220             :   void printList(StringRef Label, const T &List, const U &Printer) {
     221             :     startLine() << Label << ": [";
     222             :     bool Comma = false;
     223             :     for (const auto &Item : List) {
     224             :       if (Comma)
     225             :         OS << ", ";
     226             :       Printer(OS, Item);
     227             :       Comma = true;
     228             :     }
     229             :     OS << "]\n";
     230             :   }
     231             : 
     232          16 :   template <typename T> void printHexList(StringRef Label, const T &List) {
     233          16 :     startLine() << Label << ": [";
     234          16 :     bool Comma = false;
     235          63 :     for (const auto &Item : List) {
     236          31 :       if (Comma)
     237          16 :         OS << ", ";
     238          62 :       OS << hex(Item);
     239          31 :       Comma = true;
     240             :     }
     241          16 :     OS << "]\n";
     242          16 :   }
     243             : 
     244      288077 :   template <typename T> void printHex(StringRef Label, T Value) {
     245      576154 :     startLine() << Label << ": " << hex(Value) << "\n";
     246      288077 :   }
     247             : 
     248      142172 :   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
     249      284344 :     startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
     250      142172 :   }
     251             : 
     252             :   template <typename T>
     253         286 :   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
     254        1144 :     startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
     255         286 :   }
     256             : 
     257          56 :   void printString(StringRef Value) { startLine() << Value << "\n"; }
     258             : 
     259       10967 :   void printString(StringRef Label, StringRef Value) {
     260       10967 :     startLine() << Label << ": " << Value << "\n";
     261       10967 :   }
     262             : 
     263         538 :   void printString(StringRef Label, const std::string &Value) {
     264        1076 :     startLine() << Label << ": " << Value << "\n";
     265         538 :   }
     266             : 
     267             :   template <typename T>
     268      140055 :   void printNumber(StringRef Label, StringRef Str, T Value) {
     269      417594 :     startLine() << Label << ": " << Str << " (" << Value << ")\n";
     270      140055 :   }
     271             : 
     272             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
     273             :     printBinaryImpl(Label, Str, Value, false);
     274             :   }
     275             : 
     276             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
     277        1136 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     278        2272 :                           Value.size());
     279        1136 :     printBinaryImpl(Label, Str, V, false);
     280             :   }
     281             : 
     282             :   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
     283         470 :     printBinaryImpl(Label, StringRef(), Value, false);
     284             :   }
     285             : 
     286             :   void printBinary(StringRef Label, ArrayRef<char> Value) {
     287             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     288             :                           Value.size());
     289             :     printBinaryImpl(Label, StringRef(), V, false);
     290             :   }
     291             : 
     292             :   void printBinary(StringRef Label, StringRef Value) {
     293             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     294             :                           Value.size());
     295             :     printBinaryImpl(Label, StringRef(), V, false);
     296             :   }
     297             : 
     298             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
     299             :                         uint32_t StartOffset) {
     300             :     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
     301             :   }
     302             : 
     303             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
     304           1 :     printBinaryImpl(Label, StringRef(), Value, true);
     305             :   }
     306             : 
     307             :   void printBinaryBlock(StringRef Label, StringRef Value) {
     308        1995 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     309        3990 :                           Value.size());
     310        1995 :     printBinaryImpl(Label, StringRef(), V, true);
     311             :   }
     312             : 
     313             :   template <typename T> void printObject(StringRef Label, const T &Value) {
     314             :     startLine() << Label << ": " << Value << "\n";
     315             :   }
     316             : 
     317             :   raw_ostream &startLine() {
     318     2060750 :     printIndent();
     319     2060750 :     return OS;
     320             :   }
     321             : 
     322             :   raw_ostream &getOStream() { return OS; }
     323             : 
     324             : private:
     325             :   template <typename T> void printVersionInternal(T Value) {
     326             :     getOStream() << Value;
     327             :   }
     328             : 
     329             :   template <typename S, typename T, typename... TArgs>
     330             :   void printVersionInternal(S Value, T Value2, TArgs... Args) {
     331             :     getOStream() << Value << ".";
     332             :     printVersionInternal(Value2, Args...);
     333             :   }
     334             : 
     335             :   template <typename T>
     336        6993 :   static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
     337        6993 :     return lhs.Name < rhs.Name;
     338             :   }
     339             : 
     340             :   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
     341             :                        bool Block, uint32_t StartOffset = 0);
     342             : 
     343             :   raw_ostream &OS;
     344             :   int IndentLevel;
     345             :   StringRef Prefix;
     346             : };
     347             : 
     348             : template <>
     349             : inline void
     350         261 : ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
     351             :                                               support::ulittle16_t Value) {
     352         522 :   startLine() << Label << ": " << hex(Value) << "\n";
     353         261 : }
     354             : 
     355             : template<char Open, char Close>
     356             : struct DelimitedScope {
     357             :   explicit DelimitedScope(ScopedPrinter &W) : W(W) {
     358             :     W.startLine() << Open << '\n';
     359             :     W.indent();
     360             :   }
     361             : 
     362      147905 :   DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
     363      147905 :     W.startLine() << N;
     364      147905 :     if (!N.empty())
     365      147905 :       W.getOStream() << ' ';
     366      443715 :     W.getOStream() << Open << '\n';
     367      295810 :     W.indent();
     368      147905 :   }
     369             : 
     370      147890 :   ~DelimitedScope() {
     371      295780 :     W.unindent();
     372      591560 :     W.startLine() << Close << '\n';
     373      147890 :   }
     374             : 
     375             :   ScopedPrinter &W;
     376             : };
     377             : 
     378             : using DictScope = DelimitedScope<'{', '}'>;
     379             : using ListScope = DelimitedScope<'[', ']'>;
     380             : 
     381             : } // namespace llvm
     382             : 
     383             : #endif

Generated by: LCOV version 1.13