Reapply part of r237975, "Fix Clang -Wmissing-override warning", except for DIContext...
[oota-llvm.git] / include / llvm / Support / TargetRegistry.h
index 88081307ac6b60429f86623f9f1ed538af1bd297..afcdbb85f853b0d4c31a761d9ae3444f2660085a 100644 (file)
 #ifndef LLVM_SUPPORT_TARGETREGISTRY_H
 #define LLVM_SUPPORT_TARGETREGISTRY_H
 
-#include "llvm/Support/CodeGen.h"
+#include "llvm-c/Disassembler.h"
 #include "llvm/ADT/Triple.h"
-#include <string>
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/FormattedStream.h"
 #include <cassert>
+#include <memory>
+#include <string>
 
 namespace llvm {
   class AsmPrinter;
-  class Module;
-  class MCAssembler;
   class MCAsmBackend;
   class MCAsmInfo;
   class MCAsmParser;
@@ -41,21 +42,39 @@ namespace llvm {
   class MCRegisterInfo;
   class MCStreamer;
   class MCSubtargetInfo;
-  class MCTargetAsmLexer;
+  class MCSymbolizer;
+  class MCRelocationInfo;
   class MCTargetAsmParser;
+  class MCTargetOptions;
+  class MCTargetStreamer;
   class TargetMachine;
   class TargetOptions;
   class raw_ostream;
+  class raw_pwrite_stream;
   class formatted_raw_ostream;
 
-  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
-                                bool isVerboseAsm,
-                                bool useLoc, bool useCFI,
-                                bool useDwarfDirectory,
-                                MCInstPrinter *InstPrint,
-                                MCCodeEmitter *CE,
-                                MCAsmBackend *TAB,
-                                bool ShowInst);
+  MCStreamer *createNullStreamer(MCContext &Ctx);
+  MCStreamer *createAsmStreamer(MCContext &Ctx,
+                                std::unique_ptr<formatted_raw_ostream> OS,
+                                bool isVerboseAsm, bool useDwarfDirectory,
+                                MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+                                MCAsmBackend *TAB, bool ShowInst);
+
+  /// Takes ownership of \p TAB and \p CE.
+  MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+                                raw_pwrite_stream &OS, MCCodeEmitter *CE,
+                                bool RelaxAll);
+  MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+                                  raw_pwrite_stream &OS, MCCodeEmitter *CE,
+                                  bool RelaxAll, bool DWARFMustBeAtTheEnd,
+                                  bool LabelSections = false);
+
+  MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
+
+  MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+                                   LLVMSymbolLookupCallback SymbolLookUp,
+                                   void *DisInfo, MCContext *Ctx,
+                                   std::unique_ptr<MCRelocationInfo> &&RelInfo);
 
   /// Target - Wrapper for Target specific information.
   ///
@@ -69,9 +88,9 @@ namespace llvm {
   public:
     friend struct TargetRegistry;
 
-    typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+    typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
 
-    typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T,
+    typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
                                             StringRef TT);
     typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
                                                     Reloc::Model RM,
@@ -91,52 +110,63 @@ namespace llvm {
                                                   Reloc::Model RM,
                                                   CodeModel::Model CM,
                                                   CodeGenOpt::Level OL);
-    typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
-                                            MCStreamer &Streamer);
-    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT);
-    typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T,
-                                                  const MCRegisterInfo &MRI,
-                                                  const MCAsmInfo &MAI);
-    typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
-                                                    MCAsmParser &P);
+    // If it weren't for layering issues (this header is in llvm/Support, but
+    // depends on MC?) this should take the Streamer by value rather than rvalue
+    // reference.
+    typedef AsmPrinter *(*AsmPrinterCtorTy)(
+        TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
+    typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
+                                                const MCRegisterInfo &MRI,
+                                                StringRef TT,
+                                                StringRef CPU);
+    typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
+        MCSubtargetInfo &STI,
+        MCAsmParser &P,
+        const MCInstrInfo &MII,
+        const MCTargetOptions &Options);
     typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
-                                                    const MCSubtargetInfo &STI);
-    typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
+                                                    const MCSubtargetInfo &STI,
+                                                    MCContext &Ctx);
+    typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Triple &T,
                                                   unsigned SyntaxVariant,
                                                   const MCAsmInfo &MAI,
                                                   const MCInstrInfo &MII,
-                                                  const MCRegisterInfo &MRI,
-                                                  const MCSubtargetInfo &STI);
+                                                  const MCRegisterInfo &MRI);
     typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
