Remove the Tools DensMap from the toolchain.

Each toolchain has a set of tools, but they are all of known types. It can
have a linker, an assembler, a "clang" (compile, analyze, ...) a non-clang
compiler, etc.

Instead of keeping a map, just have member variable for each type of tool.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177479 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 3733d45..68d0db1 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -13,6 +13,7 @@
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
+#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/Path.h"
@@ -58,12 +59,20 @@
   /// programs.
   path_list ProgramPaths;
 
-  mutable llvm::DenseMap<unsigned, Tool*> Tools;
+  mutable OwningPtr<Tool> Clang;
+  mutable OwningPtr<Tool> Assemble;
+  mutable OwningPtr<Tool> Link;
+  Tool *getClang() const;
+  Tool *getAssemble() const;
+  Tool *getLink() const;
+  Tool *getClangAs() const;
 
 protected:
   ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args);
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+  virtual Tool *getTool(Action::ActionClass AC) const;
 
   /// \name Utilities for implementing subclasses.
   ///@{
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index def3b3d..59932f6 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -28,10 +28,6 @@
 }
 
 ToolChain::~ToolChain() {
-  // Free tool implementations.
-  for (llvm::DenseMap<unsigned, Tool*>::iterator
-       it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
-    delete it->second;
 }
 
 const Driver &ToolChain::getDriver() const {
@@ -63,12 +59,48 @@
   return false;
 }
 
-Tool *ToolChain::constructTool(Action::ActionClass AC) const {
+Tool *ToolChain::getClang() const {
+  if (!Clang)
+    Clang.reset(new tools::Clang(*this));
+  return Clang.get();
+}
+
+Tool *ToolChain::buildAssembler() const {
+  return new tools::ClangAs(*this);
+}
+
+Tool *ToolChain::buildLinker() const {
+  llvm_unreachable("Linking is not supported by this toolchain");
+}
+
+Tool *ToolChain::getAssemble() const {
+  if (!Assemble)
+    Assemble.reset(buildAssembler());
+  return Assemble.get();
+}
+
+Tool *ToolChain::getClangAs() const {
+  if (!Assemble)
+    Assemble.reset(new tools::ClangAs(*this));
+  return Assemble.get();
+}
+
+Tool *ToolChain::getLink() const {
+  if (!Link)
+    Link.reset(buildLinker());
+  return Link.get();
+}
+
+Tool *ToolChain::getTool(Action::ActionClass AC) const {
   switch (AC) {
+  case Action::AssembleJobClass:
+    return getAssemble();
+
+  case Action::LinkJobClass:
+    return getLink();
+
   case Action::InputClass:
   case Action::BindArchClass:
-  case Action::AssembleJobClass:
-  case Action::LinkJobClass:
   case Action::LipoJobClass:
   case Action::DsymutilJobClass:
   case Action::VerifyJobClass:
@@ -79,29 +111,17 @@
   case Action::PreprocessJobClass:
   case Action::AnalyzeJobClass:
   case Action::MigrateJobClass:
-    return new tools::Clang(*this);
+    return getClang();
   }
 }
 
 Tool &ToolChain::SelectTool(const JobAction &JA) const {
-  Action::ActionClass Key;
   if (getDriver().ShouldUseClangCompiler(JA))
-    Key = Action::AnalyzeJobClass;
-  else
-    Key = JA.getKind();
-
-  Tool *&T = Tools[Key];
-  if (T)
-    return *T;
-
-  if (getDriver().ShouldUseClangCompiler(JA))
-    T = new tools::Clang(*this);
-  else if (Key == Action::AssembleJobClass && useIntegratedAs())
-    T = new tools::ClangAs(*this);
-  else
-    T = constructTool(Key);
-
-  return *T;
+    return *getClang();
+  Action::ActionClass AC = JA.getKind();
+  if (AC == Action::AssembleJobClass && useIntegratedAs())
+    return *getClangAs();
+  return *getTool(AC);
 }
 
 std::string ToolChain::GetFilePath(const char *Name) const {
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 0e29ba0..e28f801 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -172,23 +172,32 @@
 
 void Generic_ELF::anchor() {}
 
-Tool *Darwin::constructTool(Action::ActionClass AC) const {
+Tool *Darwin::getTool(Action::ActionClass AC) const {
   switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::darwin::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::darwin::Link(*this);
   case Action::LipoJobClass:
-    return new tools::darwin::Lipo(*this);
+    if (!Lipo)
+      Lipo.reset(new tools::darwin::Lipo(*this));
+    return Lipo.get();
   case Action::DsymutilJobClass:
-    return new tools::darwin::Dsymutil(*this);
+    if (!Dsymutil)
+      Dsymutil.reset(new tools::darwin::Dsymutil(*this));
+    return Dsymutil.get();
   case Action::VerifyJobClass:
-    return new tools::darwin::VerifyDebug(*this);
+    if (!VerifyDebug)
+      VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
+    return VerifyDebug.get();
   default:
-    return ToolChain::constructTool(AC);
+    return ToolChain::getTool(AC);
   }
 }
 
+Tool *Darwin::buildLinker() const {
+  return new tools::darwin::Link(*this);
+}
+
+Tool *Darwin::buildAssembler() const {
+  return new tools::darwin::Assemble(*this);
+}
 
 DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
                          const ArgList &Args)
@@ -1350,23 +1359,33 @@
 Generic_GCC::~Generic_GCC() {
 }
 
-Tool *Generic_GCC::constructTool(Action::ActionClass AC) const {
+Tool *Generic_GCC::getTool(Action::ActionClass AC) const {
   switch (AC) {
   case Action::PreprocessJobClass:
-    return new tools::gcc::Preprocess(*this);
+    if (!Preprocess)
+      Preprocess.reset(new tools::gcc::Preprocess(*this));
+    return Preprocess.get();
   case Action::PrecompileJobClass:
-    return new tools::gcc::Precompile(*this);
+    if (!Precompile)
+      Precompile.reset(new tools::gcc::Precompile(*this));
+    return Precompile.get();
   case Action::CompileJobClass:
-    return new tools::gcc::Compile(*this);
-  case Action::AssembleJobClass:
-    return new tools::gcc::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::gcc::Link(*this);
+    if (!Compile)
+      Compile.reset(new tools::gcc::Compile(*this));
+    return Compile.get();
   default:
-    return ToolChain::constructTool(AC);
+    return ToolChain::getTool(AC);
   }
 }
 
+Tool *Generic_GCC::buildAssembler() const {
+  return new tools::gcc::Assemble(*this);
+}
+
+Tool *Generic_GCC::buildLinker() const {
+  return new tools::gcc::Link(*this);
+}
+
 bool Generic_GCC::IsUnwindTablesDefault() const {
   return getArch() == llvm::Triple::x86_64;
 }
@@ -1491,15 +1510,12 @@
 Hexagon_TC::~Hexagon_TC() {
 }
 
-Tool *Hexagon_TC::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::hexagon::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::hexagon::Link(*this);
-  default:
-    return Linux::constructTool(AC);
-  }
+Tool *Hexagon_TC::buildAssembler() const {
+  return new tools::hexagon::Assemble(*this);
+}
+
+Tool *Hexagon_TC::buildLinker() const {
+  return new tools::hexagon::Link(*this);
 }
 
 void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
@@ -1624,15 +1640,12 @@
   getFilePaths().push_back("/usr/lib");
 }
 
-Tool *OpenBSD::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::openbsd::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::openbsd::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *OpenBSD::buildAssembler() const {
+  return new tools::openbsd::Assemble(*this);
+}
+
+Tool *OpenBSD::buildLinker() const {
+  return new tools::openbsd::Link(*this);
 }
 
 /// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
@@ -1643,15 +1656,12 @@
   getFilePaths().push_back("/usr/lib");
 }
 
