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/FunctionDumper.cpp | |
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/FunctionDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbdump/FunctionDumper.cpp | 80 |
1 files changed, 69 insertions, 11 deletions
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) |