-                                                  const MCSubtargetInfo &STI,
+                                                  const MCRegisterInfo &MRI,
                                                   MCContext &Ctx);
-    typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
-                                                  StringRef TT,
-                                                  MCContext &Ctx,
-                                                  MCAsmBackend &TAB,
-                                                  raw_ostream &_OS,
-                                                  MCCodeEmitter *_Emitter,
-                                                  bool RelaxAll,
-                                                  bool NoExecStack);
-    typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
-                                             formatted_raw_ostream &OS,
-                                             bool isVerboseAsm,
-                                             bool useLoc,
-                                             bool useCFI,
-                                             bool useDwarfDirectory,
-                                             MCInstPrinter *InstPrint,
-                                             MCCodeEmitter *CE,
-                                             MCAsmBackend *TAB,
-                                             bool ShowInst);
+    typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx,
+                                             MCAsmBackend &TAB,
+                                             raw_pwrite_stream &OS,
+                                             MCCodeEmitter *Emitter,
+                                             bool RelaxAll);
+    typedef MCStreamer *(*MachOStreamerCtorTy)(
+        MCContext &Ctx, MCAsmBackend &TAB, raw_pwrite_stream &OS,
+        MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd);
+    typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
+                                              raw_pwrite_stream &OS,
+                                              MCCodeEmitter *Emitter,
+                                              bool RelaxAll);
+    typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
+    typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
+        MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
+        bool IsVerboseAsm);
+    typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)(
+        MCStreamer &S, const MCSubtargetInfo &STI);
+    typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
+                                                        MCContext &Ctx);
+    typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
+        StringRef TT, LLVMOpInfoCallback GetOpInfo,
+        LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
+        std::unique_ptr<MCRelocationInfo> &&RelInfo);
 
   private:
     /// Next - The next registered target in the linked list, maintained by the
     /// TargetRegistry.
     Target *Next;
 
-    /// TripleMatchQualityFn - The target function for rating the match quality
-    /// of a triple.
-    TripleMatchQualityFnTy TripleMatchQualityFn;
+    /// The target function for checking if an architecture is supported.
+    ArchMatchFnTy ArchMatchFn;
 
     /// Name - The target name.
     const char *Name;
@@ -179,10 +209,6 @@ namespace llvm {
     /// MCAsmBackend, if registered.
     MCAsmBackendCtorTy MCAsmBackendCtorFn;
 
-    /// MCAsmLexerCtorFn - Construction function for this target's
-    /// MCTargetAsmLexer, if registered.
-    MCAsmLexerCtorTy MCAsmLexerCtorFn;
-
     /// MCAsmParserCtorFn - Construction function for this target's
     /// MCTargetAsmParser, if registered.
     MCAsmParserCtorTy MCAsmParserCtorFn;
@@ -203,16 +229,37 @@ namespace llvm {
     /// CodeEmitter, if registered.
     MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
 
-    /// MCObjectStreamerCtorFn - Construction function for this target's
-    /// MCObjectStreamer, if registered.
-    MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
+    // Construction functions for the various object formats, if registered.
+    COFFStreamerCtorTy COFFStreamerCtorFn;
+    MachOStreamerCtorTy MachOStreamerCtorFn;
+    ELFStreamerCtorTy ELFStreamerCtorFn;
+
+    /// Construction function for this target's null TargetStreamer, if
+    /// registered (default = nullptr).
+    NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
 
-    /// AsmStreamerCtorFn - Construction function for this target's
-    /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
-    AsmStreamerCtorTy AsmStreamerCtorFn;
+    /// Construction function for this target's asm TargetStreamer, if
+    /// registered (default = nullptr).
+    AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn;
+
+    /// Construction function for this target's obj TargetStreamer, if
+    /// registered (default = nullptr).
+    ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn;
+
+    /// MCRelocationInfoCtorFn - Construction function for this target's
+    /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
+    MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
+
+    /// MCSymbolizerCtorFn - Construction function for this target's
+    /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
+    MCSymbolizerCtorTy MCSymbolizerCtorFn;
 
   public:
-    Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {}
+    Target()
+        : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
+          ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
+          AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
+          MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
 
     /// @name Target Information
     /// @{
@@ -234,34 +281,10 @@ namespace llvm {
     bool hasJIT() const { return HasJIT; }
 
     /// hasTargetMachine - Check if this target supports code generation.
-    bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
+    bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
 
     /// hasMCAsmBackend - Check if this target supports .o generation.
-    bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
-
-    /// hasMCAsmLexer - Check if this target supports .s lexing.
-    bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; }
-
-    /// hasAsmParser - Check if this target supports .s parsing.
-    bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; }
-
-    /// hasAsmPrinter - Check if this target supports .s printing.
-    bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
-
-    /// hasMCDisassembler - Check if this target has a disassembler.
-    bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
-
-    /// hasMCInstPrinter - Check if this target has an instruction printer.
-    bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
-
-    /// hasMCCodeEmitter - Check if this target supports instruction encoding.
-    bool hasMCCodeEmitter() const { return MCCodeEmitterCtorFn != 0; }
-
-    /// hasMCObjectStreamer - Check if this target supports streaming to files.
-    bool hasMCObjectStreamer() const { return MCObjectStreamerCtorFn != 0; }
-
-    /// hasAsmStreamer - Check if this target supports streaming to files.
-    bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; }
+    bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
 
     /// @}
     /// @name Feature Constructors
