]> granicus.if.org Git - clang/blobdiff - lib/Driver/Tools.h
Header guard canonicalization, clang part.
[clang] / lib / Driver / Tools.h
index 6729da8370a5af265da201e4cf75444d14a9e967..b7330af75968b8279befeec666d55014b83ec52d 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef CLANG_LIB_DRIVER_TOOLS_H_
-#define CLANG_LIB_DRIVER_TOOLS_H_
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLS_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLS_H
 
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
-
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
 #include "llvm/Support/Compiler.h"
 
 namespace clang {
+  class ObjCRuntime;
+
 namespace driver {
+  class Command;
   class Driver;
 
 namespace toolchains {
-  class Darwin;
+  class MachO;
 }
 
 namespace tools {
 
-  class VISIBILITY_HIDDEN Clang : public Tool {
-    void AddPreprocessingOptions(const Driver &D,
-                                 const ArgList &Args,
-                                 ArgStringList &CmdArgs,
+namespace visualstudio {
+  class Compile;
+}
+
+using llvm::opt::ArgStringList;
+
+  /// \brief Clang compiler tool.
+  class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
+  public:
+    static const char *getBaseInputName(const llvm::opt::ArgList &Args,
+                                        const InputInfoList &Inputs);
+    static const char *getBaseInputStem(const llvm::opt::ArgList &Args,
+                                        const InputInfoList &Inputs);
+    static const char *getDependencyFileName(const llvm::opt::ArgList &Args,
+                                             const InputInfoList &Inputs);
+
+  private:
+    void AddPreprocessingOptions(Compilation &C, const JobAction &JA,
+                                 const Driver &D,
+                                 const llvm::opt::ArgList &Args,
+                                 llvm::opt::ArgStringList &CmdArgs,
                                  const InputInfo &Output,
                                  const InputInfoList &Inputs) const;
 
-    void AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
-    void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
+                              llvm::opt::ArgStringList &CmdArgs) const;
+    void AddARMTargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs,
+                          bool KernelOrKext) const;
+    void AddARM64TargetArgs(const llvm::opt::ArgList &Args,
+                            llvm::opt::ArgStringList &CmdArgs) const;
+    void AddMIPSTargetArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const;
+    void AddPPCTargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs) const;
+    void AddR600TargetArgs(const llvm::opt::ArgList &Args,
+                           llvm::opt::ArgStringList &CmdArgs) const;
+    void AddSparcTargetArgs(const llvm::opt::ArgList &Args,
+                            llvm::opt::ArgStringList &CmdArgs) const;
+    void AddSystemZTargetArgs(const llvm::opt::ArgList &Args,
+                              llvm::opt::ArgStringList &CmdArgs) const;
+    void AddX86TargetArgs(const llvm::opt::ArgList &Args,
+                          llvm::opt::ArgStringList &CmdArgs) const;
+    void AddHexagonTargetArgs(const llvm::opt::ArgList &Args,
+                              llvm::opt::ArgStringList &CmdArgs) const;
+
+    enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
+
+    ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args,
+                                   llvm::opt::ArgStringList &cmdArgs,
+                                   RewriteKind rewrite) const;
+
+    void AddClangCLArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const;
+
+    visualstudio::Compile *getCLFallback() const;
+
+    mutable std::unique_ptr<visualstudio::Compile> CLFallback;
+
+  public:
+    Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
+
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedAssembler() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
 
+  /// \brief Clang integrated assembler tool.
+  class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool {
   public:
-    Clang(const ToolChain &TC) : Tool("clang", TC) {}
+    ClangAs(const ToolChain &TC) : Tool("clang::as",
+                                        "clang integrated assembler", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedAssembler() const override { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
   /// gcc - Generic GCC tool implementations.
 namespace gcc {
-  class VISIBILITY_HIDDEN Common : public Tool {
+  class LLVM_LIBRARY_VISIBILITY Common : public Tool {
   public:
-    Common(const char *Name, const ToolChain &TC) : Tool(Name, TC) {}
+    Common(const char *Name, const char *ShortName,
+           const ToolChain &TC) : Tool(Name, ShortName, TC) {}
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
 
     /// RenderExtraToolArgs - Render any arguments necessary to force
     /// the particular tool mode.
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const = 0;
+    virtual void
+        RenderExtraToolArgs(const JobAction &JA,
+                            llvm::opt::ArgStringList &CmdArgs) const = 0;
   };
 
-
-  class VISIBILITY_HIDDEN Preprocess : public Common {
+  class LLVM_LIBRARY_VISIBILITY Preprocess : public Common {
   public:
-    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess", TC) {}
+    Preprocess(const ToolChain &TC) : Common("gcc::Preprocess",
+                                             "gcc preprocessor", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
 
-  class VISIBILITY_HIDDEN Precompile : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Compile : public Common  {
   public:
-    Precompile(const ToolChain &TC) : Common("gcc::Precompile", TC) {}
+    Compile(const ToolChain &TC) : Common("gcc::Compile",
+                                          "gcc frontend", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
 
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
 
-  class VISIBILITY_HIDDEN Compile : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Common  {
   public:
-    Compile(const ToolChain &TC) : Common("gcc::Compile", TC) {}
+    Link(const ToolChain &TC) : Common("gcc::Link",
+                                       "linker (via gcc)", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
+} // end namespace gcc
 
-  class VISIBILITY_HIDDEN Assemble : public Common  {
+namespace hexagon {
+  // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
+  // We simply use "clang -cc1" for those actions.
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
   public:
-    Assemble(const ToolChain &TC) : Common("gcc::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("hexagon::Assemble",
+      "hexagon-as", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
-  class VISIBILITY_HIDDEN Link : public Common  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool {
   public:
-    Link(const ToolChain &TC) : Common("gcc::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("hexagon::Link",
+      "hexagon-ld", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    virtual void RenderExtraToolArgs(const JobAction &JA,
+                                     llvm::opt::ArgStringList &CmdArgs) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+} // end namespace hexagon.
+
+namespace arm {
+  StringRef getARMTargetCPU(const llvm::opt::ArgList &Args,
+                            const llvm::Triple &Triple);
+  const char* getARMCPUForMArch(const llvm::opt::ArgList &Args,
+                                const llvm::Triple &Triple);
+  const char* getLLVMArchSuffixForARM(StringRef CPU);
+}
 
-    virtual bool acceptsPipedInput() const { return false; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+namespace mips {
+  void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
+                        const llvm::Triple &Triple, StringRef &CPUName,
+                        StringRef &ABIName);
+  bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+  bool isUCLibc(const llvm::opt::ArgList &Args);
+  bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+  bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+                     StringRef ABIName);
+}
 
-    virtual void RenderExtraToolArgs(ArgStringList &CmdArgs) const;
-  };
-} // end namespace gcc
+namespace ppc {
+  bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+}
 
 namespace darwin {
-  class VISIBILITY_HIDDEN DarwinTool : public Tool {
+  llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
+  void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
+
+  class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
+    virtual void anchor();
   protected:
-    void AddDarwinArch(const ArgList &Args, ArgStringList &CmdArgs) const;
-    void AddDarwinSubArch(const ArgList &Args, ArgStringList &CmdArgs) const;
+    void AddMachOArch(const llvm::opt::ArgList &Args,
+                       llvm::opt::ArgStringList &CmdArgs) const;
 
-    const toolchains::Darwin &getDarwinToolChain() const {
-      return reinterpret_cast<const toolchains::Darwin&>(getToolChain());
+    const toolchains::MachO &getMachOToolChain() const {
+      return reinterpret_cast<const toolchains::MachO&>(getToolChain());
     }
 
   public:
-    DarwinTool(const char *Name, const ToolChain &TC) : Tool(Name, TC) {};
+    MachOTool(const char *Name, const char *ShortName,
+               const ToolChain &TC) : Tool(Name, ShortName, TC) {}
   };
 
-  class VISIBILITY_HIDDEN CC1 : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public MachOTool  {
   public:
-    static const char *getBaseInputName(const ArgList &Args,
-                                 const InputInfoList &Input);
-    static const char *getBaseInputStem(const ArgList &Args,
-                                 const InputInfoList &Input);
-    static const char *getDependencyFileName(const ArgList &Args,
-                                             const InputInfoList &Inputs);
+    Assemble(const ToolChain &TC) : MachOTool("darwin::Assemble",
+                                              "assembler", TC) {}
 
-  protected:
-    const char *getCC1Name(types::ID Type) const;
-
-    void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;
-    void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
-                           const InputInfoList &Inputs,
-                           const ArgStringList &OutputArgs) const;
-    void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
-                           const InputInfoList &Inputs,
-                           const ArgStringList &OutputArgs) const;
-    void AddCPPUniqueOptionsArgs(const ArgList &Args,
-                                 ArgStringList &CmdArgs,
-                                 const InputInfoList &Inputs) const;
-    void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+    bool hasIntegratedCPP() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+
+  class LLVM_LIBRARY_VISIBILITY Link : public MachOTool  {
+    bool NeedsTempPath(const InputInfoList &Inputs) const;
+    void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args,
+                     llvm::opt::ArgStringList &CmdArgs,
+                     const InputInfoList &Inputs) const;
 
   public:
-    CC1(const char *Name, const ToolChain &TC) : DarwinTool(Name, TC) {}
+    Link(const ToolChain &TC) : MachOTool("darwin::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
-  class VISIBILITY_HIDDEN Preprocess : public CC1  {
+  class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool  {
   public:
-    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess", TC) {}
+    Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
-  class VISIBILITY_HIDDEN Compile : public CC1  {
+  class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool  {
   public:
-    Compile(const ToolChain &TC) : CC1("darwin::Compile", TC) {}
+    Dsymutil(const ToolChain &TC) : MachOTool("darwin::Dsymutil",
+                                              "dsymutil", TC) {}
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    bool hasIntegratedCPP() const override { return false; }
+    bool isDsymutilJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
-  class VISIBILITY_HIDDEN Assemble : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool  {
   public:
-    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble", TC) {}
+    VerifyDebug(const ToolChain &TC) : MachOTool("darwin::VerifyDebug",
+                                                 "dwarfdump", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
-  class VISIBILITY_HIDDEN Link : public DarwinTool  {
-    void AddLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
+}
 
+  /// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Link(const ToolChain &TC) : DarwinTool("darwin::Link", TC) {}
+    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler",
+                                         TC) {}
 
-    virtual bool acceptsPipedInput() const { return false; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-
-  class VISIBILITY_HIDDEN Lipo : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", TC) {}
+    Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {}
 
-    virtual bool acceptsPipedInput() const { return false; }
-    virtual bool canPipeOutput() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-}
+} // end namespace openbsd
 
-  /// openbsd -- Directly call GNU Binutils assembler and linker
-namespace openbsd {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  /// bitrig -- Directly call GNU Binutils assembler and linker
+namespace bitrig {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("bitrig::Assemble", "assembler",
+                                         TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-  class VISIBILITY_HIDDEN Link : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("bitrig::Link", "linker", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-} // end namespace openbsd
+} // end namespace bitrig
 
   /// freebsd -- Directly call GNU Binutils assembler and linker
 namespace freebsd {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler",
+                                         TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-  class VISIBILITY_HIDDEN Link : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("freebsd::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 } // end namespace freebsd
 
+  /// netbsd -- Directly call GNU Binutils assembler and linker
+namespace netbsd {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+
+  public:
+    Assemble(const ToolChain &TC)
+      : Tool("netbsd::Assemble", "assembler", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+
+  public:
+    Link(const ToolChain &TC)
+      : Tool("netbsd::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+} // end namespace netbsd
+
+  /// Directly call GNU Binutils' assembler and linker.
+namespace gnutools {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("GNU::Assemble", "assembler", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("GNU::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+}
+  /// minix -- Directly call GNU Binutils assembler and linker
+namespace minix {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler",
+                                         TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+} // end namespace minix
+
+  /// solaris -- Directly call Solaris assembler and linker
+namespace solaris {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler",
+                                         TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+} // end namespace solaris
+
   /// auroraux -- Directly call GNU Binutils assembler and linker
 namespace auroraux {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler",
+                                         TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-  class VISIBILITY_HIDDEN Link : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("auroraux::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 } // end namespace auroraux
 
   /// dragonfly -- Directly call GNU Binutils assembler and linker
 namespace dragonfly {
-  class VISIBILITY_HIDDEN Assemble : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
   public:
-    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", TC) {}
+    Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler",
+                                         TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
-  class VISIBILITY_HIDDEN Link : public Tool  {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
   public:
-    Link(const ToolChain &TC) : Tool("dragonfly::Link", TC) {}
+    Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {}
 
-    virtual bool acceptsPipedInput() const { return true; }
-    virtual bool canPipeOutput() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              Job &Dest,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 } // end namespace dragonfly
 
+/// Visual studio tools.
+namespace visualstudio {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool {
+  public:
+    Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+
+  class LLVM_LIBRARY_VISIBILITY Compile : public Tool {
+  public:
+    Compile(const ToolChain &TC) : Tool("visualstudio::Compile", "compiler", TC) {}
+
+    bool hasIntegratedAssembler() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
+    bool isLinkJob() const override { return false; }
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+
+    Command *GetCommand(Compilation &C, const JobAction &JA,
+                        const InputInfo &Output,
+                        const InputInfoList &Inputs,
+                        const llvm::opt::ArgList &TCArgs,
+                        const char *LinkingOutput) const;
+  };
+} // end namespace visualstudio
+
+namespace arm {
+  StringRef getARMFloatABI(const Driver &D, const llvm::opt::ArgList &Args,
+                         const llvm::Triple &Triple);
+}
+namespace XCore {
+  // For XCore, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
+  // We simply use "clang -cc1" for those actions.
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool {
+  public:
+    Assemble(const ToolChain &TC) : Tool("XCore::Assemble",
+      "XCore-as", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool {
+  public:
+    Link(const ToolChain &TC) : Tool("XCore::Link",
+      "XCore-ld", TC) {}
+
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+} // end namespace XCore.
+
+
 } // end namespace toolchains
 } // end namespace driver
 } // end namespace clang
 
-#endif // CLANG_LIB_DRIVER_TOOLS_H_
+#endif