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-05-20 00:06:23 Functions: 117 131 89.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        5366 :   EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
      36      413070 :   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        1040 :   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
      48          13 :   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       18096 :   HexNumber(unsigned char Value) : Value(Value) {}
      52        6367 :   HexNumber(unsigned short Value) : Value(Value) {}
      53      198943 :   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      263699 : template <class T> const std::string to_string(const T &Value) {
      63             :   std::string number;
      64      263699 :   llvm::raw_string_ostream stream(number);
      65      190695 :   stream << Value;
      66      263699 :   return stream.str();
      67             : }
      68             : 
      69             : class ScopedPrinter {
      70             : public:
      71        3382 :   ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
      72             : 
      73             :   void flush() { OS.flush(); }
      74             : 
      75      168222 :   void indent(int Levels = 1) { IndentLevel += Levels; }
      76             : 
      77             :   void unindent(int Levels = 1) {
      78      336377 :     IndentLevel = std::max(0, IndentLevel - Levels);
      79             :   }
      80             : 
      81             :   void resetIndent() { IndentLevel = 0; }
      82             : 
      83             :   int getIndentLevel() { return IndentLevel; }
      84             : 
      85         366 :   void setPrefix(StringRef P) { Prefix = P; }
      86             : 
      87     2150626 :   void printIndent() {
      88     2150626 :     OS << Prefix;
      89    10154946 :     for (int i = 0; i < IndentLevel; ++i)
      90     4002160 :       OS << "  ";
      91     2150626 :   }
      92             : 
      93             :   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
      94             : 
      95             :   template <typename T, typename TEnum>
      96       32242 :   void printEnum(StringRef Label, T Value,
      97             :                  ArrayRef<EnumEntry<TEnum>> EnumValues) {
      98             :     StringRef Name;
      99             :     bool Found = false;
     100     1116954 :     for (const auto &EnumItem : EnumValues) {
     101      598981 :       if (EnumItem.Value == Value) {
     102       31567 :         Name = EnumItem.Name;
     103             :         Found = true;
     104             :         break;
     105             :       }
     106             :     }
     107             : 
     108             :     if (Found) {
     109       63134 :       startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
     110             :     } else {
     111        1350 :       startLine() << Label << ": " << hex(Value) << "\n";
     112             :     }
     113       32242 :   }
     114             : 
     115             :   template <typename T, typename TFlag>
     116      140653 :   void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
     117             :                   TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
     118             :                   TFlag EnumMask3 = {}) {
     119             :     typedef EnumEntry<TFlag> FlagEntry;
     120             :     typedef SmallVector<FlagEntry, 10> FlagVector;
     121             :     FlagVector SetFlags;
     122             : 
     123     4346645 :     for (const auto &Flag : Flags) {
     124     2102996 :       if (Flag.Value == 0)
     125         276 :         continue;
     126             : 
     127             :       TFlag EnumMask{};
     128     2102720 :       if (Flag.Value & EnumMask1)
     129             :         EnumMask = EnumMask1;
     130     2090805 :       else if (Flag.Value & EnumMask2)
     131             :         EnumMask = EnumMask2;
     132     2090125 :       else if (Flag.Value & EnumMask3)
     133             :         EnumMask = EnumMask3;
     134     2102720 :       bool IsEnum = (Flag.Value & EnumMask) != 0;
     135     4164739 :       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
     136       15655 :           (IsEnum && (Value & EnumMask) == Flag.Value)) {
     137       11104 :         SetFlags.push_back(Flag);
     138             :       }
     139             :     }
     140             : 
     141             :     llvm::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
     142             : 
     143      281306 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     144      162861 :     for (const auto &Flag : SetFlags) {
     145       22208 :       startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
     146             :     }
     147      140653 :     startLine() << "]\n";
     148      140653 :   }
     149             : 
     150         111 :   template <typename T> void printFlags(StringRef Label, T Value) {
     151         222 :     startLine() << Label << " [ (" << hex(Value) << ")\n";
     152             :     uint64_t Flag = 1;
     153         111 :     uint64_t Curr = Value;
     154         273 :     while (Curr > 0) {
     155          81 :       if (Curr & 1)
     156          16 :         startLine() << "  " << hex(Flag) << "\n";
     157          81 :       Curr >>= 1;
     158          81 :       Flag <<= 1;
     159             :     }
     160         111 :     startLine() << "]\n";
     161         111 :   }
     162             : 
     163      407352 :   void printNumber(StringRef Label, uint64_t Value) {
     164      407352 :     startLine() << Label << ": " << Value << "\n";
     165      407352 :   }
     166             : 
     167      289443 :   void printNumber(StringRef Label, uint32_t Value) {
     168      578886 :     startLine() << Label << ": " << Value << "\n";
     169      289443 :   }
     170             : 
     171        9449 :   void printNumber(StringRef Label, uint16_t Value) {
     172       18898 :     startLine() << Label << ": " << Value << "\n";
     173        9449 :   }
     174             : 
     175        1996 :   void printNumber(StringRef Label, uint8_t Value) {
     176        3992 :     startLine() << Label << ": " << unsigned(Value) << "\n";
     177        1996 :   }
     178             : 
     179         187 :   void printNumber(StringRef Label, int64_t Value) {
     180         187 :     startLine() << Label << ": " << Value << "\n";
     181         187 :   }
     182             : 
     183      142433 :   void printNumber(StringRef Label, int32_t Value) {
     184      284866 :     startLine() << Label << ": " << Value << "\n";
     185      142433 :   }
     186             : 
     187             :   void printNumber(StringRef Label, int16_t Value) {
     188             :     startLine() << Label << ": " << Value << "\n";
     189             :   }
     190             : 
     191             :   void printNumber(StringRef Label, int8_t Value) {
     192             :     startLine() << Label << ": " << int(Value) << "\n";
     193             :   }
     194             : 
     195        6095 :   void printNumber(StringRef Label, const APSInt &Value) {
     196       12190 :     startLine() << Label << ": " << Value << "\n";
     197        6095 :   }
     198             : 
     199         659 :   void printBoolean(StringRef Label, bool Value) {
     200         659 :     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
     201         659 :   }
     202             : 
     203             :   template <typename... T> void printVersion(StringRef Label, T... Version) {
     204             :     startLine() << Label << ": ";
     205             :     printVersionInternal(Version...);
     206             :     getOStream() << "\n";
     207             :   }
     208             : 
     209          18 :   template <typename T> void printList(StringRef Label, const T &List) {
     210          18 :     startLine() << Label << ": [";
     211             :     bool Comma = false;
     212         138 :     for (const auto &Item : List) {
     213          51 :       if (Comma)
     214          33 :         OS << ", ";
     215          51 :       OS << Item;
     216             :       Comma = true;
     217             :     }
     218          18 :     OS << "]\n";
     219          18 :   }
     220             : 
     221             :   template <typename T, typename U>
     222             :   void printList(StringRef Label, const T &List, const U &Printer) {
     223             :     startLine() << Label << ": [";
     224             :     bool Comma = false;
     225             :     for (const auto &Item : List) {
     226             :       if (Comma)
     227             :         OS << ", ";
     228             :       Printer(OS, Item);
     229             :       Comma = true;
     230             :     }
     231             :     OS << "]\n";
     232             :   }
     233             : 
     234          24 :   template <typename T> void printHexList(StringRef Label, const T &List) {
     235          24 :     startLine() << Label << ": [";
     236             :     bool Comma = false;
     237         168 :     for (const auto &Item : List) {
     238          60 :       if (Comma)
     239          37 :         OS << ", ";
     240         120 :       OS << hex(Item);
     241             :       Comma = true;
     242             :     }
     243          24 :     OS << "]\n";
     244          24 :   }
     245             : 
     246      297585 :   template <typename T> void printHex(StringRef Label, T Value) {
     247      592704 :     startLine() << Label << ": " << hex(Value) << "\n";
     248      297585 :   }
     249             : 
     250      146487 :   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
     251      292974 :     startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
     252      146487 :   }
     253             : 
     254             :   template <typename T>
     255         400 :   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
     256        1200 :     startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
     257         400 :   }
     258             : 
     259         554 :   void printString(StringRef Value) { startLine() << Value << "\n"; }
     260             : 
     261       25721 :   void printString(StringRef Label, StringRef Value) {
     262       25721 :     startLine() << Label << ": " << Value << "\n";
     263       25721 :   }
     264             : 
     265             :   void printString(StringRef Label, const std::string &Value) {
     266        3131 :     printString(Label, StringRef(Value));
     267             :   }
     268             : 
     269         135 :   void printString(StringRef Label, const char* Value) {
     270         135 :     printString(Label, StringRef(Value));
     271         135 :   }
     272             : 
     273             :   template <typename T>
     274      141540 :   void printNumber(StringRef Label, StringRef Str, T Value) {
     275      283020 :     startLine() << Label << ": " << Str << " (" << Value << ")\n";
     276      141540 :   }
     277             : 
     278             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
     279             :     printBinaryImpl(Label, Str, Value, false);
     280             :   }
     281             : 
     282             :   void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
     283             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     284        1335 :                           Value.size());
     285        1335 :     printBinaryImpl(Label, Str, V, false);
     286             :   }
     287             : 
     288             :   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
     289        1064 :     printBinaryImpl(Label, StringRef(), Value, false);
     290             :   }
     291             : 
     292             :   void printBinary(StringRef Label, ArrayRef<char> 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 printBinary(StringRef Label, StringRef Value) {
     299             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     300             :                           Value.size());
     301             :     printBinaryImpl(Label, StringRef(), V, false);
     302             :   }
     303             : 
     304             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
     305             :                         uint32_t StartOffset) {
     306             :     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
     307             :   }
     308             : 
     309             :   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
     310           1 :     printBinaryImpl(Label, StringRef(), Value, true);
     311             :   }
     312             : 
     313             :   void printBinaryBlock(StringRef Label, StringRef Value) {
     314             :     auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
     315        2316 :                           Value.size());
     316        2316 :     printBinaryImpl(Label, StringRef(), V, true);
     317             :   }
     318             : 
     319             :   template <typename T> void printObject(StringRef Label, const T &Value) {
     320             :     startLine() << Label << ": " << Value << "\n";
     321             :   }
     322             : 
     323             :   raw_ostream &startLine() {
     324     2150626 :     printIndent();
     325     2150626 :     return OS;
     326             :   }
     327             : 
     328             :   raw_ostream &getOStream() { return OS; }
     329             : 
     330             : private:
     331             :   template <typename T> void printVersionInternal(T Value) {
     332             :     getOStream() << Value;
     333             :   }
     334             : 
     335             :   template <typename S, typename T, typename... TArgs>
     336             :   void printVersionInternal(S Value, T Value2, TArgs... Args) {
     337             :     getOStream() << Value << ".";
     338             :     printVersionInternal(Value2, Args...);
     339             :   }
     340             : 
     341             :   template <typename T>
     342        8584 :   static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
     343        8584 :     return lhs.Name < rhs.Name;
     344             :   }
     345             : 
     346             :   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
     347             :                        bool Block, uint32_t StartOffset = 0);
     348             : 
     349             :   raw_ostream &OS;
     350             :   int IndentLevel;
     351             :   StringRef Prefix;
     352             : };
     353             : 
     354             : template <>
     355             : inline void
     356         595 : ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
     357             :                                               support::ulittle16_t Value) {
     358        1190 :   startLine() << Label << ": " << hex(Value) << "\n";
     359         595 : }
     360             : 
     361             : template<char Open, char Close>
     362             : struct DelimitedScope {
     363             :   explicit DelimitedScope(ScopedPrinter &W) : W(W) {
     364             :     W.startLine() << Open << '\n';
     365             :     W.indent();
     366             :   }
     367             : 
     368      155683 :   DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
     369      155683 :     W.startLine() << N;
     370      155683 :     if (!N.empty())
     371      155683 :       W.getOStream() << ' ';
     372      155683 :     W.getOStream() << Open << '\n';
     373             :     W.indent();
     374      155683 :   }
     375             : 
     376      155663 :   ~DelimitedScope() {
     377      155663 :     W.unindent();
     378             :     W.startLine() << Close << '\n';
     379      155663 :   }
     380             : 
     381             :   ScopedPrinter &W;
     382             : };
     383             : 
     384             : using DictScope = DelimitedScope<'{', '}'>;
     385             : using ListScope = DelimitedScope<'[', ']'>;
     386             : 
     387             : } // namespace llvm
     388             : 
     389             : #endif

Generated by: LCOV version 1.13