gollvm: refactor -###/-v helper

Relocate the helper that emits "-v" or "-###" output from the
CompileGo class back up into InternalTool. This is in preparation for
reusing it elsewhere (in a subsequent patch).

Change-Id: I0d4f279251a42ecd58116eceb4467f74592f7923
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/255049
Trust: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index 1871e47..a064858 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -90,7 +90,7 @@
 
 class CompileGoImpl {
  public:
-  CompileGoImpl(ToolChain &tc, const std::string &executablePath);
+  CompileGoImpl(CompileGo &cg, ToolChain &tc, const std::string &executablePath);
 
   // Perform compilation.
   bool performAction(Compilation &compilation,
@@ -99,6 +99,7 @@
                      const Artifact &output);
 
  private:
+  CompileGo &cg_;
   Triple triple_;
   const ToolChain &toolchain_;
   Driver &driver_;
@@ -130,10 +131,6 @@
   void setupGoSearchPath();
   void setCConv();
 
-  // This routine emits output for -### and/or -v, then returns TRUE
-  // of the compilation should be stubbed out (-###) or FALSE otherwise.
-  bool preamble(const Artifact &output);
-
   // The routines below return TRUE for success, FALSE for failure/error/
   bool setup();
   bool initBridge();
@@ -144,16 +141,15 @@
                           const ArtifactList &inputArtifacts,
                           const Artifact &output);
 
-  // Helpers for -### output
-  void dumpArg(opt::Arg &arg, bool doquote);
-  void quoteDump(const std::string &str, bool doquote);
-
   // Misc
   bool enableVectorization(bool slp);
 };
 
-CompileGoImpl::CompileGoImpl(ToolChain &tc, const std::string &executablePath)
-    : triple_(tc.driver().triple()),
+CompileGoImpl::CompileGoImpl(CompileGo &cg,
+                             ToolChain &tc,
+                             const std::string &executablePath)
+    : cg_(cg),
+      triple_(tc.driver().triple()),
       toolchain_(tc),
       driver_(tc.driver()),
       cconv_(CallingConv::MaxID),
@@ -176,7 +172,7 @@
                                   const ArtifactList &inputArtifacts,
                                   const Artifact &output)
 {
-  if (preamble(output))
+  if (cg_.emitMinusVOrHashHashHash(triple_, output, jobAction))
     return true;
 
   // Resolve input/output files.
@@ -243,66 +239,6 @@
   RemarkCtl &r_;
 };
 
-void CompileGoImpl::quoteDump(const std::string &str, bool doquote)
-{
-  Regex qureg("^[-_/A-Za-z0-9_\\.]+$");
-  errs() << " ";
-  if (doquote)
-    doquote = !qureg.match(str);
-  errs() << (doquote ? "\"" : "") << str << (doquote ? "\"" : "");
-}
-
-void CompileGoImpl::dumpArg(opt::Arg &arg, bool doquote)
-{
-  if (arg.getOption().getKind() != opt::Option::InputClass)
-    quoteDump(arg.getSpelling().str(), doquote);
-  for (auto &val : arg.getValues())
-    quoteDump(val, doquote);
-}
-
-bool CompileGoImpl::preamble(const Artifact &output)
-{
-  // If -v is in effect, print something to show the effect of the
-  // compilation. This is in some sense a fiction, because the top
-  // level driver is not invoking an external tool to perform the
-  // compile, but there is an expectation with compilers that if you
-  // take the "-v" output and then execute each command shown by hand,
-  // you'll get the same effect as the original command that produced
-  // the "-v" output.
-  bool hashHashHash = args_.hasArg(gollvm::options::OPT__HASH_HASH_HASH);
-  if (args_.hasArg(gollvm::options::OPT_v) || hashHashHash) {
-    errs() << "Target: " << triple_.str() << "\n";
-    errs() << " " << executablePath_;
-    if (!args_.hasArg(gollvm::options::OPT_S) &&
-        !args_.hasArg(gollvm::options::OPT_emit_llvm))
-      errs() << " " << "-S";
-    for (auto arg : args_) {
-      // Special case for -L. Here even if the user said "-L /x"
-      // we render it as -L/x so as to be compatible with existing
-      // code in the imported that expects the former and not the latter.
-      if (arg->getOption().matches(gollvm::options::OPT_L))
-        errs() << " -L" << arg->getValue();
-      if (arg->getOption().getGroup().isValid() &&
-          (arg->getOption().getGroup().getID() ==
-           gollvm::options::OPT_Link_Group))
-        continue;
-      if (arg->getOption().matches(gollvm::options::OPT_v) ||
-          arg->getOption().matches(gollvm::options::OPT_c) ||
-          arg->getOption().matches(gollvm::options::OPT_o) ||
-          arg->getOption().matches(gollvm::options::OPT__HASH_HASH_HASH) ||
-          arg->getOption().matches(gollvm::options::OPT_save_temps))
-        continue;
-      dumpArg(*arg, hashHashHash);
-    }
-
-    errs() << " " << "-L" << driver_.installedLibDir() << " " << "-o";
-    quoteDump(output.file(), hashHashHash);
-    errs() << "\n";
-  }
-
-  return hashHashHash;
-}
-
 bool CompileGoImpl::resolveInputOutput(const Action &jobAction,
                                        const ArtifactList &inputArtifacts,
                                        const Artifact &output)
