diff --git a/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp b/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp new file mode 100644 index 000000000000..5f803e698494 --- /dev/null +++ b/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.cpp @@ -0,0 +1,29 @@ +// Compile with "cl /c /Zi /GR- FilterTest.cpp" +// Link with "link FilterTest.obj /debug /nodefaultlib /entry:main" + +class FilterTestClass { +public: + typedef int NestedTypedef; + enum NestedEnum { + NestedEnumValue1 + }; + + void MemberFunc() {} + +private: + int IntMemberVar; + double DoubleMemberVar; +}; + +int IntGlobalVar; +double DoubleGlobalVar; +typedef int GlobalTypedef; +enum GlobalEnum { + GlobalEnumVal1 +} GlobalEnumVar; + +int main(int argc, char **argv) { + FilterTestClass TestClass; + GlobalTypedef v1; + return 0; +} diff --git a/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb b/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb new file mode 100644 index 000000000000..5f01ec701b81 Binary files /dev/null and b/llvm/test/tools/llvm-pdbdump/Inputs/FilterTest.pdb differ diff --git a/llvm/test/tools/llvm-pdbdump/lit.local.cfg b/llvm/test/tools/llvm-pdbdump/lit.local.cfg new file mode 100644 index 000000000000..28a895f51148 --- /dev/null +++ b/llvm/test/tools/llvm-pdbdump/lit.local.cfg @@ -0,0 +1 @@ +config.unsupported = not config.have_dia_sdk diff --git a/llvm/test/tools/llvm-pdbdump/regex-filter.test b/llvm/test/tools/llvm-pdbdump/regex-filter.test new file mode 100644 index 000000000000..5f08d7348d98 --- /dev/null +++ b/llvm/test/tools/llvm-pdbdump/regex-filter.test @@ -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--- diff --git a/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp index 8a0c04fc5e49..d6fcaea3edad 100644 --- a/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp +++ b/llvm/tools/llvm-pdbdump/ClassDefinitionDumper.cpp @@ -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); diff --git a/llvm/tools/llvm-pdbdump/CompilandDumper.cpp b/llvm/tools/llvm-pdbdump/CompilandDumper.cpp index e15384ce71c4..14197a8b48e1 100644 --- a/llvm/tools/llvm-pdbdump/CompilandDumper.cpp +++ b/llvm/tools/llvm-pdbdump/CompilandDumper.cpp @@ -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(); diff --git a/llvm/tools/llvm-pdbdump/LinePrinter.cpp b/llvm/tools/llvm-pdbdump/LinePrinter.cpp index 09ba329ad0a7..7aa93599a20b 100644 --- a/llvm/tools/llvm-pdbdump/LinePrinter.cpp +++ b/llvm/tools/llvm-pdbdump/LinePrinter.cpp @@ -9,6 +9,8 @@ #include "LinePrinter.h" +#include "llvm/Support/Regex.h" + #include 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(); diff --git a/llvm/tools/llvm-pdbdump/LinePrinter.h b/llvm/tools/llvm-pdbdump/LinePrinter.h index 0f66d1f7c85f..003e847bbb44 100644 --- a/llvm/tools/llvm-pdbdump/LinePrinter.h +++ b/llvm/tools/llvm-pdbdump/LinePrinter.h @@ -12,6 +12,9 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Regex.h" + +#include namespace llvm { @@ -21,17 +24,34 @@ class LinePrinter { public: LinePrinter(int Indent, raw_ostream &Stream); + template void SetTypeFilters(Iter Begin, Iter End) { + TypeFilters.assign(Begin, End); + } + template void SetSymbolFilters(Iter Begin, Iter End) { + SymbolFilters.assign(Begin, End); + } + template 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 CompilandFilters; + std::list TypeFilters; + std::list SymbolFilters; }; template diff --git a/llvm/tools/llvm-pdbdump/TypeDumper.cpp b/llvm/tools/llvm-pdbdump/TypeDumper.cpp index 71ed203637af..8bca68e8d8b6 100644 --- a/llvm/tools/llvm-pdbdump/TypeDumper.cpp +++ b/llvm/tools/llvm-pdbdump/TypeDumper.cpp @@ -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(); @@ -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); diff --git a/llvm/tools/llvm-pdbdump/TypeDumper.h b/llvm/tools/llvm-pdbdump/TypeDumper.h index b0bfe570e91f..51d2d4a55537 100644 --- a/llvm/tools/llvm-pdbdump/TypeDumper.h +++ b/llvm/tools/llvm-pdbdump/TypeDumper.h @@ -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; }; } diff --git a/llvm/tools/llvm-pdbdump/VariableDumper.cpp b/llvm/tools/llvm-pdbdump/VariableDumper.cpp index 90c418cf52af..ec72d16fef9a 100644 --- a/llvm/tools/llvm-pdbdump/VariableDumper.cpp +++ b/llvm/tools/llvm-pdbdump/VariableDumper.cpp @@ -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 "; diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index 98b26144e348..9ad79ad3b328 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -63,6 +63,19 @@ cl::opt Globals("globals", cl::desc("Dump global symbols")); cl::opt Types("types", cl::desc("Display types")); cl::opt ClassDefs("class-definitions", cl::desc("Display full class definitions")); + +cl::list + ExcludeTypes("exclude-types", + cl::desc("Exclude types by regular expression"), + cl::ZeroOrMore); +cl::list + ExcludeSymbols("exclude-symbols", + cl::desc("Exclude symbols by regular expression"), + cl::ZeroOrMore); +cl::list + 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(); }