[llvm] r230203 - [llvm-pdbdump] Add an option to dump full class definitions.

Zachary Turner zturner at google.com
Sun Feb 22 21:58:35 PST 2015


Author: zturner
Date: Sun Feb 22 23:58:34 2015
New Revision: 230203

URL: http://llvm.org/viewvc/llvm-project?rev=230203&view=rev
Log:
[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.

Added:
    llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.h
    llvm/trunk/tools/llvm-pdbdump/VariableDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/VariableDumper.h
      - copied, changed from r230202, llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolData.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBSymbolData.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.pdb
    llvm/trunk/test/DebugInfo/PDB/pdbdump-symbol-format.test
    llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt
    llvm/trunk/tools/llvm-pdbdump/CompilandDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h
    llvm/trunk/tools/llvm-pdbdump/TypeDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/TypeDumper.h
    llvm/trunk/tools/llvm-pdbdump/TypedefDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbol.h Sun Feb 22 23:58:34 2015
@@ -86,9 +86,9 @@ public:
 
   const IPDBSession &getSession() const { return Session; }
 
-protected:
   std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const;
 
+protected:
   const IPDBSession &Session;
   const std::unique_ptr<IPDBRawSymbol> RawSymbol;
 };

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolData.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolData.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolData.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolData.h Sun Feb 22 23:58:34 2015
@@ -24,6 +24,8 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data)
 
+  std::unique_ptr<PDBSymbol> getType() const;
+
   void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
 
   FORWARD_SYMBOL_METHOD(getAccess)

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=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h Sun Feb 22 23:58:34 2015
@@ -25,6 +25,8 @@ public:
   void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
 
   std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;
+  std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
+  std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> getArguments() const;
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function)
 
@@ -32,6 +34,7 @@ public:
   FORWARD_SYMBOL_METHOD(getAddressOffset)
   FORWARD_SYMBOL_METHOD(getAddressSection)
   FORWARD_SYMBOL_METHOD(getClassParentId)
+  FORWARD_SYMBOL_METHOD(isCompilerGenerated)
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(hasCustomCallingConvention)
   FORWARD_SYMBOL_METHOD(hasFarReturn)

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h Sun Feb 22 23:58:34 2015
@@ -24,6 +24,8 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType)
 
+  std::unique_ptr<PDBSymbol> getElementType() const;
+
   void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
 
   FORWARD_SYMBOL_METHOD(getArrayIndexTypeId)

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h Sun Feb 22 23:58:34 2015
@@ -28,6 +28,7 @@ public:
 
   FORWARD_SYMBOL_METHOD(getBuiltinType)
   FORWARD_SYMBOL_METHOD(getClassParentId)
+  FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
   FORWARD_SYMBOL_METHOD(hasConstructor)
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(hasAssignmentOperator)

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=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h Sun Feb 22 23:58:34 2015
@@ -33,6 +33,7 @@ public:
 
   FORWARD_SYMBOL_METHOD(getCallingConvention)
   FORWARD_SYMBOL_METHOD(getClassParentId)
+  FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(getCount)
   FORWARD_SYMBOL_METHOD(getLexicalParentId)

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h Sun Feb 22 23:58:34 2015
@@ -24,6 +24,8 @@ public:
 
   DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType)
 
+  std::unique_ptr<PDBSymbol> getPointeeType() const;
+
   void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
 
   FORWARD_SYMBOL_METHOD(isConstType)

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h Sun Feb 22 23:58:34 2015
@@ -27,6 +27,7 @@ public:
   void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
 
   FORWARD_SYMBOL_METHOD(getClassParentId)
+  FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
   FORWARD_SYMBOL_METHOD(hasConstructor)
   FORWARD_SYMBOL_METHOD(isConstType)
   FORWARD_SYMBOL_METHOD(hasAssignmentOperator)

Modified: llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp Sun Feb 22 23:58:34 2015
@@ -127,8 +127,9 @@ void DumpDIAValue(llvm::raw_ostream &OS,
                   HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) {
   ArgType Value;
   if (S_OK == (Symbol->*Method)(&Value)) {
+    OS << "\n";
     OS.indent(Indent);
-    OS << Name << ": " << Value << "\n";
+    OS << Name << ": " << Value;
   }
 }
 
@@ -142,8 +143,9 @@ void DumpDIAValue(llvm::raw_ostream &OS,
   ArrayRef<char> ByteArray(Bytes, ::SysStringByteLen(Value));
   std::string Result;
   if (llvm::convertUTF16ToUTF8String(ByteArray, Result)) {
+    OS << "\n";
     OS.indent(Indent);
-    OS << Name << ": " << Result << "\n";
+    OS << Name << ": " << Result;
   }
   ::SysFreeString(Value);
 }