-Tool *Bitrig::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::bitrig::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::bitrig::Link(*this); break;
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *Bitrig::buildAssembler() const {
+  return new tools::bitrig::Assemble(*this);
+}
+
+Tool *Bitrig::buildLinker() const {
+  return new tools::bitrig::Link(*this);
 }
 
 void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
@@ -1714,15 +1724,12 @@
     getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
 }
 
-Tool *FreeBSD::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::freebsd::Assemble(*this);
-  case Action::LinkJobClass:
-    return  new tools::freebsd::Link(*this); break;
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *FreeBSD::buildAssembler() const {
+  return new tools::freebsd::Assemble(*this);
+}
+
+Tool *FreeBSD::buildLinker() const {
+  return new tools::freebsd::Link(*this);
 }
 
 bool FreeBSD::UseSjLjExceptions() const {
@@ -1756,15 +1763,12 @@
   }
 }
 
-Tool *NetBSD::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::netbsd::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::netbsd::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *NetBSD::buildAssembler() const {
+  return new tools::netbsd::Assemble(*this);
+}
+
+Tool *NetBSD::buildLinker() const {
+  return new tools::netbsd::Link(*this);
 }
 
 /// Minix - Minix tool chain which can call as(1) and ld(1) directly.
@@ -1775,15 +1779,12 @@
   getFilePaths().push_back("/usr/lib");
 }
 
