1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===- VariableDumper.cpp - -------------------------------------*- C++ -*-===// 2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// The LLVM Compiler Infrastructure 4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file is distributed under the University of Illinois Open Source 6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// License. See LICENSE.TXT for details. 7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "VariableDumper.h" 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "BuiltinDumper.h" 134c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "LinePrinter.h" 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm-pdbdump.h" 15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "FunctionDumper.h" 16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" 204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" 22ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 27ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Format.h" 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesusing namespace llvm; 30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarusing namespace llvm::pdb; 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarVariableDumper::VariableDumper(LinePrinter &P) 334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : PDBSymDumper(true), Printer(P) {} 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::start(const PDBSymbolData &Var) { 36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (Var.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated) 374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Printer.IsSymbolExcluded(Var.getName())) 394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return; 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto VarType = Var.getType(); 42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (auto LocType = Var.getLocationType()) { 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case PDB_LocType::Static: 454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer.NewLine(); 464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "data ["; 474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Address).get() 486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar << format_hex(Var.getVirtualAddress(), 10); 494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "] "; 504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Keyword).get() << "static "; 514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar dumpSymbolTypeAndName(*VarType, Var.getName()); 52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case PDB_LocType::Constant: 544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (isa<PDBSymbolTypeEnum>(*VarType)) 554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer.NewLine(); 574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "data "; 584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar dumpSymbolTypeAndName(*VarType, Var.getName()); 604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << " = "; 614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue(); 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case PDB_LocType::ThisRel: 644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer.NewLine(); 654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "data "; 664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Offset).get() 674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar << "+" << format_hex(Var.getOffset(), 4) << " "; 684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar dumpSymbolTypeAndName(*VarType, Var.getName()); 694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case PDB_LocType::BitField: 714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer.NewLine(); 724c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "data "; 734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Offset).get() 744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar << "+" << format_hex(Var.getOffset(), 4) << " "; 754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar dumpSymbolTypeAndName(*VarType, Var.getName()); 764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << " : "; 774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength(); 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer.NewLine(); 814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "data "; 824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << "unknown(" << LocType << ") "; 834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName(); 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) { 894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar BuiltinDumper Dumper(Printer); 904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Dumper.start(Symbol); 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) { 944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); 95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {} 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypePointer &Symbol) { 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto PointeeType = Symbol.getPointeeType(); 101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!PointeeType) 102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) { 1054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionDumper NestedDumper(Printer); 106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FunctionDumper::PointerType Pointer = 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Symbol.isReference() ? FunctionDumper::PointerType::Reference 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : FunctionDumper::PointerType::Pointer; 1094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar NestedDumper.start(*Func, Pointer); 110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Symbol.isConstType()) 1124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Keyword).get() << "const "; 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Symbol.isVolatileType()) 1144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile "; 1154c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PointeeType->dump(*this); 1164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << (Symbol.isReference() ? "&" : "*"); 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) { 1214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef "; 1224c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); 123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) { 1264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName(); 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type, 1304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef Name) { 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) { 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string IndexSpec; 133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines raw_string_ostream IndexStream(IndexSpec); 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType(); 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) { 1364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IndexStream << "["; 1374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IndexStream << NestedArray->getCount(); 1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IndexStream << "]"; 139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ElementType = NestedArray->getElementType(); 140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IndexStream << "[" << ArrayType->getCount() << "]"; 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ElementType->dump(*this); 1434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Printer << IndexStream.str(); 145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else { 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!tryDumpFunctionPointer(Type, Name)) { 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type.dump(*this); 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name; 1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 1524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type, 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StringRef Name) { 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // Function pointers come across as pointers to function signatures. But the 1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar // signature carries no name, so we have to handle this case separately. 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (auto *PointerType = dyn_cast<PDBSymbolTypePointer>(&Type)) { 1584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto PointeeType = PointerType->getPointeeType(); 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (auto *FunctionSig = 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) { 1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionDumper Dumper(Printer); 1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer; 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (PointerType->isReference()) 1644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar PT = FunctionDumper::PointerType::Reference; 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar std::string NameStr(Name.begin(), Name.end()); 1664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Dumper.start(*FunctionSig, NameStr.c_str(), PT); 1674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return true; 1684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 1704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return false; 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 172