[llvm] r229129 - llvm-pdbdump: Improve printing of functions and signatures.
Zachary Turner
zturner at google.com
Fri Feb 13 10:35:45 PST 2015
As far as a specific timeline goes, I would expect by the end of next week
there will be a healthy number of tests.
On Fri Feb 13 2015 at 10:32:56 AM Zachary Turner <zturner at google.com> wrote:
> Good question. I mentioned it in one of the very first commit messages,
> but I guess that's been a while with many more commit messages since then,
> so it's been lost.
>
> Basically, the dwarf tests are tests against llvm-dwarfdump. So without
> llvm-pdbdump, there can't be any tests. I could iterate, as you said, but
> right now llvm-pdbdump doesn't really support many command line options or
> ways to specify what to dump. It just dumps everything. Which is often
> very slow and pollutes the output, making it difficult to check that only
> the thing you care about is the way you expect and also making the test
> suite run slowly. Also, it's not just that I'm iterating right now, it's
> that some stuff just prints wrong, or doesn't print at all.
>
> Most of those kinks are worked out though, and the patch I'm working on
> right now is one to finally add the correct options for limiting the output
> to specific interesting things. After that, I plan to start adding tests.
>
> One question I have, is that some information about what's in the PDB you
> can only learn by looking in it. How would one test that? It doesn't seem
> very useful to look in the PDB, then write a test that it matches what you
> know it already is. I guess it's useful for verifying someone doesn't
> break the formatting. What are your thoughts there?
>
> On Fri Feb 13 2015 at 10:27:32 AM David Blaikie <dblaikie at gmail.com>
> wrote:
>
>> On Fri, Feb 13, 2015 at 9:57 AM, Zachary Turner <zturner at google.com>
>> wrote:
>>
>>> Author: zturner
>>> Date: Fri Feb 13 11:57:09 2015
>>> New Revision: 229129
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=229129&view=rev
>>> Log:
>>> llvm-pdbdump: Improve printing of functions and signatures.
>>>
>>> This correctly prints the function pointers, and also prints
>>> function signatures for symbols as opposed to just types. So
>>> actual functions in your program will now be printed with full
>>> name and signature, as opposed to just name as before.
>>>
>>
>> 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.
>>
>>
>>>
>>> Modified:
>>> llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
>>> llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
>>> llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp
>>> llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
>>> llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
>>> llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
>>> llvm/DebugInfo/PDB/PDBSymbolFunc.h?rev=229129&r1=
>>> 229128&r2=229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h (original)
>>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h Fri Feb 13
>>> 11:57:09 2015
>>> @@ -24,6 +24,8 @@ public:
>>>
>>> void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const
>>> override;
>>>
>>> + std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;
>>> +
>>> DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function)
>>>
>>> FORWARD_SYMBOL_METHOD(getAccess)
>>>
>>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/
>>> PDBSymbolTypeFunctionSig.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/
>>> llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h?rev=229129&r1=229128&r2=
>>> 229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
>>> (original)
>>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
>>> Fri Feb 13 11:57:09 2015
>>> @@ -24,7 +24,12 @@ public:
>>>
>>> DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionSig)
>>>
>>> + std::unique_ptr<PDBSymbol> getReturnType() const;
>>> + std::unique_ptr<IPDBEnumSymbols> getArguments() const;
>>> + std::unique_ptr<PDBSymbol> getClassParent() const;
>>> +
>>> void dump(raw_ostream &OS, int Indent, PDB_DumpLevel Level) const
>>> override;
>>> + void dumpArgList(raw_ostream &OS) const;
>>>
>>> FORWARD_SYMBOL_METHOD(getCallingConvention)
>>> FORWARD_SYMBOL_METHOD(getClassParentId)
>>>
>>> Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
>>> DebugInfo/PDB/PDBSymbolExe.cpp?rev=229129&r1=229128&r2=229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp (original)
>>> +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolExe.cpp Fri Feb 13 11:57:09
>>> 2015
>>> @@ -47,6 +47,26 @@ void PDBSymbolExe::dump(raw_ostream &OS,
>>> auto ChildrenEnum = getChildStats(Stats);
>>> OS << stream_indent(Indent + 2) << "Children: " << Stats << "\n";
>>> while (auto Child = ChildrenEnum->getNext()) {
>>> + // Skip uninteresting types. These are useful to print as part of
>>> type
>>> + // hierarchies, but as general children of the global scope, they
>>> are
>>> + // not very interesting.
>>> + switch (Child->getSymTag()) {
>>> + case PDB_SymType::ArrayType:
>>> + case PDB_SymType::BaseClass:
>>> + case PDB_SymType::BuiltinType:
>>> + case PDB_SymType::CompilandEnv:
>>> + case PDB_SymType::CustomType:
>>> + case PDB_SymType::Dimension:
>>> + case PDB_SymType::Friend:
>>> + case PDB_SymType::ManagedType:
>>> + case PDB_SymType::VTableShape:
>>> + case PDB_SymType::PointerType:
>>> + case PDB_SymType::FunctionSig:
>>> + case PDB_SymType::FunctionArg:
>>> + continue;
>>> + default:
>>> + break;
>>> + }
>>> Child->dump(OS, Indent + 4, PDB_DumpLevel::Normal);
>>> OS << "\n";
>>> }
>>>
>>> Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
>>> DebugInfo/PDB/PDBSymbolFunc.cpp?rev=229129&r1=229128&r2=229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp (original)
>>> +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp Fri Feb 13 11:57:09
>>> 2015
>>> @@ -23,6 +23,10 @@ PDBSymbolFunc::PDBSymbolFunc(const IPDBS
>>> std::unique_ptr<IPDBRawSymbol> Symbol)
>>> : PDBSymbol(PDBSession, std::move(Symbol)) {}
>>>
>>> +std::unique_ptr<PDBSymbolTypeFunctionSig>
>>> PDBSymbolFunc::getSignature() const {
>>> + return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(
>>> getTypeId());
>>> +}
>>> +
>>> void PDBSymbolFunc::dump(raw_ostream &OS, int Indent,
>>> PDB_DumpLevel Level) const {
>>> OS << stream_indent(Indent);
>>> @@ -30,7 +34,7 @@ void PDBSymbolFunc::dump(raw_ostream &OS
>>> uint32_t FuncStart = getRelativeVirtualAddress();
>>> uint32_t FuncEnd = FuncStart + getLength();
>>> if (FuncStart == 0 && FuncEnd == 0) {
>>> - OS << "func [???]";
>>> + OS << "func [???] ";
>>> } else {
>>> OS << "func ";
>>> OS << "[" << format_hex(FuncStart, 8);
>>> @@ -52,21 +56,34 @@ void PDBSymbolFunc::dump(raw_ostream &OS
>>>
>>> OS << " ";
>>> uint32_t FuncSigId = getTypeId();
>>> - if (auto FuncSig = Session.getConcreteSymbolById<
>>> PDBSymbolTypeFunctionSig>(
>>> - FuncSigId)) {
>>> - OS << "(" << FuncSig->getCallingConvention() << ") ";
>>> - }
>>> + if (auto FuncSig = getSignature()) {
>>> + // If we have a signature, dump the name with the signature.
>>> + if (auto ReturnType = FuncSig->getReturnType()) {
>>> + ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << " ";
>>> + }
>>> +
>>> + OS << FuncSig->getCallingConvention() << " ";
>>>
>>> - uint32_t ClassId = getClassParentId();
>>> - if (ClassId != 0) {
>>> - if (auto Class = Session.getSymbolById(ClassId)) {
>>> - if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))
>>> - OS << UDT->getName() << "::";
>>> - else
>>> - OS << "{class " << Class->getSymTag() << "}::";
>>> + if (auto ClassParent = FuncSig->getClassParent()) {
>>> + ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << "::";
>>> }
>>> +
>>> + OS << getName();
>>> + FuncSig->dumpArgList(OS);
>>> + } else {
>>> + uint32_t ClassId = getClassParentId();
>>> + if (ClassId != 0) {
>>> + if (auto Class = Session.getSymbolById(ClassId)) {
>>> + if (auto UDT = dyn_cast<PDBSymbolTypeUDT>(Class.get()))
>>> + OS << UDT->getName() << "::";
>>> + else
>>> + OS << "{class " << Class->getSymTag() << "}::";
>>> + }
>>> + }
>>> + OS << getName();
>>> }
>>> - OS << getName();
>>> } else {
>>> OS << getName();
>>> }
>>>
>>> Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/
>>> PDBSymbolTypeFunctionSig.cpp?rev=229129&r1=229128&r2=229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp (original)
>>> +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp Fri Feb
>>> 13 11:57:09 2015
>>> @@ -17,35 +17,72 @@
>>>
>>> using namespace llvm;
>>>
>>> +namespace {
>>> +class FunctionArgEnumerator : public IPDBEnumSymbols {
>>> +public:
>>> + typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>
>>> ArgEnumeratorType;
>>> +
>>> + FunctionArgEnumerator(const IPDBSession &PDBSession,
>>> + const PDBSymbolTypeFunctionSig &Sig)
>>> + : Session(PDBSession),
>>> + Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {}
>>> +
>>> + FunctionArgEnumerator(const IPDBSession &PDBSession,
>>> + std::unique_ptr<ArgEnumeratorType>
>>> ArgEnumerator)
>>> + : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {}
>>> +
>>> + uint32_t getChildCount() const { return Enumerator->getChildCount(); }
>>> +
>>> + std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const {
>>> + auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index);
>>> + if (!FunctionArgSymbol)
>>> + return nullptr;
>>> + return Session.getSymbolById(FunctionArgSymbol->getTypeId());
>>> + }
>>> +
>>> + std::unique_ptr<PDBSymbol> getNext() {
>>> + auto FunctionArgSymbol = Enumerator->getNext();
>>> + if (!FunctionArgSymbol)
>>> + return nullptr;
>>> + return Session.getSymbolById(FunctionArgSymbol->getTypeId());
>>> + }
>>> +
>>> + void reset() { Enumerator->reset(); }
>>> +
>>> + MyType *clone() const {
>>> + std::unique_ptr<ArgEnumeratorType> Clone(Enumerator->clone());
>>> + return new FunctionArgEnumerator(Session, std::move(Clone));
>>> + }
>>> +
>>> +private:
>>> + const IPDBSession &Session;
>>> + std::unique_ptr<ArgEnumeratorType> Enumerator;
>>> +};
>>> +}
>>> +
>>> PDBSymbolTypeFunctionSig::PDBSymbolTypeFunctionSig(
>>> const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol>
>>> Symbol)
>>> : PDBSymbol(PDBSession, std::move(Symbol)) {}
>>>
>>> -void PDBSymbolTypeFunctionSig::dump(raw_ostream &OS, int Indent,
>>> - PDB_DumpLevel Level) const {
>>> - OS << stream_indent(Indent);
>>> +std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getReturnType()
>>> const {
>>> + return Session.getSymbolById(getTypeId());
>>> +}
>>>
>>> - uint32_t ReturnTypeId = getTypeId();
>>> - if (auto ReturnType = Session.getSymbolById(ReturnTypeId)) {
>>> - ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> - OS << " ";
>>> - }
>>> - // TODO: We need a way to detect if this is a pointer to function so
>>> that we
>>> - // can print the * between the return type and the argument list.
>>> The only
>>> - // way to do this is to pass the parent into this function, but that
>>> will
>>> - // require a larger interface change.
>>> - OS << getCallingConvention() << " ";
>>> +std::unique_ptr<IPDBEnumSymbols>
>>> +PDBSymbolTypeFunctionSig::getArguments() const {
>>> + return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
>>> +}
>>> +
>>> +std::unique_ptr<PDBSymbol> PDBSymbolTypeFunctionSig::getClassParent()
>>> const {
>>> uint32_t ClassId = getClassParentId();
>>> - if (ClassId != 0) {
>>> - if (auto ClassParent = Session.getSymbolById(ClassId)) {
>>> - OS << "(";
>>> - ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
>>> - OS << "::*)";
>>> - }
>>> - }
>>> - OS.flush();
>>> + if (ClassId == 0)
>>> + return nullptr;
>>> + return Session.getSymbolById(ClassId);
>>> +}
>>> +
>>> +void PDBSymbolTypeFunctionSig::dumpArgList(raw_ostream &OS) const {
>>> OS << "(";
>>> - if (auto ChildEnum = findAllChildren<PDBSymbolTypeFunctionArg>()) {
>>> + if (auto ChildEnum = getArguments()) {
>>> uint32_t Index = 0;
>>> while (auto Arg = ChildEnum->getNext()) {
>>> Arg->dump(OS, 0, PDB_DumpLevel::Compact);
>>> @@ -54,4 +91,27 @@ void PDBSymbolTypeFunctionSig::dump(raw_
>>> }
>>> }
>>> OS << ")";
>>> + if (isConstType())
>>> + OS << " const";
>>> + if (isVolatileType())
>>> + OS << " volatile";
>>> +}
>>> +
>>> +void PDBSymbolTypeFunctionSig::dump(raw_ostream &OS, int Indent,
>>> + PDB_DumpLevel Level) const {
>>> + OS << stream_indent(Indent);
>>> +
>>> + if (auto ReturnType = getReturnType()) {
>>> + ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << " ";
>>> + }
>>> +
>>> + OS << getCallingConvention() << " ";
>>> + if (auto ClassParent = getClassParent()) {
>>> + OS << "(";
>>> + ClassParent->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << "::*)";
>>> + }
>>> +
>>> + dumpArgList(OS);
>>> }
>>>
>>> Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/
>>> PDBSymbolTypePointer.cpp?rev=229129&r1=229128&r2=229129&view=diff
>>> ============================================================
>>> ==================
>>> --- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp (original)
>>> +++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp Fri Feb 13
>>> 11:57:09 2015
>>> @@ -10,6 +10,7 @@
>>>
>>> #include "llvm/DebugInfo/PDB/IPDBSession.h"
>>> #include "llvm/DebugInfo/PDB/PDBSymbol.h"
>>> +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
>>> #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
>>> #include <utility>
>>>
>>> @@ -27,7 +28,18 @@ void PDBSymbolTypePointer::dump(raw_ostr
>>> if (isVolatileType())
>>> OS << "volatile ";
>>> uint32_t PointeeId = getTypeId();
>>> - if (auto PointeeType = Session.getSymbolById(PointeeId))
>>> - PointeeType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> - OS << ((isReference()) ? "&" : "*");
>>> + if (auto PointeeType = Session.getSymbolById(PointeeId)) {
>>> + // Function pointers get special treatment, since we need to print
>>> the * in
>>> + // the middle of the signature.
>>> + if (auto FuncSig = dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType.get()))
>>> {
>>> + if (auto ReturnType = FuncSig->getReturnType())
>>> + ReturnType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << " (" << FuncSig->getCallingConvention() << " ";
>>> + OS << ((isReference()) ? "&" : "*") << ")";
>>> + FuncSig->dumpArgList(OS);
>>> + } else {
>>> + PointeeType->dump(OS, 0, PDB_DumpLevel::Compact);
>>> + OS << ((isReference()) ? "&" : "*");
>>> + }
>>> + }
>>> }
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150213/355b32ac/attachment.html>
More information about the llvm-commits
mailing list