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 22namespace llvm { 23class BinaryStreamReader; 24namespace msf { 25class MSFStreamLayout; 26} // namespace msf 27namespace pdb { 28 29class ClassLayout; 30class PDBFile; 31 32class LinePrinter { 33 friend class WithColor; 34 35public: 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 73private: 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 95struct 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 106inline Optional<PrintScope> withLabelWidth(const Optional<PrintScope> &Scope, 107 uint32_t W) { 108 if (!Scope) 109 return None; 110 return PrintScope{*Scope, W}; 111} 112 113struct 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 133template <class T> 134inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { 135 return Printer.getStream() << Item; 136} 137 138enum 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 153class WithColor { 154public: 155 WithColor(LinePrinter &P, PDB_ColorItem C); 156 ~WithColor(); 157 158 raw_ostream &get() { return OS; } 159 160private: 161 void applyColor(PDB_ColorItem C); 162 raw_ostream &OS; 163 bool UseColor; 164}; 165} 166} 167 168#endif 169