@@ -270,14 +293,15 @@ namespace llvm {
     /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
     /// target triple.
     ///
-    /// \arg Triple - This argument is used to determine the target machine
+    /// \param Triple This argument is used to determine the target machine
     /// feature set; it should always be provided. Generally this should be
     /// either the target triple from the module, or the target triple of the
     /// host if that does not exist.
-    MCAsmInfo *createMCAsmInfo(StringRef Triple) const {
+    MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
+                               StringRef Triple) const {
       if (!MCAsmInfoCtorFn)
-        return 0;
-      return MCAsmInfoCtorFn(*this, Triple);
+        return nullptr;
+      return MCAsmInfoCtorFn(MRI, Triple);
     }
 
     /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
@@ -286,7 +310,7 @@ namespace llvm {
                                        CodeModel::Model CM,
                                        CodeGenOpt::Level OL) const {
       if (!MCCodeGenInfoCtorFn)
-        return 0;
+        return nullptr;
       return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
     }
 
@@ -294,7 +318,7 @@ namespace llvm {
     ///
     MCInstrInfo *createMCInstrInfo() const {
       if (!MCInstrInfoCtorFn)
-        return 0;
+        return nullptr;
       return MCInstrInfoCtorFn();
     }
 
@@ -302,7 +326,7 @@ namespace llvm {
     ///
     MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
       if (!MCInstrAnalysisCtorFn)
-        return 0;
+        return nullptr;
       return MCInstrAnalysisCtorFn(Info);
     }
 
@@ -310,30 +334,30 @@ namespace llvm {
     ///
     MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
       if (!MCRegInfoCtorFn)
-        return 0;
+        return nullptr;
       return MCRegInfoCtorFn(Triple);
     }
 
     /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
     ///
-    /// \arg Triple - This argument is used to determine the target machine
+    /// \param Triple This argument is used to determine the target machine
     /// feature set; it should always be provided. Generally this should be
     /// either the target triple from the module, or the target triple of the
     /// host if that does not exist.
-    /// \arg CPU - This specifies the name of the target CPU.
-    /// \arg Features - This specifies the string representation of the
+    /// \param CPU This specifies the name of the target CPU.
+    /// \param Features This specifies the string representation of the
     /// additional target features.
     MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
                                            StringRef Features) const {
       if (!MCSubtargetInfoCtorFn)
-        return 0;
+        return nullptr;
       return MCSubtargetInfoCtorFn(Triple, CPU, Features);
     }
 
     /// createTargetMachine - Create a target specific machine implementation
-    /// for the specified \arg Triple.
+    /// for the specified \p Triple.
     ///
-    /// \arg Triple - This argument is used to determine the target machine
+    /// \param Triple This argument is used to determine the target machine
     /// feature set; it should always be provided. Generally this should be
     /// either the target triple from the module, or the target triple of the
     /// host if that does not exist.
@@ -343,110 +367,175 @@ namespace llvm {
                              CodeModel::Model CM = CodeModel::Default,
                              CodeGenOpt::Level OL = CodeGenOpt::Default) const {
       if (!TargetMachineCtorFn)
-        return 0;
+        return nullptr;
       return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
                                  RM, CM, OL);
     }
 
     /// createMCAsmBackend - Create a target specific assembly parser.
     ///
-    /// \arg Triple - The target triple string.
-    /// \arg Backend - The target independent assembler object.
-    MCAsmBackend *createMCAsmBackend(StringRef Triple) const {
+    /// \param Triple The target triple string.
+    MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
+                                     StringRef Triple, StringRef CPU) const {
       if (!MCAsmBackendCtorFn)
-        return 0;
-      return MCAsmBackendCtorFn(*this, Triple);
-    }
-
-    /// createMCAsmLexer - Create a target specific assembly lexer.
-    ///
-    MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI,
-                                       const MCAsmInfo &MAI) const {
-      if (!MCAsmLexerCtorFn)
-        return 0;
-      return MCAsmLexerCtorFn(*this, MRI, MAI);
+        return nullptr;
+      return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
     }
 
     /// createMCAsmParser - Create a target specific assembly parser.
     ///
