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 35 VariableDumper::VariableDumper(LinePrinter &P) 36 : PDBSymDumper(true), Printer(P) {} 37 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 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 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 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 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 130 void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { 131 BuiltinDumper Dumper(Printer); 132 Dumper.start(Symbol); 133 } 134 135 void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) { 136 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); 137 } 138 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 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 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 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 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 217 void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) { 218 WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); 219 } 220 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