LCOV - code coverage report
Current view: top level - include/llvm/Support - ScopedPrinter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 135 135 100.0 %
Date: 2018-02-23 15:42:53 Functions: 115 126 91.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        5040 :   EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
      36      341888 :   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        1034 :   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
      48          12 :   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       16362 :   HexNumber(unsigned char Value) : Value(Value) {}
      52        4832 :   HexNumber(unsigned short Value) : Value(Value) {}
      53      188898 :   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      171884 : template <class T> const std::string to_string(const T &Value) {
      63             :   std::string number;
      64      171884 :   llvm::raw_string_ostream stream(number);
      65      119831 :   stream << Value;
      66      171884 :   return stream.str();
      67             : }
      68             : 
      69             : class ScopedPrinter {
      70             : public:
      71        3133 :   ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
      72             : 
      73             :   void flush() { OS.flush(); }
      74             : 
      75      164107 :   void indent(int Levels = 1) { IndentLevel += Levels; }
      76             : 
      77             :   void unindent(int Levels = 1) {
      78      328156 :     IndentLevel = std::max(0, IndentLevel - Levels);
      79             :   }
      80             : 
      81             :   void resetIndent() { IndentLevel = 0; }
      82             : 
      83         309 :   void setPrefix(StringRef P) { Prefix = P; }
      84             : 
      85     2116534 :   void printIndent() {
      86     2116534 :     OS << Prefix;
      87     9988766 :     for (int i = 0; i < IndentLevel; ++i)
      88     3936116 :       OS << "  ";
      89     2116534 :   }
      90             : 
      91             :   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
      92             : 
      93             :   template <typename T, typename TEnum>
      94       28383 :   void printEnum(StringRef Label, T Value,
      95             :                  ArrayRef<EnumEntry<TEnum>> EnumValues) {
      96             :     StringRef Name;
      97             :     bool Found = false;
      98      932759 :     for (const auto &EnumItem : EnumValues) {
      99      503543 :       if (EnumItem.Value == Value) {
     100       27725 :         Name = EnumItem.Name;
     101             :         Found = true;
     102             :         break;
     103             :       }
     104             :     }
     105             : 
     106             :     if (Found) {
     107       55450 :       startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
     108             :     } else {
     109        1316 :       startLine() << Label << ": " << hex(Value) << "\n";
     110             :     }
     111       28383 :   }
     112             : 
     113             :   template <typename T, typename TFlag>
     114      139706 :   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             :     FlagVector SetFlags;
     120             : 
     121     4324936 :     for (const auto &Flag : Flags) {
     122     2092615 :       if (Flag.Value == 0)
     123         268 :         continue;
     124             : 
     125             :       TFlag EnumMask{};
     126     2092347 :       if (Flag.Value & EnumMask1)
     127             :         EnumMask = EnumMask1;
     128     2081376 :       else if (Flag.Value & EnumMask2)
     129             :         EnumMask = EnumMask2;
     130     2080712 :       else if (Flag.Value & EnumMask3)
     131             :         EnumMask = EnumMask3;
     132     2092347 :       bool IsEnum = (Flag.Value & EnumMask) != 0;
     133     4150393 :       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
     134       14623 :           (IsEnum && (Value & EnumMask) == Flag.Value)) {
     135        9840 :         SetFlags.push_back(Flag);
     136             :       }
     137             :     }
     138             : 
     139             :     std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
     140             : 
     141      279412 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     142      159386 :     for (const auto &Flag : SetFlags) {
     143       19680 :       startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
     144             :     }
     145      139706 :     startLine() << "]\n";
     146      139706 :   }
     147             : 
     148          99 :   template <typename T> void printFlags(StringRef Label, T Value) {
     149         198 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     150             :     uint64_t Flag = 1;
     151          99 :     uint64_t Curr = Value;
     152         237 :     while (Curr > 0) {
     153          69 :       if (Curr & 1)
     154          10 :         startLine() << "  " << hex(Flag) << "\n";
     155          69 :       Curr >>= 1;
     156          69 :       Flag <<= 1;
     157             :     }
     158          99 :     startLine() << "]\n";
     159          99 :   }
     160             : 
     161      406206 :   void printNumber(StringRef Label, uint64_t Value) {
     162      406206 :     startLine() << Label << ": " << Value << "\n";
     163      406206 :   }
     164             : 
     165      288087 :   void printNumber(StringRef Label, uint32_t Value) {
     166      576174 :     startLine() << Label << ": " << Value << "\n";
     167      288087 :   }
     168             : 
     169        7579 :   void printNumber(StringRef Label, uint16_t Value) {
     170       15158 :     startLine() << Label << ": " << Value << "\n";
     171        7579 :   }
     172             : 
     173        1716 :   void printNumber(StringRef Label, uint8_t Value) {
     174        3432 :     startLine() << Label << ": " << unsigned(Value) << "\n";
     175        1716 :   }
     176             : 
     177         184 :   void printNumber(StringRef Label, int64_t Value) {
     178         184 :     startLine() << Label << ": " << Value << "\n";
     179         184 :   }
     180             : 
     181      140688 :   void printNumber(StringRef Label, int32_t Value) {
     182      281376 :     startLine() << Label << ": " << Value << "\n";
     183      140688 :   }
     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         551 :   void printBoolean(StringRef Label, bool Value) {
     198         551 :     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
     199         551 :   }
     200             : 
     201             :   template <typename... T> void printVersion(StringRef Label, T... Version) {
     202             :     startLine() << Label << ": ";
     203             :     printVersionInternal(Version...);
     204             :     getOStream() << "\n";
     205             :   }
     206             : 
     207          17 :   template <typename T> void printList(StringRef Label, const T &List) {
     208          17 :     startLine() << Label << ": [";
     209             :     bool Comma = false;
     210         132 :     for (const auto &Item : List) {
     211          49 :       if (Comma)
     212          33 :         OS << ", ";
     213          49 :       OS << Item;
     214             :       Comma = true;
     215             :     }
     216          17 :     OS << "]\n";
     217          17 :   }
     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          22 :   template <typename T> void printHexList(StringRef Label, const T &List) {
     233          22 :     startLine() << Label << ": [";
     234             :     bool Comma = false;
     235         158 :     for (const auto &Item : List) {
     236          57 :       if (Comma)
     237          36 :         OS << ", ";
     238         114 :       OS << hex(Item);
     239             :       Comma = true;
     240             :     }
     241          22 :     OS << "]\n";
     242          22 :   }
     243             : 
     244      293616 :   template <typename T> void printHex(StringRef Label, T Value) {
     245      585002 :     startLine() << Label << ": " << hex(Value) << "\n";
     246      293616 :   }
     247             : 
     248      143604 :   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
     249      287208 :     startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
     250      143604 :   }
     251             : 
     252             :   template <typename T>
     253         332 :   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
     254         996 :     startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
     255         332 :   }
     256             : 
     257         518 :   void printString(StringRef Value) { startLine() << Value << "\n"; }
     258             : 
     259       23480 :   void printString(StringRef Label, StringRef Value) {
     260       23480 :     startLine() << Label << ": " << Value << "\n";
     261       23480 :   }
     262             : 
     263             :   void printString(StringRef Label, const std::string &Value) {
     264        2979 :     printString(Label, StringRef(Value));
     265             :   }
     266             : 
     267         108 :   void printString(StringRef Label, const char* Value) {
     268         108 :     printString(Label, StringRef(Value));
     269         108 :   }
     270             : 
     271             :   template <typename T>
     272      141110 :   void printNumber(StringRef Label, StringRef Str, T Value) {
     273      282165 :     startLine() << Label << ": " << Str << " (" << Value << ")\n";
     274      141110 :   }
     275             : 
     276             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
     277             :     printBinaryImpl(Label, Str, Value, false);
     278             :   }
     279             : 
     280             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
     281             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     282        1296 :                           Value.size());
     283        1296 :     printBinaryImpl(Label, Str, V, false);
     284             :   }
     285             : 
     286             :   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
     287         898 :     printBinaryImpl(Label, StringRef(), Value, false);
     288             :   }
     289             : 
     290             :   void printBinary(StringRef Label, ArrayRef<char> Value) {
     291             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     292             :                           Value.size());
     293             :     printBinaryImpl(Label, StringRef(), V, false);
     294             :   }
     295             : 
     296             :   void printBinary(StringRef Label, StringRef Value) {
     297             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     298             :                           Value.size());
     299             :     printBinaryImpl(Label, StringRef(), V, false);
     300             :   }
     301             : 
     302             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
     303             :                         uint32_t StartOffset) {
     304             :     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
     305             :   }
     306             : 
     307             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
     308           1 :     printBinaryImpl(Label, StringRef(), Value, true);
     309             :   }
     310             : 
     311             :   void printBinaryBlock(StringRef Label, StringRef Value) {
     312             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     313        2247 :                           Value.size());
     314        2247 :     printBinaryImpl(Label, StringRef(), V, true);
     315             :   }
     316             : 
     317             :   template <typename T> void printObject(StringRef Label, const T &Value) {
     318             :     startLine() << Label << ": " << Value << "\n";
     319             :   }
     320             : 
     321             :   raw_ostream &startLine() {
     322     2116534 :     printIndent();
     323     2116534 :     return OS;
     324             :   }
     325             : 
     326             :   raw_ostream &getOStream() { return OS; }
     327             : 
     328             : private:
     329             :   template <typename T> void printVersionInternal(T Value) {
     330             :     getOStream() << Value;
     331             :   }
     332             : 
     333             :   template <typename S, typename T, typename... TArgs>
     334             :   void printVersionInternal(S Value, T Value2, TArgs... Args) {
     335             :     getOStream() << Value << ".";
     336             :     printVersionInternal(Value2, Args...);
     337             :   }
     338             : 
     339             :   template <typename T>
     340        7635 :   static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
     341        7635 :     return lhs.Name < rhs.Name;
     342             :   }
     343             : 
     344             :   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
     345             :                        bool Block, uint32_t StartOffset = 0);
     346             : 
     347             :   raw_ostream &OS;
     348             :   int IndentLevel;
     349             :   StringRef Prefix;
     350             : };
     351             : 
     352             : template <>
     353             : inline void
     354         501 : ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
     355             :                                               support::ulittle16_t Value) {
     356        1002 :   startLine() << Label << ": " << hex(Value) << "\n";
     357         501 : }
     358             : 
     359             : template<char Open, char Close>
     360             : struct DelimitedScope {
     361             :   explicit DelimitedScope(ScopedPrinter &W) : W(W) {
     362             :     W.startLine() << Open << '\n';
     363             :     W.indent();
     364             :   }
     365             : 
     366      153614 :   DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
     367      153614 :     W.startLine() << N;
     368      153614 :     if (!N.empty())
     369      153614 :       W.getOStream() << ' ';
     370      153614 :     W.getOStream() << Open << '\n';
     371             :     W.indent();
     372      153614 :   }
     373             : 
     374      153594 :   ~DelimitedScope() {
     375      153594 :     W.unindent();
     376             :     W.startLine() << Close << '\n';
     377      153594 :   }
     378             : 
     379             :   ScopedPrinter &W;
     380             : };
     381             : 
     382             : using DictScope = DelimitedScope<'{', '}'>;
     383             : using ListScope = DelimitedScope<'[', ']'>;
     384             : 
     385             : } // namespace llvm
     386             : 
     387             : #endif

Generated by: LCOV version 1.13