@@ -1040,8 +976,8 @@
 //......................................................................
 
 CompileGo::CompileGo(ToolChain &tc, const std::string &executablePath)
-    : InternalTool("gocompiler", tc),
-      impl_(new CompileGoImpl(tc, executablePath))
+    : InternalTool("gocompiler", tc, executablePath),
+      impl_(new CompileGoImpl(*this, tc, executablePath))
 {
 }
 
diff --git a/driver/ReadStdin.cpp b/driver/ReadStdin.cpp
index a3f47fe..c5f0baa 100644
--- a/driver/ReadStdin.cpp
+++ b/driver/ReadStdin.cpp
@@ -24,7 +24,7 @@
 
 
 ReadStdin::ReadStdin(ToolChain &tc, bool mustBeEmpty)
-    : InternalTool("stdinreader", tc),
+    : InternalTool("stdinreader", tc, ""),
       mustBeEmpty_(mustBeEmpty)
 {
 }
diff --git a/driver/Tool.cpp b/driver/Tool.cpp
index 9c8d259..7a91dd7 100644
--- a/driver/Tool.cpp
+++ b/driver/Tool.cpp
@@ -12,6 +12,16 @@
 
 #include "Tool.h"
 
+using namespace llvm;
+
+#include "GollvmOptions.h"
+#include "Driver.h"
+#include "ToolChain.h"
+
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/Regex.h"
+
 namespace gollvm {
 namespace driver {
 
@@ -24,8 +34,12 @@
 {
 }
 
-InternalTool::InternalTool(const char *name, ToolChain &tc)
-      : Tool(name, tc, Tool::Internal)
+InternalTool::InternalTool(const char *name,
+                           ToolChain &tc,
+                           const std::string &executablePath)
+    : Tool(name, tc, Tool::Internal),
+      tc_(tc),
+      executablePath_(executablePath)
 {
 }
 
@@ -33,6 +47,70 @@
 {
 }
 
+static void quoteDump(const std::string &str, bool doquote)
+{
+  Regex qureg("^[-_/A-Za-z0-9_\\.]+$");
+  errs() << " ";
+  if (doquote)
+    doquote = !qureg.match(str);
+  errs() << (doquote ? "\"" : "") << str << (doquote ? "\"" : "");
+}
+
+static void dumpArg(opt::Arg &arg, bool doquote)
+{
+  if (arg.getOption().getKind() != opt::Option::InputClass)
+    quoteDump(arg.getSpelling().str(), doquote);
+  for (auto &val : arg.getValues())
+    quoteDump(val, doquote);
+}
+
+bool InternalTool::emitMinusVOrHashHashHash(const Triple &triple,
+                                            const Artifact &output,
+                                            const Action &jobAction)
+{
+  // If -v is in effect, print something to show the effect of the
+  // compilation. This is in some sense a fiction, because the top
+  // level driver is not invoking an external tool to perform the
+  // compile, but there is an expectation with compilers that if you
+  // take the "-v" output and then execute each command shown by hand,
+  // you'll get the same effect as the original command that produced
+  // the "-v" output.
+  opt::InputArgList &args = tc_.driver().args();
+  bool hashHashHash = args.hasArg(gollvm::options::OPT__HASH_HASH_HASH);
+  if (args.hasArg(gollvm::options::OPT_v) || hashHashHash) {
+    errs() << "Target: " << triple.str() << "\n";
+    errs() << " " << executablePath_;
+    if (!args.hasArg(gollvm::options::OPT_S) &&
+        jobAction.type() == Action::A_Compile &&
+        !args.hasArg(gollvm::options::OPT_emit_llvm))
+      errs() << " " << "-S";
+    for (auto arg : args) {
+      // Special case for -L. Here even if the user said "-L /x"
+      // we render it as -L/x so as to be compatible with existing
+      // code in the imported that expects the former and not the latter.
+      if (arg->getOption().matches(gollvm::options::OPT_L))
+        errs() << " -L" << arg->getValue();
+      if (arg->getOption().getGroup().isValid() &&
+          (arg->getOption().getGroup().getID() ==
+           gollvm::options::OPT_Link_Group))
+        continue;
+      if (arg->getOption().matches(gollvm::options::OPT_v) ||
+          arg->getOption().matches(gollvm::options::OPT_c) ||
+          arg->getOption().matches(gollvm::options::OPT_o) ||
+          arg->getOption().matches(gollvm::options::OPT__HASH_HASH_HASH) ||
+          arg->getOption().matches(gollvm::options::OPT_save_temps))
+        continue;
+      dumpArg(*arg, hashHashHash);
+    }
+
+    errs() << " " << "-L" << tc_.driver().installedLibDir() << " " << "-o";
+    quoteDump(output.file(), hashHashHash);
+    errs() << "\n";
+  }
+
+  return hashHashHash;
+}
+
 ExternalTool::ExternalTool(const char *name, ToolChain &tc)
       : Tool(name, tc, Tool::External)
 {
diff --git a/driver/Tool.h b/driver/Tool.h
index 832ab27..abde3ca 100644
--- a/driver/Tool.h
+++ b/driver/Tool.h
@@ -14,6 +14,7 @@
 #define GOLLVM_DRIVER_TOOL_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
 #include "Artifact.h"
 
 namespace gollvm {
@@ -58,7 +59,9 @@
 
 class InternalTool : public Tool {
  public:
-  InternalTool(const char *name, ToolChain &tc);
+  InternalTool(const char *name,
+               ToolChain &tc,
+               const std::string &executablePath);
   virtual ~InternalTool();
 
   // Given a specific action, perform the action now (as opposed to
@@ -68,7 +71,22 @@
                              const Action &jobAction,
                              const ArtifactList &inputArtifacts,
                              const Artifact &output) = 0;
+
+  // Helper to emit output for "-v" or "-###" command line option when supplied
+  // to an internal tool. Return value is TRUE if if the compilation should be
+  // stubbed out (-###) or FALSE otherwise.
+  bool emitMinusVOrHashHashHash(const llvm::Triple &triple,
+                                const Artifact &output,
+                                const Action &jobAction);
+
+  // Executable path, if applicable.
+  std::string executablePath() const {
+    return executablePath_;
+  }
+
  private:
+  ToolChain &tc_;
+  std::string executablePath_;
 };
 
 // An "external" tool -- carries out the steps needs to perform