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 | std::optional<uint32_t> DumpModi; |
34 | std::optional<uint32_t> ParentRecurseDepth; |
35 | std::optional<uint32_t> ChildrenRecurseDepth; |
36 | std::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(T: formatv(Fmt, std::forward<Ts>(Items)...)); |
65 | } |
66 | template <typename... Ts> void format(const char *Fmt, Ts &&...Items) { |
67 | print(T: 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(args: 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 | , |
160 | Padding, |
161 | Keyword, |
162 | Offset, |
163 | Identifier, |
164 | Path, |
165 | , |
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 | |