-Tool *Minix::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::minix::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::minix::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *Minix::buildAssembler() const {
+  return new tools::minix::Assemble(*this);
+}
+
+Tool *Minix::buildLinker() const {
+  return new tools::minix::Link(*this);
 }
 
 /// AuroraUX - AuroraUX tool chain which can call as(1) and ld(1) directly.
@@ -1804,15 +1805,12 @@
 
 }
 
-Tool *AuroraUX::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::auroraux::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::auroraux::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *AuroraUX::buildAssembler() const {
+  return new tools::auroraux::Assemble(*this);
+}
+
+Tool *AuroraUX::buildLinker() const {
+  return new tools::auroraux::Link(*this);
 }
 
 /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
@@ -1829,15 +1827,12 @@
   getFilePaths().push_back("/usr/lib");
 }
 
-Tool *Solaris::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::solaris::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::solaris::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *Solaris::buildAssembler() const {
+  return new tools::solaris::Assemble(*this);
+}
+
+Tool *Solaris::buildLinker() const {
+  return new tools::solaris::Link(*this);
 }
 
 /// Linux toolchain (very bare-bones at the moment).
@@ -2206,15 +2201,12 @@
   return true;
 }
 
-Tool *Linux::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::linuxtools::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::linuxtools::Link(*this); break;
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *Linux::buildLinker() const {
+  return new tools::linuxtools::Link(*this);
+}
+
+Tool *Linux::buildAssembler() const {
+  return new tools::linuxtools::Assemble(*this);
 }
 
 void Linux::addClangTargetOptions(const ArgList &DriverArgs,
@@ -2443,13 +2435,10 @@
   getFilePaths().push_back("/usr/lib/gcc41");
 }
 
-Tool *DragonFly::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    return new tools::dragonfly::Assemble(*this);
-  case Action::LinkJobClass:
-    return new tools::dragonfly::Link(*this);
-  default:
-    return Generic_GCC::constructTool(AC);
-  }
+Tool *DragonFly::buildAssembler() const {
+  return new tools::dragonfly::Assemble(*this);
+}
+
+Tool *DragonFly::buildLinker() const {
+  return new tools::dragonfly::Link(*this);
 }
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index fb40a61..3421c53 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -121,13 +121,15 @@
   Generic_GCC(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
   ~Generic_GCC();
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual bool IsUnwindTablesDefault() const;
   virtual bool isPICDefault() const;
   virtual bool isPICDefaultForced() const;
 
 protected:
+  virtual Tool *getTool(Action::ActionClass AC) const;
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+
   /// \name ToolChain Implementation Helper Functions
   /// @{
 
@@ -138,6 +140,11 @@
   bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
 
   /// @}
+
+private:
+  mutable OwningPtr<tools::gcc::Preprocess> Preprocess;
+  mutable OwningPtr<tools::gcc::Precompile> Precompile;
+  mutable OwningPtr<tools::gcc::Compile> Compile;
 };
 
   /// Darwin - The base Darwin tool chain.
@@ -146,7 +153,16 @@
   /// The host version.
   unsigned DarwinVersion[3];
 
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+  virtual Tool *getTool(Action::ActionClass AC) const;
+
 private:
