1 //===- PrettyVariableDumper.cpp ---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "PrettyVariableDumper.h"
11 #include "PrettyBuiltinDumper.h"
12 #include "PrettyFunctionDumper.h"
13 #include "llvm-pdbutil.h"
15 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
16 #include "llvm/DebugInfo/PDB/IPDBSession.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
19 #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
21 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
22 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
23 #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
24 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
25 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
26 #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
27 #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
28 #include "llvm/DebugInfo/PDB/PDBTypes.h"
30 #include "llvm/Support/Format.h"
33 using namespace llvm::codeview
;
34 using namespace llvm::pdb
;
36 VariableDumper::VariableDumper(LinePrinter
&P
)
37 : PDBSymDumper(true), Printer(P
) {}
39 void VariableDumper::start(const PDBSymbolData
&Var
, uint32_t Offset
) {
40 if (Var
.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated
)
42 if (Printer
.IsSymbolExcluded(Var
.getName()))
45 auto VarType
= Var
.getType();
47 uint64_t Length
= VarType
->getRawSymbol().getLength();
49 switch (auto LocType
= Var
.getLocationType()) {
50 case PDB_LocType::Static
:
53 WithColor(Printer
, PDB_ColorItem::Address
).get()
54 << format_hex(Var
.getVirtualAddress(), 10);
55 Printer
<< ", sizeof=" << Length
<< "] ";
56 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << "static ";
57 dumpSymbolTypeAndName(*VarType
, Var
.getName());
59 case PDB_LocType::Constant
:
60 if (isa
<PDBSymbolTypeEnum
>(*VarType
))
63 Printer
<< "data [sizeof=" << Length
<< "] ";
64 dumpSymbolTypeAndName(*VarType
, Var
.getName());
66 WithColor(Printer
, PDB_ColorItem::LiteralValue
).get() << Var
.getValue();
68 case PDB_LocType::ThisRel
:
71 WithColor(Printer
, PDB_ColorItem::Offset
).get()
72 << "+" << format_hex(Offset
+ Var
.getOffset(), 4)
73 << " [sizeof=" << Length
<< "] ";
74 dumpSymbolTypeAndName(*VarType
, Var
.getName());
76 case PDB_LocType::BitField
:
79 WithColor(Printer
, PDB_ColorItem::Offset
).get()
80 << "+" << format_hex(Offset
+ Var
.getOffset(), 4)
81 << " [sizeof=" << Length
<< "] ";
82 dumpSymbolTypeAndName(*VarType
, Var
.getName());
84 WithColor(Printer
, PDB_ColorItem::LiteralValue
).get() << Var
.getLength();
88 Printer
<< "data [sizeof=" << Length
<< "] ";
89 Printer
<< "unknown(" << LocType
<< ") ";
90 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << Var
.getName();
95 void VariableDumper::startVbptr(uint32_t Offset
, uint32_t Size
) {
99 WithColor(Printer
, PDB_ColorItem::Offset
).get()
100 << "+" << format_hex(Offset
, 4) << " [sizeof=" << Size
<< "] ";
103 void VariableDumper::start(const PDBSymbolTypeVTable
&Var
, uint32_t Offset
) {
106 auto VTableType
= cast
<PDBSymbolTypePointer
>(Var
.getType());
107 uint32_t PointerSize
= VTableType
->getLength();
109 WithColor(Printer
, PDB_ColorItem::Offset
).get()
110 << "+" << format_hex(Offset
+ Var
.getOffset(), 4)
111 << " [sizeof=" << PointerSize
<< "] ";
114 void VariableDumper::dump(const PDBSymbolTypeArray
&Symbol
) {
115 auto ElementType
= Symbol
.getElementType();
119 ElementType
->dump(*this);
122 void VariableDumper::dumpRight(const PDBSymbolTypeArray
&Symbol
) {
123 auto ElementType
= Symbol
.getElementType();
127 Printer
<< '[' << Symbol
.getCount() << ']';
128 ElementType
->dumpRight(*this);
131 void VariableDumper::dump(const PDBSymbolTypeBuiltin
&Symbol
) {
132 BuiltinDumper
Dumper(Printer
);
133 Dumper
.start(Symbol
);
136 void VariableDumper::dump(const PDBSymbolTypeEnum
&Symbol
) {
137 WithColor(Printer
, PDB_ColorItem::Type
).get() << Symbol
.getName();
140 void VariableDumper::dump(const PDBSymbolTypeFunctionSig
&Symbol
) {
141 auto ReturnType
= Symbol
.getReturnType();
142 ReturnType
->dump(*this);
145 uint32_t ClassParentId
= Symbol
.getClassParentId();
147 Symbol
.getSession().getConcreteSymbolById
<PDBSymbolTypeUDT
>(
151 WithColor(Printer
, PDB_ColorItem::Identifier
).get()
152 << ClassParent
->getName();
157 void VariableDumper::dumpRight(const PDBSymbolTypeFunctionSig
&Symbol
) {
159 if (auto Arguments
= Symbol
.getArguments()) {
161 while (auto Arg
= Arguments
->getNext()) {
163 if (++Index
< Arguments
->getChildCount())
169 if (Symbol
.isConstType())
170 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " const";
171 if (Symbol
.isVolatileType())
172 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " volatile";
174 if (Symbol
.getRawSymbol().isRestrictedType())
175 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " __restrict";
178 void VariableDumper::dump(const PDBSymbolTypePointer
&Symbol
) {
179 auto PointeeType
= Symbol
.getPointeeType();
182 PointeeType
->dump(*this);
183 if (auto FuncSig
= unique_dyn_cast
<PDBSymbolTypeFunctionSig
>(PointeeType
)) {
184 // A hack to get the calling convention in the right spot.
186 PDB_CallingConv CC
= FuncSig
->getCallingConvention();
187 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << CC
<< " ";
188 } else if (isa
<PDBSymbolTypeArray
>(PointeeType
)) {
191 Printer
<< (Symbol
.isReference() ? "&" : "*");
192 if (Symbol
.isConstType())
193 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " const ";
194 if (Symbol
.isVolatileType())
195 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " volatile ";
197 if (Symbol
.getRawSymbol().isRestrictedType())
198 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << " __restrict ";
201 void VariableDumper::dumpRight(const PDBSymbolTypePointer
&Symbol
) {
202 auto PointeeType
= Symbol
.getPointeeType();
206 if (isa
<PDBSymbolTypeFunctionSig
>(PointeeType
) ||
207 isa
<PDBSymbolTypeArray
>(PointeeType
)) {
210 PointeeType
->dumpRight(*this);
213 void VariableDumper::dump(const PDBSymbolTypeTypedef
&Symbol
) {
214 WithColor(Printer
, PDB_ColorItem::Keyword
).get() << "typedef ";
215 WithColor(Printer
, PDB_ColorItem::Type
).get() << Symbol
.getName();
218 void VariableDumper::dump(const PDBSymbolTypeUDT
&Symbol
) {
219 WithColor(Printer
, PDB_ColorItem::Type
).get() << Symbol
.getName();
222 void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol
&Type
,
225 WithColor(Printer
, PDB_ColorItem::Identifier
).get() << " " << Name
;
226 Type
.dumpRight(*this);