gollvm: add support for -Xassembler, -Wa, and -gz options

Accept the -Wa and -Xassembler options to allow users to pass
arguments to the assembler. Also add support for the -gz and -gz=<arg>
(compressed debug sections) command line flags.

Change-Id: Ibc969d09d9c8ed4e13387bae2d79b7381e9a4209
Reviewed-on: https://go-review.googlesource.com/105820
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/driver/llvm-goc.cpp b/driver/llvm-goc.cpp
index ff6c44d..42d8f1e 100644
--- a/driver/llvm-goc.cpp
+++ b/driver/llvm-goc.cpp
@@ -921,21 +921,37 @@
     return false;
   }
 
-  std::vector<const char *> args;
-  args.push_back("as");
+  // Note: ArgStringList is effectively a vector of "const char *".
+  opt::ArgStringList asmcmd;
+  asmcmd.push_back("as");
   if (compileMode_ == CompileAssemblyMode) {
     for (auto &fn : inputFileNames_)
-      args.push_back(fn.c_str());
+      asmcmd.push_back(fn.c_str());
   } else {
-    args.push_back(asmOutFileName_.c_str());
+    asmcmd.push_back(asmOutFileName_.c_str());
   }
-  args.push_back("-o");
-  args.push_back(outFileName_.c_str());
-  args.push_back(nullptr);
+  asmcmd.push_back("-o");
+  asmcmd.push_back(outFileName_.c_str());
+  args_.AddAllArgValues(asmcmd,
+                        gollvm::options::OPT_Wa_COMMA,
+                        gollvm::options::OPT_Xassembler);
+  opt::Arg *gzarg = args_.getLastArg(gollvm::options::OPT_gz,
+                                     gollvm::options::OPT_gz_EQ);
+  std::string cds;
+  if (gzarg != nullptr) {
+    if (gzarg->getOption().matches(gollvm::options::OPT_gz)) {
+      asmcmd.push_back("-compress-debug-sections");
+    } else {
+      cds = "-compress-debug-sections=";
+      cds += gzarg->getValue();
+      asmcmd.push_back(cds.c_str());
+    }
+  }
+  asmcmd.push_back(nullptr);
 
   if (args_.hasArg(gollvm::options::OPT_v)) {
     bool first = true;
-    for (auto arg : args) {
+    for (auto arg : asmcmd) {
       errs() << (first ? "" : " ") << arg;
       first = false;
     }
@@ -944,7 +960,7 @@
 
   std::string errMsg;
   bool rval = true;
-  int rc = sys::ExecuteAndWait(*aspath, args.data(),
+  int rc = sys::ExecuteAndWait(*aspath, asmcmd.data(),
                                /*env=*/nullptr, /*Redirects*/{},
                                /*secondsToWait=*/0,
                                /*memoryLimit=*/0, &errMsg);