[llvm-pdbdump] Add regex-based filtering.
authorZachary Turner <zturner@google.com>
Sun, 1 Mar 2015 06:49:49 +0000 (06:49 +0000)
committerZachary Turner <zturner@google.com>
Sun, 1 Mar 2015 06:49:49 +0000 (06:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230888 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
test/tools/llvm-pdbdump/Inputs/FilterTest.cpp [new file with mode: 0644]
test/tools/llvm-pdbdump/Inputs/FilterTest.pdb [new file with mode: 0644]
test/tools/llvm-pdbdump/lit.local.cfg [new file with mode: 0644]
test/tools/llvm-pdbdump/regex-filter.test [new file with mode: 0644]
tools/llvm-pdbdump/ClassDefinitionDumper.cpp
tools/llvm-pdbdump/CompilandDumper.cpp
tools/llvm-pdbdump/LinePrinter.cpp
tools/llvm-pdbdump/LinePrinter.h
tools/llvm-pdbdump/TypeDumper.cpp
tools/llvm-pdbdump/TypeDumper.h
tools/llvm-pdbdump/VariableDumper.cpp
tools/llvm-pdbdump/llvm-pdbdump.cpp

diff --git a/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp b/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp
new file mode 100644 (file)
index 0000000..5f803e6
--- /dev/null
@@ -0,0 +1,29 @@
+// Compile with "cl /c /Zi /GR- FilterTest.cpp"\r
+// Link with "link FilterTest.obj /debug /nodefaultlib /entry:main"\r
+\r
+class FilterTestClass {\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
+int IntGlobalVar;\r
+double DoubleGlobalVar;\r
+typedef int GlobalTypedef;\r
+enum GlobalEnum {\r
+  GlobalEnumVal1\r
+} GlobalEnumVar;\r
+\r
+int main(int argc, char **argv) {\r
+  FilterTestClass TestClass;\r
+  GlobalTypedef v1;\r
+  return 0;\r
+}\r
diff --git a/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb b/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb
new file mode 100644 (file)
index 0000000..5f01ec7
Binary files /dev/null and b/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb differ
diff --git a/test/tools/llvm-pdbdump/lit.local.cfg b/test/tools/llvm-pdbdump/lit.local.cfg
new file mode 100644 (file)
index 0000000..28a895f
--- /dev/null
@@ -0,0 +1 @@
+config.unsupported = not config.have_dia_sdk
diff --git a/test/tools/llvm-pdbdump/regex-filter.test b/test/tools/llvm-pdbdump/regex-filter.test
new file mode 100644 (file)
index 0000000..5f08d73
--- /dev/null
@@ -0,0 +1,76 @@
+; RUN: llvm-pdbdump -symbols -globals -class-definitions -types %p/Inputs/FilterTest.pdb \
+; RUN:    | FileCheck --check-prefix=NO_FILTER %s
+; RUN: llvm-pdbdump -class-definitions -types -exclude-types="GlobalTypedef|NestedTypedef" \
+; RUN:    %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_TYPEDEFS %s
+; RUN: llvm-pdbdump -class-definitions -types -exclude-types="GlobalEnum|NestedEnum" \
+; RUN:    %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=EXCLUDE_ENUMS %s
+; RUN: llvm-pdbdump -class-definitions -types -symbols -globals \
+; RUN:    -exclude-symbols="MemberVar|GlobalVar" %p/Inputs/FilterTest.pdb | FileCheck \
+; RUN:    --check-prefix=EXCLUDE_VARS %s
+; RUN: llvm-pdbdump -types -class-definitions -exclude-types="FilterTestClass" \
+; RUN:    %p/Inputs/FilterTest.pdb | FileCheck  --check-prefix=EXCLUDE_WHOLE_CLASS %s
+; RUN: llvm-pdbdump -symbols -globals -exclude-compilands="FilterTest.obj"  \
+; RUN:    %p/Inputs/FilterTest.pdb | FileCheck  --check-prefix=EXCLUDE_COMPILAND %s
+
+; NO_FILTER: ---TYPES---
+; NO_FILTER: Enums:
+; NO_FILTER: enum GlobalEnum
+; NO_FILTER: Typedefs
+; NO_FILTER: typedef int GlobalTypedef
+; NO_FILTER: Classes:
+; NO_FILTER: class __vc_attributes
+; NO_FILTER: class FilterTestClass
+; NO_FILTER-DAG: typedef int NestedTypedef
+; NO_FILTER-DAG: enum NestedEnum
+; NO_FILTER-DAG: int IntMemberVar
+; NO_FILTER-DAG: double DoubleMemberVar
+; NO_FILTER: ---SYMBOLS---
+; NO_FILTER: Inputs\FilterTest.obj
+; NO_FILTER: int __cdecl main(int argc, char** argv)
+; NO_FILTER: ---GLOBALS---
+; NO_FILTER-DAG: double DoubleGlobalVar
+; NO_FILTER-DAG: int IntGlobalVar
+; 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_ENUMS: ---TYPES---
+; EXCLUDE_ENUMS: Enums:
+; EXCLUDE_ENUMS-NOT: GlobalEnum
+; EXCLUDE_ENUMS: Typedefs
+; 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: ---GLOBALS---
+; EXCLUDE_VARS-NOT: DoubleGlobalVar
+; EXCLUDE_VARS-NOT: IntGlobalVar
+
+; EXCLUDE_WHOLE_CLASS: ---TYPES---
+; EXCLUDE_WHOLE_CLASS-NOT: class FilterTestClass
+; EXCLUDE_WHOLE_CLASS-NOT: typedef int NestedTypedef
+; EXCLUDE_WHOLE_CLASS-NOT: enum NestedEnum
+; EXCLUDE_WHOLE_CLASS-NOT: int IntMemberVar
+; EXCLUDE_WHOLE_CLASS-NOT: double DoubleMemberVar
+
+; EXCLUDE_COMPILAND: ---SYMBOLS---
+; EXCLUDE_COMPILAND-NOT: FilterTest.obj
+; EXCLUDE_COMPILAND-NOT: __cdecl main
+; EXCLUDE_COMPILAND: * Linker *
+; EXCLUDE_COMPILAND: ---GLOBALS---
index 8a0c04fc5e4951b5ebf316f305bb4d179cc9ddd7..d6fcaea3edadbce778d1c5331c781b1c12346084 100644 (file)
@@ -142,6 +142,9 @@ void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS,
 
 void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
                                  int Indent) {
+  if (Printer.IsSymbolExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
   FunctionDumper Dumper(Printer);
   Dumper.start(Symbol, FunctionDumper::PointerType::None, OS, Indent);
@@ -152,6 +155,9 @@ void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol,
 
 void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol,
                                  raw_ostream &OS, int Indent) {
+  if (Printer.IsTypeExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
   WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum ";
   WithColor(Printer, PDB_ColorItem::Type).get() << Symbol.getName();
@@ -159,6 +165,9 @@ void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol,
 
 void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol,
                                  raw_ostream &OS, int Indent) {
+  if (Printer.IsTypeExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
   TypedefDumper Dumper(Printer);
   Dumper.start(Symbol, OS, Indent);
index e15384ce71c4fc5c2aaa1619a09ca9f039340d2b..14197a8b48e151b97efead6678c85e8d81cfa5ba 100644 (file)
@@ -47,6 +47,9 @@ void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol, raw_ostream &OS,
 void CompilandDumper::start(const PDBSymbolCompiland &Symbol, raw_ostream &OS,
                             int Indent, bool Children) {
   std::string FullName = Symbol.getName();
+  if (Printer.IsCompilandExcluded(FullName))
+    return;
+
   Printer.NewLine();
   WithColor(Printer, PDB_ColorItem::Path).get() << FullName;
   if (!Children)
@@ -61,6 +64,9 @@ void CompilandDumper::start(const PDBSymbolCompiland &Symbol, raw_ostream &OS,
 
 void CompilandDumper::dump(const PDBSymbolData &Symbol, raw_ostream &OS,
                            int Indent) {
+  if (Printer.IsSymbolExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
 
   switch (auto LocType = Symbol.getLocationType()) {
@@ -86,6 +92,8 @@ void CompilandDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
                            int Indent) {
   if (Symbol.getLength() == 0)
     return;
+  if (Printer.IsSymbolExcluded(Symbol.getName()))
+    return;
 
   Printer.NewLine();
   FunctionDumper Dumper(Printer);
@@ -94,6 +102,9 @@ void CompilandDumper::dump(const PDBSymbolFunc &Symbol, raw_ostream &OS,
 
 void CompilandDumper::dump(const PDBSymbolLabel &Symbol, raw_ostream &OS,
                            int Indent) {
+  if (Printer.IsSymbolExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
   Printer << "label ";
   WithColor(Printer, PDB_ColorItem::Address).get()
@@ -103,6 +114,9 @@ void CompilandDumper::dump(const PDBSymbolLabel &Symbol, raw_ostream &OS,
 
 void CompilandDumper::dump(const PDBSymbolThunk &Symbol, raw_ostream &OS,
                            int Indent) {
+  if (Printer.IsSymbolExcluded(Symbol.getName()))
+    return;
+
   Printer.NewLine();
   Printer << "thunk ";
   PDB_ThunkOrdinal Ordinal = Symbol.getThunkOrdinal();
index 09ba329ad0a7172e0c3d9130866348dc0c0a909f..7aa93599a20b75be1d0f86b9c868421af969cadb 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "LinePrinter.h"
 
+#include "llvm/Support/Regex.h"
+
 #include <algorithm>
 
 using namespace llvm;
@@ -27,6 +29,39 @@ void LinePrinter::NewLine() {
   OS.indent(CurrentIndent);
 }
 
+bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName) {
+  if (TypeName.empty())
+    return false;
+
+  for (auto &Expr : TypeFilters) {
+    if (Expr.match(TypeName))
+      return true;
+  }
+  return false;
+}
+
+bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) {
+  if (SymbolName.empty())
+    return false;
+
+  for (auto &Expr : SymbolFilters) {
+    if (Expr.match(SymbolName))
+      return true;
+  }
+  return false;
+}
+
+bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) {
+  if (CompilandName.empty())
+    return false;
+
+  for (auto &Expr : CompilandFilters) {
+    if (Expr.match(CompilandName))
+      return true;
+  }
+  return false;
+}
+
 WithColor::WithColor(LinePrinter &P, PDB_ColorItem C) : OS(P.OS) {
   if (C == PDB_ColorItem::None)
     OS.resetColor();
index 0f66d1f7c85fbc526ee820a00439bc865a52b7fe..003e847bbb448df4b2810ee1c16878b74139643c 100644 (file)
@@ -12,6 +12,9 @@
 
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Regex.h"
+
+#include <list>
 
 namespace llvm {
 
@@ -21,17 +24,34 @@ class LinePrinter {
 public:
   LinePrinter(int Indent, raw_ostream &Stream);
 
+  template <typename Iter> void SetTypeFilters(Iter Begin, Iter End) {
+    TypeFilters.assign(Begin, End);
+  }
+  template <typename Iter> void SetSymbolFilters(Iter Begin, Iter End) {
+    SymbolFilters.assign(Begin, End);
+  }
+  template <typename Iter> void SetCompilandFilters(Iter Begin, Iter End) {
+    CompilandFilters.assign(Begin, End);
+  }
+
   void Indent();
   void Unindent();
-
   void NewLine();
 
   raw_ostream &getStream() { return OS; }
 
+  bool IsTypeExcluded(llvm::StringRef TypeName);
+  bool IsSymbolExcluded(llvm::StringRef SymbolName);
+  bool IsCompilandExcluded(llvm::StringRef CompilandName);
+
 private:
   raw_ostream &OS;
   int IndentSpaces;
   int CurrentIndent;
+
+  std::list<Regex> CompilandFilters;
+  std::list<Regex> TypeFilters;
+  std::list<Regex> SymbolFilters;
 };
 
 template <class T>
index 71ed203637afe4e048042bc815fd05a4dd868e6b..8bca68e8d8b6f073f700dffabada18a036df6612 100644 (file)
@@ -22,9 +22,8 @@
 
 using namespace llvm;
 
-TypeDumper::TypeDumper(LinePrinter &P, bool Inline, bool ClassDefs)
-    : PDBSymDumper(true), Printer(P), InlineDump(Inline),
-      FullClassDefs(ClassDefs) {}
+TypeDumper::TypeDumper(LinePrinter &P, bool ClassDefs)
+    : PDBSymDumper(true), Printer(P), FullClassDefs(ClassDefs) {}
 
 void TypeDumper::start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent) {
   auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>();
@@ -59,9 +58,9 @@ void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
                       int Indent) {
   if (Symbol.getUnmodifiedTypeId() != 0)
     return;
-
-  if (!InlineDump)
-    Printer.NewLine();
+  if (Printer.IsTypeExcluded(Symbol.getName()))
+    return;
+  Printer.NewLine();
 
   WithColor(Printer, PDB_ColorItem::Keyword).get() << "enum ";
   WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
@@ -69,9 +68,10 @@ void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
 
 void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
                       int Indent) {
-  if (!InlineDump)
-    Printer.NewLine();
+  if (Printer.IsTypeExcluded(Symbol.getName()))
+    return;
 
+  Printer.NewLine();
   TypedefDumper Dumper(Printer);
   Dumper.start(Symbol, OS, Indent);
 }
@@ -80,8 +80,10 @@ void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
                       int Indent) {
   if (Symbol.getUnmodifiedTypeId() != 0)
     return;
-  if (!InlineDump)
-    Printer.NewLine();
+  if (Printer.IsTypeExcluded(Symbol.getName()))
+    return;
+
+  Printer.NewLine();
 
   if (FullClassDefs) {
     ClassDefinitionDumper Dumper(Printer);
index b0bfe570e91fd6f472983fad79be6c99cef54543..51d2d4a555371191b561283728f375799014a81f 100644 (file)
@@ -18,7 +18,7 @@ class LinePrinter;
 
 class TypeDumper : public PDBSymDumper {
 public:
-  TypeDumper(LinePrinter &P, bool Inline, bool ClassDefs);
+  TypeDumper(LinePrinter &P, bool ClassDefs);
 
   void start(const PDBSymbolExe &Exe, raw_ostream &OS, int Indent);
 
@@ -31,7 +31,6 @@ public:
 
 private:
   LinePrinter &Printer;
-  bool InlineDump;
   bool FullClassDefs;
 };
 }
index 90c418cf52afcb29533342be0b3ed35a21ac8b2c..ec72d16fef9aff925ce42f24a8f8facfdf9b18e7 100644 (file)
@@ -32,6 +32,9 @@ VariableDumper::VariableDumper(LinePrinter &P)
 
 void VariableDumper::start(const PDBSymbolData &Var, raw_ostream &OS,
                            int Indent) {
+  if (Printer.IsSymbolExcluded(Var.getName()))
+    return;
+
   Printer.NewLine();
   Printer << "data ";
 
index 98b26144e3489703d3ae61346198bd4393e1ebdf..9ad79ad3b328d152a9804c2b0ba871b72b3a118a 100644 (file)
@@ -63,6 +63,19 @@ 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::list<std::string>
+    ExcludeTypes("exclude-types",
+                 cl::desc("Exclude types by regular expression"),
+                 cl::ZeroOrMore);
+cl::list<std::string>
+    ExcludeSymbols("exclude-symbols",
+                   cl::desc("Exclude symbols by regular expression"),
+                   cl::ZeroOrMore);
+cl::list<std::string>
+    ExcludeCompilands("exclude-compilands",
+                      cl::desc("Exclude compilands by regular expression"),
+                      cl::ZeroOrMore);
 }
 
 static void dumpInput(StringRef Path) {
@@ -90,6 +103,11 @@ 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());
@@ -140,7 +158,7 @@ static void dumpInput(StringRef Path) {
     Printer.NewLine();
     WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
     Printer.Indent();
-    TypeDumper Dumper(Printer, false, opts::ClassDefs);
+    TypeDumper Dumper(Printer, opts::ClassDefs);
     Dumper.start(*GlobalScope, outs(), 2);
     Printer.Unindent();
   }