<div dir="ltr">Thx, committed as r183227</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 4, 2013 at 4:40 PM, Pavel Labath <span dir="ltr"><<a href="mailto:labath@google.com" target="_blank">labath@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  Address issues<br>
<br>
Hi klimek,<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D914" target="_blank">http://llvm-reviews.chandlerc.com/D914</a><br>
<br>
CHANGE SINCE LAST DIFF<br>
  <a href="http://llvm-reviews.chandlerc.com/D914?vs=2258&id=2260#toc" target="_blank">http://llvm-reviews.chandlerc.com/D914?vs=2258&id=2260#toc</a><br>
<div><div class="h5"><br>
Files:<br>
  include/clang/Tooling/Tooling.h<br>
  lib/Tooling/Tooling.cpp<br>
  unittests/Tooling/ToolingTest.cpp<br>
<br>
Index: include/clang/Tooling/Tooling.h<br>
===================================================================<br>
--- include/clang/Tooling/Tooling.h<br>
+++ include/clang/Tooling/Tooling.h<br>
@@ -175,8 +175,8 @@<br>
 /// This class is written to be usable for command line utilities.<br>
 /// By default the class uses ClangSyntaxOnlyAdjuster to modify<br>
 /// command line arguments before the arguments are used to run<br>
-/// a frontend action. One could install another command line<br>
-/// arguments adjuster by call setArgumentsAdjuster() method.<br>
+/// a frontend action. One could install an additional command line<br>
+/// arguments adjuster by calling the appendArgumentsAdjuster() method.<br>
 class ClangTool {<br>
  public:<br>
   /// \brief Constructs a clang tool to run over a list of files.<br>
@@ -188,7 +188,7 @@<br>
   ClangTool(const CompilationDatabase &Compilations,<br>
             ArrayRef<std::string> SourcePaths);<br>
<br>
-  virtual ~ClangTool() {}<br>
+  virtual ~ClangTool() { clearArgumentsAdjusters(); }<br>
<br>
   /// \brief Map a virtual file to be used while running the tool.<br>
   ///<br>
</div></div>@@ -199,8 +199,20 @@<br>
<div class="im">   /// \brief Install command line arguments adjuster.<br>
   ///<br>
   /// \param Adjuster Command line arguments adjuster.<br>
+  //<br>
</div>+  /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead.<br>
<div class="im">+  /// Remove it once all callers are gone.<br>
   void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster);<br>
<br>
+  /// \brief Append a command line arguments adjuster to the adjuster chain.<br>
+  ///<br>
</div>+  /// \param Adjuster An argument adjuster, which will be run on the output of<br>
+  ///        previous argument adjusters.<br>
<div class="im">+  void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster);<br>
+<br>
</div>+  /// \brief Clear the command line arguments adjuster chain.<br>
<div class="im">+  void clearArgumentsAdjusters();<br>
+<br>
   /// Runs a frontend action over all files specified in the command line.<br>
   ///<br>
   /// \param ActionFactory Factory generating the frontend actions. The function<br>
</div>@@ -221,7 +233,7 @@<br>
<div class="HOEnZb"><div class="h5">   // Contains a list of pairs (<file name>, <file content>).<br>
   std::vector< std::pair<StringRef, StringRef> > MappedFileContents;<br>
<br>
-  OwningPtr<ArgumentsAdjuster> ArgsAdjuster;<br>
+  SmallVector<ArgumentsAdjuster *, 1> ArgsAdjusters;<br>
 };<br>
<br>
 template <typename T><br>
Index: lib/Tooling/Tooling.cpp<br>
===================================================================<br>
--- lib/Tooling/Tooling.cpp<br>
+++ lib/Tooling/Tooling.cpp<br>
@@ -237,7 +237,7 @@<br>
 ClangTool::ClangTool(const CompilationDatabase &Compilations,<br>
                      ArrayRef<std::string> SourcePaths)<br>
     : Files((FileSystemOptions())),<br>
-      ArgsAdjuster(new ClangSyntaxOnlyAdjuster()) {<br>
+      ArgsAdjusters(1, new ClangSyntaxOnlyAdjuster()) {<br>
   for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {<br>
     SmallString<1024> File(getAbsolutePath(SourcePaths[I]));<br>
<br>
@@ -264,7 +264,18 @@<br>
 }<br>
<br>
 void ClangTool::setArgumentsAdjuster(ArgumentsAdjuster *Adjuster) {<br>
-  ArgsAdjuster.reset(Adjuster);<br>
+  clearArgumentsAdjusters();<br>
+  appendArgumentsAdjuster(Adjuster);<br>
+}<br>
+<br>
+void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster) {<br>
+  ArgsAdjusters.push_back(Adjuster);<br>
+}<br>
+<br>
+void ClangTool::clearArgumentsAdjusters() {<br>
+  for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I)<br>
+    delete ArgsAdjusters[I];<br>
+  ArgsAdjusters.clear();<br>
 }<br>
<br>
 int ClangTool::run(FrontendActionFactory *ActionFactory) {<br>
@@ -292,8 +303,9 @@<br>
     if (chdir(CompileCommands[I].second.Directory.c_str()))<br>
       llvm::report_fatal_error("Cannot chdir into \"" +<br>
                                CompileCommands[I].second.Directory + "\n!");<br>
-    std::vector<std::string> CommandLine =<br>
-      ArgsAdjuster->Adjust(CompileCommands[I].second.CommandLine);<br>
+    std::vector<std::string> CommandLine = CompileCommands[I].second.CommandLine;<br>
+    for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I)<br>
+      CommandLine = ArgsAdjusters[I]->Adjust(CommandLine);<br>
     assert(!CommandLine.empty());<br>
     CommandLine[0] = MainExecutable;<br>
     // FIXME: We need a callback mechanism for the tool writer to output a<br>
Index: unittests/Tooling/ToolingTest.cpp<br>
===================================================================<br>
--- unittests/Tooling/ToolingTest.cpp<br>
+++ unittests/Tooling/ToolingTest.cpp<br>
@@ -193,5 +193,46 @@<br>
                              "int skipMeNot() { an_error_here }"));<br>
 }<br>
<br>
+struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {<br>
+  bool &Found;<br>
+  bool &Ran;<br>
+<br>
+  CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }<br>
+<br>
+  virtual CommandLineArguments<br>
+  Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE {<br>
+    Ran = true;<br>
+    for (unsigned I = 0, E = Args.size(); I != E; ++I) {<br>
+      if (Args[I] == "-fsyntax-only") {<br>
+        Found = true;<br>
+        break;<br>
+      }<br>
+    }<br>
+    return Args;<br>
+  }<br>
+};<br>
+<br>
+TEST(ClangToolTest, ArgumentAdjusters) {<br>
+  FixedCompilationDatabase Compilations("/", std::vector<std::string>());<br>
+<br>
+  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));<br>
+  Tool.mapVirtualFile("/a.cc", "void a() {}");<br>
+<br>
+  bool Found = false;<br>
+  bool Ran = false;<br>
+  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));<br>
+  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());<br>
+  EXPECT_TRUE(Ran);<br>
+  EXPECT_TRUE(Found);<br>
+<br>
+  Ran = Found = false;<br>
+  Tool.clearArgumentsAdjusters();<br>
+  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));<br>
+  Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());<br>
+  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());<br>
+  EXPECT_TRUE(Ran);<br>
+  EXPECT_FALSE(Found);<br>
+}<br>
+<br>
 } // end namespace tooling<br>
 } // end namespace clang<br>
</div></div></blockquote></div><br></div>