[pp-trace] Modernize the code

Use InitLLVM and WithColor
Delete PPTraceConsumer, add the callback in PPTraceAction
Migrae to tooling::createExecutorFromCommandLineArgs
Don't specialize empty OutputFileName

llvm-svn: 356849
This commit is contained in:
Fangrui Song 2019-03-24 06:55:08 +00:00
parent 88f4054f48
commit 10f69948fb
10 changed files with 64 additions and 124 deletions

View File

@ -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<std::string> SourcePaths(cl::Positional,
cl::desc("<source0> [... <sourceN>]"),
cl::OneOrMore);
static cl::OptionCategory Cat("pp-trace options");
static cl::opt<std::string> 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<std::string> 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<std::string>
CC1Arguments(cl::ConsumeAfter,
cl::desc("<arguments to be passed to front end>..."));
// 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<CallbackCall> &CallbackCalls, Preprocessor &PP) {
// PP takes ownership.
PP.addPPCallbacks(
llvm::make_unique<PPCallbacksTracker>(Filters, CallbackCalls, PP));
}
};
class PPTraceAction : public SyntaxOnlyAction {
class PPTraceAction : public ASTFrontendAction {
public:
PPTraceAction(const FilterType &Filters,
std::vector<CallbackCall> &CallbackCalls)
: Filters(Filters), CallbackCalls(CallbackCalls) {}
PPTraceAction(const FilterType &Filters, raw_ostream &OS)
: Filters(Filters), OS(OS) {}
protected:
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
return llvm::make_unique<PPTraceConsumer>(Filters, CallbackCalls,
CI.getPreprocessor());
Preprocessor &PP = CI.getPreprocessor();
PP.addPPCallbacks(
make_unique<PPCallbacksTracker>(Filters, CallbackCalls, PP));
return make_unique<ASTConsumer>();
}
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<CallbackCall> &CallbackCalls;
raw_ostream &OS;
std::vector<CallbackCall> CallbackCalls;
};
class PPTraceFrontendActionFactory : public FrontendActionFactory {
public:
PPTraceFrontendActionFactory(const FilterType &Filters,
std::vector<CallbackCall> &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<CallbackCall> &CallbackCalls;
raw_ostream &OS;
};
} // namespace
// Output the trace given its data structure and a stream.
static int outputPPTrace(std::vector<CallbackCall> &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<CallbackCall>::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<StringRef, 32> Patterns;
@ -169,51 +142,18 @@ int main(int Argc, const char **Argv) {
bool Enabled = !Pattern.consume_front("-");
if (Expected<GlobPattern> 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<CompilationDatabase> 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<CallbackCall> 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<PPTraceFrontendActionFactory>(Filters, Out.os())))
error(toString(std::move(Err)));
Out.keep();
return 0;
}

View File

@ -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

View File

@ -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;

View File

@ -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$"

View File

@ -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"

View File

@ -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;

View File

@ -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: ---

View File

@ -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

View File

@ -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")

View File

@ -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