16fb882906c1140c75953c7cc91dd9389c7c94ae
[oota-llvm.git] / include / llvm / Support / TargetRegistry.h
1 //===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file exposes the TargetRegistry interface, which tools can use to access
11 // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
12 // which have been registered.
13 //
14 // Target specific class implementations should register themselves using the
15 // appropriate TargetRegistry interfaces.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_SUPPORT_TARGETREGISTRY_H
20 #define LLVM_SUPPORT_TARGETREGISTRY_H
21
22 #include "llvm-c/Disassembler.h"
23 #include "llvm/ADT/Triple.h"
24 #include "llvm/Support/CodeGen.h"
25 #include <cassert>
26 #include <memory>
27 #include <string>
28
29 namespace llvm {
30   class AsmPrinter;
31   class Module;
32   class MCAssembler;
33   class MCAsmBackend;
34   class MCAsmInfo;
35   class MCAsmParser;
36   class MCCodeEmitter;
37   class MCCodeGenInfo;
38   class MCContext;
39   class MCDisassembler;
40   class MCInstrAnalysis;
41   class MCInstPrinter;
42   class MCInstrInfo;
43   class MCRegisterInfo;
44   class MCStreamer;
45   class MCSubtargetInfo;
46   class MCSymbolizer;
47   class MCRelocationInfo;
48   class MCTargetAsmParser;
49   class MCTargetOptions;
50   class TargetMachine;
51   class TargetOptions;
52   class raw_ostream;
53   class formatted_raw_ostream;
54
55   MCStreamer *createNullStreamer(MCContext &Ctx);
56   MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
57                                 bool isVerboseAsm, bool useDwarfDirectory,
58                                 MCInstPrinter *InstPrint, MCCodeEmitter *CE,
59                                 MCAsmBackend *TAB, bool ShowInst);
60
61   MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
62
63   MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
64                                    LLVMSymbolLookupCallback SymbolLookUp,
65                                    void *DisInfo,
66                                    MCContext *Ctx,
67                                    MCRelocationInfo *RelInfo);
68
69   /// Target - Wrapper for Target specific information.
70   ///
71   /// For registration purposes, this is a POD type so that targets can be
72   /// registered without the use of static constructors.
73   ///
74   /// Targets should implement a single global instance of this class (which
75   /// will be zero initialized), and pass that instance to the TargetRegistry as
76   /// part of their initialization.
77   class Target {
78   public:
79     friend struct TargetRegistry;
80
81     typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
82
83     typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
84                                             StringRef TT);
85     typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
86                                                     Reloc::Model RM,
87                                                     CodeModel::Model CM,
88                                                     CodeGenOpt::Level OL);
89     typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
90     typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
91     typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
92     typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
93                                                         StringRef CPU,
94                                                         StringRef Features);
95     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
96                                                   StringRef TT,
97                                                   StringRef CPU,
98                                                   StringRef Features,
99                                                   const TargetOptions &Options,
100                                                   Reloc::Model RM,
101                                                   CodeModel::Model CM,
102                                                   CodeGenOpt::Level OL);
103     // If it weren't for layering issues (this header is in llvm/Support, but
104     // depends on MC?) this should take the Streamer by value rather than rvalue
105     // reference.
106     typedef AsmPrinter *(*AsmPrinterCtorTy)(
107         TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
108     typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
109                                                 const MCRegisterInfo &MRI,
110                                                 StringRef TT,
111                                                 StringRef CPU);
112     typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
113         MCSubtargetInfo &STI,
114         MCAsmParser &P,
115         const MCInstrInfo &MII,
116         const MCTargetOptions &Options);
117     typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
118                                                     const MCSubtargetInfo &STI,
119                                                     MCContext &Ctx);
120     typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
121                                                   unsigned SyntaxVariant,
122                                                   const MCAsmInfo &MAI,
123                                                   const MCInstrInfo &MII,
124                                                   const MCRegisterInfo &MRI,
125                                                   const MCSubtargetInfo &STI);
126     typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
127                                                   const MCRegisterInfo &MRI,
128                                                   const MCSubtargetInfo &STI,
129                                                   MCContext &Ctx);
130     typedef MCStreamer *(*MCObjectStreamerCtorTy)(
131         const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB,
132         raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI,
133         bool RelaxAll);
134     typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
135                                              formatted_raw_ostream &OS,
136                                              bool isVerboseAsm,
137                                              bool useDwarfDirectory,
138                                              MCInstPrinter *InstPrint,
139                                              MCCodeEmitter *CE,
140                                              MCAsmBackend *TAB,
141                                              bool ShowInst);
142     typedef MCStreamer *(*NullStreamerCtorTy)(MCContext &Ctx);
143     typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
144                                                         MCContext &Ctx);
145     typedef MCSymbolizer *(*MCSymbolizerCtorTy)(StringRef TT,
146                                    LLVMOpInfoCallback GetOpInfo,
147                                    LLVMSymbolLookupCallback SymbolLookUp,
148                                    void *DisInfo,
149                                    MCContext *Ctx,
150                                    MCRelocationInfo *RelInfo);
151
152   private:
153     /// Next - The next registered target in the linked list, maintained by the
154     /// TargetRegistry.
155     Target *Next;
156
157     /// The target function for checking if an architecture is supported.
158     ArchMatchFnTy ArchMatchFn;
159
160     /// Name - The target name.
161     const char *Name;
162
163     /// ShortDesc - A short description of the target.
164     const char *ShortDesc;
165
166     /// HasJIT - Whether this target supports the JIT.
167     bool HasJIT;
168
169     /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
170     /// registered.
171     MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
172
173     /// MCCodeGenInfoCtorFn - Constructor function for this target's
174     /// MCCodeGenInfo, if registered.
175     MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
176
177     /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
178     /// if registered.
179     MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
180
181     /// MCInstrAnalysisCtorFn - Constructor function for this target's
182     /// MCInstrAnalysis, if registered.
183     MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
184
185     /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
186     /// if registered.
187     MCRegInfoCtorFnTy MCRegInfoCtorFn;
188
189     /// MCSubtargetInfoCtorFn - Constructor function for this target's
190     /// MCSubtargetInfo, if registered.
191     MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
192
193     /// TargetMachineCtorFn - Construction function for this target's
194     /// TargetMachine, if registered.
195     TargetMachineCtorTy TargetMachineCtorFn;
196
197     /// MCAsmBackendCtorFn - Construction function for this target's
198     /// MCAsmBackend, if registered.
199     MCAsmBackendCtorTy MCAsmBackendCtorFn;
200
201     /// MCAsmParserCtorFn - Construction function for this target's
202     /// MCTargetAsmParser, if registered.
203     MCAsmParserCtorTy MCAsmParserCtorFn;
204
205     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
206     /// if registered.
207     AsmPrinterCtorTy AsmPrinterCtorFn;
208
209     /// MCDisassemblerCtorFn - Construction function for this target's
210     /// MCDisassembler, if registered.
211     MCDisassemblerCtorTy MCDisassemblerCtorFn;
212
213     /// MCInstPrinterCtorFn - Construction function for this target's
214     /// MCInstPrinter, if registered.
215     MCInstPrinterCtorTy MCInstPrinterCtorFn;
216
217     /// MCCodeEmitterCtorFn - Construction function for this target's
218     /// CodeEmitter, if registered.
219     MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
220
221     /// MCObjectStreamerCtorFn - Construction function for this target's
222     /// MCObjectStreamer, if registered.
223     MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
224
225     /// AsmStreamerCtorFn - Construction function for this target's
226     /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
227     AsmStreamerCtorTy AsmStreamerCtorFn;
228
229     /// Construction function for this target's NullStreamer, if registered
230     /// (default = llvm::createNullStreamer).
231     NullStreamerCtorTy NullStreamerCtorFn;
232
233     /// MCRelocationInfoCtorFn - Construction function for this target's
234     /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
235     MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
236
237     /// MCSymbolizerCtorFn - Construction function for this target's
238     /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
239     MCSymbolizerCtorTy MCSymbolizerCtorFn;
240
241   public:
242     Target()
243         : AsmStreamerCtorFn(nullptr), NullStreamerCtorFn(nullptr),
244           MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
245
246     /// @name Target Information
247     /// @{
248
249     // getNext - Return the next registered target.
250     const Target *getNext() const { return Next; }
251
252     /// getName - Get the target name.
253     const char *getName() const { return Name; }
254
255     /// getShortDescription - Get a short description of the target.
256     const char *getShortDescription() const { return ShortDesc; }
257
258     /// @}
259     /// @name Feature Predicates
260     /// @{
261
262     /// hasJIT - Check if this targets supports the just-in-time compilation.
263     bool hasJIT() const { return HasJIT; }
264
265     /// hasTargetMachine - Check if this target supports code generation.
266     bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
267
268     /// hasMCAsmBackend - Check if this target supports .o generation.
269     bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
270
271     /// @}
272     /// @name Feature Constructors
273     /// @{
274
275     /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
276     /// target triple.
277     ///
278     /// \param Triple This argument is used to determine the target machine
279     /// feature set; it should always be provided. Generally this should be
280     /// either the target triple from the module, or the target triple of the
281     /// host if that does not exist.
282     MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
283                                StringRef Triple) const {
284       if (!MCAsmInfoCtorFn)
285         return nullptr;
286       return MCAsmInfoCtorFn(MRI, Triple);
287     }
288
289     /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
290     ///
291     MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
292                                        CodeModel::Model CM,
293                                        CodeGenOpt::Level OL) const {
294       if (!MCCodeGenInfoCtorFn)
295         return nullptr;
296       return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
297     }
298
299     /// createMCInstrInfo - Create a MCInstrInfo implementation.
300     ///
301     MCInstrInfo *createMCInstrInfo() const {
302       if (!MCInstrInfoCtorFn)
303         return nullptr;
304       return MCInstrInfoCtorFn();
305     }
306
307     /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
308     ///
309     MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
310       if (!MCInstrAnalysisCtorFn)
311         return nullptr;
312       return MCInstrAnalysisCtorFn(Info);
313     }
314
315     /// createMCRegInfo - Create a MCRegisterInfo implementation.
316     ///
317     MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
318       if (!MCRegInfoCtorFn)
319         return nullptr;
320       return MCRegInfoCtorFn(Triple);
321     }
322
323     /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
324     ///
325     /// \param Triple This argument is used to determine the target machine
326     /// feature set; it should always be provided. Generally this should be
327     /// either the target triple from the module, or the target triple of the
328     /// host if that does not exist.
329     /// \param CPU This specifies the name of the target CPU.
330     /// \param Features This specifies the string representation of the
331     /// additional target features.
332     MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
333                                            StringRef Features) const {
334       if (!MCSubtargetInfoCtorFn)
335         return nullptr;
336       return MCSubtargetInfoCtorFn(Triple, CPU, Features);
337     }
338
339     /// createTargetMachine - Create a target specific machine implementation
340     /// for the specified \p Triple.
341     ///
342     /// \param Triple This argument is used to determine the target machine
343     /// feature set; it should always be provided. Generally this should be
344     /// either the target triple from the module, or the target triple of the
345     /// host if that does not exist.
346     TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
347                              StringRef Features, const TargetOptions &Options,
348                              Reloc::Model RM = Reloc::Default,
349                              CodeModel::Model CM = CodeModel::Default,
350                              CodeGenOpt::Level OL = CodeGenOpt::Default) const {
351       if (!TargetMachineCtorFn)
352         return nullptr;
353       return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
354                                  RM, CM, OL);
355     }
356
357     /// createMCAsmBackend - Create a target specific assembly parser.
358     ///
359     /// \param Triple The target triple string.
360     MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
361                                      StringRef Triple, StringRef CPU) const {
362       if (!MCAsmBackendCtorFn)
363         return nullptr;
364       return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
365     }
366
367     /// createMCAsmParser - Create a target specific assembly parser.
368     ///
369     /// \param Parser The target independent parser implementation to use for
370     /// parsing and lexing.
371     MCTargetAsmParser *createMCAsmParser(
372         MCSubtargetInfo &STI,
373         MCAsmParser &Parser,
374         const MCInstrInfo &MII,
375         const MCTargetOptions &Options) const {
376       if (!MCAsmParserCtorFn)
377         return nullptr;
378       return MCAsmParserCtorFn(STI, Parser, MII, Options);
379     }
380
381     /// createAsmPrinter - Create a target specific assembly printer pass.  This
382     /// takes ownership of the MCStreamer object.
383     AsmPrinter *createAsmPrinter(TargetMachine &TM,
384                                  std::unique_ptr<MCStreamer> Streamer) const {
385       if (!AsmPrinterCtorFn)
386         return nullptr;
387       return AsmPrinterCtorFn(TM, std::move(Streamer));
388     }
389
390     MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
391                                          MCContext &Ctx) const {
392       if (!MCDisassemblerCtorFn)
393         return nullptr;
394       return MCDisassemblerCtorFn(*this, STI, Ctx);
395     }
396
397     MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
398                                        const MCAsmInfo &MAI,
399                                        const MCInstrInfo &MII,
400                                        const MCRegisterInfo &MRI,
401                                        const MCSubtargetInfo &STI) const {
402       if (!MCInstPrinterCtorFn)
403         return nullptr;
404       return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
405     }
406
407
408     /// createMCCodeEmitter - Create a target specific code emitter.
409     MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
410                                        const MCRegisterInfo &MRI,
411                                        const MCSubtargetInfo &STI,
412                                        MCContext &Ctx) const {
413       if (!MCCodeEmitterCtorFn)
414         return nullptr;
415       return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
416     }
417
418     /// createMCObjectStreamer - Create a target specific MCStreamer.
419     ///
420     /// \param TT The target triple.
421     /// \param Ctx The target context.
422     /// \param TAB The target assembler backend object. Takes ownership.
423     /// \param _OS The stream object.
424     /// \param _Emitter The target independent assembler object.Takes ownership.
425     /// \param RelaxAll Relax all fixups?
426     MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
427                                        MCAsmBackend &TAB, raw_ostream &_OS,
428                                        MCCodeEmitter *_Emitter,
429                                        const MCSubtargetInfo &STI,
430                                        bool RelaxAll) const {
431       if (!MCObjectStreamerCtorFn)
432         return nullptr;
433       return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
434                                     RelaxAll);
435     }
436
437     /// createAsmStreamer - Create a target specific MCStreamer.
438     MCStreamer *createAsmStreamer(MCContext &Ctx,
439                                   formatted_raw_ostream &OS,
440                                   bool isVerboseAsm,
441                                   bool useDwarfDirectory,
442                                   MCInstPrinter *InstPrint,
443                                   MCCodeEmitter *CE,
444                                   MCAsmBackend *TAB,
445                                   bool ShowInst) const {
446       if (AsmStreamerCtorFn)
447         return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
448                                  InstPrint, CE, TAB, ShowInst);
449       return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
450                                      InstPrint, CE, TAB, ShowInst);
451     }
452
453     MCStreamer *createNullStreamer(MCContext &Ctx) const {
454       if (NullStreamerCtorFn)
455         return NullStreamerCtorFn(Ctx);
456       return llvm::createNullStreamer(Ctx);
457     }
458
459     /// createMCRelocationInfo - Create a target specific MCRelocationInfo.
460     ///
461     /// \param TT The target triple.
462     /// \param Ctx The target context.
463     MCRelocationInfo *
464       createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
465       MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
466                                       ? MCRelocationInfoCtorFn
467                                       : llvm::createMCRelocationInfo;
468       return Fn(TT, Ctx);
469     }
470
471     /// createMCSymbolizer - Create a target specific MCSymbolizer.
472     ///
473     /// \param TT The target triple.
474     /// \param GetOpInfo The function to get the symbolic information for operands.
475     /// \param SymbolLookUp The function to lookup a symbol name.
476     /// \param DisInfo The pointer to the block of symbolic information for above call
477     /// back.
478     /// \param Ctx The target context.
479     /// \param RelInfo The relocation information for this target. Takes ownership.
480     MCSymbolizer *
481     createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
482                        LLVMSymbolLookupCallback SymbolLookUp,
483                        void *DisInfo,
484                        MCContext *Ctx, MCRelocationInfo *RelInfo) const {
485       MCSymbolizerCtorTy Fn =
486           MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
487       return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo);
488     }
489
490     /// @}
491   };
492
493   /// TargetRegistry - Generic interface to target specific features.
494   struct TargetRegistry {
495     class iterator {
496       const Target *Current;
497       explicit iterator(Target *T) : Current(T) {}
498       friend struct TargetRegistry;
499     public:
500       iterator() : Current(nullptr) {}
501
502       bool operator==(const iterator &x) const {
503         return Current == x.Current;
504       }
505       bool operator!=(const iterator &x) const {
506         return !operator==(x);
507       }
508
509       // Iterator traversal: forward iteration only
510       iterator &operator++() {          // Preincrement
511         assert(Current && "Cannot increment end iterator!");
512         Current = Current->getNext();
513         return *this;
514       }
515       iterator operator++(int) {        // Postincrement
516         iterator tmp = *this;
517         ++*this;
518         return tmp;
519       }
520
521       const Target &operator*() const {
522         assert(Current && "Cannot dereference end iterator!");
523         return *Current;
524       }
525
526       const Target *operator->() const {
527         return &operator*();
528       }
529     };
530
531     /// printRegisteredTargetsForVersion - Print the registered targets
532     /// appropriately for inclusion in a tool's version output.
533     static void printRegisteredTargetsForVersion();
534
535     /// @name Registry Access
536     /// @{
537
538     static iterator begin();
539
540     static iterator end() { return iterator(); }
541
542     /// lookupTarget - Lookup a target based on a target triple.
543     ///
544     /// \param Triple - The triple to use for finding a target.
545     /// \param Error - On failure, an error string describing why no target was
546     /// found.
547     static const Target *lookupTarget(const std::string &Triple,
548                                       std::string &Error);
549
550     /// lookupTarget - Lookup a target based on an architecture name
551     /// and a target triple.  If the architecture name is non-empty,
552     /// then the lookup is done by architecture.  Otherwise, the target
553     /// triple is used.
554     ///
555     /// \param ArchName - The architecture to use for finding a target.
556     /// \param TheTriple - The triple to use for finding a target.  The
557     /// triple is updated with canonical architecture name if a lookup
558     /// by architecture is done.
559     /// \param Error - On failure, an error string describing why no target was
560     /// found.
561     static const Target *lookupTarget(const std::string &ArchName,
562                                       Triple &TheTriple,
563                                       std::string &Error);
564
565     /// @}
566     /// @name Target Registration
567     /// @{
568
569     /// RegisterTarget - Register the given target. Attempts to register a
570     /// target which has already been registered will be ignored.
571     ///
572     /// Clients are responsible for ensuring that registration doesn't occur
573     /// while another thread is attempting to access the registry. Typically
574     /// this is done by initializing all targets at program startup.
575     ///
576     /// @param T - The target being registered.
577     /// @param Name - The target name. This should be a static string.
578     /// @param ShortDesc - A short target description. This should be a static
579     /// string.
580     /// @param ArchMatchFn - The arch match checking function for this target.
581     /// @param HasJIT - Whether the target supports JIT code
582     /// generation.
583     static void RegisterTarget(Target &T,
584                                const char *Name,
585                                const char *ShortDesc,
586                                Target::ArchMatchFnTy ArchMatchFn,
587                                bool HasJIT = false);
588
589     /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
590     /// given target.
591     ///
592     /// Clients are responsible for ensuring that registration doesn't occur
593     /// while another thread is attempting to access the registry. Typically
594     /// this is done by initializing all targets at program startup.
595     ///
596     /// @param T - The target being registered.
597     /// @param Fn - A function to construct a MCAsmInfo for the target.
598     static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
599       T.MCAsmInfoCtorFn = Fn;
600     }
601
602     /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
603     /// given target.
604     ///
605     /// Clients are responsible for ensuring that registration doesn't occur
606     /// while another thread is attempting to access the registry. Typically
607     /// this is done by initializing all targets at program startup.
608     ///
609     /// @param T - The target being registered.
610     /// @param Fn - A function to construct a MCCodeGenInfo for the target.
611     static void RegisterMCCodeGenInfo(Target &T,
612                                      Target::MCCodeGenInfoCtorFnTy Fn) {
613       T.MCCodeGenInfoCtorFn = Fn;
614     }
615
616     /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
617     /// given target.
618     ///
619     /// Clients are responsible for ensuring that registration doesn't occur
620     /// while another thread is attempting to access the registry. Typically
621     /// this is done by initializing all targets at program startup.
622     ///
623     /// @param T - The target being registered.
624     /// @param Fn - A function to construct a MCInstrInfo for the target.
625     static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
626       T.MCInstrInfoCtorFn = Fn;
627     }
628
629     /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
630     /// the given target.
631     static void RegisterMCInstrAnalysis(Target &T,
632                                         Target::MCInstrAnalysisCtorFnTy Fn) {
633       T.MCInstrAnalysisCtorFn = Fn;
634     }
635
636     /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
637     /// given target.
638     ///
639     /// Clients are responsible for ensuring that registration doesn't occur
640     /// while another thread is attempting to access the registry. Typically
641     /// this is done by initializing all targets at program startup.
642     ///
643     /// @param T - The target being registered.
644     /// @param Fn - A function to construct a MCRegisterInfo for the target.
645     static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
646       T.MCRegInfoCtorFn = Fn;
647     }
648
649     /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
650     /// the given target.
651     ///
652     /// Clients are responsible for ensuring that registration doesn't occur
653     /// while another thread is attempting to access the registry. Typically
654     /// this is done by initializing all targets at program startup.
655     ///
656     /// @param T - The target being registered.
657     /// @param Fn - A function to construct a MCSubtargetInfo for the target.
658     static void RegisterMCSubtargetInfo(Target &T,
659                                         Target::MCSubtargetInfoCtorFnTy Fn) {
660       T.MCSubtargetInfoCtorFn = Fn;
661     }
662
663     /// RegisterTargetMachine - Register a TargetMachine implementation for the
664     /// given target.
665     ///
666     /// Clients are responsible for ensuring that registration doesn't occur
667     /// while another thread is attempting to access the registry. Typically
668     /// this is done by initializing all targets at program startup.
669     ///
670     /// @param T - The target being registered.
671     /// @param Fn - A function to construct a TargetMachine for the target.
672     static void RegisterTargetMachine(Target &T,
673                                       Target::TargetMachineCtorTy Fn) {
674       T.TargetMachineCtorFn = Fn;
675     }
676
677     /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
678     /// given target.
679     ///
680     /// Clients are responsible for ensuring that registration doesn't occur
681     /// while another thread is attempting to access the registry. Typically
682     /// this is done by initializing all targets at program startup.
683     ///
684     /// @param T - The target being registered.
685     /// @param Fn - A function to construct an AsmBackend for the target.
686     static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
687       T.MCAsmBackendCtorFn = Fn;
688     }
689
690     /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
691     /// the given target.
692     ///
693     /// Clients are responsible for ensuring that registration doesn't occur
694     /// while another thread is attempting to access the registry. Typically
695     /// this is done by initializing all targets at program startup.
696     ///
697     /// @param T - The target being registered.
698     /// @param Fn - A function to construct an MCTargetAsmParser for the target.
699     static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
700       T.MCAsmParserCtorFn = Fn;
701     }
702
703     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
704     /// target.
705     ///
706     /// Clients are responsible for ensuring that registration doesn't occur
707     /// while another thread is attempting to access the registry. Typically
708     /// this is done by initializing all targets at program startup.
709     ///
710     /// @param T - The target being registered.
711     /// @param Fn - A function to construct an AsmPrinter for the target.
712     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
713       T.AsmPrinterCtorFn = Fn;
714     }
715
716     /// RegisterMCDisassembler - Register a MCDisassembler implementation for
717     /// the given target.
718     ///
719     /// Clients are responsible for ensuring that registration doesn't occur
720     /// while another thread is attempting to access the registry. Typically
721     /// this is done by initializing all targets at program startup.
722     ///
723     /// @param T - The target being registered.
724     /// @param Fn - A function to construct an MCDisassembler for the target.
725     static void RegisterMCDisassembler(Target &T,
726                                        Target::MCDisassemblerCtorTy Fn) {
727       T.MCDisassemblerCtorFn = Fn;
728     }
729
730     /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
731     /// given target.
732     ///
733     /// Clients are responsible for ensuring that registration doesn't occur
734     /// while another thread is attempting to access the registry. Typically
735     /// this is done by initializing all targets at program startup.
736     ///
737     /// @param T - The target being registered.
738     /// @param Fn - A function to construct an MCInstPrinter for the target.
739     static void RegisterMCInstPrinter(Target &T,
740                                       Target::MCInstPrinterCtorTy Fn) {
741       T.MCInstPrinterCtorFn = Fn;
742     }
743
744     /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
745     /// given target.
746     ///
747     /// Clients are responsible for ensuring that registration doesn't occur
748     /// while another thread is attempting to access the registry. Typically
749     /// this is done by initializing all targets at program startup.
750     ///
751     /// @param T - The target being registered.
752     /// @param Fn - A function to construct an MCCodeEmitter for the target.
753     static void RegisterMCCodeEmitter(Target &T,
754                                       Target::MCCodeEmitterCtorTy Fn) {
755       T.MCCodeEmitterCtorFn = Fn;
756     }
757
758     /// RegisterMCObjectStreamer - Register a object code MCStreamer
759     /// implementation for the given target.
760     ///
761     /// Clients are responsible for ensuring that registration doesn't occur
762     /// while another thread is attempting to access the registry. Typically
763     /// this is done by initializing all targets at program startup.
764     ///
765     /// @param T - The target being registered.
766     /// @param Fn - A function to construct an MCStreamer for the target.
767     static void RegisterMCObjectStreamer(Target &T,
768                                          Target::MCObjectStreamerCtorTy Fn) {
769       T.MCObjectStreamerCtorFn = Fn;
770     }
771
772     /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
773     /// for the given target.
774     ///
775     /// Clients are responsible for ensuring that registration doesn't occur
776     /// while another thread is attempting to access the registry. Typically
777     /// this is done by initializing all targets at program startup.
778     ///
779     /// @param T - The target being registered.
780     /// @param Fn - A function to construct an MCStreamer for the target.
781     static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
782       T.AsmStreamerCtorFn = Fn;
783     }
784
785     static void RegisterNullStreamer(Target &T, Target::NullStreamerCtorTy Fn) {
786       T.NullStreamerCtorFn = Fn;
787     }
788
789     /// RegisterMCRelocationInfo - Register an MCRelocationInfo
790     /// implementation for the given target.
791     ///
792     /// Clients are responsible for ensuring that registration doesn't occur
793     /// while another thread is attempting to access the registry. Typically
794     /// this is done by initializing all targets at program startup.
795     ///
796     /// @param T - The target being registered.
797     /// @param Fn - A function to construct an MCRelocationInfo for the target.
798     static void RegisterMCRelocationInfo(Target &T,
799                                          Target::MCRelocationInfoCtorTy Fn) {
800       T.MCRelocationInfoCtorFn = Fn;
801     }
802
803     /// RegisterMCSymbolizer - Register an MCSymbolizer
804     /// implementation for the given target.
805     ///
806     /// Clients are responsible for ensuring that registration doesn't occur
807     /// while another thread is attempting to access the registry. Typically
808     /// this is done by initializing all targets at program startup.
809     ///
810     /// @param T - The target being registered.
811     /// @param Fn - A function to construct an MCSymbolizer for the target.
812     static void RegisterMCSymbolizer(Target &T,
813                                      Target::MCSymbolizerCtorTy Fn) {
814       T.MCSymbolizerCtorFn = Fn;
815     }
816
817     /// @}
818   };
819
820
821   //===--------------------------------------------------------------------===//
822
823   /// RegisterTarget - Helper template for registering a target, for use in the
824   /// target's initialization function. Usage:
825   ///
826   ///
827   /// Target TheFooTarget; // The global target instance.
828   ///
829   /// extern "C" void LLVMInitializeFooTargetInfo() {
830   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
831   /// }
832   template<Triple::ArchType TargetArchType = Triple::UnknownArch,
833            bool HasJIT = false>
834   struct RegisterTarget {
835     RegisterTarget(Target &T, const char *Name, const char *Desc) {
836       TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
837     }
838
839     static bool getArchMatch(Triple::ArchType Arch) {
840       return Arch == TargetArchType;
841     }
842   };
843
844   /// RegisterMCAsmInfo - Helper template for registering a target assembly info
845   /// implementation.  This invokes the static "Create" method on the class to
846   /// actually do the construction.  Usage:
847   ///
848   /// extern "C" void LLVMInitializeFooTarget() {
849   ///   extern Target TheFooTarget;
850   ///   RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
851   /// }
852   template<class MCAsmInfoImpl>
853   struct RegisterMCAsmInfo {
854     RegisterMCAsmInfo(Target &T) {
855       TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
856     }
857   private:
858     static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
859       return new MCAsmInfoImpl(TT);
860     }
861
862   };
863
864   /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
865   /// implementation.  This invokes the specified function to do the
866   /// construction.  Usage:
867   ///
868   /// extern "C" void LLVMInitializeFooTarget() {
869   ///   extern Target TheFooTarget;
870   ///   RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
871   /// }
872   struct RegisterMCAsmInfoFn {
873     RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
874       TargetRegistry::RegisterMCAsmInfo(T, Fn);
875     }
876   };
877
878   /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
879   /// implementation.  This invokes the static "Create" method on the class
880   /// to actually do the construction.  Usage:
881   ///
882   /// extern "C" void LLVMInitializeFooTarget() {
883   ///   extern Target TheFooTarget;
884   ///   RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
885   /// }
886   template<class MCCodeGenInfoImpl>
887   struct RegisterMCCodeGenInfo {
888     RegisterMCCodeGenInfo(Target &T) {
889       TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
890     }
891   private:
892     static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
893                                     CodeModel::Model /*CM*/,
894                                     CodeGenOpt::Level /*OL*/) {
895       return new MCCodeGenInfoImpl();
896     }
897   };
898
899   /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
900   /// info implementation.  This invokes the specified function to do the
901   /// construction.  Usage:
902   ///
903   /// extern "C" void LLVMInitializeFooTarget() {
904   ///   extern Target TheFooTarget;
905   ///   RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
906   /// }
907   struct RegisterMCCodeGenInfoFn {
908     RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
909       TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
910     }
911   };
912
913   /// RegisterMCInstrInfo - Helper template for registering a target instruction
914   /// info implementation.  This invokes the static "Create" method on the class
915   /// to actually do the construction.  Usage:
916   ///
917   /// extern "C" void LLVMInitializeFooTarget() {
918   ///   extern Target TheFooTarget;
919   ///   RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
920   /// }
921   template<class MCInstrInfoImpl>
922   struct RegisterMCInstrInfo {
923     RegisterMCInstrInfo(Target &T) {
924       TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
925     }
926   private:
927     static MCInstrInfo *Allocator() {
928       return new MCInstrInfoImpl();
929     }
930   };
931
932   /// RegisterMCInstrInfoFn - Helper template for registering a target
933   /// instruction info implementation.  This invokes the specified function to
934   /// do the construction.  Usage:
935   ///
936   /// extern "C" void LLVMInitializeFooTarget() {
937   ///   extern Target TheFooTarget;
938   ///   RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
939   /// }
940   struct RegisterMCInstrInfoFn {
941     RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
942       TargetRegistry::RegisterMCInstrInfo(T, Fn);
943     }
944   };
945
946   /// RegisterMCInstrAnalysis - Helper template for registering a target
947   /// instruction analyzer implementation.  This invokes the static "Create"
948   /// method on the class to actually do the construction.  Usage:
949   ///
950   /// extern "C" void LLVMInitializeFooTarget() {
951   ///   extern Target TheFooTarget;
952   ///   RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
953   /// }
954   template<class MCInstrAnalysisImpl>
955   struct RegisterMCInstrAnalysis {
956     RegisterMCInstrAnalysis(Target &T) {
957       TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
958     }
959   private:
960     static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
961       return new MCInstrAnalysisImpl(Info);
962     }
963   };
964
965   /// RegisterMCInstrAnalysisFn - Helper template for registering a target
966   /// instruction analyzer implementation.  This invokes the specified function
967   /// to do the construction.  Usage:
968   ///
969   /// extern "C" void LLVMInitializeFooTarget() {
970   ///   extern Target TheFooTarget;
971   ///   RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
972   /// }
973   struct RegisterMCInstrAnalysisFn {
974     RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
975       TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
976     }
977   };
978
979   /// RegisterMCRegInfo - Helper template for registering a target register info
980   /// implementation.  This invokes the static "Create" method on the class to
981   /// actually do the construction.  Usage:
982   ///
983   /// extern "C" void LLVMInitializeFooTarget() {
984   ///   extern Target TheFooTarget;
985   ///   RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
986   /// }
987   template<class MCRegisterInfoImpl>
988   struct RegisterMCRegInfo {
989     RegisterMCRegInfo(Target &T) {
990       TargetRegistry::RegisterMCRegInfo(T, &Allocator);
991     }
992   private:
993     static MCRegisterInfo *Allocator(StringRef /*TT*/) {
994       return new MCRegisterInfoImpl();
995     }
996   };
997
998   /// RegisterMCRegInfoFn - Helper template for registering a target register
999   /// info implementation.  This invokes the specified function to do the
1000   /// construction.  Usage:
1001   ///
1002   /// extern "C" void LLVMInitializeFooTarget() {
1003   ///   extern Target TheFooTarget;
1004   ///   RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
1005   /// }
1006   struct RegisterMCRegInfoFn {
1007     RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
1008       TargetRegistry::RegisterMCRegInfo(T, Fn);
1009     }
1010   };
1011
1012   /// RegisterMCSubtargetInfo - Helper template for registering a target
1013   /// subtarget info implementation.  This invokes the static "Create" method
1014   /// on the class to actually do the construction.  Usage:
1015   ///
1016   /// extern "C" void LLVMInitializeFooTarget() {
1017   ///   extern Target TheFooTarget;
1018   ///   RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
1019   /// }
1020   template<class MCSubtargetInfoImpl>
1021   struct RegisterMCSubtargetInfo {
1022     RegisterMCSubtargetInfo(Target &T) {
1023       TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
1024     }
1025   private:
1026     static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
1027                                       StringRef /*FS*/) {
1028       return new MCSubtargetInfoImpl();
1029     }
1030   };
1031
1032   /// RegisterMCSubtargetInfoFn - Helper template for registering a target
1033   /// subtarget info implementation.  This invokes the specified function to
1034   /// do the construction.  Usage:
1035   ///
1036   /// extern "C" void LLVMInitializeFooTarget() {
1037   ///   extern Target TheFooTarget;
1038   ///   RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
1039   /// }
1040   struct RegisterMCSubtargetInfoFn {
1041     RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
1042       TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
1043     }
1044   };
1045
1046   /// RegisterTargetMachine - Helper template for registering a target machine
1047   /// implementation, for use in the target machine initialization
1048   /// function. Usage:
1049   ///
1050   /// extern "C" void LLVMInitializeFooTarget() {
1051   ///   extern Target TheFooTarget;
1052   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
1053   /// }
1054   template<class TargetMachineImpl>
1055   struct RegisterTargetMachine {
1056     RegisterTargetMachine(Target &T) {
1057       TargetRegistry::RegisterTargetMachine(T, &Allocator);
1058     }
1059
1060   private:
1061     static TargetMachine *Allocator(const Target &T, StringRef TT,
1062                                     StringRef CPU, StringRef FS,
1063                                     const TargetOptions &Options,
1064                                     Reloc::Model RM,
1065                                     CodeModel::Model CM,
1066                                     CodeGenOpt::Level OL) {
1067       return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
1068     }
1069   };
1070
1071   /// RegisterMCAsmBackend - Helper template for registering a target specific
1072   /// assembler backend. Usage:
1073   ///
1074   /// extern "C" void LLVMInitializeFooMCAsmBackend() {
1075   ///   extern Target TheFooTarget;
1076   ///   RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
1077   /// }
1078   template<class MCAsmBackendImpl>
1079   struct RegisterMCAsmBackend {
1080     RegisterMCAsmBackend(Target &T) {
1081       TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
1082     }
1083
1084   private:
1085     static MCAsmBackend *Allocator(const Target &T,
1086                                    const MCRegisterInfo &MRI,
1087                                    StringRef Triple, StringRef CPU) {
1088       return new MCAsmBackendImpl(T, MRI, Triple, CPU);
1089     }
1090   };
1091
1092   /// RegisterMCAsmParser - Helper template for registering a target specific
1093   /// assembly parser, for use in the target machine initialization
1094   /// function. Usage:
1095   ///
1096   /// extern "C" void LLVMInitializeFooMCAsmParser() {
1097   ///   extern Target TheFooTarget;
1098   ///   RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
1099   /// }
1100   template<class MCAsmParserImpl>
1101   struct RegisterMCAsmParser {
1102     RegisterMCAsmParser(Target &T) {
1103       TargetRegistry::RegisterMCAsmParser(T, &Allocator);
1104     }
1105
1106   private:
1107     static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
1108                                         const MCInstrInfo &MII,
1109                                         const MCTargetOptions &Options) {
1110       return new MCAsmParserImpl(STI, P, MII, Options);
1111     }
1112   };
1113
1114   /// RegisterAsmPrinter - Helper template for registering a target specific
1115   /// assembly printer, for use in the target machine initialization
1116   /// function. Usage:
1117   ///
1118   /// extern "C" void LLVMInitializeFooAsmPrinter() {
1119   ///   extern Target TheFooTarget;
1120   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
1121   /// }
1122   template<class AsmPrinterImpl>
1123   struct RegisterAsmPrinter {
1124     RegisterAsmPrinter(Target &T) {
1125       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
1126     }
1127
1128   private:
1129     static AsmPrinter *Allocator(TargetMachine &TM,
1130                                  std::unique_ptr<MCStreamer> &&Streamer) {
1131       return new AsmPrinterImpl(TM, std::move(Streamer));
1132     }
1133   };
1134
1135   /// RegisterMCCodeEmitter - Helper template for registering a target specific
1136   /// machine code emitter, for use in the target initialization
1137   /// function. Usage:
1138   ///
1139   /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
1140   ///   extern Target TheFooTarget;
1141   ///   RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
1142   /// }
1143   template<class MCCodeEmitterImpl>
1144   struct RegisterMCCodeEmitter {
1145     RegisterMCCodeEmitter(Target &T) {
1146       TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
1147     }
1148
1149   private:
1150     static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
1151                                     const MCRegisterInfo &/*MRI*/,
1152                                     const MCSubtargetInfo &/*STI*/,
1153                                     MCContext &/*Ctx*/) {
1154       return new MCCodeEmitterImpl();
1155     }
1156   };
1157
1158 }
1159
1160 #endif