[llvm-pdbdump] Many minor fixes and improvements
authorZachary Turner <zturner@google.com>
Mon, 2 Mar 2015 04:39:56 +0000 (04:39 +0000)
committerZachary Turner <zturner@google.com>
Mon, 2 Mar 2015 04:39:56 +0000 (04:39 +0000)
A short list of some of the improvements:

1) Now supports -all command line argument, which implies many
   other command line arguments to simplify usage.
2) Now supports -no-compiler-generated command line argument to
   exclude compiler generated types.
3) Prints base class list.
4) -class-definitions implies -types.
5) Proper display of bitfields.
6) Can now distinguish between struct/class/interface/union.

And a few other minor tweaks.

llvm-svn: 230933

18 files changed:
llvm/include/llvm/DebugInfo/PDB/PDBExtras.h
llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
llvm/lib/DebugInfo/PDB/PDBExtras.cpp
llvm/test/DebugInfo/PDB/pdbdump-symbol-format.test
llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.cpp [new file with mode: 0644]
llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.pdb [new file with mode: 0644]
llvm/test/tools/llvm-pdbdump/class-layout.test [new file with mode: 0644]
llvm/test/tools/llvm-pdbdump/regex-filter.test
llvm/tools/llvm-pdbdump/BuiltinDumper.cpp
llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp
llvm/tools/llvm-pdbdump/CompilandDumper.cpp
llvm/tools/llvm-pdbdump/FunctionDumper.cpp
llvm/tools/llvm-pdbdump/LinePrinter.cpp
llvm/tools/llvm-pdbdump/LinePrinter.h
llvm/tools/llvm-pdbdump/TypedefDumper.cpp
llvm/tools/llvm-pdbdump/VariableDumper.cpp
llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
llvm/tools/llvm-pdbdump/llvm-pdbdump.h

index 104fb6f..48ce1c1 100644 (file)
@@ -26,6 +26,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_ThunkOrdinal &Thunk);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
 raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id);
 
 raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
index 2bee608..686e08f 100644 (file)
@@ -470,8 +470,31 @@ struct Variant {
     uint16_t UInt16;
     uint32_t UInt32;
     uint64_t UInt64;
-    void* Pointer;
   };
+#define VARIANT_EQUAL_CASE(Enum)                                               \
+  case PDB_VariantType::Enum:                                                  \
+    return Enum == Other.Enum;
+  bool operator==(const Variant &Other) const {
+    if (Type != Other.Type)
+      return false;
+    switch (Type) {
+      VARIANT_EQUAL_CASE(Bool)
+      VARIANT_EQUAL_CASE(Int8)
+      VARIANT_EQUAL_CASE(Int16)
+      VARIANT_EQUAL_CASE(Int32)
+      VARIANT_EQUAL_CASE(Int64)
+      VARIANT_EQUAL_CASE(Single)
+      VARIANT_EQUAL_CASE(Double)
+      VARIANT_EQUAL_CASE(UInt8)
+      VARIANT_EQUAL_CASE(UInt16)
+      VARIANT_EQUAL_CASE(UInt32)
+      VARIANT_EQUAL_CASE(UInt64)
+    default:
+      return true;
+    }
+  }
+#undef VARIANT_EQUAL_CASE
+  bool operator!=(const Variant &Other) const { return !(*this == Other); }
 };
 
 } // namespace llvm
index 5a2856f..beec327 100644 (file)
@@ -247,6 +247,25 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_SymType &Tag) {
   return OS;
 }
 
+raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_MemberAccess &Access) {
+  switch (Access) {
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Public, "public", OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Protected, "protected", OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Private, "private", OS)
+  }
+  return OS;
+}
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {
+  switch (Type) {
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Class, "class", OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Struct, "struct", OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Interface, "interface", OS)
+    CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Union, "union", OS)
+  }
+  return OS;
+}
+
 raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_UniqueId &Id) {
   static const char *Lookup = "0123456789ABCDEF";
 
@@ -304,7 +323,6 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Variant &Value) {
     default:
       OS << Value.Type;
   }