@@ -155,8 +157,9 @@ void DumpDIAValue(llvm::raw_ostream &OS,
   Value.vt = VT_EMPTY;
   if (S_OK != (Symbol->*Method)(&Value))
     return;
-  Variant V = VariantFromVARIANT(Value);
+  OS << "\n";
   OS.indent(Indent);
+  Variant V = VariantFromVARIANT(Value);
   OS << V;
 }
 }
@@ -201,7 +204,6 @@ void DIARawSymbol::dump(raw_ostream &OS,
   RAW_METHOD_DUMP(OS, get_frontEndMinor)
   RAW_METHOD_DUMP(OS, get_frontEndBuild)
   RAW_METHOD_DUMP(OS, get_frontEndQFE)
-  RAW_METHOD_DUMP(OS, get_count)
   RAW_METHOD_DUMP(OS, get_lexicalParentId)
   RAW_METHOD_DUMP(OS, get_libraryName)
   RAW_METHOD_DUMP(OS, get_liveRangeStartAddressOffset)

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolData.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolData.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolData.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolData.cpp Sun Feb 22 23:58:34 2015
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
 
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
 
 #include <utility>
@@ -19,6 +20,10 @@ PDBSymbolData::PDBSymbolData(const IPDBS
                              std::unique_ptr<IPDBRawSymbol> DataSymbol)
     : PDBSymbol(PDBSession, std::move(DataSymbol)) {}
 
+std::unique_ptr<PDBSymbol> PDBSymbolData::getType() const {
+  return Session.getSymbolById(getTypeId());
+}
+
 void PDBSymbolData::dump(raw_ostream &OS, int Indent,
                          PDBSymDumper &Dumper) const {
   Dumper.dump(*this, OS, Indent);

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolFunc.cpp Sun Feb 22 23:58:34 2015
@@ -9,13 +9,78 @@
 
 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
 
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
 #include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
 
+#include <unordered_set>
 #include <utility>
+#include <vector>
 
 using namespace llvm;
+
+namespace {
+class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
+public:
+  typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
+
+  FunctionArgEnumerator(const IPDBSession &PDBSession,
+                        const PDBSymbolFunc &PDBFunc)
+      : Session(PDBSession), Func(PDBFunc) {
+    // Arguments can appear multiple times if they have live range
+    // information, so we only take the first occurrence.
+    std::unordered_set<std::string> SeenNames;
+    auto DataChildren = Func.findAllChildren<PDBSymbolData>();
+    while (auto Child = DataChildren->getNext()) {
+      if (Child->getDataKind() == PDB_DataKind::Param) {
+        std::string Name = Child->getName();
+        if (SeenNames.find(Name) != SeenNames.end())
+          continue;
+        Args.push_back(std::move(Child));
+        SeenNames.insert(Name);
+      }
+    }
+    reset();
+  }
+
+  uint32_t getChildCount() const { return Args.size(); }
+
+  std::unique_ptr<PDBSymbolData> getChildAtIndex(uint32_t Index) const {
+    if (Index >= Args.size())
+      return nullptr;
+
+    return Session.getConcreteSymbolById<PDBSymbolData>(
+        Args[Index]->getSymIndexId());
+  }
+
+  std::unique_ptr<PDBSymbolData> getNext() {
+    if (CurIter == Args.end())
+      return nullptr;
+    const auto &Result = **CurIter;
+    ++CurIter;
+    return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
+  }
+
+  void reset() { CurIter = Args.empty() ? Args.end() : Args.begin(); }
+
+  FunctionArgEnumerator *clone() const {
+    return new FunctionArgEnumerator(Session, Func);
+  }
+
+private:
+  typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
+  const IPDBSession &Session;
+  const PDBSymbolFunc &Func;
+  ArgListType Args;
+  ArgListType::const_iterator CurIter;
+};
+}
+
 PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
                              std::unique_ptr<IPDBRawSymbol> Symbol)
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
@@ -24,6 +89,15 @@ std::unique_ptr<PDBSymbolTypeFunctionSig
   return Session.getConcreteSymbolById<PDBSymbolTypeFunctionSig>(getTypeId());
 }
 
