summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbdump
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-02-23 05:58:34 +0000
committerZachary Turner <zturner@google.com>2015-02-23 05:58:34 +0000
commit29c69105fb02de4aec7ad0e614bc299c807370cd (patch)
tree704e1f63cf99a214a6ff0d8a09ba8c40eabf2c2b /llvm/tools/llvm-pdbdump
parent203540f2d6f54eec322ec7d4aeefa811ecb2335c (diff)
downloadbcm5719-llvm-29c69105fb02de4aec7ad0e614bc299c807370cd.tar.gz
bcm5719-llvm-29c69105fb02de4aec7ad0e614bc299c807370cd.zip
[llvm-pdbdump] Add an option to dump full class definitions.
This adds the --class-definitions flag. If specified, when dumping types, instead of "class Foo" you will see the full class definition, with member functions, constructors, access specifiers. NOTE: Using this option can be very slow, as generating a full class definition requires accessing many different parts of the PDB. llvm-svn: 230203
Diffstat (limited to 'llvm/tools/llvm-pdbdump')
-rw-r--r--llvm/tools/llvm-pdbdump/CMakeLists.txt2
-rw-r--r--llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp154
-rw-r--r--llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h64
-rw-r--r--llvm/tools/llvm-pdbdump/CompilandDumper.cpp21
-rw-r--r--llvm/tools/llvm-pdbdump/FunctionDumper.cpp80
-rw-r--r--llvm/tools/llvm-pdbdump/FunctionDumper.h3
-rw-r--r--llvm/tools/llvm-pdbdump/TypeDumper.cpp42
-rw-r--r--llvm/tools/llvm-pdbdump/TypeDumper.h8
-rw-r--r--llvm/tools/llvm-pdbdump/TypedefDumper.cpp3
-rw-r--r--llvm/tools/llvm-pdbdump/VariableDumper.cpp125
-rw-r--r--llvm/tools/llvm-pdbdump/VariableDumper.h43
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp4
12 files changed, 512 insertions, 37 deletions
diff --git a/llvm/tools/llvm-pdbdump/CMakeLists.txt b/llvm/tools/llvm-pdbdump/CMakeLists.txt
index 64b3d620837..0519bf0634c 100644
--- a/llvm/tools/llvm-pdbdump/CMakeLists.txt
+++ b/llvm/tools/llvm-pdbdump/CMakeLists.txt
@@ -5,8 +5,10 @@ set(LLVM_LINK_COMPONENTS
add_llvm_tool(llvm-pdbdump
llvm-pdbdump.cpp
+ ClassDefinitionDumper.cpp
CompilandDumper.cpp
FunctionDumper.cpp
TypeDumper.cpp
TypedefDumper.cpp
+ VariableDumper.cpp
)
diff --git a/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp
new file mode 100644
index 00000000000..f6bb6958d8b
--- /dev/null
+++ b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp
@@ -0,0 +1,154 @@
+//===- ClassDefinitionDumper.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClassDefinitionDumper.h"
+#include "FunctionDumper.h"
+#include "llvm-pdbdump.h"
+#include "TypedefDumper.h"
+#include "VariableDumper.h"
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+ClassDefinitionDumper::ClassDefinitionDumper() : PDBSymDumper(true) {}
+
+void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class,
+ raw_ostream &OS, int Indent) {
+ OS << "class " << Class.getName() << " {";
+ auto Children = Class.findAllChildren();
+ if (Children->getChildCount() == 0) {
+ OS << "}";
+ return;
+ }
+
+ // Try to dump symbols organized by member access level. Public members
+ // first, then protected, then private. This might be slow, so it's worth
+ // reconsidering the value of this if performance of large PDBs is a problem.
+ // NOTE: Access level of nested types is not recorded in the PDB, so we have
+ // a special case for them.
+ SymbolGroupByAccess Groups;
+ Groups.insert(std::make_pair((PDB_MemberAccess)0, SymbolGroup()));
+ Groups.insert(std::make_pair(PDB_MemberAccess::Private, SymbolGroup()));
+ Groups.insert(std::make_pair(PDB_MemberAccess::Protected, SymbolGroup()));
+ Groups.insert(std::make_pair(PDB_MemberAccess::Public, SymbolGroup()));
+
+ while (auto Child = Children->getNext()) {
+ PDB_MemberAccess Access = Child->getRawSymbol().getAccess();
+ if (isa<PDBSymbolTypeBaseClass>(*Child))
+ continue;
+
+ SymbolGroup *InsertGroup = nullptr;
+ auto &AccessGroup = Groups.find(Access)->second;
+
+ if (auto Func = dyn_cast<PDBSymbolFunc>(Child.get())) {
+ if (Func->isCompilerGenerated())
+ continue;
+ if (Func->getLength() == 0 && !Func->isPureVirtual())
+ continue;
+ Child.release();
+ AccessGroup.Functions.push_back(std::unique_ptr<PDBSymbolFunc>(Func));
+ } else if (auto Data = dyn_cast<PDBSymbolData>(Child.get())) {
+ Child.release();
+ AccessGroup.Data.push_back(std::unique_ptr<PDBSymbolData>(Data));
+ } else {
+ AccessGroup.Unknown.push_back(std::move(Child));
+ }
+ }
+
+ int Count = 0;
+ Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[(PDB_MemberAccess)0], OS,
+ Indent);
+ Count += dumpAccessGroup(PDB_MemberAccess::Public,
+ Groups[PDB_MemberAccess::Public], OS, Indent);
+ Count += dumpAccessGroup(PDB_MemberAccess::Protected,
+ Groups[PDB_MemberAccess::Protected], OS, Indent);
+ Count += dumpAccessGroup(PDB_MemberAccess::Private,
+ Groups[PDB_MemberAccess::Private], OS, Indent);
+
+ if (Count > 0)
+ OS << newline(Indent);
+ OS << "}";
+ OS.flush();
+}
+
+int ClassDefinitionDumper::dumpAccessGroup(PDB_MemberAccess Access,
+ const SymbolGroup &Group,
+ raw_ostream &OS, int Indent) {
+ if (Group.Functions.empty() && Group.Data.empty() && Group.Unknown.empty())
+ return 0;
+
+ int Count = 0;
+ if (Access == PDB_MemberAccess::Private)
+ OS << newline(Indent) << "private:";
+ else if (Access == PDB_MemberAccess::Protected)
+ OS << newline(Indent) << "protected:";
+ else if (Access == PDB_MemberAccess::Public)
+ OS << newline(Indent) << "public:";
+ for (auto iter = Group.Functions.begin(), end = Group.Functions.end();
+ iter != end; ++iter) {
+ ++Count;
+ (*iter)->dump(OS, Indent + 2, *this);
+ }
+ for (auto iter = Group.Data.begin(), end = Group.Data.end(); iter != end;
+ ++iter) {
+ ++Count;
+ (*iter)->dump(OS, Indent + 2, *this);
+ }
+ for (auto iter = Group.Unknown.begin(), end = Group.Unknown.end();
+ iter != end; ++iter) {
+ ++Count;
+ (*iter)->dump(OS, Indent + 2, *this);
+ }
+ return Count;
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol,
+ raw_ostream &OS, int Indent) {}
+
+void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS,
+ int Indent) {
+ VariableDumper Dumper;
+ Dumper.start(Symbol, OS, Indent);
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
+ int Indent) {
+ FunctionDumper Dumper;
+ Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent);
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol,
+ raw_ostream &OS, int Indent) {}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol,
+ raw_ostream &OS, int Indent) {
+ OS << newline(Indent) << "enum " << Symbol.getName();
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol,
+ raw_ostream &OS, int Indent) {
+ OS << newline(Indent);
+ TypedefDumper Dumper;
+ Dumper.start(Symbol, OS, Indent);
+ OS.flush();
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol,
+ raw_ostream &OS, int Indent) {}
diff --git a/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h
new file mode 100644
index 00000000000..f82d9760bcc
--- /dev/null
+++ b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h
@@ -0,0 +1,64 @@
+//===- ClassDefinitionDumper.h - --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_CLASSDEFINITIONDUMPER_H
+#define LLVM_TOOLS_LLVMPDBDUMP_CLASSDEFINITIONDUMPER_H
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+
+#include <list>
+#include <memory>
+#include <unordered_map>
+
+namespace llvm {
+
+class ClassDefinitionDumper : public PDBSymDumper {
+public:
+ ClassDefinitionDumper();
+
+ void start(const PDBSymbolTypeUDT &Exe, raw_ostream &OS, int Indent);
+
+ void dump(const PDBSymbolTypeBaseClass &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent) override;
+ void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent) override;
+ void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeVTable &Symbol, raw_ostream &OS,
+ int Indent) override;
+
+private:
+ struct SymbolGroup {
+ SymbolGroup() {}
+ SymbolGroup(SymbolGroup &&Other) {
+ Functions = std::move(Other.Functions);
+ Data = std::move(Other.Data);
+ Unknown = std::move(Other.Unknown);
+ }
+
+ std::list<std::unique_ptr<PDBSymbolFunc>> Functions;
+ std::list<std::unique_ptr<PDBSymbolData>> Data;
+ std::list<std::unique_ptr<PDBSymbol>> Unknown;
+ SymbolGroup(const SymbolGroup &other) = delete;
+ SymbolGroup &operator=(const SymbolGroup &other) = delete;
+ };
+ typedef std::unordered_map<PDB_MemberAccess, SymbolGroup> SymbolGroupByAccess;
+
+ int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group,
+ raw_ostream &OS, int Indent);
+};
+}
+
+#endif
diff --git a/llvm/tools/llvm-pdbdump/CompilandDumper.cpp b/llvm/tools/llvm-pdbdump/CompilandDumper.cpp
index ee55228309d..852ddfa02a5 100644
--- a/llvm/tools/llvm-pdbdump/CompilandDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/CompilandDumper.cpp
@@ -75,26 +75,11 @@ void CompilandDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS,
void CompilandDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
int Indent) {
- uint32_t FuncStart = Symbol.getRelativeVirtualAddress();
- uint32_t FuncEnd = FuncStart + Symbol.getLength();
- OS << newline(Indent) << "func [" << format_hex(FuncStart, 8);
- if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>())
- OS << "+" << DebugStart->getRelativeVirtualAddress() - FuncStart;
- OS << " - " << format_hex(FuncEnd, 8);
- if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>())
- OS << "-" << FuncEnd - DebugEnd->getRelativeVirtualAddress();
- OS << "] ";
-
- if (Symbol.hasFramePointer())
- OS << "(" << Symbol.getLocalBasePointerRegisterId() << ")";
- else
- OS << "(FPO)";
-
- OS << " ";
+ if (Symbol.getLength() == 0)
+ return;
FunctionDumper Dumper;
- Dumper.start(Symbol, OS);
- OS.flush();
+ Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent);
}
void CompilandDumper::dump(const PDBSymbolLabel &Symbol, raw_ostream &OS,
diff --git a/llvm/tools/llvm-pdbdump/FunctionDumper.cpp b/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
index 955d6499f9d..1bd201b8f69 100644
--- a/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/FunctionDumper.cpp
@@ -8,9 +8,13 @@
//===----------------------------------------------------------------------===//
#include "FunctionDumper.h"
+#include "llvm-pdbdump.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
@@ -19,6 +23,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/Support/Format.h"
using namespace llvm;
@@ -49,12 +54,23 @@ void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
ClassParentId);
+ PDB_CallingConv CC = Symbol.getCallingConvention();
+ bool ShouldDumpCallingConvention = true;
+ if ((ClassParent && CC == PDB_CallingConv::Thiscall) ||
+ (!ClassParent && CC == PDB_CallingConv::NearStdcall)) {
+ ShouldDumpCallingConvention = false;
+ }
+
if (Pointer == PointerType::None) {
- OS << Symbol.getCallingConvention() << " ";
+ if (ShouldDumpCallingConvention)
+ OS << CC << " ";
if (ClassParent)
OS << "(" << ClassParent->getName() << "::)";
} else {
- OS << "(" << Symbol.getCallingConvention() << " ";
+ OS << "(";
+ if (ShouldDumpCallingConvention)
+ OS << CC << " ";
+ OS << Symbol.getCallingConvention() << " ";
if (ClassParent)
OS << ClassParent->getName() << "::";
if (Pointer == PointerType::Reference)
@@ -81,33 +97,74 @@ void FunctionDumper::start(const PDBSymbolTypeFunctionSig &Symbol,
OS << " volatile";
}
-void FunctionDumper::start(const PDBSymbolFunc &Symbol, raw_ostream &OS) {
+void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer,
+ raw_ostream &OS, int Indent) {
+ uint32_t FuncStart = Symbol.getRelativeVirtualAddress();
+ uint32_t FuncEnd = FuncStart + Symbol.getLength();
+
+ OS << newline(Indent);
+
+ OS << "func [" << format_hex(FuncStart, 8);
+ if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>())
+ OS << "+" << DebugStart->getRelativeVirtualAddress() - FuncStart;
+ OS << " - " << format_hex(FuncEnd, 8);
+ if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>())
+ OS << "-" << FuncEnd - DebugEnd->getRelativeVirtualAddress();
+ OS << "] ";
+
+ if (Symbol.hasFramePointer())
+ OS << "(" << Symbol.getLocalBasePointerRegisterId() << ")";
+ else
+ OS << "(FPO)";
+
+ OS << " ";
if (Symbol.isVirtual() || Symbol.isPureVirtual())
OS << "virtual ";
auto Signature = Symbol.getSignature();
if (!Signature) {
OS << Symbol.getName();
+ if (Pointer == PointerType::Pointer)
+ OS << "*";
+ else if (Pointer == FunctionDumper::PointerType::Reference)
+ OS << "&";
return;
}
auto ReturnType = Signature->getReturnType();
ReturnType->dump(OS, 0, *this);
+ OS << " ";
+
+ auto ClassParent = Symbol.getClassParent();
+ PDB_CallingConv CC = Signature->getCallingConvention();
+ if (Pointer != FunctionDumper::PointerType::None)
+ OS << "(";
- OS << " " << Signature->getCallingConvention() << " ";
+ if ((ClassParent && CC != PDB_CallingConv::Thiscall) ||
+ (!ClassParent && CC != PDB_CallingConv::NearStdcall))
+ OS << Signature->getCallingConvention() << " ";
OS << Symbol.getName();
+ if (Pointer != FunctionDumper::PointerType::None) {
+ if (Pointer == PointerType::Pointer)
+ OS << "*";
+ else if (Pointer == FunctionDumper::PointerType::Reference)
+ OS << "&";
+ OS << ")";
+ }
OS << "(";
- if (auto ChildEnum = Signature->getArguments()) {
+ if (auto Arguments = Symbol.getArguments()) {
uint32_t Index = 0;
- while (auto Arg = ChildEnum->getNext()) {
- Arg->dump(OS, 0, *this);
- if (++Index < ChildEnum->getChildCount())
+ while (auto Arg = Arguments->getNext()) {
+ auto ArgType = Arg->getType();
+ ArgType->dump(OS, 0, *this);
+ OS << " " << Arg->getName();
+ if (++Index < Arguments->getChildCount())
OS << ", ";
}
}
+ OS.flush();
OS << ")";
-
if (Symbol.isConstType())
OS << " const";
if (Symbol.isVolatileType())
@@ -144,8 +201,9 @@ void FunctionDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
void FunctionDumper::dump(const PDBSymbolTypeFunctionArg &Symbol,
raw_ostream &OS, int Indent) {
// PDBSymbolTypeFunctionArg is just a shim over the real argument. Just drill
- // through to the
- // real thing and dump it.
+ // through to the real thing and dump it.
+ Symbol.defaultDump(OS, Indent, PDB_DumpLevel::Detailed);
+ OS.flush();
uint32_t TypeId = Symbol.getTypeId();
auto Type = Symbol.getSession().getSymbolById(TypeId);
if (!Type)
diff --git a/llvm/tools/llvm-pdbdump/FunctionDumper.h b/llvm/tools/llvm-pdbdump/FunctionDumper.h
index 287a79c02c2..f9338cb8764 100644
--- a/llvm/tools/llvm-pdbdump/FunctionDumper.h
+++ b/llvm/tools/llvm-pdbdump/FunctionDumper.h
@@ -22,7 +22,8 @@ public:
void start(const PDBSymbolTypeFunctionSig &Symbol, PointerType Pointer,
raw_ostream &OS);
- void start(const PDBSymbolFunc &Symbol, raw_ostream &OS);
+ void start(const PDBSymbolFunc &Symbol, PointerType Pointer, raw_ostream &OS,
+ int Indent);
void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
int Indent) override;
diff --git a/llvm/tools/llvm-pdbdump/TypeDumper.cpp b/llvm/tools/llvm-pdbdump/TypeDumper.cpp
index 72171b0f318..c4e2eabda90 100644
--- a/llvm/tools/llvm-pdbdump/TypeDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/TypeDumper.cpp
@@ -9,6 +9,7 @@
#include "TypeDumper.h"
+#include "ClassDefinitionDumper.h"
#include "FunctionDumper.h"
#include "llvm-pdbdump.h"
#include "TypedefDumper.h"
@@ -18,10 +19,12 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
using namespace llvm;
-TypeDumper::TypeDumper() : PDBSymDumper(true) {}
+TypeDumper::TypeDumper(bool Inline, bool ClassDefs)
+ : PDBSymDumper(true), InlineDump(Inline), FullClassDefs(ClassDefs) {}
void TypeDumper::start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent) {
auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>();
@@ -40,24 +43,55 @@ void TypeDumper::start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent) {
<< " items)";
while (auto Typedef = Typedefs->getNext())
Typedef->dump(OS, Indent + 2, *this);
+
+ auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>();
+ OS << newline(Indent) << "Classes: (" << Classes->getChildCount()
+ << " items)";
+ while (auto Class = Classes->getNext())
+ Class->dump(OS, Indent + 2, *this);
}
void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
int Indent) {
- OS << newline(Indent) << "enum " << Symbol.getName();
+ if (Symbol.getUnmodifiedTypeId() != 0)
+ return;
+
+ if (!InlineDump)
+ OS << newline(Indent);
+
+ OS << "enum " << Symbol.getName();
}
void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS,
int Indent) {
- OS << newline(Indent);
+ if (!InlineDump)
+ OS << newline(Indent);
+
FunctionDumper Dumper;
Dumper.start(Symbol, FunctionDumper::PointerType::None, OS);
}
void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
int Indent) {
- OS << newline(Indent);
+ if (!InlineDump)
+ OS << newline(Indent);
+
TypedefDumper Dumper;
Dumper.start(Symbol, OS, Indent);
OS.flush();
}
+
+void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) {
+ if (Symbol.getUnmodifiedTypeId() != 0)
+ return;
+ if (!InlineDump)
+ OS << newline(Indent);
+
+ if (FullClassDefs) {
+ ClassDefinitionDumper Dumper;
+ Dumper.start(Symbol, OS, Indent);
+ } else {
+ OS << "class " << Symbol.getName();
+ }
+}
diff --git a/llvm/tools/llvm-pdbdump/TypeDumper.h b/llvm/tools/llvm-pdbdump/TypeDumper.h
index 6c51d155df8..d96c24c87fa 100644
--- a/llvm/tools/llvm-pdbdump/TypeDumper.h
+++ b/llvm/tools/llvm-pdbdump/TypeDumper.h
@@ -16,7 +16,7 @@ namespace llvm {
class TypeDumper : public PDBSymDumper {
public:
- TypeDumper();
+ TypeDumper(bool Inline, bool ClassDefs);
void start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent);
@@ -26,6 +26,12 @@ public:
int Indent) override;
void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
int Indent) override;
+ void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) override;
+
+private:
+ bool InlineDump;
+ bool FullClassDefs;
};
}
diff --git a/llvm/tools/llvm-pdbdump/TypedefDumper.cpp b/llvm/tools/llvm-pdbdump/TypedefDumper.cpp
index 55fcb1a3ade..e3ac76a63b3 100644
--- a/llvm/tools/llvm-pdbdump/TypedefDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/TypedefDumper.cpp
@@ -27,10 +27,11 @@ TypedefDumper::TypedefDumper() : PDBSymDumper(true) {}
void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
int Indent) {
- OS << "typedef:" << Symbol.getName() << " -> ";
+ OS << "typedef ";
uint32_t TargetId = Symbol.getTypeId();
if (auto TypeSymbol = Symbol.getSession().getSymbolById(TargetId))
TypeSymbol->dump(OS, 0, *this);
+ OS << " " << Symbol.getName();
}
void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
diff --git a/llvm/tools/llvm-pdbdump/VariableDumper.cpp b/llvm/tools/llvm-pdbdump/VariableDumper.cpp
new file mode 100644
index 00000000000..cb9c66a94b9
--- /dev/null
+++ b/llvm/tools/llvm-pdbdump/VariableDumper.cpp
@@ -0,0 +1,125 @@
+//===- 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: {
+ int Offset = Var.getOffset();
+ OS << "+" << format_hex(Var.getOffset(), 4) << " ";
+ OS.flush();
+ 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) {
+ uint32_t PointeeId = Symbol.getTypeId();
+ 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)) {
+ bool Done = false;
+ 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;
+ }
+}
diff --git a/llvm/tools/llvm-pdbdump/VariableDumper.h b/llvm/tools/llvm-pdbdump/VariableDumper.h
new file mode 100644
index 00000000000..e6e71faca31
--- /dev/null
+++ b/llvm/tools/llvm-pdbdump/VariableDumper.h
@@ -0,0 +1,43 @@
+//===- VariableDumper.h - PDBSymDumper implementation for types -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_VARIABLEDUMPER_H
+#define LLVM_TOOLS_LLVMPDBDUMP_VARIABLEDUMPER_H
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class VariableDumper : public PDBSymDumper {
+public:
+ VariableDumper();
+
+ void start(const PDBSymbolData &Var, raw_ostream &OS, int Indent);
+
+ void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+ int Indent) override;
+ void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+ int Indent) override;
+
+private:
+ void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name,
+ raw_ostream &OS);
+};
+}
+
+#endif
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index cf305d3328e..e33e71562d3 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -54,6 +54,8 @@ cl::opt<bool> DumpCompilands("compilands", cl::desc("Display compilands"));
cl::opt<bool> DumpSymbols("symbols",
cl::desc("Display symbols (implies --compilands"));
cl::opt<bool> DumpTypes("types", cl::desc("Display types"));
+cl::opt<bool> DumpClassDefs("class-definitions",
+ cl::desc("Display full class definitions"));
}
static void dumpInput(StringRef Path) {
@@ -85,7 +87,7 @@ static void dumpInput(StringRef Path) {
if (opts::DumpTypes) {
outs() << "\nDumping types";
- TypeDumper Dumper;
+ TypeDumper Dumper(false, opts::DumpClassDefs);
Dumper.start(*GlobalScope, outs(), 2);
}
OpenPOWER on IntegriCloud