diff --git a/clang-tools-extra/pp-trace/PPTrace.cpp b/clang-tools-extra/pp-trace/PPTrace.cpp index 69b2adfe6ba2..597d9ac31ae2 100644 --- a/clang-tools-extra/pp-trace/PPTrace.cpp +++ b/clang-tools-extra/pp-trace/PPTrace.cpp @@ -34,6 +34,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Lex/Preprocessor.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Execution.h" #include "clang/Tooling/Tooling.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" @@ -42,6 +43,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/GlobPattern.h" +#include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/ToolOutputFile.h" @@ -56,108 +58,79 @@ using namespace clang; using namespace clang::tooling; using namespace llvm; -// Options: - -// Collect the source files. -static cl::list SourcePaths(cl::Positional, - cl::desc(" [... ]"), - cl::OneOrMore); +static cl::OptionCategory Cat("pp-trace options"); 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*'.")); + "'*,-Macro*'."), + cl::cat(Cat)); -// Option to specify the trace output file name. static cl::opt OutputFileName( - "output", cl::init(""), - cl::desc("Output trace to the given file name or '-' for stdout.")); + "output", cl::init("-"), + cl::desc("Output trace to the given file name or '-' for stdout."), + cl::cat(Cat)); -// Collect all other arguments, which will be passed to the front end. -static cl::list - CC1Arguments(cl::ConsumeAfter, - cl::desc("...")); - -// Frontend action stuff: +LLVM_ATTRIBUTE_NORETURN static void error(Twine Message) { + WithColor::error() << Message << '\n'; + exit(1); +} namespace { -// Consumer is responsible for setting up the callbacks. -class PPTraceConsumer : public ASTConsumer { -public: - PPTraceConsumer(const FilterType &Filters, - std::vector &CallbackCalls, Preprocessor &PP) { - // PP takes ownership. - PP.addPPCallbacks( - llvm::make_unique(Filters, CallbackCalls, PP)); - } -}; -class PPTraceAction : public SyntaxOnlyAction { +class PPTraceAction : public ASTFrontendAction { public: - PPTraceAction(const FilterType &Filters, - std::vector &CallbackCalls) - : Filters(Filters), CallbackCalls(CallbackCalls) {} + PPTraceAction(const FilterType &Filters, raw_ostream &OS) + : Filters(Filters), OS(OS) {} protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { - return llvm::make_unique(Filters, CallbackCalls, - CI.getPreprocessor()); + Preprocessor &PP = CI.getPreprocessor(); + PP.addPPCallbacks( + make_unique(Filters, CallbackCalls, PP)); + return make_unique(); + } + + void EndSourceFileAction() override { + OS << "---\n"; + for (const CallbackCall &Callback : CallbackCalls) { + OS << "- Callback: " << Callback.Name << "\n"; + for (const Argument &Arg : Callback.Arguments) + OS << " " << Arg.Name << ": " << Arg.Value << "\n"; + } + OS << "...\n"; + + CallbackCalls.clear(); } private: const FilterType &Filters; - std::vector &CallbackCalls; + raw_ostream &OS; + std::vector CallbackCalls; }; class PPTraceFrontendActionFactory : public FrontendActionFactory { public: - PPTraceFrontendActionFactory(const FilterType &Filters, - std::vector &CallbackCalls) - : Filters(Filters), CallbackCalls(CallbackCalls) {} + PPTraceFrontendActionFactory(const FilterType &Filters, raw_ostream &OS) + : Filters(Filters), OS(OS) {} - PPTraceAction *create() override { - return new PPTraceAction(Filters, CallbackCalls); - } + PPTraceAction *create() override { return new PPTraceAction(Filters, OS); } private: const FilterType &Filters; - std::vector &CallbackCalls; + raw_ostream &OS; }; } // namespace -// Output the trace given its data structure and a stream. -static int outputPPTrace(std::vector &CallbackCalls, - llvm::raw_ostream &OS) { - // Mark start of document. - OS << "---\n"; +int main(int argc, const char **argv) { + InitLLVM X(argc, argv); - for (std::vector::const_iterator I = CallbackCalls.begin(), - E = CallbackCalls.end(); - I != E; ++I) { - const CallbackCall &Callback = *I; - OS << "- Callback: " << Callback.Name << "\n"; - - for (auto AI = Callback.Arguments.begin(), AE = Callback.Arguments.end(); - AI != AE; ++AI) { - const Argument &Arg = *AI; - OS << " " << Arg.Name << ": " << Arg.Value << "\n"; - } - } - - // Mark end of document. - OS << "...\n"; - - return 0; -} - -// Program entry point. -int main(int Argc, const char **Argv) { - - // Parse command line. - cl::ParseCommandLineOptions(Argc, Argv, "pp-trace.\n"); + auto Exec = tooling::createExecutorFromCommandLineArgs(argc, argv, Cat); + if (!Exec) + error(toString(Exec.takeError())); // Parse the IgnoreCallbacks list into strings. SmallVector Patterns; @@ -169,51 +142,18 @@ int main(int Argc, const char **Argv) { 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; - } + else + error(toString(Pat.takeError())); } - // Create the compilation database. - SmallString<256> PathBuf; - sys::fs::current_path(PathBuf); - std::unique_ptr Compilations; - Compilations.reset( - new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments)); + std::error_code EC; + llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text); + if (EC) + error(EC.message()); - // Store the callback trace information here. - std::vector CallbackCalls; - - // Create the tool and run the compilation. - ClangTool Tool(*Compilations, SourcePaths); - PPTraceFrontendActionFactory Factory(Filters, CallbackCalls); - int HadErrors = Tool.run(&Factory); - - // If we had errors, exit early. - if (HadErrors) - return HadErrors; - - // Do the output. - if (!OutputFileName.size()) { - HadErrors = outputPPTrace(CallbackCalls, llvm::outs()); - } else { - // Set up output file. - std::error_code EC; - llvm::ToolOutputFile Out(OutputFileName, EC, llvm::sys::fs::F_Text); - if (EC) { - llvm::errs() << "pp-trace: error creating " << OutputFileName << ":" - << EC.message() << "\n"; - return 1; - } - - HadErrors = outputPPTrace(CallbackCalls, Out.os()); - - // Tell ToolOutputFile that we want to keep the file. - if (HadErrors == 0) - Out.keep(); - } - - return HadErrors; + if (Error Err = Exec->get()->execute( + make_unique(Filters, Out.os()))) + error(toString(std::move(Err))); + Out.keep(); + return 0; } diff --git a/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp b/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp index 7787c5862ddc..0ad6c5936edb 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-conditional.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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 diff --git a/clang-tools-extra/test/pp-trace/pp-trace-filter.cpp b/clang-tools-extra/test/pp-trace/pp-trace-filter.cpp index 915945eaffda..1cd2ce7ef14d 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-filter.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-filter.cpp @@ -1,6 +1,6 @@ -// 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 +// 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; diff --git a/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp b/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp index 8c93c7280f34..cdd9fd38230f 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-ident.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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$" diff --git a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp index 7d925d845f80..ba6ad112dfa4 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-include.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-include.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace %s -- -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #include "Inputs/Level1A.h" #include "Inputs/Level1B.h" diff --git a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp index bd711e9e778c..47f9e1c4ff6a 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-macro.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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; diff --git a/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp b/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp index bfe376e20216..32d6c48e5d44 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-modules.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// 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 +// 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: --- diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp index 75c53984c2b2..f01ebd1ec67d 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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 diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp index 31a757b91fcd..5df30ad8efc2 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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") diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp index 413b5d07b3c0..8ba26c3b7396 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -callbacks '*,-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