[clang][ifs] Clang Interface Stubs ToolChain plumbing.

Second Landing Attempt:

This patch enables end to end support for generating ELF interface stubs
directly from clang. Now the following:

clang -emit-interface-stubs -o libfoo.so a.cpp b.cpp c.cpp

will product an ELF binary with visible symbols populated. Visibility attributes
and -fvisibility can be used to control what gets populated.

* Adding ToolChain support for clang Driver IFS Merge Phase
* Implementing a default InterfaceStubs Merge clang Tool, used by ToolChain
* Adds support for the clang Driver to involve llvm-ifs on ifs files.
* Adds -emit-merged-ifs flag, to tell llvm-ifs to emit a merged ifs text file
  instead of the final object format (normally ELF)


Differential Revision: https://reviews.llvm.org/D63978

llvm-svn: 374061
diff --git a/clang/lib/Driver/ToolChains/InterfaceStubs.cpp b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp
new file mode 100644
index 0000000..6677843
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/InterfaceStubs.cpp
@@ -0,0 +1,37 @@
+//===---  InterfaceStubs.cpp - Base InterfaceStubs Implementations C++  ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "InterfaceStubs.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace ifstool {
+void Merger::ConstructJob(Compilation &C, const JobAction &JA,
+                          const InputInfo &Output, const InputInfoList &Inputs,
+                          const llvm::opt::ArgList &Args,
+                          const char *LinkingOutput) const {
+  std::string Merger = getToolChain().GetProgramPath(getShortName());
+  llvm::opt::ArgStringList CmdArgs;
+  CmdArgs.push_back("-action");
+  CmdArgs.push_back(Args.getLastArg(options::OPT_emit_merged_ifs)
+                        ? "write-ifs"
+                        : "write-bin");
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  for (const auto &Input : Inputs)
+    CmdArgs.push_back(Input.getFilename());
+  C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),
+                                         CmdArgs, Inputs));
+}
+} // namespace ifstool
+} // namespace tools
+} // namespace driver
+} // namespace clang