diff options
author | Zachary Turner <zturner@google.com> | 2015-02-23 05:58:34 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-02-23 05:58:34 +0000 |
commit | 29c69105fb02de4aec7ad0e614bc299c807370cd (patch) | |
tree | 704e1f63cf99a214a6ff0d8a09ba8c40eabf2c2b /llvm/tools/llvm-pdbdump | |
parent | 203540f2d6f54eec322ec7d4aeefa811ecb2335c (diff) | |
download | bcm5719-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.txt | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp | 154 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/ClassDefinitionDumper.h | 64 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/CompilandDumper.cpp | 21 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/FunctionDumper.cpp | 80 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/FunctionDumper.h | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/TypeDumper.cpp | 42 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/TypeDumper.h | 8 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/TypedefDumper.cpp | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/VariableDumper.cpp | 125 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/VariableDumper.h | 43 | ||||
-rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 4 |
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); } |