+std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
+PDBSymbolFunc::getArguments() const {
+  return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+}
+
+std::unique_ptr<PDBSymbolTypeUDT> PDBSymbolFunc::getClassParent() const {
+  return Session.getConcreteSymbolById<PDBSymbolTypeUDT>(getClassParentId());
+}
+
 void PDBSymbolFunc::dump(raw_ostream &OS, int Indent,
                          PDBSymDumper &Dumper) const {
   Dumper.dump(*this, OS, Indent);

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp Sun Feb 22 23:58:34 2015
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
 
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
 
 #include <utility>
@@ -19,6 +20,10 @@ PDBSymbolTypeArray::PDBSymbolTypeArray(c
                                        std::unique_ptr<IPDBRawSymbol> Symbol)
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
+std::unique_ptr<PDBSymbol> PDBSymbolTypeArray::getElementType() const {
+  return Session.getSymbolById(getTypeId());
+}
+
 void PDBSymbolTypeArray::dump(raw_ostream &OS, int Indent,
                               PDBSymDumper &Dumper) const {
   Dumper.dump(*this, OS, Indent);

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp Sun Feb 22 23:58:34 2015
@@ -9,6 +9,7 @@
 
 #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
 
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
 
 #include <utility>
@@ -19,6 +20,10 @@ PDBSymbolTypePointer::PDBSymbolTypePoint
     const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
     : PDBSymbol(PDBSession, std::move(Symbol)) {}
 
+std::unique_ptr<PDBSymbol> PDBSymbolTypePointer::getPointeeType() const {
+  return Session.getSymbolById(getTypeId());
+}
+
 void PDBSymbolTypePointer::dump(raw_ostream &OS, int Indent,
                                 PDBSymDumper &Dumper) const {
   Dumper.dump(*this, OS, Indent);

Modified: llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp (original)
+++ llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.cpp Sun Feb 22 23:58:34 2015
@@ -5,20 +5,49 @@
 
 int __cdecl _purecall(void) { return 0; }
 
+enum TestEnum {
+  Value,
+  Value10 = 10
+};
+
+enum class TestEnumClass {
+  Value,
+  Value10 = 10
+};
+
 struct A {
   virtual void PureFunc() = 0 {}
   virtual void VirtualFunc() {}
   void RegularFunc() {}
 };
 
-struct B : public A {
+struct VirtualBase {
+};
+
+struct B : public A, protected virtual VirtualBase {
   void PureFunc() override {}
+
+  enum NestedEnum {
+    FirstVal,
+    SecondVal
+  };
+
+  typedef int NestedTypedef;
+  NestedEnum EnumVar;
+  NestedTypedef TypedefVar;
 };
 
+typedef int IntType;
+typedef A ClassAType;
+
 int main(int argc, char **argv) {
   B b;
   auto PureAddr = &B::PureFunc;
   auto VirtualAddr = &A::PureFunc;
   auto RegularAddr = &A::RegularFunc;
+  TestEnum Enum = Value;
+  TestEnumClass EnumClass = TestEnumClass::Value10;
+  IntType Int = 12;
+  ClassAType *ClassA = &b;
   return 0;
 }

Modified: llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.pdb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.pdb?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
Binary files llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.pdb (original) and llvm/trunk/test/DebugInfo/PDB/Inputs/symbolformat.pdb Sun Feb 22 23:58:34 2015 differ

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-symbol-format.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-symbol-format.test?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-symbol-format.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-symbol-format.test Sun Feb 22 23:58:34 2015
@@ -1,27 +1,49 @@
 ; RUN: llvm-pdbdump -symbols %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=SYM_FORMAT %s
 ; RUN: llvm-pdbdump -types %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=TYPES_FORMAT %s
+; RUN: llvm-pdbdump -types -class-definitions %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=FULL_CLASS %s
 
 ; The format is func [0x<rva_start>+<prologue_length> - 0x<rva_end>-<epilogue_length>]
 ; SYM_FORMAT: symbolformat-fpo.obj
-; SYM_FORMAT-DAG: func [0x001130+0 - 0x001137-1] (FPO) uint32_t __cdecl fpo_func(uint32_t)
+; SYM_FORMAT-DAG: func [0x001130+0 - 0x001137-1] (FPO) uint32_t __cdecl fpo_func(uint32_t n)
 ; SYM_FORMAT: symbolformat.obj
-; SYM_FORMAT-DAG: func [0x001060+3 - 0x001067-2] (EBP) int32_t __cdecl _purecall()
-; SYM_FORMAT-DAG: func [0x001070+6 - 0x001099-4] (EBP) int32_t __cdecl main(int32_t, char**)
-; SYM_FORMAT-DAG: func [0x0010b0+7 - 0x0010c7-4] (EBP) void __thiscall A::A()
-; SYM_FORMAT-DAG: func [0x0010d0+7 - 0x0010ef-4] (EBP) void __thiscall B::B()
+; SYM_FORMAT-DAG: func [0x001140+3 - 0x001147-2] (EBP) int32_t __cdecl _purecall()
+; SYM_FORMAT-DAG: func [0x001150+6 - 0x0011b6-4] (EBP) int32_t __cdecl main(int32_t argc, char** argv)
+; SYM_FORMAT-DAG: func [0x0010b0+7 - 0x0010c7-4] (EBP) void A::A()
+; SYM_FORMAT-DAG: func [0x0011c0+7 - 0x0011f1-6] (EBP) void B::B()
 ; SYM_FORMAT-DAG: thunk [0x000010f6 - 0x000010fa] (Pcode) B::`vcall'{0}'
-; SYM_FORMAT-DAG: func [0x001100+7 - 0x00110b-4] (EBP) virtual void __thiscall B::PureFunc()
-; SYM_FORMAT-DAG: func [0x001110+7 - 0x00111b-4] (EBP) void __thiscall A::RegularFunc()
-; SYM_FORMAT-DAG: func [0x001120+7 - 0x00112b-4] (EBP) virtual void __thiscall A::VirtualFunc()
+; SYM_FORMAT-DAG: func [0x001100+7 - 0x00110b-4] (EBP) virtual void B::PureFunc()
+; SYM_FORMAT-DAG: func [0x001110+7 - 0x00111b-4] (EBP) void A::RegularFunc()
+; SYM_FORMAT-DAG: func [0x001120+7 - 0x00112b-4] (EBP) virtual void A::VirtualFunc()
 
+; TYPES_FORMAT: Enums
+; TYPES_FORMAT-DAG: enum TestEnum
+; TYPES_FORMAT-DAG: enum TestEnumClass
 ; TYPES_FORMAT: Function Signatures
 ; TYPES_FORMAT-DAG: int32_t __cdecl ()
 ; TYPES_FORMAT-DAG: int32_t __cdecl (int32_t, char**)
-; TYPES_FORMAT-DAG: void __thiscall (A::)()
-; TYPES_FORMAT-DAG: void __thiscall (B::)()
-; TYPES_FORMAT-DAG: void __thiscall (B::)(B&)
-; TYPES_FORMAT-DAG: void __thiscall (B::)()
-; TYPES_FORMAT-DAG: B& __thiscall (B::)(B&)
-; TYPES_FORMAT-DAG: void __thiscall (A::)(A&)
-; TYPES_FORMAT-DAG: void __thiscall (A::)()
-; TYPES_FORMAT-DAG: A& __thiscall (A::)(A&)
+; TYPES_FORMAT-DAG: void (A::)()
+; TYPES_FORMAT-DAG: void (B::)()
+; TYPES_FORMAT-DAG: void (B::)(B&)
+; TYPES_FORMAT-DAG: void (B::)()
+; TYPES_FORMAT-DAG: B& (B::)(B&)
+; TYPES_FORMAT-DAG: void (A::)(A&)
+; TYPES_FORMAT-DAG: void (A::)()
+; TYPES_FORMAT-DAG: A& (A::)(A&)
+; TYPES_FORMAT: Typedefs
+; TYPES_FORMAT-DAG: typedef int32_t IntType
+; TYPES_FORMAT-DAG: typedef class A ClassAType
+; TYPES_FORMAT: Classes
+; TYPES_FORMAT-DAG: class A
+; TYPES_FORMAT-DAG: class B
+
+; FULL_CLASS: Classes
+; FULL_CLASS-DAG: class A {
+; FULL_CLASS: public:
+; FULL_CLASS: virtual void PureFunc() = 0
+; FULL_CLASS: virtual void VirtualFunc()
+; FULL_CLASS: void RegularFunc()
+; FULL_CLASS: }
+; FULL_CLASS-DAG: class B {
+; FULL_CLASS: public:
+; FULL_CLASS: virtual void PureFunc()
+; FULL_CLASS: }
\ No newline at end of file

Modified: llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt Sun Feb 22 23:58:34 2015
@@ -5,8 +5,10 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_tool(llvm-pdbdump
   llvm-pdbdump.cpp
+  ClassDefinitionDumper.cpp
   CompilandDumper.cpp
   FunctionDumper.cpp
   TypeDumper.cpp
   TypedefDumper.cpp
+  VariableDumper.cpp
   )

Added: llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.cpp?rev=230203&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.cpp (added)
+++ llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.cpp Sun Feb 22 23:58:34 2015
@@ -0,0 +1,154 @@
+//===- ClassDefinitionDumper.cpp --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClassDefinitionDumper.h"
+#include "FunctionDumper.h"
+#include "llvm-pdbdump.h"
+#include "TypedefDumper.h"
+#include "VariableDumper.h"
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+ClassDefinitionDumper::ClassDefinitionDumper() : PDBSymDumper(true) {}
+
+void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class,
+                                  raw_ostream &OS, int Indent) {
+  OS << "class " << Class.getName() << " {";
+  auto Children = Class.findAllChildren();
+  if (Children->getChildCount() == 0) {
+    OS << "}";
+    return;
+  }
+
+  // Try to dump symbols organized by member access level.  Public members
+  // first, then protected, then private.  This might be slow, so it's worth
+  // reconsidering the value of this if performance of large PDBs is a problem.
+  // NOTE: Access level of nested types is not recorded in the PDB, so we have
+  // a special case for them.
+  SymbolGroupByAccess Groups;
+  Groups.insert(std::make_pair((PDB_MemberAccess)0, SymbolGroup()));
+  Groups.insert(std::make_pair(PDB_MemberAccess::Private, SymbolGroup()));
+  Groups.insert(std::make_pair(PDB_MemberAccess::Protected, SymbolGroup()));
+  Groups.insert(std::make_pair(PDB_MemberAccess::Public, SymbolGroup()));
+
+  while (auto Child = Children->getNext()) {
+    PDB_MemberAccess Access = Child->getRawSymbol().getAccess();
+    if (isa<PDBSymbolTypeBaseClass>(*Child))
+      continue;
+
+    SymbolGroup *InsertGroup = nullptr;
+    auto &AccessGroup = Groups.find(Access)->second;
+
+    if (auto Func = dyn_cast<PDBSymbolFunc>(Child.get())) {
+      if (Func->isCompilerGenerated())
+        continue;
+      if (Func->getLength() == 0 && !Func->isPureVirtual())
+        continue;
+      Child.release();
+      AccessGroup.Functions.push_back(std::unique_ptr<PDBSymbolFunc>(Func));
+    } else if (auto Data = dyn_cast<PDBSymbolData>(Child.get())) {
+      Child.release();
+      AccessGroup.Data.push_back(std::unique_ptr<PDBSymbolData>(Data));
+    } else {
+      AccessGroup.Unknown.push_back(std::move(Child));
+    }
+  }
+
+  int Count = 0;
+  Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[(PDB_MemberAccess)0], OS,
+                           Indent);
+  Count += dumpAccessGroup(PDB_MemberAccess::Public,
+                           Groups[PDB_MemberAccess::Public], OS, Indent);
+  Count += dumpAccessGroup(PDB_MemberAccess::Protected,
+                           Groups[PDB_MemberAccess::Protected], OS, Indent);
+  Count += dumpAccessGroup(PDB_MemberAccess::Private,
+                           Groups[PDB_MemberAccess::Private], OS, Indent);
+
+  if (Count > 0)
+    OS << newline(Indent);
+  OS << "}";
+  OS.flush();
+}
+
+int ClassDefinitionDumper::dumpAccessGroup(PDB_MemberAccess Access,
+                                           const SymbolGroup &Group,
+                                           raw_ostream &OS, int Indent) {
+  if (Group.Functions.empty() && Group.Data.empty() && Group.Unknown.empty())
+    return 0;
+
+  int Count = 0;
+  if (Access == PDB_MemberAccess::Private)
+    OS << newline(Indent) << "private:";
+  else if (Access == PDB_MemberAccess::Protected)
+    OS << newline(Indent) << "protected:";
+  else if (Access == PDB_MemberAccess::Public)
+    OS << newline(Indent) << "public:";
+  for (auto iter = Group.Functions.begin(), end = Group.Functions.end();
+       iter != end; ++iter) {
+    ++Count;
+    (*iter)->dump(OS, Indent + 2, *this);
+  }
+  for (auto iter = Group.Data.begin(), end = Group.Data.end(); iter != end;
+       ++iter) {
+    ++Count;
+    (*iter)->dump(OS, Indent + 2, *this);
+  }
+  for (auto iter = Group.Unknown.begin(), end = Group.Unknown.end();
+       iter != end; ++iter) {
+    ++Count;
+    (*iter)->dump(OS, Indent + 2, *this);
+  }
+  return Count;
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol,
+                                 raw_ostream &OS, int Indent) {}
+
+void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS,
+                                 int Indent) {
+  VariableDumper Dumper;
+  Dumper.start(Symbol, OS, Indent);
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
+                                 int Indent) {
+  FunctionDumper Dumper;
+  Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent);
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol,
+                                 raw_ostream &OS, int Indent) {}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol,
+                                 raw_ostream &OS, int Indent) {
+  OS << newline(Indent) << "enum " << Symbol.getName();
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol,
+                                 raw_ostream &OS, int Indent) {
+  OS << newline(Indent);
+  TypedefDumper Dumper;
+  Dumper.start(Symbol, OS, Indent);
+  OS.flush();
+}
+
+void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol,
+                                 raw_ostream &OS, int Indent) {}

Added: llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.h?rev=230203&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.h (added)
+++ llvm/trunk/tools/llvm-pdbdump/ClassDefinitionDumper.h Sun Feb 22 23:58:34 2015
@@ -0,0 +1,64 @@
+//===- ClassDefinitionDumper.h - --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_CLASSDEFINITIONDUMPER_H
+#define LLVM_TOOLS_LLVMPDBDUMP_CLASSDEFINITIONDUMPER_H
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+
+#include <list>
+#include <memory>
+#include <unordered_map>
+
+namespace llvm {
+
+class ClassDefinitionDumper : public PDBSymDumper {
+public:
+  ClassDefinitionDumper();
+
+  void start(const PDBSymbolTypeUDT &Exe, raw_ostream &OS, int Indent);
+
+  void dump(const PDBSymbolTypeBaseClass &Symbol, raw_ostream &OS,
+            int Indent) override;
+  void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent) override;
+  void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+            int Indent) override;
+  void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent) override;
+  void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+            int Indent) override;
+  void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+            int Indent) override;
+  void dump(const PDBSymbolTypeVTable &Symbol, raw_ostream &OS,
+            int Indent) override;
+
+private:
+  struct SymbolGroup {
+    SymbolGroup() {}
+    SymbolGroup(SymbolGroup &&Other) {
+      Functions = std::move(Other.Functions);
+      Data = std::move(Other.Data);
+      Unknown = std::move(Other.Unknown);
+    }
+
+    std::list<std::unique_ptr<PDBSymbolFunc>> Functions;
+    std::list<std::unique_ptr<PDBSymbolData>> Data;
+    std::list<std::unique_ptr<PDBSymbol>> Unknown;
+    SymbolGroup(const SymbolGroup &other) = delete;
+    SymbolGroup &operator=(const SymbolGroup &other) = delete;
+  };
+  typedef std::unordered_map<PDB_MemberAccess, SymbolGroup> SymbolGroupByAccess;
+
+  int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group,
+                      raw_ostream &OS, int Indent);
+};
+}
+
+#endif

Modified: llvm/trunk/tools/llvm-pdbdump/CompilandDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CompilandDumper.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CompilandDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/CompilandDumper.cpp Sun Feb 22 23:58:34 2015
@@ -75,26 +75,11 @@ void CompilandDumper::dump(const PDBSymb
 
 void CompilandDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
                            int Indent) {
-  uint32_t FuncStart = Symbol.getRelativeVirtualAddress();
-  uint32_t FuncEnd = FuncStart + Symbol.getLength();
-  OS << newline(Indent) << "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.getLength() == 0)
+    return;
 
   FunctionDumper Dumper;
-  Dumper.start(Symbol, OS);
-  OS.flush();
+  Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent);
 }
 
 void CompilandDumper::dump(const PDBSymbolLabel &Symbol, raw_ostream &OS,

Modified: llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp Sun Feb 22 23:58:34 2015
@@ -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 PDBSymb
       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 PDBSymb
     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 << " ";
 
-  OS << " " << Signature->getCallingConvention() << " ";
+  auto ClassParent = Symbol.getClassParent();
+  PDB_CallingConv CC = Signature->getCallingConvention();
+  if (Pointer != FunctionDumper::PointerType::None)
+    OS << "(";
+
+  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 PDBSymbo
 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)

Modified: llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h Sun Feb 22 23:58:34 2015
@@ -22,7 +22,8 @@ public:
 
   void start(const PDBSymbolTypeFunctionSig &Symbol, PointerType Pointer,
              raw_ostream &OS);
-  void start(const PDBSymbolFunc &Symbol, raw_ostream &OS);
+  void start(const PDBSymbolFunc &Symbol, PointerType Pointer, raw_ostream &OS,
+             int Indent);
 
   void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
             int Indent) override;

Modified: llvm/trunk/tools/llvm-pdbdump/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/TypeDumper.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/TypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/TypeDumper.cpp Sun Feb 22 23:58:34 2015
@@ -9,6 +9,7 @@
 
 #include "TypeDumper.h"
 
+#include "ClassDefinitionDumper.h"
 #include "FunctionDumper.h"
 #include "llvm-pdbdump.h"
 #include "TypedefDumper.h"
@@ -18,10 +19,12 @@
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
 
 using namespace llvm;
 
-TypeDumper::TypeDumper() : PDBSymDumper(true) {}
+TypeDumper::TypeDumper(bool Inline, bool ClassDefs)
+    : PDBSymDumper(true), InlineDump(Inline), FullClassDefs(ClassDefs) {}
 
 void TypeDumper::start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent) {
   auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>();
@@ -40,24 +43,55 @@ void TypeDumper::start(const PDBSymbolEx
      << " items)";
   while (auto Typedef = Typedefs->getNext())
     Typedef->dump(OS, Indent + 2, *this);
+
+  auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>();
+  OS << newline(Indent) << "Classes: (" << Classes->getChildCount()
+     << " items)";
+  while (auto Class = Classes->getNext())
+    Class->dump(OS, Indent + 2, *this);
 }
 
 void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
                       int Indent) {
-  OS << newline(Indent) << "enum " << Symbol.getName();
+  if (Symbol.getUnmodifiedTypeId() != 0)
+    return;
+
+  if (!InlineDump)
+    OS << newline(Indent);
+
+  OS << "enum " << Symbol.getName();
 }
 
 void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS,
                       int Indent) {
-  OS << newline(Indent);
+  if (!InlineDump)
+    OS << newline(Indent);
+
   FunctionDumper Dumper;
   Dumper.start(Symbol, FunctionDumper::PointerType::None, OS);
 }
 
 void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
                       int Indent) {
-  OS << newline(Indent);
+  if (!InlineDump)
+    OS << newline(Indent);
+
   TypedefDumper Dumper;
   Dumper.start(Symbol, OS, Indent);
   OS.flush();
 }
+
+void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+                      int Indent) {
+  if (Symbol.getUnmodifiedTypeId() != 0)
+    return;
+  if (!InlineDump)
+    OS << newline(Indent);
+
+  if (FullClassDefs) {
+    ClassDefinitionDumper Dumper;
+    Dumper.start(Symbol, OS, Indent);
+  } else {
+    OS << "class " << Symbol.getName();
+  }
+}

Modified: llvm/trunk/tools/llvm-pdbdump/TypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/TypeDumper.h?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/TypeDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/TypeDumper.h Sun Feb 22 23:58:34 2015
@@ -16,7 +16,7 @@ namespace llvm {
 
 class TypeDumper : public PDBSymDumper {
 public:
-  TypeDumper();
+  TypeDumper(bool Inline, bool ClassDefs);
 
   void start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent);
 
@@ -26,6 +26,12 @@ public:
             int Indent) override;
   void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
             int Indent) override;
+  void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+            int Indent) override;
+
+private:
+  bool InlineDump;
+  bool FullClassDefs;
 };
 }
 

Modified: llvm/trunk/tools/llvm-pdbdump/TypedefDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/TypedefDumper.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/TypedefDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/TypedefDumper.cpp Sun Feb 22 23:58:34 2015
@@ -27,10 +27,11 @@ TypedefDumper::TypedefDumper() : PDBSymD
 
 void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
                           int Indent) {
-  OS << "typedef:" << Symbol.getName() << " -> ";
+  OS << "typedef ";
   uint32_t TargetId = Symbol.getTypeId();
   if (auto TypeSymbol = Symbol.getSession().getSymbolById(TargetId))
     TypeSymbol->dump(OS, 0, *this);
+  OS << " " << Symbol.getName();
 }
 
 void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,

Added: llvm/trunk/tools/llvm-pdbdump/VariableDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/VariableDumper.cpp?rev=230203&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/VariableDumper.cpp (added)
+++ llvm/trunk/tools/llvm-pdbdump/VariableDumper.cpp Sun Feb 22 23:58:34 2015
@@ -0,0 +1,125 @@
+//===- VariableDumper.cpp - -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VariableDumper.h"
+
+#include "llvm-pdbdump.h"
+#include "FunctionDumper.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+VariableDumper::VariableDumper() : PDBSymDumper(true) {}
+
+void VariableDumper::start(const PDBSymbolData &Var, raw_ostream &OS,
+                           int Indent) {
+  OS << newline(Indent);
+  OS << "data ";
+
+  auto VarType = Var.getType();
+
+  switch (auto LocType = Var.getLocationType()) {
+  case PDB_LocType::Static:
+    OS << "[" << format_hex(Var.getRelativeVirtualAddress(), 10) << "] ";
+    OS << "static ";
+    dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+    break;
+  case PDB_LocType::Constant:
+    OS << "const ";
+    dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+    OS << "[" << Var.getValue() << "]";
+    break;
+  case PDB_LocType::ThisRel: {
+    int Offset = Var.getOffset();
+    OS << "+" << format_hex(Var.getOffset(), 4) << " ";
+    OS.flush();
+    dumpSymbolTypeAndName(*VarType, Var.getName(), OS);
+    break;
+  }
+  default:
+    break;
+    OS << "unknown(" << LocType << ") " << Var.getName();
+  }
+}
+
+void VariableDumper::dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
+                          int Indent) {
+  OS << Symbol.getBuiltinType();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
+                          int Indent) {
+  OS << Symbol.getName();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeFunctionSig &Symbol,
+                          raw_ostream &OS, int Indent) {}
+
+void VariableDumper::dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
+                          int Indent) {
+  uint32_t PointeeId = Symbol.getTypeId();
+  auto PointeeType = Symbol.getPointeeType();
+  if (!PointeeType)
+    return;
+
+  if (auto Func = dyn_cast<PDBSymbolFunc>(PointeeType.get())) {
+    FunctionDumper NestedDumper;
+    FunctionDumper::PointerType Pointer =
+        Symbol.isReference() ? FunctionDumper::PointerType::Reference
+                             : FunctionDumper::PointerType::Pointer;
+    NestedDumper.start(*Func, Pointer, OS, Indent);
+  } else {
+    if (Symbol.isConstType())
+      OS << "const ";
+    if (Symbol.isVolatileType())
+      OS << "volatile ";
+    PointeeType->dump(OS, Indent, *this);
+    OS << (Symbol.isReference() ? "&" : "*");
+  }
+}
+
+void VariableDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
+                          int Indent) {
+  OS << "typedef " << Symbol.getName();
+}
+
+void VariableDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
+                          int Indent) {
+  OS << Symbol.getName();
+}
+
+void VariableDumper::dumpSymbolTypeAndName(const PDBSymbol &Type,
+                                           StringRef Name, raw_ostream &OS) {
+  if (auto *ArrayType = dyn_cast<PDBSymbolTypeArray>(&Type)) {
+    bool Done = false;
+    std::string IndexSpec;
+    raw_string_ostream IndexStream(IndexSpec);
+    std::unique_ptr<PDBSymbol> ElementType = ArrayType->getElementType();
+    while (auto NestedArray = dyn_cast<PDBSymbolTypeArray>(ElementType.get())) {
+      IndexStream << "[" << NestedArray->getCount() << "]";
+      ElementType = NestedArray->getElementType();
+    }
+    IndexStream << "[" << ArrayType->getCount() << "]";
+    ElementType->dump(OS, 0, *this);
+    OS << " " << Name << IndexStream.str();
+  } else {
+    Type.dump(OS, 0, *this);
+    OS << " " << Name;
+  }
+}

Copied: llvm/trunk/tools/llvm-pdbdump/VariableDumper.h (from r230202, llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/VariableDumper.h?p2=llvm/trunk/tools/llvm-pdbdump/VariableDumper.h&p1=llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h&r1=230202&r2=230203&rev=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/FunctionDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/VariableDumper.h Sun Feb 22 23:58:34 2015
@@ -1,4 +1,4 @@
-//===- FunctionDumper.h --------------------------------------- *- C++ --*-===//
+//===- VariableDumper.h - PDBSymDumper implementation for types -*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,30 +7,25 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_TOOLS_LLVMPDBDUMP_FUNCTIONDUMPER_H
-#define LLVM_TOOLS_LLVMPDBDUMP_FUNCTIONDUMPER_H
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_VARIABLEDUMPER_H
+#define LLVM_TOOLS_LLVMPDBDUMP_VARIABLEDUMPER_H
 
 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/ADT/StringRef.h"
 
 namespace llvm {
 
-class FunctionDumper : public PDBSymDumper {
+class VariableDumper : public PDBSymDumper {
 public:
-  FunctionDumper();
+  VariableDumper();
 
-  enum class PointerType { None, Pointer, Reference };
+  void start(const PDBSymbolData &Var, raw_ostream &OS, int Indent);
 
-  void start(const PDBSymbolTypeFunctionSig &Symbol, PointerType Pointer,
-             raw_ostream &OS);
-  void start(const PDBSymbolFunc &Symbol, raw_ostream &OS);
-
-  void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
-            int Indent) override;
   void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
             int Indent) override;
   void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
             int Indent) override;
-  void dump(const PDBSymbolTypeFunctionArg &Symbol, raw_ostream &OS,
+  void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS,
             int Indent) override;
   void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
             int Indent) override;
@@ -38,6 +33,10 @@ public:
             int Indent) override;
   void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
             int Indent) override;
+
+private:
+  void dumpSymbolTypeAndName(const PDBSymbol &Type, StringRef Name,
+                             raw_ostream &OS);
 };
 }
 

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=230203&r1=230202&r2=230203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Sun Feb 22 23:58:34 2015
@@ -54,6 +54,8 @@ cl::opt<bool> DumpCompilands("compilands
 cl::opt<bool> DumpSymbols("symbols",
                           cl::desc("Display symbols (implies --compilands"));
 cl::opt<bool> DumpTypes("types", cl::desc("Display types"));
+cl::opt<bool> DumpClassDefs("class-definitions",
+                            cl::desc("Display full class definitions"));
 }
 
 static void dumpInput(StringRef Path) {
@@ -85,7 +87,7 @@ static void dumpInput(StringRef Path) {
 
   if (opts::DumpTypes) {
     outs() << "\nDumping types";
-    TypeDumper Dumper;
+    TypeDumper Dumper(false, opts::DumpClassDefs);
     Dumper.start(*GlobalScope, outs(), 2);
   }
 





More information about the llvm-commits mailing list