-    /// \arg Parser - The target independent parser implementation to use for
+    /// \param Parser The target independent parser implementation to use for
     /// parsing and lexing.
-    MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
-                                         MCAsmParser &Parser) const {
+    MCTargetAsmParser *createMCAsmParser(
+        MCSubtargetInfo &STI,
+        MCAsmParser &Parser,
+        const MCInstrInfo &MII,
+        const MCTargetOptions &Options) const {
       if (!MCAsmParserCtorFn)
-        return 0;
-      return MCAsmParserCtorFn(STI, Parser);
+        return nullptr;
+      return MCAsmParserCtorFn(STI, Parser, MII, Options);
     }
 
     /// createAsmPrinter - Create a target specific assembly printer pass.  This
     /// takes ownership of the MCStreamer object.
-    AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
+    AsmPrinter *createAsmPrinter(TargetMachine &TM,
+                                 std::unique_ptr<MCStreamer> &&Streamer) const {
       if (!AsmPrinterCtorFn)
-        return 0;
-      return AsmPrinterCtorFn(TM, Streamer);
+        return nullptr;
+      return AsmPrinterCtorFn(TM, std::move(Streamer));
     }
 
-    MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const {
+    MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
+                                         MCContext &Ctx) const {
       if (!MCDisassemblerCtorFn)
-        return 0;
-      return MCDisassemblerCtorFn(*this, STI);
+        return nullptr;
+      return MCDisassemblerCtorFn(*this, STI, Ctx);
     }
 
-    MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
+    MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant,
                                        const MCAsmInfo &MAI,
                                        const MCInstrInfo &MII,
-                                       const MCRegisterInfo &MRI,
-                                       const MCSubtargetInfo &STI) const {
+                                       const MCRegisterInfo &MRI) const {
       if (!MCInstPrinterCtorFn)
-        return 0;
-      return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
+        return nullptr;
+      return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
     }
 
 
     /// createMCCodeEmitter - Create a target specific code emitter.
     MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
-                                       const MCSubtargetInfo &STI,
+                                       const MCRegisterInfo &MRI,
                                        MCContext &Ctx) const {
       if (!MCCodeEmitterCtorFn)
-        return 0;
-      return MCCodeEmitterCtorFn(II, STI, Ctx);
+        return nullptr;
+      return MCCodeEmitterCtorFn(II, MRI, Ctx);
     }
 
-    /// createMCObjectStreamer - Create a target specific MCStreamer.
+    /// Create a target specific MCStreamer.
     ///
-    /// \arg TT - The target triple.
-    /// \arg Ctx - The target context.
-    /// \arg TAB - The target assembler backend object. Takes ownership.
-    /// \arg _OS - The stream object.
-    /// \arg _Emitter - The target independent assembler object.Takes ownership.
-    /// \arg RelaxAll - Relax all fixups?
-    /// \arg NoExecStack - Mark file as not needing a executable stack.
-    MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
-                                       MCAsmBackend &TAB,
-                                       raw_ostream &_OS,
-                                       MCCodeEmitter *_Emitter,
+    /// \param T The target triple.
+    /// \param Ctx The target context.
+    /// \param TAB The target assembler backend object. Takes ownership.
+    /// \param OS The stream object.
+    /// \param Emitter The target independent assembler object.Takes ownership.
+    /// \param RelaxAll Relax all fixups?
+    MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
+                                       MCAsmBackend &TAB, raw_pwrite_stream &OS,
+                                       MCCodeEmitter *Emitter,
+                                       const MCSubtargetInfo &STI,
                                        bool RelaxAll,
-                                       bool NoExecStack) const {
-      if (!MCObjectStreamerCtorFn)
-        return 0;
-      return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter,
-                                    RelaxAll, NoExecStack);
+                                       bool DWARFMustBeAtTheEnd) const {
+      MCStreamer *S;
+      switch (T.getObjectFormat()) {
+      default:
+        llvm_unreachable("Unknown object format");
+      case Triple::COFF:
+        assert(T.isOSWindows() && "only Windows COFF is supported");
+        S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
+        break;
+      case Triple::MachO:
+        if (MachOStreamerCtorFn)
+          S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
+                                  DWARFMustBeAtTheEnd);
+        else
+          S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+                                  DWARFMustBeAtTheEnd);
+        break;
+      case Triple::ELF:
+        if (ELFStreamerCtorFn)
+          S = ELFStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll);
+        else
+          S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+        break;
+      }
+      if (ObjectTargetStreamerCtorFn)
+        ObjectTargetStreamerCtorFn(*S, STI);
+      return S;
     }
 
