[llvm] r299733 - Allow specification of what kinds of class members to dump.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 6 16:43:39 PDT 2017


Author: zturner
Date: Thu Apr  6 18:43:39 2017
New Revision: 299733

URL: http://llvm.org/viewvc/llvm-project?rev=299733&view=rev
Log:
Allow specification of what kinds of class members to dump.

Previously when dumping class definitions, there were only
two modes - on or off.  But it's useful to sometimes get a
little more fine-grained.  For example, you might only want
to see the record layout (for example to look for extraneous
padding).  This patch adds a third mode, layout mode, which
does exactly that.  Only this-relative data members are
displayed in this mode.

Differential Revision: https://reviews.llvm.org/D31794

Modified:
    llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test
    llvm/trunk/test/tools/llvm-pdbdump/class-layout.test
    llvm/trunk/test/tools/llvm-pdbdump/regex-filter.test
    llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
    llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h

Modified: llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/DIA/pdbdump-symbol-format.test Thu Apr  6 18:43:39 2017
@@ -30,7 +30,6 @@
 
 ; TYPES_1: Classes
 ; TYPES_1: struct A {
-; TYPES_1: public:
 ; TYPES_1: virtual void PureFunc() = 0
 ; TYPES_1: virtual void VirtualFunc()
 ; TYPES_1: void RegularFunc()

Modified: llvm/trunk/test/tools/llvm-pdbdump/class-layout.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/class-layout.test?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/class-layout.test (original)
+++ llvm/trunk/test/tools/llvm-pdbdump/class-layout.test Thu Apr  6 18:43:39 2017
@@ -17,9 +17,7 @@
 ; MEMBERS_TEST: class MembersTest::A {
 ; MEMBERS_TEST-DAG: typedef int NestedTypedef
 ; MEMBERS_TEST-DAG: enum NestedEnum
-; MEMBERS_TEST: public:
-; MEMBERS_TEST-NEXT: void MemberFunc()
-; MEMBERS_TEST-NEXT: private:
+; MEMBERS_TEST: void MemberFunc()
 ; MEMBERS_TEST-DAG: int IntMemberVar
 ; MEMBERS_TEST-DAG: double DoubleMemberVar
 ; MEMBERS_TEST: }
@@ -48,7 +46,6 @@
 
 ; BITFIELD_TEST: ---TYPES---
 ; BITFIELD_TEST: struct BitFieldTest::A {
-; BITFIELD_TEST-NEXT: public:
 ; BITFIELD_TEST-NEXT: +0x00 int Bits1 : 1
 ; BITFIELD_TEST-NEXT: +0x00 int Bits2 : 2
 ; BITFIELD_TEST-NEXT: +0x00 int Bits3 : 3

Modified: llvm/trunk/test/tools/llvm-pdbdump/regex-filter.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/regex-filter.test?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/regex-filter.test (original)
+++ llvm/trunk/test/tools/llvm-pdbdump/regex-filter.test Thu Apr  6 18:43:39 2017
@@ -1,9 +1,16 @@
 ; RUN: llvm-pdbdump pretty -symbols -globals -types %p/Inputs/FilterTest.pdb \
 ; RUN:    | FileCheck --check-prefix=NO_FILTER %s
+
 ; RUN: llvm-pdbdump pretty -types -exclude-types="GlobalTypedef|NestedTypedef" \
 ; RUN:    %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_TYPEDEFS %s
+; RUN: llvm-pdbdump pretty -classes -enums %p/Inputs/FilterTest.pdb \
+; RUN:    | FileCheck --check-prefix=EXCLUDE_TYPEDEFS %s
+
 ; RUN: llvm-pdbdump pretty -types -exclude-types="GlobalEnum|NestedEnum" \
 ; RUN:    %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_ENUMS %s
+; RUN: llvm-pdbdump pretty -classes -typedefs %p/Inputs/FilterTest.pdb \
+; RUN:    | FileCheck --check-prefix=EXCLUDE_ENUMS %s
+
 ; RUN: llvm-pdbdump pretty -types -symbols -globals -exclude-symbols="MemberVar|GlobalVar" \
 ; RUN:    %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_VARS %s
 ; RUN: llvm-pdbdump pretty -types -exclude-types="FilterTestClass" \
@@ -36,31 +43,25 @@
 ; NO_FILTER-DAG: GlobalEnum GlobalEnumVar
 
 ; EXCLUDE_TYPEDEFS: ---TYPES---
-; EXCLUDE_TYPEDEFS: Enums:
-; EXCLUDE_TYPEDEFS: GlobalEnum
-; EXCLUDE_TYPEDEFS: Typedefs
 ; EXCLUDE_TYPEDEFS-NOT: GlobalTypedef
-; EXCLUDE_TYPEDEFS: Classes
-; EXCLUDE_TYPEDEFS: class FilterTestClass
 ; EXCLUDE_TYPEDEFS-NOT: NestedTypedef
-; EXCLUDE_TYPEDEFS: private:
+; EXCLUDE_TYPEDEFS-DAG: GlobalEnum
+; EXCLUDE_TYPEDEFS-DAG: NestedEnum
+; EXCLUDE_TYPEDEFS: class FilterTestClass
 
 ; EXCLUDE_ENUMS: ---TYPES---
-; EXCLUDE_ENUMS: Enums:
 ; EXCLUDE_ENUMS-NOT: GlobalEnum
-; EXCLUDE_ENUMS: Typedefs
+; EXCLUDE_ENUMS-NOT: NestedEnum
 ; EXCLUDE_ENUMS: GlobalTypedef
-; EXCLUDE_ENUMS: Classes
 ; EXCLUDE_ENUMS: class FilterTestClass
-; EXCLUDE_ENUMS-NOT: NestedEnum
-; EXCLUDE_ENUMS: private:
 
 ; EXCLUDE_VARS: ---TYPES---
-; EXCLUDE_VARS: Classes:
-; EXCLUDE_VARS: class FilterTestClass
-; EXCLUDE_VARS: private:
 ; EXCLUDE_VARS-NOT: IntMemberVar
 ; EXCLUDE_VARS-NOT: DoubleMemberVar
+; EXCLUDE_VARS-DAG: GlobalEnum
+; EXCLUDE_VARS-DAG: NestedEnum
+; EXCLUDE_VARS: GlobalTypedef
+; EXCLUDE_VARS: class FilterTestClass
 ; EXCLUDE_VARS: ---GLOBALS---
 ; EXCLUDE_VARS-NOT: DoubleGlobalVar
 ; EXCLUDE_VARS-NOT: IntGlobalVar

Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp Thu Apr  6 18:43:39 2017
@@ -35,6 +35,9 @@ ClassDefinitionDumper::ClassDefinitionDu
     : PDBSymDumper(true), Printer(P) {}
 
 void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
+  assert(opts::pretty::ClassFormat !=
+         opts::pretty::ClassDefinitionFormat::None);
+
   std::string Name = Class.getName();
   WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
   WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
@@ -61,98 +64,50 @@ void ClassDefinitionDumper::start(const
 
   Printer << " {";
   auto Children = Class.findAllChildren();
-  if (Children->getChildCount() == 0) {
-    Printer << "}";
-    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(0, SymbolGroup()));
-  Groups.insert(std::make_pair((int)PDB_MemberAccess::Private, SymbolGroup()));
-  Groups.insert(
-      std::make_pair((int)PDB_MemberAccess::Protected, SymbolGroup()));
-  Groups.insert(std::make_pair((int)PDB_MemberAccess::Public, SymbolGroup()));
-
+  Printer.Indent();
+  int DumpedCount = 0;
   while (auto Child = Children->getNext()) {
-    PDB_MemberAccess Access = Child->getRawSymbol().getAccess();
-    if (isa<PDBSymbolTypeBaseClass>(*Child))
-      continue;
 
-    auto &AccessGroup = Groups.find((int)Access)->second;
+    if (opts::pretty::ClassFormat ==
+        opts::pretty::ClassDefinitionFormat::LayoutOnly) {
+      if (auto Data = dyn_cast<PDBSymbolData>(Child.get())) {
+        switch (Data->getLocationType()) {
+        case PDB_LocType::ThisRel:
+        case PDB_LocType::BitField:
+          break;
+        default:
+          // All other types of data field do not occupy any storage (e.g. are
+          // const),
+          // so in layout mode we skip them.
+          continue;
+        }
+      } else {
+        // Only data symbols affect record layout, so skip any non-data symbols
+        // if
+        // we're in record layout mode.
+        continue;
+      }
+    }
 
     if (auto Func = dyn_cast<PDBSymbolFunc>(Child.get())) {
       if (Func->isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
         continue;
+
       if (Func->getLength() == 0 && !Func->isPureVirtual() &&
           !Func->isIntroVirtualFunction())
         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));
     }
+
+    ++DumpedCount;
+    Child->dump(*this);
   }
 
-  int Count = 0;
-  Count += dumpAccessGroup((PDB_MemberAccess)0, Groups[0]);
-  Count += dumpAccessGroup(PDB_MemberAccess::Public,
-                           Groups[(int)PDB_MemberAccess::Public]);
-  Count += dumpAccessGroup(PDB_MemberAccess::Protected,
-                           Groups[(int)PDB_MemberAccess::Protected]);
-  Count += dumpAccessGroup(PDB_MemberAccess::Private,
-                           Groups[(int)PDB_MemberAccess::Private]);
-  if (Count > 0)
+  Printer.Unindent();
+  if (DumpedCount > 0)
     Printer.NewLine();
   Printer << "}";
 }
 
-int ClassDefinitionDumper::dumpAccessGroup(PDB_MemberAccess Access,
-                                           const SymbolGroup &Group) {
-  if (Group.Functions.empty() && Group.Data.empty() && Group.Unknown.empty())
-    return 0;
-
-  int Count = 0;
-  if (Access == PDB_MemberAccess::Private) {
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Keyword).get() << "private";
-    Printer << ":";
-  } else if (Access == PDB_MemberAccess::Protected) {
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Keyword).get() << "protected";
-    Printer << ":";
-  } else if (Access == PDB_MemberAccess::Public) {
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Keyword).get() << "public";
-    Printer << ":";
-  }
-  Printer.Indent();
-  for (auto iter = Group.Functions.begin(), end = Group.Functions.end();
-       iter != end; ++iter) {
-    ++Count;
-    (*iter)->dump(*this);
-  }
-  for (auto iter = Group.Data.begin(), end = Group.Data.end(); iter != end;
-       ++iter) {
-    ++Count;
-    (*iter)->dump(*this);
-  }
-  for (auto iter = Group.Unknown.begin(), end = Group.Unknown.end();
-       iter != end; ++iter) {
-    ++Count;
-    (*iter)->dump(*this);
-  }
-  Printer.Unindent();
-  return Count;
-}
-
 void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {}
 
 void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol) {

Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h Thu Apr  6 18:43:39 2017
@@ -39,24 +39,6 @@ public:
 
 private:
   LinePrinter &Printer;
-
-  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<int, SymbolGroup> SymbolGroupByAccess;
-
-  int dumpAccessGroup(PDB_MemberAccess Access, const SymbolGroup &Group);
 };
 }
 }

