From c9736fba4b3015e8bd2d47ced90876faf5d75df4 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Tue, 29 Sep 2015 19:49:06 +0000 Subject: [PATCH] [llvm-pdbdump] Add include-only filters. PDB files have a lot of noise in them, with hundreds (or thousands) of symbols from system libraries and compiler generated types. If you're only looking for a specific type, this can be problematic. This CL allows you to display *only* types, variables, or compilands matching a particular pattern. These filters can even be combined with exclude filters. Include-only filters are given priority, so that first the set of items to display is limited only to those that match the include filters, and then the set of exclude filters is applied to those. If there are no include filters specified, then it means "display everything". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248822 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tools/llvm-pdbdump/regex-filter.test | 20 +++++++ tools/llvm-pdbdump/LinePrinter.cpp | 67 ++++++++++++++--------- tools/llvm-pdbdump/LinePrinter.h | 10 +++- tools/llvm-pdbdump/llvm-pdbdump.cpp | 14 +++++ tools/llvm-pdbdump/llvm-pdbdump.h | 3 + 5 files changed, 84 insertions(+), 30 deletions(-) diff --git a/test/tools/llvm-pdbdump/regex-filter.test b/test/tools/llvm-pdbdump/regex-filter.test index 8b9eca63f58..cfc910e0717 100644 --- a/test/tools/llvm-pdbdump/regex-filter.test +++ b/test/tools/llvm-pdbdump/regex-filter.test @@ -10,6 +10,10 @@ ; 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 +; RUN: llvm-pdbdump -types -include-types="FilterTestClass" \ +; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=INCLUDE_ONLY_TYPES %s +; RUN: llvm-pdbdump -types -symbols -globals -include-symbols="[[:<:]](IntGlobalVar|DoubleGlobalVar)[[:>:]]" \ +; RUN: %p/Inputs/FilterTest.pdb | FileCheck --check-prefix=INCLUDE_ONLY_VARS %s ; NO_FILTER: ---TYPES--- ; NO_FILTER: Enums: @@ -73,3 +77,19 @@ ; EXCLUDE_COMPILAND-NOT: __cdecl main ; EXCLUDE_COMPILAND: * Linker * ; EXCLUDE_COMPILAND: ---GLOBALS--- + +; Everything but types are displayed normally. But FilterTestClass is +; the only type that should be displayed. +; INCLUDE_ONLY_TYPES: ---TYPES--- +; INCLUDE_ONLY_TYPES-NOT: GlobalTypedef +; INCLUDE_ONLY_TYPES: class FilterTestClass + +; We should only see DoubleGlobalVar and IntGlobalVar. This means that even +; variables printed in class definitions should be filtered out. +; INCLUDE_ONLY_VARS: ---TYPES--- +; INCLUDE_ONLY_VARS: class FilterTestClass +; INCLUDE_ONLY_VARS-NOT: IntMemberVar +; INCLUDE_ONLY_VARS-NOT: IntDoubleVar +; INCLUDE_ONLY_VARS: ---GLOBALS--- +; INCLUDE_ONLY_VARS: DoubleGlobalVar +; INCLUDE_ONLY_VARS: IntGlobalVar diff --git a/tools/llvm-pdbdump/LinePrinter.cpp b/tools/llvm-pdbdump/LinePrinter.cpp index 6bbc403f5ca..9f0f5d8c068 100644 --- a/tools/llvm-pdbdump/LinePrinter.cpp +++ b/tools/llvm-pdbdump/LinePrinter.cpp @@ -15,15 +15,48 @@ #include +namespace { +template bool any_of_range(T &&R, Pred P) { + return std::any_of(R.begin(), R.end(), P); +} + +bool IsItemExcluded(llvm::StringRef Item, + std::list &IncludeFilters, + std::list &ExcludeFilters) { + if (Item.empty()) + return false; + + auto match_pred = [Item](llvm::Regex &R) { return R.match(Item); }; + + // Include takes priority over exclude. If the user specified include + // filters, and none of them include this item, them item is gone. + if (!IncludeFilters.empty() && !any_of_range(IncludeFilters, match_pred)) + return true; + + if (any_of_range(ExcludeFilters, match_pred)) + return true; + + return false; +} +} + using namespace llvm; LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream) : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) { - SetFilters(TypeFilters, opts::ExcludeTypes.begin(), opts::ExcludeTypes.end()); - SetFilters(SymbolFilters, opts::ExcludeSymbols.begin(), + SetFilters(ExcludeTypeFilters, opts::ExcludeTypes.begin(), + opts::ExcludeTypes.end()); + SetFilters(ExcludeSymbolFilters, opts::ExcludeSymbols.begin(), opts::ExcludeSymbols.end()); - SetFilters(CompilandFilters, opts::ExcludeCompilands.begin(), + SetFilters(ExcludeCompilandFilters, opts::ExcludeCompilands.begin(), opts::ExcludeCompilands.end()); + + SetFilters(IncludeTypeFilters, opts::IncludeTypes.begin(), + opts::IncludeTypes.end()); + SetFilters(IncludeSymbolFilters, opts::IncludeSymbols.begin(), + opts::IncludeSymbols.end()); + SetFilters(IncludeCompilandFilters, opts::IncludeCompilands.begin(), + opts::IncludeCompilands.end()); } void LinePrinter::Indent() { CurrentIndent += IndentSpaces; } @@ -38,36 +71,16 @@ void LinePrinter::NewLine() { } bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName) { - if (TypeName.empty()) - return false; - - for (auto &Expr : TypeFilters) { - if (Expr.match(TypeName)) - return true; - } - return false; + return IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters); } bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) { - if (SymbolName.empty()) - return false; - - for (auto &Expr : SymbolFilters) { - if (Expr.match(SymbolName)) - return true; - } - return false; + return IsItemExcluded(SymbolName, IncludeSymbolFilters, ExcludeSymbolFilters); } bool LinePrinter::IsCompilandExcluded(llvm::StringRef CompilandName) { - if (CompilandName.empty()) - return false; - - for (auto &Expr : CompilandFilters) { - if (Expr.match(CompilandName)) - return true; - } - return false; + return IsItemExcluded(CompilandName, IncludeCompilandFilters, + ExcludeCompilandFilters); } WithColor::WithColor(LinePrinter &P, PDB_ColorItem C) : OS(P.OS) { diff --git a/tools/llvm-pdbdump/LinePrinter.h b/tools/llvm-pdbdump/LinePrinter.h index b985e934190..67006b03b09 100644 --- a/tools/llvm-pdbdump/LinePrinter.h +++ b/tools/llvm-pdbdump/LinePrinter.h @@ -48,9 +48,13 @@ private: int IndentSpaces; int CurrentIndent; - std::list CompilandFilters; - std::list TypeFilters; - std::list SymbolFilters; + std::list ExcludeCompilandFilters; + std::list ExcludeTypeFilters; + std::list ExcludeSymbolFilters; + + std::list IncludeCompilandFilters; + std::list IncludeTypeFilters; + std::list IncludeSymbolFilters; }; template diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 4a4c64b80cc..24b2b79c5c2 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -91,6 +91,20 @@ cl::list ExcludeCompilands("exclude-compilands", cl::desc("Exclude compilands by regular expression"), cl::ZeroOrMore, cl::cat(FilterCategory)); + +cl::list IncludeTypes( + "include-types", + cl::desc("Include only types which match a regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list IncludeSymbols( + "include-symbols", + cl::desc("Include only symbols which match a regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); +cl::list IncludeCompilands( + "include-compilands", + cl::desc("Include only compilands those which match a regular expression"), + cl::ZeroOrMore, cl::cat(FilterCategory)); + cl::opt ExcludeCompilerGenerated( "no-compiler-generated", cl::desc("Don't show compiler generated types and symbols"), diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index 586a9ea374e..cb5bec64dec 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -27,6 +27,9 @@ extern llvm::cl::opt NoEnumDefs; extern llvm::cl::list ExcludeTypes; extern llvm::cl::list ExcludeSymbols; extern llvm::cl::list ExcludeCompilands; +extern llvm::cl::list IncludeTypes; +extern llvm::cl::list IncludeSymbols; +extern llvm::cl::list IncludeCompilands; } #endif \ No newline at end of file -- 2.34.1