+  mutable OwningPtr<tools::darwin::Lipo> Lipo;
+  mutable OwningPtr<tools::darwin::Dsymutil> Dsymutil;
+  mutable OwningPtr<tools::darwin::VerifyDebug> VerifyDebug;
+
   /// Whether the information on the target has been initialized.
   //
   // FIXME: This should be eliminated. What we want to do is make this part of
@@ -264,8 +280,6 @@
   virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
                                         const char *BoundArch) const;
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual bool IsBlocksDefault() const {
     // Always allow blocks on Darwin; users interested in versioning are
     // expected to use /usr/include/Blocks.h.
@@ -388,16 +402,20 @@
 public:
   AuroraUX(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
 public:
   Solaris(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual bool IsIntegratedAssemblerDefault() const { return true; }
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+
 };
 
 
@@ -408,7 +426,9 @@
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
@@ -419,8 +439,6 @@
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
   virtual bool IsObjCLegacyDispatchDefault() const { return false; }
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                             ArgStringList &CC1Args) const;
   virtual void AddCXXStdlibLibArgs(const ArgList &Args,
@@ -428,6 +446,10 @@
   virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
      return 1;
   }
+
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
@@ -437,8 +459,10 @@
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
   virtual bool UseSjLjExceptions() const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
@@ -448,14 +472,18 @@
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
 public:
   Minix(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
@@ -464,7 +492,9 @@
 
   virtual bool IsMathErrnoDefault() const { return false; }
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 };
 
 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
@@ -473,8 +503,6 @@
 
   virtual bool HasNativeLLVMSupport() const;
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                          ArgStringList &CC1Args) const;
   virtual void addClangTargetOptions(const ArgList &DriverArgs,
@@ -485,6 +513,10 @@
   std::string Linker;
   std::vector<std::string> ExtraOpts;
 
+protected:
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
+
 private:
   static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
                                        Twine TargetArchDir,
@@ -499,14 +531,14 @@
 class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux {
 protected:
   GCCVersion GCCLibAndIncVersion;
+  virtual Tool *buildAssembler() const;
+  virtual Tool *buildLinker() const;
 
 public:
   Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
              const ArgList &Args);
   ~Hexagon_TC();
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                          ArgStringList &CC1Args) const;
   virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
@@ -537,8 +569,6 @@
 public:
   Windows(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
 
-  virtual Tool *constructTool(Action::ActionClass AC) const;
-
   virtual bool IsIntegratedAssemblerDefault() const;
   virtual bool IsUnwindTablesDefault() const;
   virtual bool isPICDefault() const;
@@ -548,7 +578,9 @@
                                          ArgStringList &CC1Args) const;
   virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                             ArgStringList &CC1Args) const;
-
+protected:
+  virtual Tool *buildLinker() const;
+  virtual Tool *buildAssembler() const;
 };
 
 } // end namespace toolchains
diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp
index ae78272..cc52c00 100644
--- a/lib/Driver/WindowsToolChain.cpp
+++ b/lib/Driver/WindowsToolChain.cpp
@@ -36,19 +36,17 @@
   : ToolChain(D, Triple, Args) {
 }
 
-Tool *Windows::constructTool(Action::ActionClass AC) const {
-  switch (AC) {
-  case Action::AssembleJobClass:
-    if (getTriple().getEnvironment() == llvm::Triple::MachO)
-      return new tools::darwin::Assemble(*this);
+Tool *Windows::buildLinker() const {
+  return new tools::visualstudio::Link(*this);
+}
+
+Tool *Windows::buildAssembler() const {
+  if (getTriple().getEnvironment() == llvm::Triple::MachO)
+    return new tools::darwin::Assemble(*this);
+  else
     // There no assembler we can use on windows other than the integrated
     // assembler, so we ignore -no-integrated-as.
-    return new tools::ClangAs(*this);
-  case Action::LinkJobClass:
-    return new tools::visualstudio::Link(*this);
-  default:
-    return ToolChain::constructTool(AC);
-  }
+    return ToolChain::buildAssembler();
 }
 
 bool Windows::IsIntegratedAssemblerDefault() const {