-  OS << " {" << Value.Type << "}";
   return OS;
 }
 
index a34d46d..90381f1 100644 (file)
 
 ; FULL_CLASS: ---TYPES---
 ; FULL_CLASS: Classes
-; FULL_CLASS-DAG: class A {
+; FULL_CLASS-DAG: struct 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 MemberTest {
+; FULL_CLASS-DAG: struct MemberTest {
 ; FULL_CLASS: data +0x00 MemberTest::NestedEnum m_nested_enum
 ; FULL_CLASS: data +0x04 int m_typedef
 ; FULL_CLASS: data +0x08 bool m_bool
diff --git a/llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.cpp b/llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.cpp
new file mode 100644 (file)
index 0000000..51c1b9b
--- /dev/null
@@ -0,0 +1,64 @@
+// Compile with "cl /c /Zi /GR- ClassLayoutTest.cpp"\r
+// Link with "link ClassLayoutTest.obj /debug /nodefaultlib /entry:main"\r
+\r
+namespace MembersTest {\r
+  class A {\r
+  public:\r
+    typedef int NestedTypedef;\r
+    enum NestedEnum {\r
+      NestedEnumValue1\r
+    };\r
+\r
+    void MemberFunc() {}\r
+\r
+  private:\r
+    int IntMemberVar;\r
+    double DoubleMemberVar;\r
+  };\r
+}\r
+\r
+namespace GlobalsTest {\r
+  int IntVar;\r
+  double DoubleVar;\r
+  \r
+  typedef int Typedef;\r
+  enum Enum {\r
+    Val1\r
+  } EnumVar;\r
+  Typedef TypedefVar;\r
+}\r
+\r
+namespace BaseClassTest {\r
+  class A {};\r
+  class B : public virtual A {};\r
+  class C : public virtual A {};\r
+  class D : protected B, private C {};\r
+}\r
+\r
+namespace UdtKindTest {\r
+  struct A {};\r
+  class B {};\r
+  union C {};\r
+}\r
+\r
+namespace BitFieldTest {\r
+  struct A {\r
+    int Bits1 : 1;\r
+    int Bits2 : 2;\r
+    int Bits3 : 3;\r
+    int Bits4 : 4;\r
+    int Bits22 : 22;\r
+    int Offset0x04;\r
+  };\r
+};\r
+\r
+int main(int argc, char **argv) {\r
+  MembersTest::A v1;\r
+  v1.MemberFunc();\r
+  BaseClassTest::D v2;\r
+  UdtKindTest::A v3;\r
+  UdtKindTest::B v4;\r
+  UdtKindTest::C v5;\r
+  BitFieldTest::A v7;\r
+  return 0;\r
+}\r
diff --git a/llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.pdb b/llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.pdb
new file mode 100644 (file)
index 0000000..5f5190d
Binary files /dev/null and b/llvm/test/tools/llvm-pdbdump/Inputs/ClassLayoutTest.pdb differ
diff --git a/llvm/test/tools/llvm-pdbdump/class-layout.test b/llvm/test/tools/llvm-pdbdump/class-layout.test
new file mode 100644 (file)
index 0000000..c46e62b
--- /dev/null
@@ -0,0 +1,57 @@
+; RUN: llvm-pdbdump -all %p/Inputs/ClassLayoutTest.pdb > %t\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=GLOBALS_TEST\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=MEMBERS_TEST\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=BASE_CLASS_A\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=BASE_CLASS_B\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=BASE_CLASS_C\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=BASE_CLASS_D\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=UDT_KIND_TEST\r
+; RUN: FileCheck -input-file=%t %s -check-prefix=BITFIELD_TEST\r
+\r
+; GLOBALS_TEST: ---GLOBALS---\r
+; GLOBALS_TEST-DAG: int GlobalsTest::IntVar\r
+; GLOBALS_TEST-DAG: double GlobalsTest::DoubleVar\r
+; GLOBALS_TEST-DAG: GlobalsTest::Enum GlobalsTest::EnumVar\r
+\r
+; MEMBERS_TEST: ---TYPES---\r
+; MEMBERS_TEST: class MembersTest::A {\r
+; MEMBERS_TEST-DAG: typedef int NestedTypedef\r
+; MEMBERS_TEST-DAG: enum NestedEnum\r
+; MEMBERS_TEST: public:\r
+; MEMBERS_TEST-NEXT: void MemberFunc()\r
+; MEMBERS_TEST-NEXT: private:\r
+; MEMBERS_TEST-DAG: int IntMemberVar\r
+; MEMBERS_TEST-DAG: double DoubleMemberVar\r
+; MEMBERS_TEST: }\r
+\r
+; BASE_CLASS_A: ---TYPES---\r
+; BASE_CLASS_A: class BaseClassTest::A {}\r
+\r
+; BASE_CLASS_B: ---TYPES---\r
+; BASE_CLASS_B: class BaseClassTest::B\r
+; BASE_CLASS_B-NEXT: : public virtual BaseClassTest::A {\r
+\r
+; BASE_CLASS_C: ---TYPES---\r
+; BASE_CLASS_C: class BaseClassTest::C\r
+; BASE_CLASS_C-NEXT: : public virtual BaseClassTest::A {\r
+\r
+; BASE_CLASS_D: ---TYPES---\r
+; BASE_CLASS_D: class BaseClassTest::D\r
+; BASE_CLASS_D-DAG: protected BaseClassTest::B\r
+; BASE_CLASS_D-DAG: private BaseClassTest::C\r
+; BASE_CLASS_D-DAG: protected virtual BaseClassTest::A\r
+\r
+; UDT_KIND_TEST: ---TYPES---\r
+; UDT_KIND_TEST-DAG: union UdtKindTest::C {}\r
+; UDT_KIND_TEST-DAG: class UdtKindTest::B {}\r
+; UDT_KIND_TEST-DAG: struct UdtKindTest::A {}\r
+\r
+; BITFIELD_TEST: ---TYPES---\r
+; BITFIELD_TEST: struct BitFieldTest::A {\r
+; BITFIELD_TEST-NEXT: public:\r
+; BITFIELD_TEST-NEXT: +0x00 int Bits1 : 1\r
+; BITFIELD_TEST-NEXT: +0x00 int Bits2 : 2\r
+; BITFIELD_TEST-NEXT: +0x00 int Bits3 : 3\r
+; BITFIELD_TEST-NEXT: +0x00 int Bits4 : 4\r
+; BITFIELD_TEST-NEXT: +0x00 int Bits22 : 22\r
+; BITFIELD_TEST-NEXT: +0x04 int Offset0x04\r
index 5f08d73..a0ad176 100644 (file)
@@ -18,7 +18,7 @@
 ; NO_FILTER: Typedefs
 ; NO_FILTER: typedef int GlobalTypedef
 ; NO_FILTER: Classes:
-; NO_FILTER: class __vc_attributes
+; NO_FILTER: struct __vc_attributes
 ; NO_FILTER: class FilterTestClass
 ; NO_FILTER-DAG: typedef int NestedTypedef
 ; NO_FILTER-DAG: enum NestedEnum
index 1c1fe89..d808298 100644 (file)
@@ -81,7 +81,7 @@ void BuiltinDumper::start(const PDBSymbolTypeBuiltin &Symbol) {
     WithColor(Printer, PDB_ColorItem::Type).get() << "HRESULT";
     break;
   default:
-    WithColor(Printer, PDB_ColorItem::Type).get() << "(unknown)";
+    WithColor(Printer, PDB_ColorItem::Type).get() << "void";
     break;
   }
 }
index 20e3fc4..5db33a8 100644 (file)
@@ -33,8 +33,29 @@ ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
 
 void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
   std::string Name = Class.getName();
-  WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
+  WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
   WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
+
+  auto Bases = Class.findAllChildren<PDBSymbolTypeBaseClass>();
+  if (Bases->getChildCount() > 0) {
+    Printer.Indent();
+    Printer.NewLine();
+    Printer << ":";
+    uint32_t BaseIndex = 0;
+    while (auto Base = Bases->getNext()) {
+      Printer << " ";
+      WithColor(Printer, PDB_ColorItem::Keyword).get() << Base->getAccess();
+      if (Base->isVirtualBaseClass())
+        WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
+      WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base->getName();
+      if (++BaseIndex < Bases->getChildCount()) {
+        Printer.NewLine();
+        Printer << ",";
+      }
+    }
+    Printer.Unindent();
+  }
+
   Printer << " {";
   auto Children = Class.findAllChildren();
   if (Children->getChildCount() == 0) {
@@ -62,9 +83,10 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
     auto &AccessGroup = Groups.find((int)Access)->second;
 
     if (auto Func = dyn_cast<PDBSymbolFunc>(Child.get())) {
-      if (Func->isCompilerGenerated())
+      if (Func->isCompilerGenerated() && opts::ExcludeCompilerGenerated)
         continue;
-      if (Func->getLength() == 0 && !Func->isPureVirtual())
+      if (Func->getLength() == 0 && !Func->isPureVirtual() &&
+          !Func->isIntroVirtualFunction())
         continue;
       Child.release();
       AccessGroup.Functions.push_back(std::unique_ptr<PDBSymbolFunc>(Func));
index accb2de..86bf32d 100644 (file)
@@ -124,7 +124,9 @@ void CompilandDumper::dump(const PDBSymbolThunk &Symbol) {
         << "[" << format_hex(RVA, 10) << " - "
         << format_hex(RVA + Symbol.getLength(), 10) << "]";
   }
-  Printer << " (" << Ordinal << ") ";
+  Printer << " (";
+  WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal;
+  Printer << ") ";
   std::string Name = Symbol.getName();
   if (!Name.empty())
     WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
index ac7ab49..419f888 100644 (file)
@@ -112,28 +112,28 @@ void FunctionDumper::start(const PDBSymbolFunc &Symbol, PointerType Pointer) {
   uint32_t FuncStart = Symbol.getRelativeVirtualAddress();
   uint32_t FuncEnd = FuncStart + Symbol.getLength();
 
-  Printer << "func ";
-  WithColor(Printer, PDB_ColorItem::Address).get() << "["
-                                                   << format_hex(FuncStart, 8);
+  Printer << "func [";
+  WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncStart, 10);
   if (auto DebugStart = Symbol.findOneChild<PDBSymbolFuncDebugStart>()) {
     uint32_t Prologue = DebugStart->getRelativeVirtualAddress() - FuncStart;
     WithColor(Printer, PDB_ColorItem::Offset).get() << "+" << Prologue;
   }
-  WithColor(Printer, PDB_ColorItem::Address).get() << " - "
-                                                   << format_hex(FuncEnd, 8);
+  Printer << " - ";
+  WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(FuncEnd, 10);
   if (auto DebugEnd = Symbol.findOneChild<PDBSymbolFuncDebugEnd>()) {
     uint32_t Epilogue = FuncEnd - DebugEnd->getRelativeVirtualAddress();
     WithColor(Printer, PDB_ColorItem::Offset).get() << "-" << Epilogue;
   }
-  WithColor(Printer, PDB_ColorItem::Address).get() << "] ";
+  Printer << "] (";
 
-  if (Symbol.hasFramePointer())
-    WithColor(Printer, PDB_ColorItem::Address).get()
-        << "(" << Symbol.getLocalBasePointerRegisterId() << ")";
-  else
-    WithColor(Printer, PDB_ColorItem::Address).get() << "(FPO)";
+  if (Symbol.hasFramePointer()) {
+    WithColor(Printer, PDB_ColorItem::Register).get()
+        << Symbol.getLocalBasePointerRegisterId();
+  } else {
+    WithColor(Printer, PDB_ColorItem::Register).get() << "FPO";
+  }
+  Printer << ") ";
 
-  Printer << " ";
   if (Symbol.isVirtual() || Symbol.isPureVirtual())
     WithColor(Printer, PDB_ColorItem::Keyword).get() << "virtual ";
 
index 7aa9359..6bbc403 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "LinePrinter.h"
 
+#include "llvm-pdbdump.h"
+
 #include "llvm/Support/Regex.h"
 
 #include <algorithm>
 using namespace llvm;
 
 LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream)
-    : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) {}
+    : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) {
+  SetFilters(TypeFilters, opts::ExcludeTypes.begin(), opts::ExcludeTypes.end());
+  SetFilters(SymbolFilters, opts::ExcludeSymbols.begin(),
+             opts::ExcludeSymbols.end());
+  SetFilters(CompilandFilters, opts::ExcludeCompilands.begin(),
+             opts::ExcludeCompilands.end());
+}
 
 void LinePrinter::Indent() { CurrentIndent += IndentSpaces; }
 
@@ -86,6 +94,7 @@ void WithColor::translateColor(PDB_ColorItem C, raw_ostream::Colors &Color,
     Color = raw_ostream::MAGENTA;
     Bold = true;
     return;
+  case PDB_ColorItem::Register:
   case PDB_ColorItem::Offset:
     Color = raw_ostream::YELLOW;
     Bold = false;
index 51b4fa9..c2a3ab6 100644 (file)
@@ -25,33 +25,25 @@ class LinePrinter {
 public:
   LinePrinter(int Indent, raw_ostream &Stream);
 
-  template <typename Iter> void SetTypeFilters(Iter Begin, Iter End) {
-    TypeFilters.clear();
-    for (; Begin != End; ++Begin)
-      TypeFilters.push_back(StringRef(*Begin));
-  }
-  template <typename Iter> void SetSymbolFilters(Iter Begin, Iter End) {
-    SymbolFilters.clear();
-    for (; Begin != End; ++Begin)
-      SymbolFilters.push_back(StringRef(*Begin));
-  }
-  template <typename Iter> void SetCompilandFilters(Iter Begin, Iter End) {
-    CompilandFilters.clear();
-    for (; Begin != End; ++Begin)
-      CompilandFilters.push_back(StringRef(*Begin));
-  }
-
   void Indent();
   void Unindent();
   void NewLine();
 
   raw_ostream &getStream() { return OS; }
+  int getIndentLevel() const { return CurrentIndent; }
 
   bool IsTypeExcluded(llvm::StringRef TypeName);
   bool IsSymbolExcluded(llvm::StringRef SymbolName);
   bool IsCompilandExcluded(llvm::StringRef CompilandName);
 
 private:
+  template <typename Iter>
+  void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) {
+    List.clear();
+    for (; Begin != End; ++Begin)
+      List.push_back(StringRef(*Begin));
+  }
+
   raw_ostream &OS;
   int IndentSpaces;
   int CurrentIndent;
@@ -77,6 +69,7 @@ enum class PDB_ColorItem {
   Path,
   SectionHeader,
   LiteralValue,
+  Register,
 };
 
 class WithColor {
index 5e4228c..a6b5c53 100644 (file)
@@ -31,7 +31,8 @@ void TypedefDumper::start(const PDBSymbolTypeTypedef &Symbol) {
   uint32_t TargetId = Symbol.getTypeId();
   if (auto TypeSymbol = Symbol.getSession().getSymbolById(TargetId))
     TypeSymbol->dump(*this);
-  WithColor(Printer, PDB_ColorItem::Type).get() << " " << Symbol.getName();
+  WithColor(Printer, PDB_ColorItem::Identifier).get() << " "
+                                                      << Symbol.getName();
 }
 
 void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol) {}
@@ -74,5 +75,5 @@ void TypedefDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
 
 void TypedefDumper::dump(const PDBSymbolTypeUDT &Symbol) {
   WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
-  WithColor(Printer, PDB_ColorItem::Type).get() << " " << Symbol.getName();
+  WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
 }
index d520fd1..a46e1b0 100644 (file)
@@ -31,6 +31,8 @@ VariableDumper::VariableDumper(LinePrinter &P)
     : PDBSymDumper(true), Printer(P) {}
 
 void VariableDumper::start(const PDBSymbolData &Var) {
+  if (Var.isCompilerGenerated() && opts::ExcludeCompilerGenerated)
+    return;
   if (Printer.IsSymbolExcluded(Var.getName()))
     return;
 
@@ -41,23 +43,31 @@ void VariableDumper::start(const PDBSymbolData &Var) {
 
   switch (auto LocType = Var.getLocationType()) {
   case PDB_LocType::Static:
+    Printer << "[";
     WithColor(Printer, PDB_ColorItem::Address).get()
-        << "[" << format_hex(Var.getRelativeVirtualAddress(), 10) << "] ";
+        << format_hex(Var.getRelativeVirtualAddress(), 10);
+    Printer << "] ";
     WithColor(Printer, PDB_ColorItem::Keyword).get() << "static ";
     dumpSymbolTypeAndName(*VarType, Var.getName());
     break;
   case PDB_LocType::Constant:
     WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
     dumpSymbolTypeAndName(*VarType, Var.getName());
-    Printer << "[";
+    Printer << " = ";
     WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getValue();
-    Printer << "]";
     break;
   case PDB_LocType::ThisRel:
     WithColor(Printer, PDB_ColorItem::Offset).get()
         << "+" << format_hex(Var.getOffset(), 4) << " ";
     dumpSymbolTypeAndName(*VarType, Var.getName());
     break;
+  case PDB_LocType::BitField:
+    WithColor(Printer, PDB_ColorItem::Offset).get()
+        << "+" << format_hex(Var.getOffset(), 4) << " ";
+    dumpSymbolTypeAndName(*VarType, Var.getName());
+    Printer << " : ";
+    WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
+    break;
   default:
     Printer << "unknown(" << LocType << ") ";
     WithColor(Printer, PDB_ColorItem::Identifier).get() << Var.getName();
index e1f0370..1181307 100644 (file)
@@ -56,26 +56,44 @@ cl::list<std::string> InputFilenames(cl::Positional,
                                      cl::desc("<input PDB files>"),
                                      cl::OneOrMore);
 
-cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"));
-cl::opt<bool> Symbols("symbols",
-                      cl::desc("Display symbols for each compiland"));
-cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"));
-cl::opt<bool> Types("types", cl::desc("Display types"));
-cl::opt<bool> ClassDefs("class-definitions",
-                        cl::desc("Display full class definitions"));
+cl::OptionCategory TypeCategory("Symbol Type Options");
+cl::OptionCategory FilterCategory("Filtering Options");
+
+cl::opt<bool> Compilands("compilands", cl::desc("Display compilands"),
+                         cl::cat(TypeCategory));
+cl::opt<bool> Symbols("symbols", cl::desc("Display symbols for each compiland"),
+                      cl::cat(TypeCategory));
+cl::opt<bool> Globals("globals", cl::desc("Dump global symbols"),
+                      cl::cat(TypeCategory));
+cl::opt<bool> Types("types", cl::desc("Display types"), cl::cat(TypeCategory));
+cl::opt<bool>
+    ClassDefs("class-definitions",
+              cl::desc("Display full class definitions (implies -types)"),
+              cl::cat(TypeCategory));
+cl::opt<bool>
+    All("all", cl::desc("Implies all other options in 'Symbol Types' category"),
+        cl::cat(TypeCategory));
 
 cl::list<std::string>
     ExcludeTypes("exclude-types",
                  cl::desc("Exclude types by regular expression"),
-                 cl::ZeroOrMore);
+                 cl::ZeroOrMore, cl::cat(FilterCategory));
 cl::list<std::string>
     ExcludeSymbols("exclude-symbols",
                    cl::desc("Exclude symbols by regular expression"),
-                   cl::ZeroOrMore);
+                   cl::ZeroOrMore, cl::cat(FilterCategory));
 cl::list<std::string>
     ExcludeCompilands("exclude-compilands",
                       cl::desc("Exclude compilands by regular expression"),
-                      cl::ZeroOrMore);
+                      cl::ZeroOrMore, cl::cat(FilterCategory));
+cl::opt<bool> ExcludeCompilerGenerated(
+    "no-compiler-generated",
+    cl::desc("Don't show compiler generated types and symbols"),
+    cl::cat(FilterCategory));
+cl::opt<bool>
+    ExcludeSystemLibraries("no-system-libs",
+                           cl::desc("Don't show symbols from system libraries"),
+                           cl::cat(FilterCategory));
 }
 
 static void dumpInput(StringRef Path) {
@@ -103,11 +121,6 @@ static void dumpInput(StringRef Path) {
   }
 
   LinePrinter Printer(2, outs());
-  Printer.SetTypeFilters(opts::ExcludeTypes.begin(), opts::ExcludeTypes.end());
-  Printer.SetSymbolFilters(opts::ExcludeSymbols.begin(),
-                           opts::ExcludeSymbols.end());
-  Printer.SetCompilandFilters(opts::ExcludeCompilands.begin(),
-                              opts::ExcludeCompilands.end());
 
   auto GlobalScope(Session->getGlobalScope());
   std::string FileName(GlobalScope->getSymbolsFileName());
@@ -220,6 +233,23 @@ int main(int argc_, const char *argv_[]) {
   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
 
   cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
+  if (opts::ClassDefs)
+    opts::Types = true;
+  if (opts::All) {
+    opts::Compilands = true;
+    opts::Symbols = true;
+    opts::Globals = true;
+    opts::Types = true;
+    opts::ClassDefs = true;
+  }
+  if (opts::ExcludeCompilerGenerated) {
+    opts::ExcludeTypes.push_back("__vc_attributes");
+    opts::ExcludeCompilands.push_back("* Linker *");
+  }
+  if (opts::ExcludeSystemLibraries) {
+    opts::ExcludeCompilands.push_back(
+        "f:\\binaries\\Intermediate\\vctools\\crt_bld");
+  }
 
 #if defined(HAVE_DIA_SDK)
   CoInitializeEx(nullptr, COINIT_MULTITHREADED);
index 74a1718..b2f5004 100644 (file)
 #ifndef LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H
 #define LLVM_TOOLS_LLVMPDBDUMP_LLVMPDBDUMP_H
 
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 
-namespace llvm {
-struct newline {
-  newline(int IndentWidth) : Width(IndentWidth) {}
-  int Width;
-};
+namespace opts {
+extern llvm::cl::opt<bool> Compilands;
+extern llvm::cl::opt<bool> Symbols;
+extern llvm::cl::opt<bool> Globals;
+extern llvm::cl::opt<bool> Types;
+extern llvm::cl::opt<bool> ClassDefs;
+extern llvm::cl::opt<bool> All;
 
-inline raw_ostream &operator<<(raw_ostream &OS, const newline &Indent) {
-  OS << "\n";
-  OS.indent(Indent.Width);
-  return OS;
-}
+extern llvm::cl::opt<bool> ExcludeCompilerGenerated;
+
+extern llvm::cl::list<std::string> ExcludeTypes;
+extern llvm::cl::list<std::string> ExcludeSymbols;
+extern llvm::cl::list<std::string> ExcludeCompilands;
 }
 
 #endif
\ No newline at end of file