<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 13, 2015 at 9:57 AM, Zachary Turner <span dir="ltr"><<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: zturner<br>
Date: Fri Feb 13 11:57:09 2015<br>
New Revision: 229129<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=229129&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=229129&view=rev</a><br>
Log:<br>
llvm-pdbdump: Improve printing of functions and signatures.<br>
<br>
This correctly prints the function pointers, and also prints<br>
function signatures for symbols as opposed to just types. So<br>
actual functions in your program will now be printed with full<br>
name and signature, as opposed to just name as before.<br></blockquote><div><br>What's the story on testing this stuff? llvm-dwarfdump is tested with checked in binaries (though I realize pdbdump tests would only be runnable on Windows (where the library is available)) and it'd be nice to see the actual dumping format in tests changing/improving as you iterate here.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Modified:<br>
llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h<br>
llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h<br>
llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp<br>
llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp<br>
llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp<br>
llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h Fri Feb 13 11:57:09 2015<br>
@@ -24,6 +24,8 @@ public:<br>
<br>
void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;<br>
<br>
+ std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;<br>
+<br>
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function)<br>
<br>
FORWARD_SYMBOL_METHOD(getAccess)<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h Fri Feb 13 11:57:09 2015<br>
@@ -24,7 +24,12 @@ public:<br>
<br>
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionSig)<br>
<br>
+ std::unique_ptr<PDBSymbol> getReturnType() const;<br>
+ std::unique_ptr<IPDBEnumSymbols> getArguments() const;<br>
+ std::unique_ptr<PDBSymbol> getClassParent() const;<br>
+<br>
void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const override;<br>
+ void dumpArgList(raw_ostream &OS) const;<br>
<br>
FORWARD_SYMBOL_METHOD(getCallingConvention)<br>
FORWARD_SYMBOL_METHOD(getClassParentId)<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp Fri Feb 13 11:57:09 2015<br>
@@ -47,6 +47,26 @@ void PDBSymbolExe::dump(raw_ostream &OS,<br>
auto ChildrenEnum = getChildStats(Stats);<br>
OS << stream_indent(Indent + 2) << "Children: " << Stats << "\n";<br>
while (auto Child = ChildrenEnum->getNext()) {<br>
+ // Skip uninteresting types. These are useful to print as part of type<br>
+ // hierarchies, but as general children of the global scope, they are<br>
+ // not very interesting.<br>
+ switch (Child->getSymTag()) {<br>
+ case PDB_SymType::ArrayType:<br>
+ case PDB_SymType::BaseClass:<br>
+ case PDB_SymType::BuiltinType:<br>
+ case PDB_SymType::CompilandEnv:<br>
+ case PDB_SymType::CustomType:<br>
+ case PDB_SymType::Dimension:<br>
+ case PDB_SymType::Friend:<br>
+ case PDB_SymType::ManagedType:<br>
+ case PDB_SymType::VTableShape:<br>
+ case PDB_SymType::PointerType:<br>
+ case PDB_SymType::FunctionSig:<br>
+ case PDB_SymType::FunctionArg:<br>
+ continue;<br>
+ default:<br>
+ break;<br>
+ }<br>
Child->dump(OS, Indent + 4, PDB_DumpLevel::Normal);<br>
OS << "\n";<br>
}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp Fri Feb 13 11:57:09 2015<br>
@@ -23,6 +23,10 @@ PDBSymbolFunc::PDBSymbolFunc(const IPDBS<br>
std::unique_ptr<IPDBRawSymbol> Symbol)<br>
: PDBSymbol(PDBSession, std::move(Symbol)) {}<br>
<br>
+std::unique_ptr<PDBSymbolTypeFunctionSig> PDBSymbolFunc::getSignature() const {<br>
+ return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId());<br>
+}<br>
+<br>
void PDBSymbolFunc::dump(raw_ostream &OS, int Indent,<br>
PDB_DumpLevel Level) const {<br>
OS << stream_indent(Indent);<br>
@@ -30,7 +34,7 @@ void PDBSymbolFunc::dump(raw_ostream &OS<br>
uint32_t FuncStart = getRelativeVirtualAddress();<br>
uint32_t FuncEnd = FuncStart + getLength();<br>
if (FuncStart == 0 && FuncEnd == 0) {<br>
- OS << "func [???]";<br>
+ OS << "func [???] ";<br>
} else {<br>
OS << "func ";<br>
OS << "[" << format_hex(FuncStart, 8);<br>
@@ -52,21 +56,34 @@ void PDBSymbolFunc::dump(raw_ostream &OS<br>
<br>
OS << " ";<br>
uint32_t FuncSigId = getTypeId();<br>
- if (auto FuncSig = Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(<br>
- FuncSigId)) {<br>
- OS << "(" << FuncSig->getCallingConvention() << ") ";<br>
- }<br>
+ if (auto FuncSig = getSignature()) {<br>
+ // If we have a signature, dump the name with the signature.<br>
+ if (auto ReturnType = FuncSig->getReturnType()) {<br>
+ ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << " ";<br>
+ }<br>
+<br>
+ OS << FuncSig->getCallingConvention() << " ";<br>
<br>
- uint32_t ClassId = getClassParentId();<br>
- if (ClassId != 0) {<br>
- if (auto Class = Session.getSymbolById(ClassId)) {<br>
- if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))<br>
- OS << UDT->getName() << "::";<br>
- else<br>
- OS << "{class " << Class->getSymTag() << "}::";<br>
+ if (auto ClassParent = FuncSig->getClassParent()) {<br>
+ ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << "::";<br>
}<br>
+<br>
+ OS << getName();<br>
+ FuncSig->dumpArgList(OS);<br>
+ } else {<br>
+ uint32_t ClassId = getClassParentId();<br>
+ if (ClassId != 0) {<br>
+ if (auto Class = Session.getSymbolById(ClassId)) {<br>
+ if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))<br>
+ OS << UDT->getName() << "::";<br>
+ else<br>
+ OS << "{class " << Class->getSymTag() << "}::";<br>
+ }<br>
+ }<br>
+ OS << getName();<br>
}<br>
- OS << getName();<br>
} else {<br>
OS << getName();<br>
}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp Fri Feb 13 11:57:09 2015<br>
@@ -17,35 +17,72 @@<br>
<br>
using namespace llvm;<br>
<br>
+namespace {<br>
+class FunctionArgEnumerator : public IPDBEnumSymbols {<br>
+public:<br>
+ typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType;<br>
+<br>
+ FunctionArgEnumerator(const IPDBSession &PDBSession,<br>
+ const PDBSymbolTypeFunctionSig &Sig)<br>
+ : Session(PDBSession),<br>
+ Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {}<br>
+<br>
+ FunctionArgEnumerator(const IPDBSession &PDBSession,<br>
+ std::unique_ptr<ArgEnumeratorType> ArgEnumerator)<br>
+ : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {}<br>
+<br>
+ uint32_t getChildCount() const { return Enumerator->getChildCount(); }<br>
+<br>
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const {<br>
+ auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index);<br>
+ if (!FunctionArgSymbol)<br>
+ return nullptr;<br>
+ return Session.getSymbolById(FunctionArgSymbol->getTypeId());<br>
+ }<br>
+<br>
+ std::unique_ptr<PDBSymbol> getNext() {<br>
+ auto FunctionArgSymbol = Enumerator->getNext();<br>
+ if (!FunctionArgSymbol)<br>
+ return nullptr;<br>
+ return Session.getSymbolById(FunctionArgSymbol->getTypeId());<br>
+ }<br>
+<br>
+ void reset() { Enumerator->reset(); }<br>
+<br>
+ MyType *clone() const {<br>
+ std::unique_ptr<ArgEnumeratorType> Clone(Enumerator->clone());<br>
+ return new FunctionArgEnumerator(Session, std::move(Clone));<br>
+ }<br>
+<br>
+private:<br>
+ const IPDBSession &Session;<br>
+ std::unique_ptr<ArgEnumeratorType> Enumerator;<br>
+};<br>
+}<br>
+<br>
PDBSymbolTypeFunctionSig::PDBSymbolTypeFunctionSig(<br>
const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)<br>
: PDBSymbol(PDBSession, std::move(Symbol)) {}<br>
<br>
-void PDBSymbolTypeFunctionSig::dump(raw_ostream &OS, int Indent,<br>
- PDB_DumpLevel Level) const {<br>
- OS << stream_indent(Indent);<br>
+std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getReturnType() const {<br>
+ return Session.getSymbolById(getTypeId());<br>
+}<br>
<br>
- uint32_t ReturnTypeId = getTypeId();<br>
- if (auto ReturnType = Session.getSymbolById(ReturnTypeId)) {<br>
- ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
- OS << " ";<br>
- }<br>
- // TODO: We need a way to detect if this is a pointer to function so that we<br>
- // can print the * between the return type and the argument list. The only<br>
- // way to do this is to pass the parent into this function, but that will<br>
- // require a larger interface change.<br>
- OS << getCallingConvention() << " ";<br>
+std::unique_ptr<IPDBEnumSymbols><br>
+PDBSymbolTypeFunctionSig::getArguments() const {<br>
+ return llvm::make_unique<FunctionArgEnumerator>(Session, *this);<br>
+}<br>
+<br>
+std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getClassParent() const {<br>
uint32_t ClassId = getClassParentId();<br>
- if (ClassId != 0) {<br>
- if (auto ClassParent = Session.getSymbolById(ClassId)) {<br>
- OS << "(";<br>
- ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);<br>
- OS << "::*)";<br>
- }<br>
- }<br>
- OS.flush();<br>
+ if (ClassId == 0)<br>
+ return nullptr;<br>
+ return Session.getSymbolById(ClassId);<br>
+}<br>
+<br>
+void PDBSymbolTypeFunctionSig::dumpArgList(raw_ostream &OS) const {<br>
OS << "(";<br>
- if (auto ChildEnum = findAllChildren<PDBSymbolTypeFunctionArg>()) {<br>
+ if (auto ChildEnum = getArguments()) {<br>
uint32_t Index = 0;<br>
while (auto Arg = ChildEnum->getNext()) {<br>
Arg->dump(OS, 0, PDB_DumpLevel::Compact);<br>
@@ -54,4 +91,27 @@ void PDBSymbolTypeFunctionSig::dump(raw_<br>
}<br>
}<br>
OS << ")";<br>
+ if (isConstType())<br>
+ OS << " const";<br>
+ if (isVolatileType())<br>
+ OS << " volatile";<br>
+}<br>
+<br>
+void PDBSymbolTypeFunctionSig::dump(raw_ostream &OS, int Indent,<br>
+ PDB_DumpLevel Level) const {<br>
+ OS << stream_indent(Indent);<br>
+<br>
+ if (auto ReturnType = getReturnType()) {<br>
+ ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << " ";<br>
+ }<br>
+<br>
+ OS << getCallingConvention() << " ";<br>
+ if (auto ClassParent = getClassParent()) {<br>
+ OS << "(";<br>
+ ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << "::*)";<br>
+ }<br>
+<br>
+ dumpArgList(OS);<br>
}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp?rev=229129&r1=229128&r2=229129&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp?rev=229129&r1=229128&r2=229129&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp Fri Feb 13 11:57:09 2015<br>
@@ -10,6 +10,7 @@<br>
<br>
#include "llvm/DebugInfo/PDB/IPDBSession.h"<br>
#include "llvm/DebugInfo/PDB/PDBSymbol.h"<br>
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"<br>
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"<br>
#include <utility><br>
<br>
@@ -27,7 +28,18 @@ void PDBSymbolTypePointer::dump(raw_ostr<br>
if (isVolatileType())<br>
OS << "volatile ";<br>
uint32_t PointeeId = getTypeId();<br>
- if (auto PointeeType = Session.getSymbolById(PointeeId))<br>
- PointeeType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
- OS << ((isReference()) ? "&" : "*");<br>
+ if (auto PointeeType = Session.getSymbolById(PointeeId)) {<br>
+ // Function pointers get special treatment, since we need to print the * in<br>
+ // the middle of the signature.<br>
+ if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get())) {<br>
+ if (auto ReturnType = FuncSig->getReturnType())<br>
+ ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << " (" << FuncSig->getCallingConvention() << " ";<br>
+ OS << ((isReference()) ? "&" : "*") << ")";<br>
+ FuncSig->dumpArgList(OS);<br>
+ } else {<br>
+ PointeeType->dump(OS, 0, PDB_DumpLevel::Compact);<br>
+ OS << ((isReference()) ? "&" : "*");<br>
+ }<br>
+ }<br>
}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>