[llvm] r229129 - llvm-pdbdump: Improve printing of functions and signatures.

David Blaikie dblaikie at gmail.com
Fri Feb 13 10:27:32 PST 2015


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/57f3c60b/attachment.html>


More information about the llvm-commits mailing list