Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-pdbutil/PrettyClassLayoutGraphicalDumper.cpp
35259 views
1
//===- PrettyClassLayoutGraphicalDumper.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
#include "PrettyClassLayoutGraphicalDumper.h"
10
11
#include "PrettyClassDefinitionDumper.h"
12
#include "PrettyEnumDumper.h"
13
#include "PrettyFunctionDumper.h"
14
#include "PrettyTypedefDumper.h"
15
#include "PrettyVariableDumper.h"
16
#include "PrettyVariableDumper.h"
17
#include "llvm-pdbutil.h"
18
19
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
20
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
21
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
22
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
23
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
24
#include "llvm/DebugInfo/PDB/UDTLayout.h"
25
#include "llvm/Support/Format.h"
26
27
using namespace llvm;
28
using namespace llvm::pdb;
29
30
PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
31
LinePrinter &P, uint32_t RecurseLevel, uint32_t InitialOffset)
32
: PDBSymDumper(true), Printer(P), RecursionLevel(RecurseLevel),
33
ClassOffsetZero(InitialOffset), CurrentAbsoluteOffset(InitialOffset) {}
34
35
bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {
36
37
if (RecursionLevel == 1 &&
38
opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::All) {
39
for (const auto &Other : Layout.other_items())
40
Other->dump(*this);
41
for (const auto &Func : Layout.funcs())
42
Func->dump(*this);
43
}
44
45
const BitVector &UseMap = Layout.usedBytes();
46
int NextPaddingByte = UseMap.find_first_unset();
47
48
for (const auto &Item : Layout.layout_items()) {
49
// Calculate the absolute offset of the first byte of the next field.
50
uint32_t RelativeOffset = Item->getOffsetInParent();
51
CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;
52
53
// This might be an empty base, in which case it could extend outside the
54
// bounds of the parent class.
55
if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {
56
// If there is any remaining padding in this class, and the offset of the
57
// new item is after the padding, then we must have just jumped over some
58
// padding. Print a padding row and then look for where the next block
59
// of padding begins.
60
if ((NextPaddingByte >= 0) &&
61
(RelativeOffset > uint32_t(NextPaddingByte))) {
62
printPaddingRow(RelativeOffset - NextPaddingByte);
63
NextPaddingByte = UseMap.find_next_unset(RelativeOffset);
64
}
65
}
66
67
CurrentItem = Item;
68
if (Item->isVBPtr()) {
69
VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
70
71
VariableDumper VarDumper(Printer);
72
VarDumper.startVbptr(CurrentAbsoluteOffset, Layout.getSize());
73
} else {
74
if (auto Sym = Item->getSymbol())
75
Sym->dump(*this);
76
}
77
78
if (Item->getLayoutSize() > 0) {
79
uint32_t Prev = RelativeOffset + Item->getLayoutSize() - 1;
80
if (Prev < UseMap.size())
81
NextPaddingByte = UseMap.find_next_unset(Prev);
82
}
83
}
84
85
auto TailPadding = Layout.tailPadding();
86
if (TailPadding > 0) {
87
if (TailPadding != 1 || Layout.getSize() != 1) {
88
Printer.NewLine();
89
WithColor(Printer, PDB_ColorItem::Padding).get()
90
<< "<padding> (" << TailPadding << " bytes)";
91
DumpedAnything = true;
92
}
93
}
94
95
return DumpedAnything;
96
}
97
98
void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {
99
if (Amount == 0)
100
return;
101
102
Printer.NewLine();
103
WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
104
<< " bytes)";
105
DumpedAnything = true;
106
}
107
108
void PrettyClassLayoutGraphicalDumper::dump(
109
const PDBSymbolTypeBaseClass &Symbol) {
110
assert(CurrentItem != nullptr);
111
112
Printer.NewLine();
113
BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
114
115
std::string Label = "base";
116
if (Layout.isVirtualBase()) {
117
Label.insert(Label.begin(), 'v');
118
if (Layout.getBase().isIndirectVirtualBaseClass())
119
Label.insert(Label.begin(), 'i');
120
}
121
Printer << Label << " ";
122
123
uint32_t Size = Layout.isEmptyBase() ? 1 : Layout.getLayoutSize();
124
125
WithColor(Printer, PDB_ColorItem::Offset).get()
126
<< "+" << format_hex(CurrentAbsoluteOffset, 4) << " [sizeof=" << Size
127
<< "] ";
128
129
WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
130
131
if (shouldRecurse()) {
132
Printer.Indent();
133
uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
134
PrettyClassLayoutGraphicalDumper BaseDumper(Printer, RecursionLevel + 1,
135
ChildOffsetZero);
136
DumpedAnything |= BaseDumper.start(Layout);
137
Printer.Unindent();
138
}
139
140
DumpedAnything = true;
141
}
142
143
bool PrettyClassLayoutGraphicalDumper::shouldRecurse() const {
144
uint32_t Limit = opts::pretty::ClassRecursionDepth;
145
if (Limit == 0)
146
return true;
147
return RecursionLevel < Limit;
148
}
149
150
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {
151
VariableDumper VarDumper(Printer);
152
VarDumper.start(Symbol, ClassOffsetZero);
153
154
if (CurrentItem != nullptr) {
155
DataMemberLayoutItem &Layout =
156
static_cast<DataMemberLayoutItem &>(*CurrentItem);
157
158
if (Layout.hasUDTLayout() && shouldRecurse()) {
159
uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
160
Printer.Indent();
161
PrettyClassLayoutGraphicalDumper TypeDumper(Printer, RecursionLevel + 1,
162
ChildOffsetZero);
163
TypeDumper.start(Layout.getUDTLayout());
164
Printer.Unindent();
165
}
166
}
167
168
DumpedAnything = true;
169
}
170
171
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
172
assert(CurrentItem != nullptr);
173
174
VariableDumper VarDumper(Printer);
175
VarDumper.start(Symbol, ClassOffsetZero);
176
177
DumpedAnything = true;
178
}
179
180
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {
181
DumpedAnything = true;
182
Printer.NewLine();
183
EnumDumper Dumper(Printer);
184
Dumper.start(Symbol);
185
}
186
187
void PrettyClassLayoutGraphicalDumper::dump(
188
const PDBSymbolTypeTypedef &Symbol) {
189
DumpedAnything = true;
190
Printer.NewLine();
191
TypedefDumper Dumper(Printer);
192
Dumper.start(Symbol);
193
}
194
195
void PrettyClassLayoutGraphicalDumper::dump(
196
const PDBSymbolTypeBuiltin &Symbol) {}
197
198
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
199
200
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {
201
if (Printer.IsSymbolExcluded(Symbol.getName()))
202
return;
203
if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
204
return;
205
if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&
206
!Symbol.isIntroVirtualFunction())
207
return;
208
209
DumpedAnything = true;
210
Printer.NewLine();
211
FunctionDumper Dumper(Printer);
212
Dumper.start(Symbol, FunctionDumper::PointerType::None);
213
}
214
215