[clang-tidy] Move -extra-arg handling to CommonOptionsProvider

Summary:
Handle -extra-arg and -extra-arg-before options in the
CommonOptionsProvider so they can be used in all clang tools. Adjust arguments
in a CompilationDatabase wrapper instead of adding ArgumentsAdjuster to the
tool.

Reviewers: djasper, klimek

Reviewed By: klimek

Subscribers: klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D6073

llvm-svn: 221248
This commit is contained in:
Alexander Kornienko 2014-11-04 08:51:24 +00:00
parent ea9b8ee43d
commit 616860994d
5 changed files with 99 additions and 63 deletions

View File

@ -40,8 +40,7 @@ public:
/// ///
/// \returns Modified sequence of command line arguments. /// \returns Modified sequence of command line arguments.
virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0; virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0;
virtual ~ArgumentsAdjuster() { virtual ~ArgumentsAdjuster() {}
}
}; };
/// \brief Syntax check only command line adjuster. /// \brief Syntax check only command line adjuster.
@ -58,6 +57,22 @@ class ClangStripOutputAdjuster : public ArgumentsAdjuster {
CommandLineArguments Adjust(const CommandLineArguments &Args) override; CommandLineArguments Adjust(const CommandLineArguments &Args) override;
}; };
class InsertArgumentAdjuster : public ArgumentsAdjuster {
public:
enum Position { BEGIN, END };
InsertArgumentAdjuster(const CommandLineArguments &Extra, Position Pos)
: Extra(Extra), Pos(Pos) {}
InsertArgumentAdjuster(const char *Extra, Position Pos)
: Extra(1, std::string(Extra)), Pos(Pos) {}
CommandLineArguments Adjust(const CommandLineArguments &Args) override;
private:
const CommandLineArguments Extra;
const Position Pos;
};
} // end namespace tooling } // end namespace tooling
} // end namespace clang } // end namespace clang

View File

@ -89,6 +89,8 @@ public:
private: private:
std::unique_ptr<CompilationDatabase> Compilations; std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::string> SourcePathList; std::vector<std::string> SourcePathList;
std::vector<std::string> ExtraArgsBefore;
std::vector<std::string> ExtraArgsAfter;
}; };
} // namespace tooling } // namespace tooling

View File

@ -54,6 +54,22 @@ ClangStripOutputAdjuster::Adjust(const CommandLineArguments &Args) {
return AdjustedArgs; return AdjustedArgs;
} }
CommandLineArguments
InsertArgumentAdjuster::Adjust(const CommandLineArguments &Args) {
CommandLineArguments Return(Args);
CommandLineArguments::iterator I;
if (Pos == END) {
I = Return.end();
} else {
I = Return.begin();
++I; // To leave the program name in place
}
Return.insert(I, Extra.begin(), Extra.end());
return Return;
}
} // end namespace tooling } // end namespace tooling
} // end namespace clang } // end namespace clang

View File

@ -25,6 +25,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h" #include "clang/Tooling/Tooling.h"
@ -53,6 +54,42 @@ const char *const CommonOptionsParser::HelpMessage =
"\tsuffix of a path in the compile command database.\n" "\tsuffix of a path in the compile command database.\n"
"\n"; "\n";
class ArgumentsAdjustingCompilations : public CompilationDatabase {
public:
ArgumentsAdjustingCompilations(
std::unique_ptr<CompilationDatabase> Compilations)
: Compilations(std::move(Compilations)) {}
void appendArgumentsAdjuster(std::unique_ptr<ArgumentsAdjuster> Adjuster) {
Adjusters.push_back(std::move(Adjuster));
}
std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override {
return adjustCommands(Compilations->getCompileCommands(FilePath));
}
std::vector<std::string> getAllFiles() const override {
return Compilations->getAllFiles();
}
std::vector<CompileCommand> getAllCompileCommands() const override {
return adjustCommands(Compilations->getAllCompileCommands());
}
private:
std::unique_ptr<CompilationDatabase> Compilations;
std::vector<std::unique_ptr<ArgumentsAdjuster>> Adjusters;
std::vector<CompileCommand>
adjustCommands(std::vector<CompileCommand> Commands) const {
for (CompileCommand &Command : Commands)
for (const auto &Adjuster : Adjusters)
Command.CommandLine = Adjuster->Adjust(Command.CommandLine);
return Commands;
}
};
CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv, CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
cl::OptionCategory &Category, cl::OptionCategory &Category,
const char *Overview) { const char *Overview) {
@ -65,6 +102,16 @@ CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore, cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore,
cl::cat(Category)); cl::cat(Category));
static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(Category));
static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(Category));
// Hide unrelated options. // Hide unrelated options.
StringMap<cl::Option*> Options; StringMap<cl::Option*> Options;
cl::getRegisteredOptions(Options); cl::getRegisteredOptions(Options);
@ -91,4 +138,14 @@ CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
if (!Compilations) if (!Compilations)
llvm::report_fatal_error(ErrorMessage); llvm::report_fatal_error(ErrorMessage);
} }
auto AdjustingCompilations =
llvm::make_unique<ArgumentsAdjustingCompilations>(
std::move(Compilations));
AdjustingCompilations->appendArgumentsAdjuster(
llvm::make_unique<InsertArgumentAdjuster>(ArgsBefore,
InsertArgumentAdjuster::BEGIN));
AdjustingCompilations->appendArgumentsAdjuster(
llvm::make_unique<InsertArgumentAdjuster>(ArgsAfter,
InsertArgumentAdjuster::END));
Compilations = std::move(AdjustingCompilations);
} }

