Index: clang-tools-extra/trunk/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst @@ -132,3 +132,9 @@ -------------------------- The improvements are... + +Improvements to pp-trace +------------------------ + +- Added a new option `-callbacks` to filter preprocessor callbacks. It replaces + the `-ignore` option. Index: clang-tools-extra/trunk/docs/pp-trace.rst =================================================================== --- clang-tools-extra/trunk/docs/pp-trace.rst +++ clang-tools-extra/trunk/docs/pp-trace.rst @@ -40,12 +40,12 @@ Command Line Options -------------------- -.. option:: -ignore +.. option:: -callbacks - This option specifies a comma-separated list of names of callbacks - that shouldn't be traced. It can be used to eliminate unwanted - trace output. The callback names are the name of the actual - callback function names in the PPCallbacks class: + This option specifies a comma-separated list of globs describing the list of + callbacks that should be traced. Globs are processed in order of appearance. + Positive globs add matched callbacks to the set, netative globs (those with + the '-' prefix) remove callacks from the set. * FileChanged * FileSkipped Index: clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h =================================================================== --- clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h +++ clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.h @@ -26,7 +26,9 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/GlobPattern.h" #include #include @@ -53,6 +55,8 @@ std::vector Arguments; }; +using FilterType = std::vector>; + /// \brief This class overrides the PPCallbacks class for tracking preprocessor /// activity by means of its callback functions. /// @@ -74,10 +78,10 @@ public: /// \brief Note that all of the arguments are references, and owned /// by the caller. - /// \param Ignore - Set of names of callbacks to ignore. + /// \param Filters - List of (Glob,Enabled) pairs used to filter callbacks. /// \param CallbackCalls - Trace buffer. /// \param PP - The preprocessor. Needed for getting some argument strings. - PPCallbacksTracker(llvm::SmallSet &Ignore, + PPCallbacksTracker(const FilterType &Filters, std::vector &CallbackCalls, clang::Preprocessor &PP); @@ -239,8 +243,11 @@ /// after this object is destructed. std::vector &CallbackCalls; - /// \brief Names of callbacks to ignore. - llvm::SmallSet &Ignore; + // List of (Glob,Enabled) pairs used to filter callbacks. + const FilterType &Filters; + + // Whether a callback should be printed. + llvm::StringMap CallbackIsEnabled; /// \brief Inhibit trace while this is set. bool DisableTrace; Index: clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp =================================================================== --- clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp +++ clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp @@ -88,10 +88,10 @@ // PPCallbacksTracker functions. -PPCallbacksTracker::PPCallbacksTracker(llvm::SmallSet &Ignore, +PPCallbacksTracker::PPCallbacksTracker(const FilterType &Filters, std::vector &CallbackCalls, clang::Preprocessor &PP) - : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {} + : CallbackCalls(CallbackCalls), Filters(Filters), PP(PP) {} PPCallbacksTracker::~PPCallbacksTracker() {} @@ -425,7 +425,14 @@ // Start a new callback. void PPCallbacksTracker::beginCallback(const char *Name) { - DisableTrace = Ignore.count(std::string(Name)); + auto R = CallbackIsEnabled.try_emplace(Name, false); + if (R.second) { + llvm::StringRef N(Name); + for (const std::pair &Filter : Filters) + if (Filter.first.match(N)) + R.first->second = Filter.second; + } + DisableTrace = !R.first->second; if (DisableTrace) return; CallbackCalls.push_back(CallbackCall(Name)); Index: clang-tools-extra/trunk/pp-trace/PPTrace.cpp =================================================================== --- clang-tools-extra/trunk/pp-trace/PPTrace.cpp +++ clang-tools-extra/trunk/pp-trace/PPTrace.cpp @@ -22,27 +22,6 @@ // Basically you put the pp-trace options first, then the source file or files, // and then any options you want to pass to the compiler. // -// These are the pp-trace options: -// -// -ignore (callback list) Don't display output for a comma-separated -// list of callbacks, i.e.: -// -ignore "FileChanged,InclusionDirective" -// -// -output (file) Output trace to the given file in a YAML -// format, e.g.: -// -// --- -// - Callback: Name -// Argument1: Value1 -// Argument2: Value2 -// (etc.) -// ... -// -// Future Directions: -// -// 1. Add option opposite to "-ignore" that specifys a comma-separated option -// list of callbacs. Perhaps "-only" or "-exclusive". -// //===----------------------------------------------------------------------===// #include "PPCallbacksTracker.h" @@ -62,9 +41,11 @@ #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/WithColor.h" #include #include #include @@ -82,10 +63,12 @@ cl::desc(" [... ]"), cl::OneOrMore); -// Option to specify a list or one or more callback names to ignore. -static cl::opt IgnoreCallbacks( - "ignore", cl::init(""), - cl::desc("Ignore callbacks, i.e. \"Callback1, Callback2...\".")); +static cl::opt Callbacks( + "callbacks", cl::init("*"), + cl::desc("Comma-separated list of globs describing the list of callbacks " + "to output. Globs are processed in order of appearance. Globs " + "with the '-' prefix remove callbacks from the set. e.g. " + "'*,-Macro*'.")); // Option to specify the trace output file name. static cl::opt OutputFileName( @@ -103,44 +86,44 @@ // Consumer is responsible for setting up the callbacks. class PPTraceConsumer : public ASTConsumer { public: - PPTraceConsumer(SmallSet &Ignore, + PPTraceConsumer(const FilterType &Filters, std::vector &CallbackCalls, Preprocessor &PP) { // PP takes ownership. - PP.addPPCallbacks(llvm::make_unique(Ignore, - CallbackCalls, PP)); + PP.addPPCallbacks( + llvm::make_unique(Filters, CallbackCalls, PP)); } }; class PPTraceAction : public SyntaxOnlyAction { public: - PPTraceAction(SmallSet &Ignore, + PPTraceAction(const FilterType &Filters, std::vector &CallbackCalls) - : Ignore(Ignore), CallbackCalls(CallbackCalls) {} + : Filters(Filters), CallbackCalls(CallbackCalls) {} protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { - return llvm::make_unique(Ignore, CallbackCalls, + return llvm::make_unique(Filters, CallbackCalls, CI.getPreprocessor()); } private: - SmallSet &Ignore; + const FilterType &Filters; std::vector &CallbackCalls; }; class PPTraceFrontendActionFactory : public FrontendActionFactory { public: - PPTraceFrontendActionFactory(SmallSet &Ignore, + PPTraceFrontendActionFactory(const FilterType &Filters, std::vector &CallbackCalls) - : Ignore(Ignore), CallbackCalls(CallbackCalls) {} + : Filters(Filters), CallbackCalls(CallbackCalls) {} PPTraceAction *create() override { - return new PPTraceAction(Ignore, CallbackCalls); + return new PPTraceAction(Filters, CallbackCalls); } private: - SmallSet &Ignore; + const FilterType &Filters; std::vector &CallbackCalls; }; } // namespace @@ -177,14 +160,21 @@ cl::ParseCommandLineOptions(Argc, Argv, "pp-trace.\n"); // Parse the IgnoreCallbacks list into strings. - SmallVector IgnoreCallbacksStrings; - StringRef(IgnoreCallbacks).split(IgnoreCallbacksStrings, ",", - /*MaxSplit=*/ -1, /*KeepEmpty=*/false); - SmallSet Ignore; - for (SmallVector::iterator I = IgnoreCallbacksStrings.begin(), - E = IgnoreCallbacksStrings.end(); - I != E; ++I) - Ignore.insert(*I); + SmallVector Patterns; + FilterType Filters; + StringRef(Callbacks).split(Patterns, ",", + /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (StringRef Pattern : Patterns) { + Pattern = Pattern.trim(); + bool Enabled = !Pattern.consume_front("-"); + if (Expected Pat = GlobPattern::create(Pattern)) + Filters.emplace_back(std::move(*Pat), Enabled); + else { + WithColor::error(llvm::errs(), "pp-trace") + << toString(Pat.takeError()) << '\n'; + return 1; + } + } // Create the compilation database. SmallString<256> PathBuf; @@ -198,7 +188,7 @@ // Create the tool and run the compilation. ClangTool Tool(*Compilations, SourcePaths); - PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls); + PPTraceFrontendActionFactory Factory(Filters, CallbackCalls); int HadErrors = Tool.run(&Factory); // If we had errors, exit early. Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-conditional.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-conditional.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-conditional.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #if 1 #endif Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-filter.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-filter.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-filter.cpp @@ -0,0 +1,17 @@ +// RUN: pp-trace -callbacks 'File*,Macro*,-MacroUndefined' %s | FileCheck %s +// RUN: pp-trace -callbacks ' File* , Macro* , -MacroUndefined ' %s | FileCheck %s +// RUN: not pp-trace -callbacks '[' %s 2>&1 | FileCheck --check-prefix=INVALID %s + +#define M 1 +int i = M; +#undef M + +// CHECK: --- +// CHECK: - Callback: FileChanged +// CHECK: - Callback: MacroDefined +// CHECK: - Callback: MacroExpands +// CHECK-NOT: - Callback: MacroUndefined +// CHECK-NOT: - Callback: EndOfMainFile +// CHECK: ... + +// INVALID: error: invalid glob pattern: [ Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-ident.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-ident.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-ident.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #ident "$Id$" Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-macro.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-macro.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-macro.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #define MACRO 1 int i = MACRO; Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-modules.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-modules.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-modules.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s // CHECK: --- Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-general.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-general.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-general.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s | FileCheck --strict-whitespace %s #pragma clang diagnostic push #pragma clang diagnostic pop Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-ms.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-ms.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-ms.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s #pragma comment(compiler, "compiler comment") #pragma comment(exestr, "exestr comment") Index: clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-opencl.cpp =================================================================== --- clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-opencl.cpp +++ clang-tools-extra/trunk/test/pp-trace/pp-trace-pragma-opencl.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x cl | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -x cl | FileCheck --strict-whitespace %s #pragma OPENCL EXTENSION all : disable #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : disable