Home | History | Annotate | Line # | Download | only in llvm-pdbutil
      1 //===- LinePrinter.h ------------------------------------------ *- C++ --*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
     10 #define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
     11 
     12 #include "llvm/ADT/ArrayRef.h"
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/ADT/Twine.h"
     15 #include "llvm/Support/BinaryStreamRef.h"
     16 #include "llvm/Support/FormatVariadic.h"
     17 #include "llvm/Support/Regex.h"
     18 #include "llvm/Support/raw_ostream.h"
     19 
     20 #include <list>
     21 
     22 namespace llvm {
     23 class BinaryStreamReader;
     24 namespace msf {
     25 class MSFStreamLayout;
     26 } // namespace msf
     27 namespace pdb {
     28 
     29 class ClassLayout;
     30 class PDBFile;
     31 
     32 class LinePrinter {
     33   friend class WithColor;
     34 
     35 public:
     36   LinePrinter(int Indent, bool UseColor, raw_ostream &Stream);
     37 
     38   void Indent(uint32_t Amount = 0);
     39   void Unindent(uint32_t Amount = 0);
     40   void NewLine();
     41 
     42   void printLine(const Twine &T);
     43   void print(const Twine &T);
     44   template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
     45     printLine(formatv(Fmt, std::forward<Ts>(Items)...));
     46   }
     47   template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
     48     print(formatv(Fmt, std::forward<Ts>(Items)...));
     49   }
     50 
     51   void formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
     52                     uint32_t StartOffset);
     53   void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, uint64_t BaseAddr,
     54                     uint32_t StartOffset);
     55 
     56   void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx,
     57                            StringRef StreamPurpose, uint32_t Offset,
     58                            uint32_t Size);
     59   void formatMsfStreamData(StringRef Label, PDBFile &File,
     60                            const msf::MSFStreamLayout &Stream,
     61                            BinarySubstreamRef Substream);
     62   void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream);
     63 
     64   bool hasColor() const { return UseColor; }
     65   raw_ostream &getStream() { return OS; }
     66   int getIndentLevel() const { return CurrentIndent; }
     67 
     68   bool IsClassExcluded(const ClassLayout &Class);
     69   bool IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size);
     70   bool IsSymbolExcluded(llvm::StringRef SymbolName);
     71   bool IsCompilandExcluded(llvm::StringRef CompilandName);
     72 
     73 private:
     74   template <typename Iter>
     75   void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) {
     76     List.clear();
     77     for (; Begin != End; ++Begin)
     78       List.emplace_back(StringRef(*Begin));
     79   }
     80 
     81   raw_ostream &OS;
     82   int IndentSpaces;
     83   int CurrentIndent;
     84   bool UseColor;
     85 
     86   std::list<Regex> ExcludeCompilandFilters;
     87   std::list<Regex> ExcludeTypeFilters;
     88   std::list<Regex> ExcludeSymbolFilters;
     89 
     90   std::list<Regex> IncludeCompilandFilters;
     91   std::list<Regex> IncludeTypeFilters;
     92   std::list<Regex> IncludeSymbolFilters;
     93 };
     94 
     95 struct PrintScope {
     96   explicit PrintScope(LinePrinter &P, uint32_t IndentLevel)
     97       : P(P), IndentLevel(IndentLevel) {}
     98   explicit PrintScope(const PrintScope &Other, uint32_t LabelWidth)
     99       : P(Other.P), IndentLevel(Other.IndentLevel), LabelWidth(LabelWidth) {}
    100 
    101   LinePrinter &P;
    102   uint32_t IndentLevel;
    103   uint32_t LabelWidth = 0;
    104 };
    105 
    106 inline Optional<PrintScope> withLabelWidth(const Optional<PrintScope> &Scope,
    107                                            uint32_t W) {
    108   if (!Scope)
    109     return None;
    110   return PrintScope{*Scope, W};
    111 }
    112 
    113 struct AutoIndent {
    114   explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0)
    115       : L(&L), Amount(Amount) {
    116     L.Indent(Amount);
    117   }
    118   explicit AutoIndent(const Optional<PrintScope> &Scope) {
    119     if (Scope.hasValue()) {
    120       L = &Scope->P;
    121       Amount = Scope->IndentLevel;
    122     }
    123   }
    124   ~AutoIndent() {
    125     if (L)
    126       L->Unindent(Amount);
    127   }
    128 
    129   LinePrinter *L = nullptr;
    130   uint32_t Amount = 0;
    131 };
    132 
    133 template <class T>
    134 inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
    135   return Printer.getStream() << Item;
    136 }
    137 
    138 enum class PDB_ColorItem {
    139   None,
    140   Address,
    141   Type,
    142   Comment,
    143   Padding,
    144   Keyword,
    145   Offset,
    146   Identifier,
    147   Path,
    148   SectionHeader,
    149   LiteralValue,
    150   Register,
    151 };
    152 
    153 class WithColor {
    154 public:
    155   WithColor(LinePrinter &P, PDB_ColorItem C);
    156   ~WithColor();
    157 
    158   raw_ostream &get() { return OS; }
    159 
    160 private:
    161   void applyColor(PDB_ColorItem C);
    162   raw_ostream &OS;
    163   bool UseColor;
    164 };
    165 }
    166 }
    167 
    168 #endif
    169