aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-pdbdump/VariableDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-pdbdump/VariableDumper.cpp')
-rw-r--r--tools/llvm-pdbdump/VariableDumper.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/tools/llvm-pdbdump/VariableDumper.cpp b/tools/llvm-pdbdump/VariableDumper.cpp
new file mode 100644
index 0000000..913cfee
--- /dev/null
+++ b/tools/llvm-pdbdump/VariableDumper.cpp
@@ -0,0 +1,120 @@
+//===- VariableDumper.cpp - -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VariableDumper.h"
+
+#include "llvm-pdbdump.h"
+#include "FunctionDumper.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+VariableDumper::VariableDumper() : PDBSymDumper(true) {}
+
+void VariableDumper::start(const PDBSymbolData &Var, raw_ostream &OS,
+ int Indent) {
+ OS << newline(Indent);
+ OS << "data ";
+
+ auto VarType = Var.getType();
+
+ switch (auto LocType = Var.getLocationType()) {
+ case PDB_LocType::Static:
+ OS << "[" << format_hex(Var.getRelativeVirtualAddress(), 10) << "] ";
+ OS << "static ";
+ dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+ break;
+ case PDB_LocType::Constant:
+ OS << "const ";
+ dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+ OS << "[" << Var.getValue() << "]";
+ break;
+ case PDB_LocType::ThisRel:
+ OS << "+" << format_hex(Var.getOffset(), 4) << " ";
+ dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+ break;
+ default:
+ break;
+ OS << "unknown(" << LocType << ") " << Var.getName();
+ }
+}
+
+void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
+ int Indent) {
+ OS << Symbol.getBuiltinType();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+ int Indent) {
+ OS << Symbol.getName();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol,
+ raw_ostream &OS, int Indent) {}
+
+void VariableDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
+ int Indent) {
+ auto PointeeType = Symbol.getPointeeType();
+ if (!PointeeType)
+ return;
+
+ if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) {
+ FunctionDumper NestedDumper;
+ FunctionDumper::PointerType Pointer =
+ Symbol.isReference() ? FunctionDumper::PointerType::Reference
+ : FunctionDumper::PointerType::Pointer;
+ NestedDumper.start(*Func, Pointer, OS, Indent);
+ } else {
+ if (Symbol.isConstType())
+ OS << "const ";
+ if (Symbol.isVolatileType())
+ OS << "volatile ";
+ PointeeType->dump(OS, Indent, *this);
+ OS << (Symbol.isReference() ? "&" : "*");
+ }
+}
+
+void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+ int Indent) {
+ OS << "typedef " << Symbol.getName();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) {
+ OS << Symbol.getName();
+}
+
+void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type,
+ StringRef Name, raw_ostream &OS) {
+ if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) {
+ std::string IndexSpec;
+ raw_string_ostream IndexStream(IndexSpec);
+ std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType();
+ while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) {
+ IndexStream << "[" << NestedArray->getCount() << "]";
+ ElementType = NestedArray->getElementType();
+ }
+ IndexStream << "[" << ArrayType->getCount() << "]";
+ ElementType->dump(OS, 0, *this);
+ OS << " " << Name << IndexStream.str();
+ } else {
+ Type.dump(OS, 0, *this);
+ OS << " " << Name;
+ }
+}