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