-    /// createAsmStreamer - Create a target specific MCStreamer.
     MCStreamer *createAsmStreamer(MCContext &Ctx,
-                                  formatted_raw_ostream &OS,
-                                  bool isVerboseAsm,
-                                  bool useLoc,
-                                  bool useCFI,
-                                  bool useDwarfDirectory,
-                                  MCInstPrinter *InstPrint,
-                                  MCCodeEmitter *CE,
-                                  MCAsmBackend *TAB,
-                                  bool ShowInst) const {
-      // AsmStreamerCtorFn is default to llvm::createAsmStreamer
-      return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
-                               useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
+                                  std::unique_ptr<formatted_raw_ostream> OS,
+                                  bool IsVerboseAsm, bool UseDwarfDirectory,
+                                  MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+                                  MCAsmBackend *TAB, bool ShowInst) const {
+      formatted_raw_ostream &OSRef = *OS;
+      MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IsVerboseAsm,
+                                              UseDwarfDirectory, InstPrint, CE,
+                                              TAB, ShowInst);
+      createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm);
+      return S;
+    }
+
+    MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
+                                              formatted_raw_ostream &OS,
+                                              MCInstPrinter *InstPrint,
+                                              bool IsVerboseAsm) const {
+      if (AsmTargetStreamerCtorFn)
+        return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
+      return nullptr;
+    }
+
+    MCStreamer *createNullStreamer(MCContext &Ctx) const {
+      MCStreamer *S = llvm::createNullStreamer(Ctx);
+      createNullTargetStreamer(*S);
+      return S;
+    }
+
+    MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
+      if (NullTargetStreamerCtorFn)
+        return NullTargetStreamerCtorFn(S);
+      return nullptr;
+    }
+
+    /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
+    ///
+    /// \param TT The target triple.
+    /// \param Ctx The target context.
+    MCRelocationInfo *
+      createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
+      MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
+                                      ? MCRelocationInfoCtorFn
+                                      : llvm::createMCRelocationInfo;
+      return Fn(TT, Ctx);
+    }
+
+    /// createMCSymbolizer - Create a target specific MCSymbolizer.
+    ///
+    /// \param TT The target triple.
+    /// \param GetOpInfo The function to get the symbolic information for operands.
+    /// \param SymbolLookUp The function to lookup a symbol name.
+    /// \param DisInfo The pointer to the block of symbolic information for above call
+    /// back.
+    /// \param Ctx The target context.
+    /// \param RelInfo The relocation information for this target. Takes ownership.
+    MCSymbolizer *
+    createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+                       LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
+                       MCContext *Ctx,
+                       std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
+      MCSymbolizerCtorTy Fn =
+          MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
+      return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
     }
 
     /// @}
