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_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H 10 #define LLVM_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/ADT/Twine.h" 15 #include "llvm/DebugInfo/PDB/Native/FormatUtil.h" 16 #include "llvm/Support/BinaryStreamRef.h" 17 #include "llvm/Support/FormatVariadic.h" 18 #include "llvm/Support/Regex.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 #include <list> 22 23 // Container for filter options to control which elements will be printed. 24 struct FilterOptions { 25 std::list<std::string> ExcludeTypes; 26 std::list<std::string> ExcludeSymbols; 27 std::list<std::string> ExcludeCompilands; 28 std::list<std::string> IncludeTypes; 29 std::list<std::string> IncludeSymbols; 30 std::list<std::string> IncludeCompilands; 31 uint32_t PaddingThreshold; 32 uint32_t SizeThreshold; 33 llvm::Optional<uint32_t> DumpModi; 34 llvm::Optional<uint32_t> ParentRecurseDepth; 35 llvm::Optional<uint32_t> ChildrenRecurseDepth; 36 llvm::Optional<uint32_t> SymbolOffset; 37 bool JustMyCode; 38 }; 39 40 namespace llvm { 41 namespace msf { 42 class MSFStreamLayout; 43 } // namespace msf 44 namespace pdb { 45 46 class ClassLayout; 47 class PDBFile; 48 class SymbolGroup; 49 50 class LinePrinter { 51 friend class WithColor; 52 53 public: 54 LinePrinter(int Indent, bool UseColor, raw_ostream &Stream, 55 const FilterOptions &Filters); 56 57 void Indent(uint32_t Amount = 0); 58 void Unindent(uint32_t Amount = 0); 59 void NewLine(); 60 61 void printLine(const Twine &T); 62 void print(const Twine &T); 63 template <typename... Ts> void formatLine(const char *Fmt, Ts &&...Items) { 64 printLine(formatv(Fmt, std::forward<Ts>(Items)...)); 65 } 66 template <typename... Ts> void format(const char *Fmt, Ts &&...Items) { 67 print(formatv(Fmt, std::forward<Ts>(Items)...)); 68 } 69 70 void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, 71 uint64_t StartOffset); 72 void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, uint64_t BaseAddr, 73 uint64_t StartOffset); 74 75 void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx, 76 StringRef StreamPurpose, uint64_t Offset, 77 uint64_t Size); 78 void formatMsfStreamData(StringRef Label, PDBFile &File, 79 const msf::MSFStreamLayout &Stream, 80 BinarySubstreamRef Substream); 81 void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream); 82 83 bool hasColor() const { return UseColor; } 84 raw_ostream &getStream() { return OS; } 85 int getIndentLevel() const { return CurrentIndent; } 86 87 bool IsClassExcluded(const ClassLayout &Class); 88 bool IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size); 89 bool IsSymbolExcluded(llvm::StringRef SymbolName); 90 bool IsCompilandExcluded(llvm::StringRef CompilandName); 91 92 const FilterOptions &getFilters() const { return Filters; } 93 94 private: 95 template <typename Iter> 96 void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) { 97 List.clear(); 98 for (; Begin != End; ++Begin) 99 List.emplace_back(StringRef(*Begin)); 100 } 101 102 raw_ostream &OS; 103 int IndentSpaces; 104 int CurrentIndent; 105 bool UseColor; 106 const FilterOptions &Filters; 107 108 std::list<Regex> ExcludeCompilandFilters; 109 std::list<Regex> ExcludeTypeFilters; 110 std::list<Regex> ExcludeSymbolFilters; 111 112 std::list<Regex> IncludeCompilandFilters; 113 std::list<Regex> IncludeTypeFilters; 114 std::list<Regex> IncludeSymbolFilters; 115 }; 116 117 struct PrintScope { 118 explicit PrintScope(LinePrinter &P, uint32_t IndentLevel) 119 : P(P), IndentLevel(IndentLevel) {} 120 explicit PrintScope(const PrintScope &Other, uint32_t LabelWidth) 121 : P(Other.P), IndentLevel(Other.IndentLevel), LabelWidth(LabelWidth) {} 122 123 LinePrinter &P; 124 uint32_t IndentLevel; 125 uint32_t LabelWidth = 0; 126 }; 127 128 inline PrintScope withLabelWidth(const PrintScope &Scope, uint32_t W) { 129 return PrintScope{Scope, W}; 130 } 131 132 struct AutoIndent { 133 explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0) 134 : L(&L), Amount(Amount) { 135 L.Indent(Amount); 136 } 137 explicit AutoIndent(const PrintScope &Scope) { 138 L = &Scope.P; 139 Amount = Scope.IndentLevel; 140 } 141 ~AutoIndent() { 142 if (L) 143 L->Unindent(Amount); 144 } 145 146 LinePrinter *L = nullptr; 147 uint32_t Amount = 0; 148 }; 149 150 template <class T> 151 inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { 152 return Printer.getStream() << Item; 153 } 154 155 enum class PDB_ColorItem { 156 None, 157 Address, 158 Type, 159 Comment, 160 Padding, 161 Keyword, 162 Offset, 163 Identifier, 164 Path, 165 SectionHeader, 166 LiteralValue, 167 Register, 168 }; 169 170 class WithColor { 171 public: 172 WithColor(LinePrinter &P, PDB_ColorItem C); 173 ~WithColor(); 174 175 raw_ostream &get() { return OS; } 176 177 private: 178 void applyColor(PDB_ColorItem C); 179 raw_ostream &OS; 180 bool UseColor; 181 }; 182 } // namespace pdb 183 } // namespace llvm 184 185 #endif 186