summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2013-06-04 14:44:44 +0000
committerManuel Klimek <klimek@google.com>2013-06-04 14:44:44 +0000
commitd91ac930874389fa2e906d8bcd2456136defd0be (patch)
tree4c318cc29af5727e10075ce695a88ef9014e60c6
parenta5e536ab0e785dc6fcff76420b65fa592d29b7e0 (diff)
downloadbcm5719-llvm-d91ac930874389fa2e906d8bcd2456136defd0be.tar.gz
bcm5719-llvm-d91ac930874389fa2e906d8bcd2456136defd0be.zip
Enables chaining of argument adjusters in clang tools.
This enables changing clang-check to get extra arguments. Patch by Pavel Labath. llvm-svn: 183227
-rw-r--r--clang/include/clang/Tooling/Tooling.h20
-rw-r--r--clang/lib/Tooling/Tooling.cpp20
-rw-r--r--clang/unittests/Tooling/ToolingTest.cpp41
3 files changed, 73 insertions, 8 deletions
diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h
index 7de0a1fe2a5..dc8163e553f 100644
--- a/clang/include/clang/Tooling/Tooling.h
+++ b/clang/include/clang/Tooling/Tooling.h
@@ -175,8 +175,8 @@ class ToolInvocation {
/// This class is written to be usable for command line utilities.
/// By default the class uses ClangSyntaxOnlyAdjuster to modify
/// command line arguments before the arguments are used to run
-/// a frontend action. One could install another command line
-/// arguments adjuster by call setArgumentsAdjuster() method.
+/// a frontend action. One could install an additional command line
+/// arguments adjuster by calling the appendArgumentsAdjuster() method.
class ClangTool {
public:
/// \brief Constructs a clang tool to run over a list of files.
@@ -188,7 +188,7 @@ class ClangTool {
ClangTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths);
- virtual ~ClangTool() {}
+ virtual ~ClangTool() { clearArgumentsAdjusters(); }
/// \brief Map a virtual file to be used while running the tool.
///
@@ -199,8 +199,20 @@ class ClangTool {
/// \brief Install command line arguments adjuster.
///
/// \param Adjuster Command line arguments adjuster.
+ //
+ /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead.
+ /// Remove it once all callers are gone.
void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
+ /// \brief Append a command line arguments adjuster to the adjuster chain.
+ ///
+ /// \param Adjuster An argument adjuster, which will be run on the output of
+ /// previous argument adjusters.
+ void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);
+
+ /// \brief Clear the command line arguments adjuster chain.
+ void clearArgumentsAdjusters();
+
/// Runs a frontend action over all files specified in the command line.
///
/// \param ActionFactory Factory generating the frontend actions. The function
@@ -221,7 +233,7 @@ class ClangTool {
// Contains a list of pairs (<file name>, <file content>).
std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
- OwningPtr<ArgumentsAdjuster> ArgsAdjuster;
+ SmallVector<ArgumentsAdjuster *, 1> ArgsAdjusters;
};
template <typename T>
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp
index 52855f657f6..cdb9bc71ee2 100644
--- a/clang/lib/Tooling/Tooling.cpp
+++ b/clang/lib/Tooling/Tooling.cpp
@@ -237,7 +237,7 @@ void ToolInvocation::addFileMappingsTo(SourceManager &Sources) {
ClangTool::ClangTool(const CompilationDatabase &Compilations,
ArrayRef<std::string> SourcePaths)
: Files((FileSystemOptions())),
- ArgsAdjuster(new ClangSyntaxOnlyAdjuster()) {
+ ArgsAdjusters(1, new ClangSyntaxOnlyAdjuster()) {
for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
SmallString<1024> File(getAbsolutePath(SourcePaths[I]));
@@ -264,7 +264,18 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
}
void ClangTool::setArgumentsAdjuster(ArgumentsAdjuster *Adjuster) {
- ArgsAdjuster.reset(Adjuster);
+ clearArgumentsAdjusters();
+ appendArgumentsAdjuster(Adjuster);
+}
+
+void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster) {
+ ArgsAdjusters.push_back(Adjuster);
+}
+
+void ClangTool::clearArgumentsAdjusters() {
+ for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I)
+ delete ArgsAdjusters[I];
+ ArgsAdjusters.clear();
}
int ClangTool::run(FrontendActionFactory *ActionFactory) {
@@ -292,8 +303,9 @@ int ClangTool::run(FrontendActionFactory *ActionFactory) {
if (chdir(CompileCommands[I].second.Directory.c_str()))
llvm::report_fatal_error("Cannot chdir into \"" +
CompileCommands[I].second.Directory + "\n!");
- std::vector<std::string> CommandLine =
- ArgsAdjuster->Adjust(CompileCommands[I].second.CommandLine);
+ std::vector<std::string> CommandLine = CompileCommands[I].second.CommandLine;
+ for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I)
+ CommandLine = ArgsAdjusters[I]->Adjust(CommandLine);
assert(!CommandLine.empty());
CommandLine[0] = MainExecutable;
// FIXME: We need a callback mechanism for the tool writer to output a
diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp
index d96366dcd58..e435ea92e23 100644
--- a/clang/unittests/Tooling/ToolingTest.cpp
+++ b/clang/unittests/Tooling/ToolingTest.cpp
@@ -193,5 +193,46 @@ TEST(runToolOnCode, TestSkipFunctionBody) {
"int skipMeNot() { an_error_here }"));
}
+struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {
+ bool &Found;
+ bool &Ran;
+
+ CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }
+
+ virtual CommandLineArguments
+ Adjust(const CommandLineArguments &Args) LLVM_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>());
+
+ ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
+ Tool.mapVirtualFile("/a.cc", "void a() {}");
+
+ bool Found = false;
+ bool Ran = false;
+ Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
+ Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+ EXPECT_TRUE(Ran);
+ EXPECT_TRUE(Found);
+
+ Ran = Found = false;
+ Tool.clearArgumentsAdjusters();
+ Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
+ Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
+ Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+ EXPECT_TRUE(Ran);
+ EXPECT_FALSE(Found);
+}
+
} // end namespace tooling
} // end namespace clang
OpenPOWER on IntegriCloud