Home | History | Annotate | Download | only in llvm-pdbdump
      1 //===- VariableDumper.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 "VariableDumper.h"
     11 
     12 #include "BuiltinDumper.h"
     13 #include "LinePrinter.h"
     14 #include "llvm-pdbdump.h"
     15 #include "FunctionDumper.h"
     16 
     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/PDBSymbolTypeFunctionSig.h"
     22 #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
     23 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
     24 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
     25 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
     26 
     27 #include "llvm/Support/Format.h"
     28 
     29 using namespace llvm;
     30 
     31 VariableDumper::VariableDumper(LinePrinter &P)
     32     : PDBSymDumper(true), Printer(P) {}
     33 
     34 void VariableDumper::start(const PDBSymbolData &Var) {
     35   if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated)
     36     return;
     37   if (Printer.IsSymbolExcluded(Var.getName()))
     38     return;
     39 
     40   auto VarType = Var.getType();
     41 
     42   switch (auto LocType = Var.getLocationType()) {
     43   case PDB_LocType::Static:
     44     Printer.NewLine();
     45     Printer << "data [";
     46     WithColor(Printer, PDB_ColorItem::Address).get()
     47         << format_hex(Var.getVirtualAddress(), 10);
     48     Printer << "] ";
     49     WithColor(Printer, PDB_ColorItem::Keyword).get() << "static ";
     50     dumpSymbolTypeAndName(*VarType, Var.getName());
     51     break;
     52   case PDB_LocType::Constant:
     53     if (isa<PDBSymbolTypeEnum>(*VarType))
     54       break;
     55     Printer.NewLine();
     56     Printer << "data ";
     57     WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
     58     dumpSymbolTypeAndName(*VarType, Var.getName());
     59     Printer << " = ";
     60     WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue();
     61     break;
     62   case PDB_LocType::ThisRel:
     63     Printer.NewLine();
     64     Printer << "data ";
     65     WithColor(Printer, PDB_ColorItem::Offset).get()
     66         << "+" << format_hex(Var.getOffset(), 4) << " ";
     67     dumpSymbolTypeAndName(*VarType, Var.getName());
     68     break;
     69   case PDB_LocType::BitField:
     70     Printer.NewLine();
     71     Printer << "data ";
     72     WithColor(Printer, PDB_ColorItem::Offset).get()
     73         << "+" << format_hex(Var.getOffset(), 4) << " ";
     74     dumpSymbolTypeAndName(*VarType, Var.getName());
     75     Printer << " : ";
     76     WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
     77     break;
     78   default:
     79     Printer.NewLine();
     80     Printer << "data ";
     81     Printer << "unknown(" << LocType << ") ";
     82     WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName();
     83     break;
     84   }
     85 }
     86 
     87 void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
     88   BuiltinDumper Dumper(Printer);
     89   Dumper.start(Symbol);
     90 }
     91 
     92 void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol) {
     93   WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
     94 }
     95 
     96 void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {}
     97 
     98 void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) {
     99   auto PointeeType = Symbol.getPointeeType();
    100   if (!PointeeType)
    101     return;
    102 
    103   if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) {
    104     FunctionDumper NestedDumper(Printer);
    105     FunctionDumper::PointerType Pointer =
    106         Symbol.isReference() ? FunctionDumper::PointerType::Reference
    107                              : FunctionDumper::PointerType::Pointer;
    108     NestedDumper.start(*Func, Pointer);
    109   } else {
    110     if (Symbol.isConstType())
    111       WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
    112     if (Symbol.isVolatileType())
    113       WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
    114     PointeeType->dump(*this);
    115     Printer << (Symbol.isReference() ? "&" : "*");
    116   }
    117 }
    118 
    119 void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
    120   WithColor(Printer, PDB_ColorItem::Keyword).get() << "typedef ";
    121   WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
    122 }
    123 
    124 void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol) {
    125   WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
    126 }
    127 
    128 void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type,
    129                                            StringRef Name) {
    130   if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) {
    131     std::string IndexSpec;
    132     raw_string_ostream IndexStream(IndexSpec);
    133     std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType();
    134     while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) {
    135       IndexStream << "[";
    136       IndexStream << NestedArray->getCount();
    137       IndexStream << "]";
    138       ElementType = NestedArray->getElementType();
    139     }
    140     IndexStream << "[" << ArrayType->getCount() << "]";
    141     ElementType->dump(*this);
    142     WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name;
    143     Printer << IndexStream.str();
    144   } else {
    145     if (!tryDumpFunctionPointer(Type, Name)) {
    146       Type.dump(*this);
    147       WithColor(Printer, PDB_ColorItem::Identifier).get() << " " << Name;
    148     }
    149   }
    150 }
    151 
    152 bool VariableDumper::tryDumpFunctionPointer(const PDBSymbol &Type,
    153                                             StringRef Name) {
    154   // Function pointers come across as pointers to function signatures.  But the
    155   // signature carries no name, so we have to handle this case separately.
    156   if (auto *PointerType = dyn_cast<PDBSymbolTypePointer>(&Type)) {
    157     auto PointeeType = PointerType->getPointeeType();
    158     if (auto *FunctionSig =
    159             dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {
    160       FunctionDumper Dumper(Printer);
    161       FunctionDumper::PointerType PT = FunctionDumper::PointerType::Pointer;
    162       if (PointerType->isReference())
    163         PT = FunctionDumper::PointerType::Reference;
    164       std::string NameStr(Name.begin(), Name.end());
    165       Dumper.start(*FunctionSig, NameStr.c_str(), PT);
    166       return true;
    167     }
    168   }
    169   return false;
    170 }
    171