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