mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-01 12:43:47 +00:00
Make ArgumentsAdjuster an std::function.
Reviewers: klimek Reviewed By: klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D6505 llvm-svn: 223248
This commit is contained in:
parent
293d414380
commit
74e1c46a50
@ -7,74 +7,60 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares base abstract class ArgumentsAdjuster and its descendants.
|
||||
// These classes are intended to modify command line arguments obtained from
|
||||
// a compilation database before they are used to run a frontend action.
|
||||
// This file declares typedef ArgumentsAdjuster and functions to create several
|
||||
// useful argument adjusters.
|
||||
// ArgumentsAdjusters modify command line arguments obtained from a compilation
|
||||
// database before they are used to run a frontend action.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
|
||||
#define LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace tooling {
|
||||
|
||||
/// \brief A sequence of command line arguments.
|
||||
typedef std::vector<std::string> CommandLineArguments;
|
||||
|
||||
/// \brief Abstract interface for a command line adjusters.
|
||||
/// \brief A prototype of a command line adjuster.
|
||||
///
|
||||
/// This abstract interface describes a command line argument adjuster,
|
||||
/// which is responsible for command line arguments modification before
|
||||
/// the arguments are used to run a frontend action.
|
||||
class ArgumentsAdjuster {
|
||||
virtual void anchor();
|
||||
public:
|
||||
/// \brief Returns adjusted command line arguments.
|
||||
///
|
||||
/// \param Args Input sequence of command line arguments.
|
||||
///
|
||||
/// \returns Modified sequence of command line arguments.
|
||||
virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0;
|
||||
virtual ~ArgumentsAdjuster() {}
|
||||
};
|
||||
/// Command line argument adjuster is responsible for command line arguments
|
||||
/// modification before the arguments are used to run a frontend action.
|
||||
typedef std::function<CommandLineArguments(const CommandLineArguments &)>
|
||||
ArgumentsAdjuster;
|
||||
|
||||
/// \brief Syntax check only command line adjuster.
|
||||
///
|
||||
/// This class implements ArgumentsAdjuster interface and converts input
|
||||
/// command line arguments to the "syntax check only" variant.
|
||||
class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster {
|
||||
CommandLineArguments Adjust(const CommandLineArguments &Args) override;
|
||||
};
|
||||
/// \brief Gets an argument adjuster that converts input command line arguments
|
||||
/// to the "syntax check only" variant.
|
||||
ArgumentsAdjuster getClangSyntaxOnlyAdjuster();
|
||||
|
||||
/// \brief An argument adjuster which removes output-related command line
|
||||
/// \brief Gets an argument adjuster which removes output-related command line
|
||||
/// arguments.
|
||||
class ClangStripOutputAdjuster : public ArgumentsAdjuster {
|
||||
CommandLineArguments Adjust(const CommandLineArguments &Args) override;
|
||||
};
|
||||
ArgumentsAdjuster getClangStripOutputAdjuster();
|
||||
|
||||
class InsertArgumentAdjuster : public ArgumentsAdjuster {
|
||||
public:
|
||||
enum Position { BEGIN, END };
|
||||
enum class ArgumentInsertPosition { BEGIN, END };
|
||||
|
||||
InsertArgumentAdjuster(const CommandLineArguments &Extra, Position Pos)
|
||||
: Extra(Extra), Pos(Pos) {}
|
||||
/// \brief Gets an argument adjuster which inserts \p Extra arguments in the
|
||||
/// specified position.
|
||||
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
|
||||
ArgumentInsertPosition Pos);
|
||||
|
||||
InsertArgumentAdjuster(const char *Extra, Position Pos)
|
||||
: Extra(1, std::string(Extra)), Pos(Pos) {}
|
||||
/// \brief Gets an argument adjuster which inserts an \p Extra argument in the
|
||||
/// specified position.
|
||||
ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra,
|
||||
ArgumentInsertPosition Pos);
|
||||
|
||||
CommandLineArguments Adjust(const CommandLineArguments &Args) override;
|
||||
/// \brief Gets an argument adjuster which adjusts the arguments in sequence
|
||||
/// with the \p First adjuster and then with the \p Second one.
|
||||
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
|
||||
ArgumentsAdjuster Second);
|
||||
|
||||
private:
|
||||
const CommandLineArguments Extra;
|
||||
const Position Pos;
|
||||
};
|
||||
} // end namespace tooling
|
||||
} // end namespace clang
|
||||
} // namespace tooling
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H
|
||||
|
||||
|
@ -274,7 +274,7 @@ class ClangTool {
|
||||
///
|
||||
/// \param Adjuster An argument adjuster, which will be run on the output of
|
||||
/// previous argument adjusters.
|
||||
void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
|
||||
void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
|
||||
|
||||
/// \brief Clear the command line arguments adjuster chain.
|
||||
void clearArgumentsAdjusters();
|
||||
@ -301,7 +301,7 @@ class ClangTool {
|
||||
// Contains a list of pairs (<file name>, <file content>).
|
||||
std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
|
||||
|
||||
SmallVector<std::unique_ptr<ArgumentsAdjuster>, 2> ArgsAdjusters;
|
||||
ArgumentsAdjuster ArgsAdjuster;
|
||||
|
||||
DiagnosticConsumer *DiagConsumer;
|
||||
};
|
||||
|
@ -19,55 +19,66 @@
|
||||
namespace clang {
|
||||
namespace tooling {
|
||||
|
||||
void ArgumentsAdjuster::anchor() {
|
||||
}
|
||||
|
||||
/// Add -fsyntax-only option to the commnand line arguments.
|
||||
CommandLineArguments
|
||||
ClangSyntaxOnlyAdjuster::Adjust(const CommandLineArguments &Args) {
|
||||
CommandLineArguments AdjustedArgs;
|
||||
for (size_t i = 0, e = Args.size(); i != e; ++i) {
|
||||
StringRef Arg = Args[i];
|
||||
// FIXME: Remove options that generate output.
|
||||
if (!Arg.startswith("-fcolor-diagnostics") &&
|
||||
!Arg.startswith("-fdiagnostics-color"))
|
||||
AdjustedArgs.push_back(Args[i]);
|
||||
}
|
||||
AdjustedArgs.push_back("-fsyntax-only");
|
||||
return AdjustedArgs;
|
||||
}
|
||||
|
||||
CommandLineArguments
|
||||
ClangStripOutputAdjuster::Adjust(const CommandLineArguments &Args) {
|
||||
CommandLineArguments AdjustedArgs;
|
||||
for (size_t i = 0, e = Args.size(); i < e; ++i) {
|
||||
StringRef Arg = Args[i];
|
||||
if(!Arg.startswith("-o"))
|
||||
AdjustedArgs.push_back(Args[i]);
|
||||
|
||||
if(Arg == "-o") {
|
||||
// Output is specified as -o foo. Skip the next argument also.
|
||||
++i;
|
||||
ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
|
||||
return [](const CommandLineArguments &Args) {
|
||||
CommandLineArguments AdjustedArgs;
|
||||
for (size_t i = 0, e = Args.size(); i != e; ++i) {
|
||||
StringRef Arg = Args[i];
|
||||
// FIXME: Remove options that generate output.
|
||||
if (!Arg.startswith("-fcolor-diagnostics") &&
|
||||
!Arg.startswith("-fdiagnostics-color"))
|
||||
AdjustedArgs.push_back(Args[i]);
|
||||
}
|
||||
// Else, the output is specified as -ofoo. Just do nothing.
|
||||
}
|
||||
return AdjustedArgs;
|
||||
AdjustedArgs.push_back("-fsyntax-only");
|
||||
return AdjustedArgs;
|
||||
};
|
||||
}
|
||||
|
||||
CommandLineArguments
|
||||
InsertArgumentAdjuster::Adjust(const CommandLineArguments &Args) {
|
||||
CommandLineArguments Return(Args);
|
||||
ArgumentsAdjuster getClangStripOutputAdjuster() {
|
||||
return [](const CommandLineArguments &Args) {
|
||||
CommandLineArguments AdjustedArgs;
|
||||
for (size_t i = 0, e = Args.size(); i < e; ++i) {
|
||||
StringRef Arg = Args[i];
|
||||
if (!Arg.startswith("-o"))
|
||||
AdjustedArgs.push_back(Args[i]);
|
||||
|
||||
CommandLineArguments::iterator I;
|
||||
if (Pos == END) {
|
||||
I = Return.end();
|
||||
} else {
|
||||
I = Return.begin();
|
||||
++I; // To leave the program name in place
|
||||
}
|
||||
if (Arg == "-o") {
|
||||
// Output is specified as -o foo. Skip the next argument also.
|
||||
++i;
|
||||
}
|
||||
// Else, the output is specified as -ofoo. Just do nothing.
|
||||
}
|
||||
return AdjustedArgs;
|
||||
};
|
||||
}
|
||||
|
||||
Return.insert(I, Extra.begin(), Extra.end());
|
||||
return Return;
|
||||
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
|
||||
ArgumentInsertPosition Pos) {
|
||||
return [Extra, Pos](const CommandLineArguments &Args) {
|
||||
CommandLineArguments Return(Args);
|
||||
|
||||
CommandLineArguments::iterator I;
|
||||
if (Pos == ArgumentInsertPosition::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;
|
||||
};
|
||||
}
|
||||
|
||||
ArgumentsAdjuster getInsertArgumentAdjuster(const char *Extra,
|
||||
ArgumentInsertPosition Pos) {
|
||||
return getInsertArgumentAdjuster(CommandLineArguments(1, Extra), Pos);
|
||||
}
|
||||
|
||||
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
|
||||
ArgumentsAdjuster Second) {
|
||||
return std::bind(Second, std::bind(First, std::placeholders::_1));
|
||||
}
|
||||
|
||||
} // end namespace tooling
|
||||
|
@ -60,8 +60,8 @@ public:
|
||||
std::unique_ptr<CompilationDatabase> Compilations)
|
||||
: Compilations(std::move(Compilations)) {}
|
||||
|
||||
void appendArgumentsAdjuster(std::unique_ptr<ArgumentsAdjuster> Adjuster) {
|
||||
Adjusters.push_back(std::move(Adjuster));
|
||||
void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster) {
|
||||
Adjusters.push_back(Adjuster);
|
||||
}
|
||||
|
||||
std::vector<CompileCommand>
|
||||
@ -79,13 +79,13 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<CompilationDatabase> Compilations;
|
||||
std::vector<std::unique_ptr<ArgumentsAdjuster>> Adjusters;
|
||||
std::vector<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);
|
||||
Command.CommandLine = Adjuster(Command.CommandLine);
|
||||
return Commands;
|
||||
}
|
||||
};
|
||||
@ -142,10 +142,8 @@ CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
|
||||
llvm::make_unique<ArgumentsAdjustingCompilations>(
|
||||
std::move(Compilations));
|
||||
AdjustingCompilations->appendArgumentsAdjuster(
|
||||
llvm::make_unique<InsertArgumentAdjuster>(ArgsBefore,
|
||||
InsertArgumentAdjuster::BEGIN));
|
||||
getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN));
|
||||
AdjustingCompilations->appendArgumentsAdjuster(
|
||||
llvm::make_unique<InsertArgumentAdjuster>(ArgsAfter,
|
||||
InsertArgumentAdjuster::END));
|
||||
getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END));
|
||||
Compilations = std::move(AdjustingCompilations);
|
||||
}
|
||||
|
@ -279,8 +279,8 @@ ClangTool::ClangTool(const CompilationDatabase &Compilations,
|
||||
ArrayRef<std::string> SourcePaths)
|
||||
: Compilations(Compilations), SourcePaths(SourcePaths),
|
||||
Files(new FileManager(FileSystemOptions())), DiagConsumer(nullptr) {
|
||||
appendArgumentsAdjuster(new ClangStripOutputAdjuster());
|
||||
appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
|
||||
appendArgumentsAdjuster(getClangStripOutputAdjuster());
|
||||
appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
|
||||
}
|
||||
|
||||
ClangTool::~ClangTool() {}
|
||||
@ -289,12 +289,15 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
|
||||
MappedFileContents.push_back(std::make_pair(FilePath, Content));
|
||||
}
|
||||
|
||||
void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster) {
|
||||
ArgsAdjusters.push_back(std::unique_ptr<ArgumentsAdjuster>(Adjuster));
|
||||
void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster Adjuster) {
|
||||
if (ArgsAdjuster)
|
||||
ArgsAdjuster = combineAdjusters(ArgsAdjuster, Adjuster);
|
||||
else
|
||||
ArgsAdjuster = Adjuster;
|
||||
}
|
||||
|
||||
void ClangTool::clearArgumentsAdjusters() {
|
||||
ArgsAdjusters.clear();
|
||||
ArgsAdjuster = nullptr;
|
||||
}
|
||||
|
||||
int ClangTool::run(ToolAction *Action) {
|
||||
@ -347,8 +350,8 @@ int ClangTool::run(ToolAction *Action) {
|
||||
llvm::report_fatal_error("Cannot chdir into \"" +
|
||||
Twine(CompileCommand.Directory) + "\n!");
|
||||
std::vector<std::string> CommandLine = CompileCommand.CommandLine;
|
||||
for (const auto &Adjuster : ArgsAdjusters)
|
||||
CommandLine = Adjuster->Adjust(CommandLine);
|
||||
if (ArgsAdjuster)
|
||||
CommandLine = ArgsAdjuster(CommandLine);
|
||||
assert(!CommandLine.empty());
|
||||
CommandLine[0] = MainExecutable;
|
||||
// FIXME: We need a callback mechanism for the tool writer to output a
|
||||
|
@ -155,12 +155,12 @@ int main(int argc, const char **argv) {
|
||||
|
||||
// Clear adjusters because -fsyntax-only is inserted by the default chain.
|
||||
Tool.clearArgumentsAdjusters();
|
||||
Tool.appendArgumentsAdjuster(new ClangStripOutputAdjuster());
|
||||
Tool.appendArgumentsAdjuster(getClangStripOutputAdjuster());
|
||||
|
||||
// Running the analyzer requires --analyze. Other modes can work with the
|
||||
// -fsyntax-only option.
|
||||
Tool.appendArgumentsAdjuster(new InsertArgumentAdjuster(
|
||||
Analyze ? "--analyze" : "-fsyntax-only", InsertArgumentAdjuster::BEGIN));
|
||||
Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster(
|
||||
Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN));
|
||||
|
||||
ClangCheckActionFactory CheckFactory;
|
||||
std::unique_ptr<FrontendActionFactory> FrontendFactory;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
namespace clang {
|
||||
@ -260,25 +261,6 @@ TEST(runToolOnCodeWithArgs, TestNoDepFile) {
|
||||
EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str()));
|
||||
}
|
||||
|
||||
struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {
|
||||
bool &Found;
|
||||
bool &Ran;
|
||||
|
||||
CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }
|
||||
|
||||
virtual CommandLineArguments
|
||||
Adjust(const CommandLineArguments &Args) override {
|
||||
Ran = true;
|
||||
for (unsigned I = 0, E = Args.size(); I != E; ++I) {
|
||||
if (Args[I] == "-fsyntax-only") {
|
||||
Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Args;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ClangToolTest, ArgumentAdjusters) {
|
||||
FixedCompilationDatabase Compilations("/", std::vector<std::string>());
|
||||
|
||||
@ -290,15 +272,22 @@ TEST(ClangToolTest, ArgumentAdjusters) {
|
||||
|
||||
bool Found = false;
|
||||
bool Ran = false;
|
||||
Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
|
||||
ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
|
||||
[&Found, &Ran](const CommandLineArguments &Args) {
|
||||
Ran = true;
|
||||
if (std::find(Args.begin(), Args.end(), "-fsyntax-only") != Args.end())
|
||||
Found = true;
|
||||
return Args;
|
||||
};
|
||||
Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
|
||||
Tool.run(Action.get());
|
||||
EXPECT_TRUE(Ran);
|
||||
EXPECT_TRUE(Found);
|
||||
|
||||
Ran = Found = false;
|
||||
Tool.clearArgumentsAdjusters();
|
||||
Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
|
||||
Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
|
||||
Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
|
||||
Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
|
||||
Tool.run(Action.get());
|
||||
EXPECT_TRUE(Ran);
|
||||
EXPECT_FALSE(Found);
|
||||
|
Loading…
x
Reference in New Issue
Block a user