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/PrettyFunctionDumper.cpp
35259 views
1
//===- PrettyFunctionDumper.cpp --------------------------------- *- 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 "PrettyFunctionDumper.h"
10
#include "PrettyBuiltinDumper.h"
11
12
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
13
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
14
#include "llvm/DebugInfo/PDB/IPDBSession.h"
15
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
16
#include "llvm/DebugInfo/PDB/PDBExtras.h"
17
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
18
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
19
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
20
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
21
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
22
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
23
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
24
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
25
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
26
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
27
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
28
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
29
#include "llvm/Support/Format.h"
30
#include "llvm/Support/FormatVariadic.h"
31
32
using namespace llvm;
33
using namespace llvm::codeview;
34
using namespace llvm::pdb;
35
36
namespace {
37
template <class T>
38
void dumpClassParentWithScopeOperator(const T &Symbol, LinePrinter &Printer,
39
FunctionDumper &Dumper) {
40
uint32_t ClassParentId = Symbol.getClassParentId();
41
auto ClassParent =
42
Symbol.getSession().template getConcreteSymbolById<PDBSymbolTypeUDT>(
43
ClassParentId);
44
if (!ClassParent)
45
return;
46
47
WithColor(Printer, PDB_ColorItem::Type).get() << ClassParent->getName();
48
Printer << "::";
49
}
50
}
51
52
FunctionDumper::FunctionDumper(LinePrinter &P)
53
: PDBSymDumper(true), Printer(P) {}
54
55
void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
56
const char *Name, PointerType Pointer) {
57
auto ReturnType = Symbol.getReturnType();
58
if (!ReturnType)
59
Printer << "<unknown-type>";
60
else
61
ReturnType->dump(*this);
62
Printer << " ";
63
uint32_t ClassParentId = Symbol.getClassParentId();
64
auto ClassParent =
65
Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
66
ClassParentId);
67
68
PDB_CallingConv CC = Symbol.getCallingConvention();
69
bool ShouldDumpCallingConvention = true;
70
if ((ClassParent && CC == CallingConvention::ThisCall) ||
71
(!ClassParent && CC == CallingConvention::NearStdCall)) {
72
ShouldDumpCallingConvention = false;
73
}
74
75
if (Pointer == PointerType::None) {
76
if (ShouldDumpCallingConvention)
77
WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
78
if (ClassParent) {
79
Printer << "(";
80
WithColor(Printer, PDB_ColorItem::Identifier).get()
81
<< ClassParent->getName();
82
Printer << "::)";
83
}
84
} else {
85
Printer << "(";
86
if (ShouldDumpCallingConvention)
87
WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
88
if (ClassParent) {
89
WithColor(Printer, PDB_ColorItem::Identifier).get()
90
<< ClassParent->getName();
91
Printer << "::";
92
}
93
if (Pointer == PointerType::Reference)
94
Printer << "&";
95
else
96
Printer << "*";
97
if (Name)
98
WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
99
Printer << ")";
100
}
101
102
Printer << "(";
103
if (auto ChildEnum = Symbol.getArguments()) {
104
uint32_t Index = 0;
105
while (auto Arg = ChildEnum->getNext()) {
106
Arg->dump(*this);
107
if (++Index < ChildEnum->getChildCount())
108
Printer << ", ";
109
}
110
}
111
Printer << ")";
112
113
if (Symbol.isConstType())
114
WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
115
if (Symbol.isVolatileType())
116
WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
117
}
118
119
void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {
120
uint64_t FuncStart = Symbol.getVirtualAddress();
121
uint64_t FuncEnd = FuncStart + Symbol.getLength();
122
123
Printer << "func [";
124
WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);
125
if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {
126
uint64_t Prologue = DebugStart->getVirtualAddress() - FuncStart;
127
WithColor(Printer, PDB_ColorItem::Offset).get()
128
<< formatv("+{0,2}", Prologue);
129
}
130
Printer << " - ";
131
WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);
132
if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {
133
uint64_t Epilogue = FuncEnd - DebugEnd->getVirtualAddress();
134
WithColor(Printer, PDB_ColorItem::Offset).get()
135
<< formatv("-{0,2}", Epilogue);
136
}
137
138
WithColor(Printer, PDB_ColorItem::Comment).get()
139
<< formatv(" | sizeof={0,3}", Symbol.getLength());
140
Printer << "] (";
141
142
if (Symbol.hasFramePointer()) {
143
WithColor(Printer, PDB_ColorItem::Register).get()
144
<< CPURegister{Symbol.getRawSymbol().getPlatform(),
145
Symbol.getLocalBasePointerRegisterId()};
146
} else {
147
WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";
148
}
149
Printer << ") ";
150
151
if (Symbol.isVirtual() || Symbol.isPureVirtual())
152
WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";
153
154
auto Signature = Symbol.getSignature();
155
if (!Signature) {
156
WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
157
if (Pointer == PointerType::Pointer)
158
Printer << "*";
159
else if (Pointer == FunctionDumper::PointerType::Reference)
160
Printer << "&";
161
return;
162
}
163
164
auto ReturnType = Signature->getReturnType();
165
ReturnType->dump(*this);
166
Printer << " ";
167
168
auto ClassParent = Symbol.getClassParent();
169
CallingConvention CC = Signature->getCallingConvention();
170
if (Pointer != FunctionDumper::PointerType::None)
171
Printer << "(";
172
173
if ((ClassParent && CC != CallingConvention::ThisCall) ||
174
(!ClassParent && CC != CallingConvention::NearStdCall)) {
175
WithColor(Printer, PDB_ColorItem::Keyword).get()
176
<< Signature->getCallingConvention() << " ";
177
}
178
WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
179
if (Pointer != FunctionDumper::PointerType::None) {
180
if (Pointer == PointerType::Pointer)
181
Printer << "*";
182
else if (Pointer == FunctionDumper::PointerType::Reference)
183
Printer << "&";
184
Printer << ")";
185
}
186
187
Printer << "(";
188
if (auto Arguments = Symbol.getArguments()) {
189
uint32_t Index = 0;
190
while (auto Arg = Arguments->getNext()) {
191
auto ArgType = Arg->getType();
192
ArgType->dump(*this);
193
WithColor(Printer, PDB_ColorItem::Identifier).get() << " "
194
<< Arg->getName();
195
if (++Index < Arguments->getChildCount())
196
Printer << ", ";
197
}
198
if (Signature->isCVarArgs())
199
Printer << ", ...";
200
}
201
Printer << ")";
202
if (Symbol.isConstType())
203
WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
204
if (Symbol.isVolatileType())
205
WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
206
if (Symbol.isPureVirtual())
207
Printer << " = 0";
208
}
209
210
void FunctionDumper::dump(const PDBSymbolTypeArray &Symbol) {
211
auto ElementType = Symbol.getElementType();
212
213
ElementType->dump(*this);
214
Printer << "[";
215
WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getLength();
216
Printer << "]";
217
}
218
219
void FunctionDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
220
BuiltinDumper Dumper(Printer);
221
Dumper.start(Symbol);
222
}
223
224
void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
225
dumpClassParentWithScopeOperator(Symbol, Printer, *this);
226
WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
227
}
228
229
void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
230
// PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
231
// through to the real thing and dump it.
232
uint32_t TypeId = Symbol.getTypeId();
233
auto Type = Symbol.getSession().getSymbolById(TypeId);
234
if (Type)
235
Type->dump(*this);
236
else
237
Printer << "<unknown-type>";
238
}
239
240
void FunctionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
241
dumpClassParentWithScopeOperator(Symbol, Printer, *this);
242
WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
243
}
244
245
void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {
246
auto PointeeType = Symbol.getPointeeType();
247
if (!PointeeType)
248
return;
249
250
if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
251
FunctionDumper NestedDumper(Printer);
252
PointerType Pointer =
253
Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
254
NestedDumper.start(*FuncSig, nullptr, Pointer);
255
} else {
256
if (Symbol.isConstType())
257
WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
258
if (Symbol.isVolatileType())
259
WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
260
PointeeType->dump(*this);
261
Printer << (Symbol.isReference() ? "&" : "*");
262
263
if (Symbol.getRawSymbol().isRestrictedType())
264
WithColor(Printer, PDB_ColorItem::Keyword).get() << " __restrict";
265
}
266
}
267
268
void FunctionDumper::dump(const PDBSymbolTypeUDT &Symbol) {
269
WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
270
}
271
272