Modified: llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp Thu Apr  6 18:43:39 2017
@@ -100,7 +100,7 @@ void TypeDumper::dump(const PDBSymbolTyp
 
   Printer.NewLine();
 
-  if (opts::pretty::NoClassDefs) {
+  if (opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::None) {
     WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
     WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
   } else {

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=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Thu Apr  6 18:43:39 2017
@@ -170,9 +170,17 @@ cl::opt<bool>
     ExcludeSystemLibraries("no-system-libs",
                            cl::desc("Don't show symbols from system libraries"),
                            cl::cat(FilterCategory), cl::sub(PrettySubcommand));
-cl::opt<bool> NoClassDefs("no-class-definitions",
-                          cl::desc("Don't display full class definitions"),
-                          cl::cat(FilterCategory), cl::sub(PrettySubcommand));
+cl::opt<ClassDefinitionFormat> ClassFormat(
+    "class-definitions", cl::desc("Class definition format"),
+    cl::init(ClassDefinitionFormat::Full),
+    cl::values(clEnumValN(ClassDefinitionFormat::Full, "full",
+                          "Display complete class definition"),
+               clEnumValN(ClassDefinitionFormat::LayoutOnly, "layout",
+                          "Display only members which affect record layout"),
+               clEnumValN(ClassDefinitionFormat::None, "none",
+                          "Don't display class definitions")),
+    cl::cat(FilterCategory), cl::sub(PrettySubcommand));
+
 cl::opt<bool> NoEnumDefs("no-enum-definitions",
                          cl::desc("Don't display full enum definitions"),
                          cl::cat(FilterCategory), cl::sub(PrettySubcommand));

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h?rev=299733&r1=299732&r2=299733&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h Thu Apr  6 18:43:39 2017
@@ -17,6 +17,8 @@
 namespace opts {
 
 namespace pretty {
+enum class ClassDefinitionFormat { None, LayoutOnly, Full };
+
 extern llvm::cl::opt<bool> Compilands;
 extern llvm::cl::opt<bool> Symbols;
 extern llvm::cl::opt<bool> Globals;
@@ -26,7 +28,7 @@ extern llvm::cl::opt<bool> Typedefs;
 extern llvm::cl::opt<bool> All;
 extern llvm::cl::opt<bool> ExcludeCompilerGenerated;
 
-extern llvm::cl::opt<bool> NoClassDefs;
+extern llvm::cl::opt<ClassDefinitionFormat> ClassFormat;
 extern llvm::cl::opt<bool> NoEnumDefs;
 extern llvm::cl::list<std::string> ExcludeTypes;
 extern llvm::cl::list<std::string> ExcludeSymbols;




More information about the llvm-commits mailing list