Index: include/clang/Tooling/ArgumentsAdjusters.h =================================================================== --- include/clang/Tooling/ArgumentsAdjusters.h +++ include/clang/Tooling/ArgumentsAdjusters.h @@ -40,8 +40,7 @@ /// /// \returns Modified sequence of command line arguments. virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0; - virtual ~ArgumentsAdjuster() { - } + virtual ~ArgumentsAdjuster() {} }; /// \brief Syntax check only command line adjuster. @@ -58,6 +57,22 @@ 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 clang Index: include/clang/Tooling/CommonOptionsParser.h =================================================================== --- include/clang/Tooling/CommonOptionsParser.h +++ include/clang/Tooling/CommonOptionsParser.h @@ -89,6 +89,8 @@ private: std::unique_ptr Compilations; std::vector SourcePathList; + std::vector ExtraArgsBefore; + std::vector ExtraArgsAfter; }; } // namespace tooling Index: lib/Tooling/ArgumentsAdjusters.cpp =================================================================== --- lib/Tooling/ArgumentsAdjusters.cpp +++ lib/Tooling/ArgumentsAdjusters.cpp @@ -54,6 +54,22 @@ 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 clang Index: lib/Tooling/CommonOptionsParser.cpp =================================================================== --- lib/Tooling/CommonOptionsParser.cpp +++ lib/Tooling/CommonOptionsParser.cpp @@ -25,6 +25,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/CommandLine.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" @@ -53,6 +54,42 @@ "\tsuffix of a path in the compile command database.\n" "\n"; +class ArgumentsAdjustingCompilations : public CompilationDatabase { +public: + ArgumentsAdjustingCompilations( + std::unique_ptr Compilations) + : Compilations(std::move(Compilations)) {} + + void appendArgumentsAdjuster(std::unique_ptr Adjuster) { + Adjusters.push_back(std::move(Adjuster)); + } + + std::vector + getCompileCommands(StringRef FilePath) const override { + return adjustCommands(Compilations->getCompileCommands(FilePath)); + } + + std::vector getAllFiles() const override { + return Compilations->getAllFiles(); + } + + std::vector getAllCompileCommands() const override { + return adjustCommands(Compilations->getAllCompileCommands()); + } + +private: + std::unique_ptr Compilations; + std::vector> Adjusters; + + std::vector + adjustCommands(std::vector 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, cl::OptionCategory &Category, const char *Overview) { @@ -65,6 +102,16 @@ cl::Positional, cl::desc(" [... ]"), cl::OneOrMore, cl::cat(Category)); + static cl::list ArgsAfter( + "extra-arg", + cl::desc("Additional argument to append to the compiler command line"), + cl::cat(Category)); + + static cl::list ArgsBefore( + "extra-arg-before", + cl::desc("Additional argument to prepend to the compiler command line"), + cl::cat(Category)); + // Hide unrelated options. StringMap Options; cl::getRegisteredOptions(Options); @@ -91,4 +138,14 @@ if (!Compilations) llvm::report_fatal_error(ErrorMessage); } + auto AdjustingCompilations = + llvm::make_unique( + std::move(Compilations)); + AdjustingCompilations->appendArgumentsAdjuster( + llvm::make_unique(ArgsBefore, + InsertArgumentAdjuster::BEGIN)); + AdjustingCompilations->appendArgumentsAdjuster( + llvm::make_unique(ArgsAfter, + InsertArgumentAdjuster::END)); + Compilations = std::move(AdjustingCompilations); } Index: tools/clang-check/ClangCheck.cpp =================================================================== --- tools/clang-check/ClangCheck.cpp +++ tools/clang-check/ClangCheck.cpp @@ -78,15 +78,6 @@ cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)), cl::cat(ClangCheckCategory)); -static cl::list ArgsAfter( - "extra-arg", - cl::desc("Additional argument to append to the compiler command line"), - cl::cat(ClangCheckCategory)); -static cl::list ArgsBefore( - "extra-arg-before", - cl::desc("Additional argument to prepend to the compiler command line"), - cl::cat(ClangCheckCategory)); - namespace { // FIXME: Move FixItRewriteInPlace from lib/Rewrite/Frontend/FrontendActions.cpp @@ -140,58 +131,21 @@ } }; -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 { public: std::unique_ptr newASTConsumer() { if (ASTList) return clang::CreateASTDeclNodeLister(); if (ASTDump) - return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls*/ true, - /*DumpLookups*/ false); + return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true, + /*DumpLookups=*/false); if (ASTPrint) return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter); return llvm::make_unique(); } }; -} + +} // namespace int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); @@ -202,21 +156,13 @@ // Clear adjusters because -fsyntax-only is inserted by the default chain. Tool.clearArgumentsAdjusters(); 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 // -fsyntax-only option. - Tool.appendArgumentsAdjuster(new InsertAdjuster( - Analyze ? "--analyze" : "-fsyntax-only", InsertAdjuster::BEGIN)); + Tool.appendArgumentsAdjuster(new InsertArgumentAdjuster( + Analyze ? "--analyze" : "-fsyntax-only", InsertArgumentAdjuster::BEGIN)); - clang_check::ClangCheckActionFactory CheckFactory; + ClangCheckActionFactory CheckFactory; std::unique_ptr FrontendFactory; // Choose the correct factory based on the selected mode.