diff --git a/llvm/test/tools/llvm-pdbdump/regex-filter.test b/llvm/test/tools/llvm-pdbdump/regex-filter.test index 8b9eca63f585..cfc910e07171 100644 --- a/llvm/test/tools/llvm-pdbdump/regex-filter.test +++ b/llvm/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/llvm/tools/llvm-pdbdump/LinePrinter.cpp b/llvm/tools/llvm-pdbdump/LinePrinter.cpp index 6bbc403f5caf..9f0f5d8c0683 100644 --- a/llvm/tools/llvm-pdbdump/LinePrinter.cpp +++ b/llvm/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/llvm/tools/llvm-pdbdump/LinePrinter.h b/llvm/tools/llvm-pdbdump/LinePrinter.h index b985e9341909..67006b03b098 100644 --- a/llvm/tools/llvm-pdbdump/LinePrinter.h +++ b/llvm/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/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index 4a4c64b80cc1..24b2b79c5c29 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/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/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h index 586a9ea374ed..cb5bec64dec8 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/llvm/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