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