@@ -454,13 +543,19 @@ namespace llvm {
 
   /// TargetRegistry - Generic interface to target specific features.
   struct TargetRegistry {
-    class iterator {
+    // FIXME: Make this a namespace, probably just move all the Register*
+    // functions into Target (currently they all just set members on the Target
+    // anyway, and Target friends this class so those functions can...
+    // function).
+    TargetRegistry() = delete;
+
+    class iterator
+        : public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> {
       const Target *Current;
       explicit iterator(Target *T) : Current(T) {}
       friend struct TargetRegistry;
     public:
-      iterator(const iterator &I) : Current(I.Current) {}
-      iterator() : Current(0) {}
+      iterator() : Current(nullptr) {}
 
       bool operator==(const iterator &x) const {
         return Current == x.Current;
@@ -498,9 +593,7 @@ namespace llvm {
     /// @name Registry Access
     /// @{
 
-    static iterator begin();
-
-    static iterator end() { return iterator(); }
+    static iterator_range<iterator> targets();
 
     /// lookupTarget - Lookup a target based on a target triple.
     ///
@@ -510,12 +603,20 @@ namespace llvm {
     static const Target *lookupTarget(const std::string &Triple,
                                       std::string &Error);
 
-    /// getClosestTargetForJIT - Pick the best target that is compatible with
-    /// the current host.  If no close target can be found, this returns null
-    /// and sets the Error string to a reason.
+    /// lookupTarget - Lookup a target based on an architecture name
+    /// and a target triple.  If the architecture name is non-empty,
+    /// then the lookup is done by architecture.  Otherwise, the target
+    /// triple is used.
     ///
-    /// Maintained for compatibility through 2.6.
-    static const Target *getClosestTargetForJIT(std::string &Error);
+    /// \param ArchName - The architecture to use for finding a target.
+    /// \param TheTriple - The triple to use for finding a target.  The
+    /// triple is updated with canonical architecture name if a lookup
+    /// by architecture is done.
+    /// \param Error - On failure, an error string describing why no target was
+    /// found.
+    static const Target *lookupTarget(const std::string &ArchName,
+                                      Triple &TheTriple,
+                                      std::string &Error);
 
     /// @}
     /// @name Target Registration
@@ -532,14 +633,13 @@ namespace llvm {
     /// @param Name - The target name. This should be a static string.
     /// @param ShortDesc - A short target description. This should be a static
     /// string.
-    /// @param TQualityFn - The triple match quality computation function for
-    /// this target.
+    /// @param ArchMatchFn - The arch match checking function for this target.
     /// @param HasJIT - Whether the target supports JIT code
     /// generation.
     static void RegisterTarget(Target &T,
                                const char *Name,
                                const char *ShortDesc,
-                               Target::TripleMatchQualityFnTy TQualityFn,
+                               Target::ArchMatchFnTy ArchMatchFn,
                                bool HasJIT = false);
 
     /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
@@ -552,9 +652,7 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct a MCAsmInfo for the target.
     static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCAsmInfoCtorFn)
-        T.MCAsmInfoCtorFn = Fn;
+      T.MCAsmInfoCtorFn = Fn;
     }
 
     /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
@@ -568,9 +666,7 @@ namespace llvm {
     /// @param Fn - A function to construct a MCCodeGenInfo for the target.
     static void RegisterMCCodeGenInfo(Target &T,
                                      Target::MCCodeGenInfoCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCCodeGenInfoCtorFn)
-        T.MCCodeGenInfoCtorFn = Fn;
+      T.MCCodeGenInfoCtorFn = Fn;
     }
 
     /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
@@ -583,18 +679,14 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct a MCInstrInfo for the target.
     static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCInstrInfoCtorFn)
-        T.MCInstrInfoCtorFn = Fn;
+      T.MCInstrInfoCtorFn = Fn;
     }
 
     /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
     /// the given target.
     static void RegisterMCInstrAnalysis(Target &T,
                                         Target::MCInstrAnalysisCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCInstrAnalysisCtorFn)
-        T.MCInstrAnalysisCtorFn = Fn;
+      T.MCInstrAnalysisCtorFn = Fn;
     }
 
     /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
@@ -607,9 +699,7 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct a MCRegisterInfo for the target.
     static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCRegInfoCtorFn)
-        T.MCRegInfoCtorFn = Fn;
+      T.MCRegInfoCtorFn = Fn;
     }
 
     /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
@@ -623,9 +713,7 @@ namespace llvm {
     /// @param Fn - A function to construct a MCSubtargetInfo for the target.
     static void RegisterMCSubtargetInfo(Target &T,
                                         Target::MCSubtargetInfoCtorFnTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.MCSubtargetInfoCtorFn)
-        T.MCSubtargetInfoCtorFn = Fn;
+      T.MCSubtargetInfoCtorFn = Fn;
     }
 
     /// RegisterTargetMachine - Register a TargetMachine implementation for the
@@ -639,9 +727,7 @@ namespace llvm {
     /// @param Fn - A function to construct a TargetMachine for the target.
     static void RegisterTargetMachine(Target &T,
                                       Target::TargetMachineCtorTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.TargetMachineCtorFn)
-        T.TargetMachineCtorFn = Fn;
+      T.TargetMachineCtorFn = Fn;
     }
 
     /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
@@ -654,22 +740,7 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct an AsmBackend for the target.
     static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
-      if (!T.MCAsmBackendCtorFn)
-        T.MCAsmBackendCtorFn = Fn;
-    }
-
-    /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the
-    /// given target.
-    ///
-    /// Clients are responsible for ensuring that registration doesn't occur
-    /// while another thread is attempting to access the registry. Typically
-    /// this is done by initializing all targets at program startup.
-    ///
-    /// @param T - The target being registered.
-    /// @param Fn - A function to construct an MCAsmLexer for the target.
-    static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) {
-      if (!T.MCAsmLexerCtorFn)
-        T.MCAsmLexerCtorFn = Fn;
+      T.MCAsmBackendCtorFn = Fn;
     }
 
     /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
@@ -682,8 +753,7 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct an MCTargetAsmParser for the target.
     static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
