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