1 //===- PrettyVariableDumper.cpp ---------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "PrettyVariableDumper.h"
11
12 #include "LinePrinter.h"
13 #include "PrettyBuiltinDumper.h"
14 #include "PrettyFunctionDumper.h"
15 #include "llvm-pdbutil.h"
16
17 #include "llvm/DebugInfo/PDB/IPDBSession.h"
18 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
19 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
21 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
22 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
23 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
24 #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
25 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
26 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
27 #include "llvm/DebugInfo/PDB/PDBTypes.h"
28
29 #include "llvm/Support/Format.h"
30
31 using namespace llvm;
32 using namespace llvm::codeview;
33 using namespace llvm::pdb;
34
VariableDumper(LinePrinter & P)35 VariableDumper::VariableDumper(LinePrinter &P)
36 : PDBSymDumper(true), Printer(P) {}
37
start(const PDBSymbolData & Var,uint32_t Offset)38 void VariableDumper::start(const PDBSymbolData &Var, uint32_t Offset) {
39 if (Var.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
40 return;
41 if (Printer.IsSymbolExcluded(Var.getName()))
42 return;
43
44 auto VarType = Var.getType();
45
46 uint64_t Length = VarType->getRawSymbol().getLength();
47
48 switch (auto LocType = Var.getLocationType()) {
49 case PDB_LocType::Static:
50 Printer.NewLine();
51 Printer << "data [";
52 WithColor(Printer, PDB_ColorItem::Address).get()
53 << format_hex(Var.getVirtualAddress(), 10);
54 Printer << ", sizeof=" << Length << "] ";
55 WithColor(Printer, PDB_ColorItem::Keyword).get() << "static ";
56 dumpSymbolTypeAndName(*VarType, Var.getName());
57 break;
58 case PDB_LocType::Constant:
59 if (isa<PDBSymbolTypeEnum>(*VarType))
60 break;
61 Printer.NewLine();
62 Printer << "data [sizeof=" << Length << "] ";
63 dumpSymbolTypeAndName(*VarType, Var.getName());
64 Printer << " = ";
65 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue();
66 break;
67 case PDB_LocType::ThisRel:
68 Printer.NewLine();
69 Printer << "data ";
70 WithColor(Printer, PDB_ColorItem::Offset).get()
71 << "+" << format_hex(Offset + Var.getOffset(), 4)
72 << " [sizeof=" << Length << "] ";
73 dumpSymbolTypeAndName(*VarType, Var.getName());
74 break;
75 case PDB_LocType::BitField:
76 Printer.NewLine();
77 Printer << "data ";
78 WithColor(Printer, PDB_ColorItem::Offset).get()
79 << "+" << format_hex(Offset + Var.getOffset(), 4)
80 << " [sizeof=" << Length << "] ";
81 dumpSymbolTypeAndName(*VarType, Var.getName());
82 Printer << " : ";
83 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
84 break;
85 default:
86 Printer.NewLine();
87 Printer << "data [sizeof=" << Length << "] ";
88 Printer << "unknown(" << LocType << ") ";
89 WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName();
90 break;
91 }
92 }
93
startVbptr(uint32_t Offset,uint32_t Size)94 void VariableDumper::startVbptr(uint32_t Offset, uint32_t Size) {
95 Printer.NewLine();
96 Printer << "vbptr ";
97
98 WithColor(Printer, PDB_ColorItem::Offset).get()
99 << "+" << format_hex(Offset, 4) << " [sizeof=" << Size << "] ";
100 }
101
start(const PDBSymbolTypeVTable & Var,uint32_t Offset)102 void VariableDumper::start(const PDBSymbolTypeVTable &Var, uint32_t Offset) {
103 Printer.NewLine();
104 Printer << "vfptr ";
105 auto VTableType = cast<PDBSymbolTypePointer>(Var.getType());
106 uint32_t PointerSize = VTableType->getLength();
107
108 WithColor(Printer, PDB_ColorItem::Offset).get()
109 << "+" << format_hex(Offset + Var.getOffset(), 4)
110 << " [sizeof=" << PointerSize << "] ";
111 }
112
dump(const PDBSymbolTypeArray & Symbol)113 void VariableDumper::dump(const PDBSymbolTypeArray &Symbol) {
114 auto ElementType = Symbol.getElementType();
115 assert(ElementType);
116 if (!ElementType)
117 return;
118 ElementType->dump(*this);
119 }
120
dumpRight(const PDBSymbolTypeArray & Symbol)121 void VariableDumper::dumpRight(const PDBSymbolTypeArray &Symbol) {
122 auto ElementType = Symbol.getElementType();
123 assert(ElementType);
124 if (!ElementType)
125 return;
126 Printer << '[' << Symbol.getCount() << ']';
127 ElementType->dumpRight(*this);
128 }
129
dump(const PDBSymbolTypeBuiltin & Symbol)130 void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
131 BuiltinDumper Dumper(Printer);
132 Dumper.start(Symbol);
133 }
134
dump(const PDBSymbolTypeEnum & Symbol)135 void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) {
136 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
137 }
138
dump(const PDBSymbolTypeFunctionSig & Symbol)139 void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
140 auto ReturnType = Symbol.getReturnType();
141 ReturnType->dump(*this);
142 Printer << " ";
143
144 uint32_t ClassParentId = Symbol.getClassParentId();
145 auto ClassParent =
146 Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
147 ClassParentId);
148
149 if (ClassParent) {
150 WithColor(Printer, PDB_ColorItem::Identifier).get()
151 << ClassParent->getName();
152 Printer << "::";
153 }
154 }
155
dumpRight(const PDBSymbolTypeFunctionSig & Symbol)156 void VariableDumper::dumpRight(const PDBSymbolTypeFunctionSig &Symbol) {
157 Printer << "(";
158 if (auto Arguments = Symbol.getArguments()) {
159 uint32_t Index = 0;
160 while (auto Arg = Arguments->getNext()) {
161 Arg->dump(*this);
162 if (++Index < Arguments->getChildCount())
163 Printer << ", ";
164 }
165 }
166 Printer << ")";
167
168 if (Symbol.isConstType())
169 WithColor(Printer, PDB_ColorItem::Keyword).get() << " const";
170 if (Symbol.isVolatileType())
171 WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile";
172
173 if (Symbol.getRawSymbol().isRestrictedType())
174 WithColor(Printer, PDB_ColorItem::Keyword).get() << " __restrict";
175 }
176
dump(const PDBSymbolTypePointer & Symbol)177 void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) {
178 auto PointeeType = Symbol.getPointeeType();
179 if (!PointeeType)
180 return;
181 PointeeType->dump(*this);
182 if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
183 // A hack to get the calling convention in the right spot.
184 Printer << " (";
185 PDB_CallingConv CC = FuncSig->getCallingConvention();
186 WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
187 } else if (isa<PDBSymbolTypeArray>(PointeeType)) {
188 Printer << " (";
189 }
190 Printer << (Symbol.isReference() ? "&" : "*");
191 if (Symbol.isConstType())
192 WithColor(Printer, PDB_ColorItem::Keyword).get() << " const ";
193 if (Symbol.isVolatileType())
194 WithColor(Printer, PDB_ColorItem::Keyword).get() << " volatile ";
195
196 if (Symbol.getRawSymbol().isRestrictedType())
197 WithColor(Printer, PDB_ColorItem::Keyword).get() << " __restrict ";
198 }
199
dumpRight(const PDBSymbolTypePointer & Symbol)200 void VariableDumper::dumpRight(const PDBSymbolTypePointer &Symbol) {
201 auto PointeeType = Symbol.getPointeeType();
202 assert(PointeeType);
203 if (!PointeeType)
204 return;
205 if (isa<PDBSymbolTypeFunctionSig>(PointeeType) ||
206 isa<PDBSymbolTypeArray>(PointeeType)) {
207 Printer << ")";
208 }
209 PointeeType->dumpRight(*this);
210 }
211
dump(const PDBSymbolTypeTypedef & Symbol)212 void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
213 WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef ";
214 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
215 }
216
dump(const PDBSymbolTypeUDT & Symbol)217 void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) {
218 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
219 }
220
dumpSymbolTypeAndName(const PDBSymbol & Type,StringRef Name)221 void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type,
222 StringRef Name) {
223 Type.dump(*this);
224 WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name;
225 Type.dumpRight(*this);
226 }
227