-      if (!T.MCAsmParserCtorFn)
-        T.MCAsmParserCtorFn = Fn;
+      T.MCAsmParserCtorFn = Fn;
     }
 
     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
@@ -696,9 +766,7 @@ namespace llvm {
     /// @param T - The target being registered.
     /// @param Fn - A function to construct an AsmPrinter for the target.
     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
-      // Ignore duplicate registration.
-      if (!T.AsmPrinterCtorFn)
-        T.AsmPrinterCtorFn = Fn;
+      T.AsmPrinterCtorFn = Fn;
     }
 
     /// RegisterMCDisassembler - Register a MCDisassembler implementation for
@@ -712,8 +780,7 @@ namespace llvm {
     /// @param Fn - A function to construct an MCDisassembler for the target.
     static void RegisterMCDisassembler(Target &T,
                                        Target::MCDisassemblerCtorTy Fn) {
-      if (!T.MCDisassemblerCtorFn)
-        T.MCDisassemblerCtorFn = Fn;
+      T.MCDisassemblerCtorFn = Fn;
     }
 
     /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
@@ -727,8 +794,7 @@ namespace llvm {
     /// @param Fn - A function to construct an MCInstPrinter for the target.
     static void RegisterMCInstPrinter(Target &T,
                                       Target::MCInstPrinterCtorTy Fn) {
-      if (!T.MCInstPrinterCtorFn)
-        T.MCInstPrinterCtorFn = Fn;
+      T.MCInstPrinterCtorFn = Fn;
     }
 
     /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
@@ -742,11 +808,39 @@ namespace llvm {
     /// @param Fn - A function to construct an MCCodeEmitter for the target.
     static void RegisterMCCodeEmitter(Target &T,
                                       Target::MCCodeEmitterCtorTy Fn) {
-      if (!T.MCCodeEmitterCtorFn)
-        T.MCCodeEmitterCtorFn = Fn;
+      T.MCCodeEmitterCtorFn = Fn;
     }
 
-    /// RegisterMCObjectStreamer - Register a object code MCStreamer
+    static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
+      T.COFFStreamerCtorFn = Fn;
+    }
+
+    static void RegisterMachOStreamer(Target &T,
+                                      Target::MachOStreamerCtorTy Fn) {
+      T.MachOStreamerCtorFn = Fn;
+    }
+
+    static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
+      T.ELFStreamerCtorFn = Fn;
+    }
+
+    static void
+    RegisterNullTargetStreamer(Target &T, Target::NullTargetStreamerCtorTy Fn) {
+      T.NullTargetStreamerCtorFn = Fn;
+    }
+
+    static void RegisterAsmTargetStreamer(Target &T,
+                                          Target::AsmTargetStreamerCtorTy Fn) {
+      T.AsmTargetStreamerCtorFn = Fn;
+    }
+
+    static void
+    RegisterObjectTargetStreamer(Target &T,
+                                 Target::ObjectTargetStreamerCtorTy Fn) {
+      T.ObjectTargetStreamerCtorFn = Fn;
+    }
+
+    /// RegisterMCRelocationInfo - Register an MCRelocationInfo
     /// implementation for the given target.
     ///
     /// Clients are responsible for ensuring that registration doesn't occur
@@ -754,25 +848,24 @@ namespace llvm {
     /// this is done by initializing all targets at program startup.
     ///
     /// @param T - The target being registered.
-    /// @param Fn - A function to construct an MCStreamer for the target.
-    static void RegisterMCObjectStreamer(Target &T,
-                                         Target::MCObjectStreamerCtorTy Fn) {
-      if (!T.MCObjectStreamerCtorFn)
-        T.MCObjectStreamerCtorFn = Fn;
+    /// @param Fn - A function to construct an MCRelocationInfo for the target.
+    static void RegisterMCRelocationInfo(Target &T,
+                                         Target::MCRelocationInfoCtorTy Fn) {
+      T.MCRelocationInfoCtorFn = Fn;
     }
 
-    /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
-    /// for the given target.
+    /// RegisterMCSymbolizer - Register an MCSymbolizer
+    /// implementation for the given target.
     ///
     /// Clients are responsible for ensuring that registration doesn't occur
     /// while another thread is attempting to access the registry. Typically
     /// this is done by initializing all targets at program startup.
     ///
     /// @param T - The target being registered.
-    /// @param Fn - A function to construct an MCStreamer for the target.
-    static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
-      if (T.AsmStreamerCtorFn == createAsmStreamer)
-        T.AsmStreamerCtorFn = Fn;
+    /// @param Fn - A function to construct an MCSymbolizer for the target.
+    static void RegisterMCSymbolizer(Target &T,
+                                     Target::MCSymbolizerCtorTy Fn) {
+      T.MCSymbolizerCtorFn = Fn;
     }
 
     /// @}
@@ -794,15 +887,11 @@ namespace llvm {
            bool HasJIT = false>
   struct RegisterTarget {
     RegisterTarget(Target &T, const char *Name, const char *Desc) {
-      TargetRegistry::RegisterTarget(T, Name, Desc,
-                                     &getTripleMatchQuality,
-                                     HasJIT);
+      TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
     }
 
-    static unsigned getTripleMatchQuality(const std::string &TT) {
-      if (Triple(TT).getArch() == TargetArchType)
-        return 20;
-      return 0;
+    static bool getArchMatch(Triple::ArchType Arch) {
+      return Arch == TargetArchType;
     }
   };
 
@@ -820,8 +909,8 @@ namespace llvm {
       TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
     }
   private:
-    static MCAsmInfo *Allocator(const Target &T, StringRef TT) {
-      return new MCAsmInfoImpl(T, TT);
+    static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
+      return new MCAsmInfoImpl(TT);
     }
 
   };
@@ -854,8 +943,9 @@ namespace llvm {
       TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
     }
   private:
-    static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model RM,
-                                    CodeModel::Model CM, CodeGenOpt::Level OL) {
+    static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
+                                    CodeModel::Model /*CM*/,
+                                    CodeGenOpt::Level /*OL*/) {
       return new MCCodeGenInfoImpl();
     }
   };
@@ -954,7 +1044,7 @@ namespace llvm {
       TargetRegistry::RegisterMCRegInfo(T, &Allocator);
     }
   private:
-    static MCRegisterInfo *Allocator(StringRef TT) {
+    static MCRegisterInfo *Allocator(StringRef /*TT*/) {
       return new MCRegisterInfoImpl();
     }
   };
@@ -987,8 +1077,8 @@ namespace llvm {
       TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
     }
   private:
-    static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU,
-                                      StringRef FS) {
+    static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
+                                      StringRef /*FS*/) {
       return new MCSubtargetInfoImpl();
     }
   };
