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

Zachary Turner zturner at google.com
Fri Feb 13 09:57:09 PST 2015


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.

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()) ? "&" : "*");
+    }
+  }
 }





More information about the llvm-commits mailing list