Reapply part of r237975, "Fix Clang -Wmissing-override warning", except for DIContext...
[oota-llvm.git] / include / llvm / Support / TargetRegistry.h
index 5d5b86a6a2aeb634ed09881db9d19e1d96d910de..afcdbb85f853b0d4c31a761d9ae3444f2660085a 100644 (file)
 #include "llvm-c/Disassembler.h"
 #include "llvm/ADT/Triple.h"
 #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;
@@ -46,24 +46,35 @@ namespace llvm {
   class MCRelocationInfo;
   class MCTargetAsmParser;
   class MCTargetOptions;
+  class MCTargetStreamer;
   class TargetMachine;
   class TargetOptions;
   class raw_ostream;
+  class raw_pwrite_stream;
   class formatted_raw_ostream;
 
   MCStreamer *createNullStreamer(MCContext &Ctx);
-  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+  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,
-                                   MCRelocationInfo *RelInfo);
+                                   void *DisInfo, MCContext *Ctx,
+                                   std::unique_ptr<MCRelocationInfo> &&RelInfo);
 
   /// Target - Wrapper for Target specific information.
   ///
@@ -99,8 +110,11 @@ namespace llvm {
                                                   Reloc::Model RM,
                                                   CodeModel::Model CM,
                                                   CodeGenOpt::Level OL);
-    typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
-                                            MCStreamer &Streamer);
+    // 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,
@@ -113,42 +127,38 @@ namespace llvm {
     typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
                                                     const MCSubtargetInfo &STI,
                                                     MCContext &Ctx);
-    typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
+    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 MCRegisterInfo &MRI,
-                                                  const MCSubtargetInfo &STI,
                                                   MCContext &Ctx);
-    typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
-                                                  StringRef TT,
-                                                  MCContext &Ctx,
-                                                  MCAsmBackend &TAB,
-                                                  raw_ostream &_OS,
-                                                  MCCodeEmitter *_Emitter,
-                                                  const MCSubtargetInfo &STI,
-                                                  bool RelaxAll,
-                                                  bool NoExecStack);
-    typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
-                                             formatted_raw_ostream &OS,
-                                             bool isVerboseAsm,
-                                             bool useDwarfDirectory,
-                                             MCInstPrinter *InstPrint,
-                                             MCCodeEmitter *CE,
-                                             MCAsmBackend *TAB,
-                                             bool ShowInst);
-    typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
+    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,
-                                   MCRelocationInfo *RelInfo);
+    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
@@ -219,17 +229,22 @@ 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;
 
-    /// AsmStreamerCtorFn - Construction function for this target's
-    /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
-    AsmStreamerCtorTy AsmStreamerCtorFn;
+    /// Construction function for this target's null TargetStreamer, if
+    /// registered (default = nullptr).
+    NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
 
-    /// Construction function for this target's NullStreamer, if registered
-    /// (default = llvm::createNullStreamer).
-    NullStreamerCtorTy NullStreamerCtorFn;
+    /// 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)
@@ -241,7 +256,9 @@ namespace llvm {
 
   public:
     Target()
-        : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
+        : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
+          ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
+          AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
           MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
 
     /// @name Target Information
@@ -381,10 +398,11 @@ namespace llvm {
 
     /// 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 nullptr;
-      return AsmPrinterCtorFn(TM, Streamer);
+      return AsmPrinterCtorFn(TM, std::move(Streamer));
     }
 
     MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
@@ -394,69 +412,99 @@ namespace llvm {
       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 nullptr;
-      return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
+      return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI);
     }
 
 
     /// createMCCodeEmitter - Create a target specific code emitter.
     MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
                                        const MCRegisterInfo &MRI,
-                                       const MCSubtargetInfo &STI,
                                        MCContext &Ctx) const {
       if (!MCCodeEmitterCtorFn)
         return nullptr;
-      return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
+      return MCCodeEmitterCtorFn(II, MRI, Ctx);
     }
 
-    /// createMCObjectStreamer - Create a target specific MCStreamer.
+    /// Create a target specific MCStreamer.
     ///
-    /// \param TT The target triple.
+    /// \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 OS The stream object.
+    /// \param Emitter The target independent assembler object.Takes ownership.
     /// \param RelaxAll Relax all fixups?
-    /// \param NoExecStack Mark file as not needing a executable stack.
-    MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
-                                       MCAsmBackend &TAB,
-                                       raw_ostream &_OS,
-                                       MCCodeEmitter *_Emitter,
+    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 nullptr;
-      return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
-                                    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 useDwarfDirectory,
-                                  MCInstPrinter *InstPrint,
-                                  MCCodeEmitter *CE,
-                                  MCAsmBackend *TAB,
-                                  bool ShowInst) const {
-      if (AsmStreamerCtorFn)
-        return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
-                                 InstPrint, CE, TAB, ShowInst);
-      return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, 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 {
-      if (NullStreamerCtorFn)
-        return NullStreamerCtorFn(Ctx);
-      return llvm::createNullStreamer(Ctx);
+      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.
@@ -482,12 +530,12 @@ namespace llvm {
     /// \param RelInfo The relocation information for this target. Takes ownership.
     MCSymbolizer *
     createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
-                       LLVMSymbolLookupCallback SymbolLookUp,
-                       void *DisInfo,
-                       MCContext *Ctx, MCRelocationInfo *RelInfo) const {
+                       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, RelInfo);
+      return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
     }
 
     /// @}
@@ -495,7 +543,14 @@ 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;
@@ -538,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.
     ///
@@ -758,35 +811,33 @@ namespace llvm {
       T.MCCodeEmitterCtorFn = Fn;
     }
 
-    /// RegisterMCObjectStreamer - Register a object code MCStreamer
-    /// 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 RegisterMCObjectStreamer(Target &T,
-                                         Target::MCObjectStreamerCtorTy Fn) {
-      T.MCObjectStreamerCtorFn = Fn;
+    static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
+      T.COFFStreamerCtorFn = Fn;
     }
 
-    /// RegisterAsmStreamer - Register an assembly MCStreamer 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) {
-      T.AsmStreamerCtorFn = 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 RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
-      T.NullStreamerCtorFn = Fn;
+    static void
+    RegisterObjectTargetStreamer(Target &T,
+                                 Target::ObjectTargetStreamerCtorTy Fn) {
+      T.ObjectTargetStreamerCtorFn = Fn;
     }
 
     /// RegisterMCRelocationInfo - Register an MCRelocationInfo
@@ -1129,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));
     }
   };
 
@@ -1149,10 +1201,9 @@ namespace llvm {
     }
 
   private:
-    static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
-                                    const MCRegisterInfo &/*MRI*/,
-                                    const MCSubtargetInfo &/*STI*/,
-                                    MCContext &/*Ctx*/) {
+    static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
+                                    const MCRegisterInfo & /*MRI*/,
+                                    MCContext & /*Ctx*/) {
       return new MCCodeEmitterImpl();
     }
   };