@@ -1046,30 +1136,10 @@ namespace llvm {
     }
 
   private:
-    static MCAsmBackend *Allocator(const Target &T, StringRef Triple) {
-      return new MCAsmBackendImpl(T, Triple);
-    }
-  };
-
-  /// RegisterMCAsmLexer - Helper template for registering a target specific
-  /// assembly lexer, for use in the target machine initialization
-  /// function. Usage:
-  ///
-  /// extern "C" void LLVMInitializeFooMCAsmLexer() {
-  ///   extern Target TheFooTarget;
-  ///   RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget);
-  /// }
-  template<class MCAsmLexerImpl>
-  struct RegisterMCAsmLexer {
-    RegisterMCAsmLexer(Target &T) {
-      TargetRegistry::RegisterMCAsmLexer(T, &Allocator);
-    }
-
-  private:
-    static MCTargetAsmLexer *Allocator(const Target &T,
-                                       const MCRegisterInfo &MRI,
-                                       const MCAsmInfo &MAI) {
-      return new MCAsmLexerImpl(T, MRI, MAI);
+    static MCAsmBackend *Allocator(const Target &T,
+                                   const MCRegisterInfo &MRI,
+                                   StringRef Triple, StringRef CPU) {
+      return new MCAsmBackendImpl(T, MRI, Triple, CPU);
     }
   };
 
@@ -1088,8 +1158,10 @@ namespace llvm {
     }
 
   private:
-    static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) {
-      return new MCAsmParserImpl(STI, P);
+    static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
+                                        const MCInstrInfo &MII,
+                                        const MCTargetOptions &Options) {
+      return new MCAsmParserImpl(STI, P, MII, Options);
     }
   };
 
@@ -1108,8 +1180,9 @@ namespace llvm {
     }
 
   private:
-    static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
-      return new AsmPrinterImpl(TM, Streamer);
+    static AsmPrinter *Allocator(TargetMachine &TM,
+                                 std::unique_ptr<MCStreamer> &&Streamer) {
+      return new AsmPrinterImpl(TM, std::move(Streamer));
     }
   };
 
@@ -1128,9 +1201,9 @@ namespace llvm {
     }
 
   private:
-    static MCCodeEmitter *Allocator(const MCInstrInfo &II,
-                                    const MCSubtargetInfo &STI,
-                                    MCContext &Ctx) {
+    static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
+                                    const MCRegisterInfo & /*MRI*/,
+                                    MCContext & /*Ctx*/) {
       return new MCCodeEmitterImpl();
     }
   };