View File

@ -78,15 +78,6 @@ static cl::opt<bool> FixWhatYouCan(
cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)), cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)),
cl::cat(ClangCheckCategory)); cl::cat(ClangCheckCategory));
static cl::list<std::string> ArgsAfter(
"extra-arg",
cl::desc("Additional argument to append to the compiler command line"),
cl::cat(ClangCheckCategory));
static cl::list<std::string> ArgsBefore(
"extra-arg-before",
cl::desc("Additional argument to prepend to the compiler command line"),
cl::cat(ClangCheckCategory));
namespace { namespace {
// FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp // FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp
@ -140,58 +131,21 @@ public:
} }
}; };
class InsertAdjuster: public clang::tooling::ArgumentsAdjuster {
public:
enum Position { BEGIN, END };
InsertAdjuster(const CommandLineArguments &Extra, Position Pos)
: Extra(Extra), Pos(Pos) {
}
InsertAdjuster(const char *Extra, Position Pos)
: Extra(1, std::string(Extra)), Pos(Pos) {
}
virtual CommandLineArguments
Adjust(const CommandLineArguments &Args) override {
CommandLineArguments Return(Args);
CommandLineArguments::iterator I;
if (Pos == END) {
I = Return.end();
} else {
I = Return.begin();
++I; // To leave the program name in place
}
Return.insert(I, Extra.begin(), Extra.end());
return Return;
}
private:
const CommandLineArguments Extra;
const Position Pos;
};
} // namespace
// Anonymous namespace here causes problems with gcc <= 4.4 on MacOS 10.6.
// "Non-global symbol: ... can't be a weak_definition"
namespace clang_check {
class ClangCheckActionFactory { class ClangCheckActionFactory {
public: public:
std::unique_ptr<clang::ASTConsumer> newASTConsumer() { std::unique_ptr<clang::ASTConsumer> newASTConsumer() {
if (ASTList) if (ASTList)
return clang::CreateASTDeclNodeLister(); return clang::CreateASTDeclNodeLister();
if (ASTDump) if (ASTDump)
return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls*/ true, return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
/*DumpLookups*/ false); /*DumpLookups=*/false);
if (ASTPrint) if (ASTPrint)
return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter); return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
return llvm::make_unique<clang::ASTConsumer>(); return llvm::make_unique<clang::ASTConsumer>();
} }
}; };
}
} // namespace
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(); llvm::sys::PrintStackTraceOnErrorSignal();
@ -202,21 +156,13 @@ int main(int argc, const char **argv) {
// Clear adjusters because -fsyntax-only is inserted by the default chain. // Clear adjusters because -fsyntax-only is inserted by the default chain.
Tool.clearArgumentsAdjusters(); Tool.clearArgumentsAdjusters();
Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster()); Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster());
if (ArgsAfter.size() > 0) {
Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsAfter,
InsertAdjuster::END));
}
if (ArgsBefore.size() > 0) {
Tool.appendArgumentsAdjuster(new InsertAdjuster(ArgsBefore,
InsertAdjuster::BEGIN));
}
// Running the analyzer requires --analyze. Other modes can work with the // Running the analyzer requires --analyze. Other modes can work with the
// -fsyntax-only option. // -fsyntax-only option.
Tool.appendArgumentsAdjuster(new InsertAdjuster( Tool.appendArgumentsAdjuster(new InsertArgumentAdjuster(
Analyze ? "--analyze" : "-fsyntax-only", InsertAdjuster::BEGIN)); Analyze ? "--analyze" : "-fsyntax-only", InsertArgumentAdjuster::BEGIN));
clang_check::ClangCheckActionFactory CheckFactory; ClangCheckActionFactory CheckFactory;
std::unique_ptr<FrontendActionFactory> FrontendFactory; std::unique_ptr<FrontendActionFactory> FrontendFactory;
// Choose the correct factory based on the selected mode. // Choose the correct factory based on the selected mode.