50 #include "clang/AST/ASTConsumer.h" 51 #include "clang/AST/ASTContext.h" 52 #include "clang/AST/RecursiveASTVisitor.h" 53 #include "clang/Basic/SourceManager.h" 54 #include "clang/Driver/Options.h" 55 #include "clang/Frontend/CompilerInstance.h" 56 #include "clang/Frontend/FrontendActions.h" 57 #include "clang/Lex/Preprocessor.h" 58 #include "clang/Tooling/CompilationDatabase.h" 59 #include "clang/Tooling/Tooling.h" 60 #include "llvm/Option/Arg.h" 61 #include "llvm/Option/ArgList.h" 62 #include "llvm/Option/OptTable.h" 63 #include "llvm/Option/Option.h" 64 #include "llvm/Support/CommandLine.h" 65 #include "llvm/Support/FileSystem.h" 66 #include "llvm/Support/MemoryBuffer.h" 67 #include "llvm/Support/Path.h" 68 #include "llvm/Support/ToolOutputFile.h" 75 using namespace clang;
85 static cl::list<std::string>
SourcePaths(cl::Positional,
86 cl::desc(
"<source0> [... <sourceN>]"),
91 "ignore", cl::init(
""),
92 cl::desc(
"Ignore callbacks, i.e. \"Callback1, Callback2...\"."));
96 "output", cl::init(
""),
97 cl::desc(
"Output trace to the given file name or '-' for stdout."));
100 static cl::list<std::string>
102 cl::desc(
"<arguments to be passed to front end>..."));
110 PPTraceConsumer(SmallSet<std::string, 4> &Ignore,
111 std::vector<CallbackCall> &CallbackCalls, Preprocessor &PP) {
113 PP.addPPCallbacks(llvm::make_unique<PPCallbacksTracker>(Ignore,
120 PPTraceAction(SmallSet<std::string, 4> &Ignore,
121 std::vector<CallbackCall> &CallbackCalls)
122 : Ignore(Ignore), CallbackCalls(CallbackCalls) {}
125 std::unique_ptr<clang::ASTConsumer>
126 CreateASTConsumer(CompilerInstance &CI, StringRef InFile)
override {
127 return llvm::make_unique<PPTraceConsumer>(Ignore, CallbackCalls,
128 CI.getPreprocessor());
132 SmallSet<std::string, 4> &Ignore;
133 std::vector<CallbackCall> &CallbackCalls;
138 PPTraceFrontendActionFactory(SmallSet<std::string, 4> &Ignore,
139 std::vector<CallbackCall> &CallbackCalls)
140 : Ignore(Ignore), CallbackCalls(CallbackCalls) {}
142 PPTraceAction *create()
override {
143 return new PPTraceAction(Ignore, CallbackCalls);
147 SmallSet<std::string, 4> &Ignore;
148 std::vector<CallbackCall> &CallbackCalls;
154 llvm::raw_ostream &OS) {
158 for (std::vector<CallbackCall>::const_iterator I = CallbackCalls.begin(),
159 E = CallbackCalls.end();
162 OS <<
"- Callback: " << Callback.
Name <<
"\n";
167 OS <<
" " << Arg.
Name <<
": " << Arg.
Value <<
"\n";
178 int main(
int Argc,
const char **Argv) {
181 cl::ParseCommandLineOptions(Argc, Argv,
"pp-trace.\n");
184 SmallVector<StringRef, 32> IgnoreCallbacksStrings;
187 SmallSet<std::string, 4> Ignore;
188 for (SmallVector<StringRef, 32>::iterator I = IgnoreCallbacksStrings.begin(),
189 E = IgnoreCallbacksStrings.end();
194 SmallString<256> PathBuf;
195 sys::fs::current_path(PathBuf);
196 std::unique_ptr<CompilationDatabase> Compilations;
198 new FixedCompilationDatabase(Twine(PathBuf),
CC1Arguments));
201 std::vector<CallbackCall> CallbackCalls;
205 PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls);
206 int HadErrors = Tool.run(&Factory);
218 llvm::ToolOutputFile Out(
OutputFileName, EC, llvm::sys::fs::F_Text);
220 llvm::errs() <<
"pp-trace: error creating " <<
OutputFileName <<
":" 221 << EC.message() <<
"\n";
This class represents one callback function argument by name and value.
std::vector< Argument > Arguments
static cl::list< std::string > SourcePaths(cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore)
static cl::list< std::string > CC1Arguments(cl::ConsumeAfter, cl::desc("<arguments to be passed to front end>..."))
static cl::opt< std::string > OutputFileName("output", cl::init(""), cl::desc("Output trace to the given file name or '-' for stdout."))
static cl::opt< std::string > IgnoreCallbacks("ignore", cl::init(""), cl::desc("Ignore callbacks, i.e. \allback1, Callback2...\"))
Classes and definitions for preprocessor tracking.
This class represents one callback call by name and an array of arguments.
static int outputPPTrace(std::vector< CallbackCall > &CallbackCalls, llvm::raw_ostream &OS)
int main(int Argc, const char **Argv)