LCOV - code coverage report
Current view: top level - include/llvm/Support - ScopedPrinter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 556 649 85.7 %
Date: 2018-10-20 13:21:21 Functions: 101 136 74.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             :   EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
      36             :   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         975 :   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
      48          18 :   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      149246 :   HexNumber(unsigned char Value) : Value(Value) {}
      52        7200 :   HexNumber(unsigned short Value) : Value(Value) {}
      53      113622 :   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      985238 : template <class T> const std::string to_string(const T &Value) {
      63             :   std::string number;
      64      985238 :   llvm::raw_string_ostream stream(number);
      65      789885 :   stream << Value;
      66      985238 :   return stream.str();
      67             : }
      68      132272 : 
      69             : class ScopedPrinter {
      70      132272 : public:
      71        3916 :   ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
      72      132272 : 
      73           0 :   void flush() { OS.flush(); }
      74         741 : 
      75      495846 :   void indent(int Levels = 1) { IndentLevel += Levels; }
      76         741 : 
      77           0 :   void unindent(int Levels = 1) {
      78       13727 :     IndentLevel = std::max(0, IndentLevel - Levels);
      79           0 :   }
      80       66070 : 
      81             :   void resetIndent() { IndentLevel = 0; }
      82       66070 : 
      83       66070 :   int getIndentLevel() { return IndentLevel; }
      84       66070 : 
      85         562 :   void setPrefix(StringRef P) { Prefix = P; }
      86           0 : 
      87     6684873 :   void printIndent() {
      88     6684873 :     OS << Prefix;
      89    19096800 :     for (int i = 0; i < IndentLevel; ++i)
      90    12411927 :       OS << "  ";
      91     6684873 :   }
      92       66163 : 
      93           0 :   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
      94       66163 : 
      95       66163 :   template <typename T, typename TEnum>
      96       92759 :   void printEnum(StringRef Label, T Value,
      97             :                  ArrayRef<EnumEntry<TEnum>> EnumValues) {
      98         132 :     StringRef Name;
      99             :     bool Found = false;
     100      632250 :     for (const auto &EnumItem : EnumValues) {
     101      632142 :       if (EnumItem.Value == Value) {
     102       26057 :         Name = EnumItem.Name;
     103             :         Found = true;
     104           0 :         break;
     105             :       }
     106           0 :     }
     107           0 : 
     108           0 :     if (Found) {
     109       25925 :       startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
     110      530669 :     } else {
     111         671 :       startLine() << Label << ": " << hex(Value) << "\n";
     112      530669 :     }
     113      557265 :   }
     114      531086 : 
     115             :   template <typename T, typename TFlag>
     116           7 :   void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
     117             :                   TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
     118         761 :                   TFlag EnumMask3 = {}) {
     119        1182 :     typedef EnumEntry<TFlag> FlagEntry;
     120         416 :     typedef SmallVector<FlagEntry, 10> FlagVector;
     121           0 :     FlagVector SetFlags;
     122             : 
     123         605 :     for (const auto &Flag : Flags) {
     124          21 :       if (Flag.Value == 0)
     125           0 :         continue;
     126         583 : 
     127         416 :       TFlag EnumMask{};
     128          21 :       if (Flag.Value & EnumMask1)
     129           1 :         EnumMask = EnumMask1;
     130          21 :       else if (Flag.Value & EnumMask2)
     131         417 :         EnumMask = EnumMask2;
     132         528 :       else if (Flag.Value & EnumMask3)
     133             :         EnumMask = EnumMask3;
     134          21 :       bool IsEnum = (Flag.Value & EnumMask) != 0;
     135          21 :       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
     136        5093 :           (IsEnum && (Value & EnumMask) == Flag.Value)) {
     137        5215 :         SetFlags.push_back(Flag);
     138         506 :       }
     139           0 :     }
     140             : 
     141           0 :     llvm::sort(SetFlags, &flagName<TFlag>);
     142             : 
     143           7 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     144      138254 :     for (const auto &Flag : SetFlags) {
     145         511 :       startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
     146             :     }
     147           8 :     startLine() << "]\n";
     148      167829 :   }
     149      193640 : 
     150      139360 :   template <typename T> void printFlags(StringRef Label, T Value) {
     151             :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     152             :     uint64_t Flag = 1;
     153             :     uint64_t Curr = Value;
     154        7865 :     while (Curr > 0) {
     155        7197 :       if (Curr & 1)
     156         503 :         startLine() << "  " << hex(Flag) << "\n";
     157      138189 :       Curr >>= 1;
     158             :       Flag <<= 1;
     159          53 :     }
     160             :     startLine() << "]\n";
     161      138242 :   }
     162           1 : 
     163         944 :   void printNumber(StringRef Label, uint64_t Value) {
     164         441 :     startLine() << Label << ": " << Value << "\n";
     165        1109 :   }
     166           6 : 
     167        4900 :   void printNumber(StringRef Label, uint32_t Value) {
     168        8691 :     startLine() << Label << ": " << Value << "\n";
     169        3717 :   }
     170         863 : 
     171         907 :   void printNumber(StringRef Label, uint16_t Value) {
     172       45979 :     startLine() << Label << ": " << Value << "\n";
     173       45086 :   }
     174        1256 : 
     175        1682 :   void printNumber(StringRef Label, uint8_t Value) {
     176        3362 :     startLine() << Label << ": " << unsigned(Value) << "\n";
     177       10931 :   }
     178        8387 : 
     179           1 :   void printNumber(StringRef Label, int64_t Value) {
     180          28 :     startLine() << Label << ": " << Value << "\n";
     181        1256 :   }
     182        8387 : 
     183          79 :   void printNumber(StringRef Label, int32_t Value) {
     184        8582 :     startLine() << Label << ": " << Value << "\n";
     185        1409 :   }
     186       16634 : 
     187             :   void printNumber(StringRef Label, int16_t Value) {
     188        8387 :     startLine() << Label << ": " << Value << "\n";
     189        8387 :   }
     190       32890 : 
     191       33335 :   void printNumber(StringRef Label, int8_t Value) {
     192        8219 :     startLine() << Label << ": " << int(Value) << "\n";
     193          28 :   }
     194             : 
     195           0 :   void printNumber(StringRef Label, const APSInt &Value) {
     196             :     startLine() << Label << ": " << Value << "\n";
     197         891 :   }
     198        2072 : 
     199        8720 :   void printBoolean(StringRef Label, bool Value) {
     200          56 :     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
     201         919 :   }
     202       25176 : 
     203       57087 :   template <typename... T> void printVersion(StringRef Label, T... Version) {
     204       14082 :     startLine() << Label << ": ";
     205          53 :     printVersionInternal(Version...);
     206             :     getOStream() << "\n";
     207             :   }
     208      537962 : 
     209      537962 :   template <typename T> void printList(StringRef Label, const T &List) {
     210       15035 :     startLine() << Label << ": [";
     211        2186 :     bool Comma = false;
     212           0 :     for (const auto &Item : List) {
     213          53 :       if (Comma)
     214           0 :         OS << ", ";
     215        2247 :       OS << Item;
     216         140 :       Comma = true;
     217       14748 :     }
     218           0 :     OS << "]\n";
     219        1479 :   }
     220        1069 : 
     221       16866 :   template <typename T, typename U>
     222        2118 :   void printList(StringRef Label, const T &List, const U &Printer) {
     223           0 :     startLine() << Label << ": [";
     224        2131 :     bool Comma = false;
     225             :     for (const auto &Item : List) {
     226         511 :       if (Comma)
     227         511 :         OS << ", ";
     228         511 :       Printer(OS, Item);
     229         132 :       Comma = true;
     230         295 :     }
     231       21580 :     OS << "]\n";
     232       19197 :   }
     233         132 : 
     234      137612 :   template <typename T> void printHexList(StringRef Label, const T &List) {
     235         806 :     startLine() << Label << ": [";
     236       19722 :     bool Comma = false;
     237           0 :     for (const auto &Item : List) {
     238      161559 :       if (Comma)
     239      142916 :         OS << ", ";
     240      156581 :       OS << hex(Item);
     241             :       Comma = true;
     242       19154 :     }
     243       26634 :     OS << "]\n";
     244        7077 :   }
     245        2299 : 
     246        7385 :   template <typename T> void printHex(StringRef Label, T Value) {
     247      144592 :     startLine() << Label << ": " << hex(Value) << "\n";
     248       14187 :   }
     249         551 : 
     250       14491 :   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
     251      146984 :     startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
     252       21771 :   }
     253        5853 : 
     254      407428 :   template <typename T>
     255        9000 :   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
     256        2088 :     startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
     257        1359 :   }
     258         914 : 
     259             :   void printString(StringRef Value) { startLine() << Value << "\n"; }
     260             : 
     261     6369978 :   void printString(StringRef Label, StringRef Value) {
     262     5975037 :     startLine() << Label << ": " << Value << "\n";
     263       20144 :   }
     264        6276 : 
     265        4237 :   void printString(StringRef Label, const std::string &Value) {
     266     5958234 :     printString(Label, StringRef(Value));
     267         568 :   }
     268     5954627 : 
     269        3687 :   void printString(StringRef Label, const char* Value) {
     270     5953984 :     printString(Label, StringRef(Value));
     271        4600 :   }
     272     5955406 : 
     273     5958953 :   template <typename T>
     274        2535 :   void printNumber(StringRef Label, StringRef Str, T Value) {
     275      270096 :     startLine() << Label << ": " << Str << " (" << Value << ")\n";
     276        3571 :   }
     277           0 : 
     278         419 :   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
     279             :     printBinaryImpl(Label, Str, Value, false);
     280         141 :   }
     281      397189 : 
     282      662604 :   void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
     283      265810 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     284        1021 :                           Value.size());
     285      398329 :     printBinaryImpl(Label, Str, V, false);
     286      397344 :   }
     287      395728 : 
     288         865 :   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
     289        1070 :     printBinaryImpl(Label, StringRef(), Value, false);
     290         289 :   }
     291          32 : 
     292          64 :   void printBinary(StringRef Label, ArrayRef<char> Value) {
     293          57 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     294     6331243 :                           Value.size());
     295     5935407 :     printBinaryImpl(Label, StringRef(), V, false);
     296             :   }
     297        5071 : 
     298        5321 :   void printBinary(StringRef Label, StringRef Value) {
     299     5935928 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     300         126 :                           Value.size());
     301     5935407 :     printBinaryImpl(Label, StringRef(), V, false);
     302        4800 :   }
     303     5935931 : 
     304        5815 :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
     305     5935931 :                         uint32_t StartOffset) {
     306     5940207 :     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
     307         126 :   }
     308      269154 : 
     309        4800 :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
     310           0 :     printBinaryImpl(Label, StringRef(), Value, true);
     311         326 :   }
     312             : 
     313             :   void printBinaryBlock(StringRef Label, StringRef Value) {
     314      398663 :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     315      660069 :                           Value.size());
     316      264377 :     printBinaryImpl(Label, StringRef(), V, true);
     317         289 :   }
     318      396199 : 
     319      395910 :   template <typename T> void printObject(StringRef Label, const T &Value) {
     320           0 :     startLine() << Label << ": " << Value << "\n";
     321       55662 :   }
     322       52709 : 
     323         970 :   raw_ostream &startLine() {
     324      521766 :     printIndent();
     325      521766 :     return OS;
     326       52216 :   }
     327           0 : 
     328       41162 :   raw_ostream &getOStream() { return OS; }
     329             : 
     330       68627 : private:
     331       26959 :   template <typename T> void printVersionInternal(T Value) {
     332       52216 :     getOStream() << Value;
     333       52216 :   }
     334       13606 : 
     335       15677 :   template <typename S, typename T, typename... TArgs>
     336           0 :   void printVersionInternal(S Value, T Value2, TArgs... Args) {
     337       10808 :     getOStream() << Value << ".";
     338           0 :     printVersionInternal(Value2, Args...);
     339       10808 :   }
     340           0 : 
     341       13761 :   template <typename T>
     342       18630 :   static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
     343        4869 :     return lhs.Name < rhs.Name;
     344        1515 :   }
     345        2953 : 
     346        2953 :   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
     347         109 :                        bool Block, uint32_t StartOffset = 0);
     348           0 : 
     349           0 :   raw_ostream &OS;
     350         970 :   int IndentLevel;
     351        2485 :   StringRef Prefix;
     352        1515 : };
     353         269 : 
     354        2278 : template <>
     355        2169 : inline void
     356           0 : ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
     357             :                                               support::ulittle16_t Value) {
     358             :   startLine() << Label << ": " << hex(Value) << "\n";
     359        1199 : }
     360        1307 : 
     361        2237 : template<char Open, char Close>
     362             : struct DelimitedScope {
     363        1199 :   explicit DelimitedScope(ScopedPrinter &W) : W(W) {
     364           0 :     W.startLine() << Open << '\n';
     365        2237 :     W.indent();
     366        1534 :   }
     367         566 : 
     368      478735 :   DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
     369      478538 :     W.startLine() << N;
     370      478991 :     if (!N.empty())
     371      480029 :       W.getOStream() << ' ';
     372      480029 :     W.getOStream() << Open << '\n';
     373         807 :     W.indent();
     374      484084 :   }
     375       11179 : 
     376       12283 :   ~DelimitedScope() {
     377       11855 :     W.unindent();
     378       11046 :     W.startLine() << Close << '\n';
     379        6273 :   }
     380        6137 : 
     381        9036 :   ScopedPrinter &W;
     382      476097 : };
     383      476258 : 
     384      476094 : using DictScope = DelimitedScope<'{', '}'>;
     385      475661 : using ListScope = DelimitedScope<'[', ']'>;
     386      472395 : 
     387       20713 : } // namespace llvm
     388      491282 : 
     389        2147 : #endif

Generated by: LCOV version 1.13