Add registry hook for assembly text output
[oota-llvm.git] / include / llvm / Target / TargetRegistry.h
1 //===-- Target/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_TARGET_TARGETREGISTRY_H
20 #define LLVM_TARGET_TARGETREGISTRY_H
21
22 #include "llvm/ADT/Triple.h"
23 #include <string>
24 #include <cassert>
25
26 namespace llvm {
27   class AsmPrinter;
28   class Module;
29   class MCAssembler;
30   class MCAsmInfo;
31   class MCAsmParser;
32   class MCCodeEmitter;
33   class MCContext;
34   class MCDisassembler;
35   class MCInstPrinter;
36   class MCStreamer;
37   class TargetAsmBackend;
38   class TargetAsmLexer;
39   class TargetAsmParser;
40   class TargetMachine;
41   class raw_ostream;
42   class formatted_raw_ostream;
43
44   MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
45                                 bool isLittleEndian, bool isVerboseAsm,
46                                 MCInstPrinter *InstPrint,
47                                 MCCodeEmitter *CE,
48                                 bool ShowInst);
49
50   /// Target - Wrapper for Target specific information.
51   ///
52   /// For registration purposes, this is a POD type so that targets can be
53   /// registered without the use of static constructors.
54   ///
55   /// Targets should implement a single global instance of this class (which
56   /// will be zero initialized), and pass that instance to the TargetRegistry as
57   /// part of their initialization.
58   class Target {
59   public:
60     friend struct TargetRegistry;
61
62     typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
63
64     typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
65                                                 StringRef TT);
66     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
67                                                   const std::string &TT,
68                                                   const std::string &Features);
69     typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
70                                             MCStreamer &Streamer);
71     typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T,
72                                                   const std::string &TT);
73     typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
74                                               const MCAsmInfo &MAI);
75     typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P,
76                                                 TargetMachine &TM);
77     typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
78     typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
79                                                   unsigned SyntaxVariant,
80                                                   const MCAsmInfo &MAI);
81     typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
82                                                 TargetMachine &TM,
83                                                 MCContext &Ctx);
84     typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T,
85                                                 const std::string &TT,
86                                                 MCContext &Ctx,
87                                                 TargetAsmBackend &TAB,
88                                                 raw_ostream &_OS,
89                                                 MCCodeEmitter *_Emitter,
90                                                 bool RelaxAll);
91     typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
92                                              formatted_raw_ostream &OS,
93                                              bool isLittleEndian,
94                                              bool isVerboseAsm,
95                                              MCInstPrinter *InstPrint,
96                                              MCCodeEmitter *CE,
97                                              bool ShowInst);
98
99   private:
100     /// Next - The next registered target in the linked list, maintained by the
101     /// TargetRegistry.
102     Target *Next;
103
104     /// TripleMatchQualityFn - The target function for rating the match quality
105     /// of a triple.
106     TripleMatchQualityFnTy TripleMatchQualityFn;
107
108     /// Name - The target name.
109     const char *Name;
110
111     /// ShortDesc - A short description of the target.
112     const char *ShortDesc;
113
114     /// HasJIT - Whether this target supports the JIT.
115     bool HasJIT;
116
117     AsmInfoCtorFnTy AsmInfoCtorFn;
118
119     /// TargetMachineCtorFn - Construction function for this target's
120     /// TargetMachine, if registered.
121     TargetMachineCtorTy TargetMachineCtorFn;
122
123     /// AsmBackendCtorFn - Construction function for this target's
124     /// TargetAsmBackend, if registered.
125     AsmBackendCtorTy AsmBackendCtorFn;
126
127     /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer,
128     /// if registered.
129     AsmLexerCtorTy AsmLexerCtorFn;
130
131     /// AsmParserCtorFn - Construction function for this target's
132     /// TargetAsmParser, if registered.
133     AsmParserCtorTy AsmParserCtorFn;
134
135     /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
136     /// if registered.
137     AsmPrinterCtorTy AsmPrinterCtorFn;
138
139     /// MCDisassemblerCtorFn - Construction function for this target's
140     /// MCDisassembler, if registered.
141     MCDisassemblerCtorTy MCDisassemblerCtorFn;
142
143     /// MCInstPrinterCtorFn - Construction function for this target's
144     /// MCInstPrinter, if registered.
145     MCInstPrinterCtorTy MCInstPrinterCtorFn;
146
147     /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
148     /// if registered.
149     CodeEmitterCtorTy CodeEmitterCtorFn;
150
151     /// ObjectStreamerCtorFn - Construction function for this target's
152     /// ObjectStreamer, if registered.
153     ObjectStreamerCtorTy ObjectStreamerCtorFn;
154
155     /// AsmStreamerCtorFn - Construction function for this target's
156     /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
157     AsmStreamerCtorTy AsmStreamerCtorFn;
158
159   public:
160     Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {}
161
162     /// @name Target Information
163     /// @{
164
165     // getNext - Return the next registered target.
166     const Target *getNext() const { return Next; }
167
168     /// getName - Get the target name.
169     const char *getName() const { return Name; }
170
171     /// getShortDescription - Get a short description of the target.
172     const char *getShortDescription() const { return ShortDesc; }
173
174     /// @}
175     /// @name Feature Predicates
176     /// @{
177
178     /// hasJIT - Check if this targets supports the just-in-time compilation.
179     bool hasJIT() const { return HasJIT; }
180
181     /// hasTargetMachine - Check if this target supports code generation.
182     bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
183
184     /// hasAsmBackend - Check if this target supports .o generation.
185     bool hasAsmBackend() const { return AsmBackendCtorFn != 0; }
186
187     /// hasAsmLexer - Check if this target supports .s lexing.
188     bool hasAsmLexer() const { return AsmLexerCtorFn != 0; }
189
190     /// hasAsmParser - Check if this target supports .s parsing.
191     bool hasAsmParser() const { return AsmParserCtorFn != 0; }
192
193     /// hasAsmPrinter - Check if this target supports .s printing.
194     bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
195
196     /// hasMCDisassembler - Check if this target has a disassembler.
197     bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
198
199     /// hasMCInstPrinter - Check if this target has an instruction printer.
200     bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
201
202     /// hasCodeEmitter - Check if this target supports instruction encoding.
203     bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
204
205     /// hasObjectStreamer - Check if this target supports streaming to files.
206     bool hasObjectStreamer() const { return ObjectStreamerCtorFn != 0; }
207
208     /// hasAsmStreamer - Check if this target supports streaming to files.
209     bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; }
210
211     /// @}
212     /// @name Feature Constructors
213     /// @{
214
215     /// createAsmInfo - Create a MCAsmInfo implementation for the specified
216     /// target triple.
217     ///
218     /// \arg Triple - This argument is used to determine the target machine
219     /// feature set; it should always be provided. Generally this should be
220     /// either the target triple from the module, or the target triple of the
221     /// host if that does not exist.
222     MCAsmInfo *createAsmInfo(StringRef Triple) const {
223       if (!AsmInfoCtorFn)
224         return 0;
225       return AsmInfoCtorFn(*this, Triple);
226     }
227
228     /// createTargetMachine - Create a target specific machine implementation
229     /// for the specified \arg Triple.
230     ///
231     /// \arg Triple - This argument is used to determine the target machine
232     /// feature set; it should always be provided. Generally this should be
233     /// either the target triple from the module, or the target triple of the
234     /// host if that does not exist.
235     TargetMachine *createTargetMachine(const std::string &Triple,
236                                        const std::string &Features) const {
237       if (!TargetMachineCtorFn)
238         return 0;
239       return TargetMachineCtorFn(*this, Triple, Features);
240     }
241
242     /// createAsmBackend - Create a target specific assembly parser.
243     ///
244     /// \arg Triple - The target triple string.
245     /// \arg Backend - The target independent assembler object.
246     TargetAsmBackend *createAsmBackend(const std::string &Triple) const {
247       if (!AsmBackendCtorFn)
248         return 0;
249       return AsmBackendCtorFn(*this, Triple);
250     }
251
252     /// createAsmLexer - Create a target specific assembly lexer.
253     ///
254     TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const {
255       if (!AsmLexerCtorFn)
256         return 0;
257       return AsmLexerCtorFn(*this, MAI);
258     }
259
260     /// createAsmParser - Create a target specific assembly parser.
261     ///
262     /// \arg Parser - The target independent parser implementation to use for
263     /// parsing and lexing.
264     TargetAsmParser *createAsmParser(MCAsmParser &Parser,
265                                      TargetMachine &TM) const {
266       if (!AsmParserCtorFn)
267         return 0;
268       return AsmParserCtorFn(*this, Parser, TM);
269     }
270
271     /// createAsmPrinter - Create a target specific assembly printer pass.  This
272     /// takes ownership of the MCStreamer object.
273     AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
274       if (!AsmPrinterCtorFn)
275         return 0;
276       return AsmPrinterCtorFn(TM, Streamer);
277     }
278
279     MCDisassembler *createMCDisassembler() const {
280       if (!MCDisassemblerCtorFn)
281         return 0;
282       return MCDisassemblerCtorFn(*this);
283     }
284
285     MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
286                                        const MCAsmInfo &MAI) const {
287       if (!MCInstPrinterCtorFn)
288         return 0;
289       return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI);
290     }
291
292
293     /// createCodeEmitter - Create a target specific code emitter.
294     MCCodeEmitter *createCodeEmitter(TargetMachine &TM, MCContext &Ctx) const {
295       if (!CodeEmitterCtorFn)
296         return 0;
297       return CodeEmitterCtorFn(*this, TM, Ctx);
298     }
299
300     /// createObjectStreamer - Create a target specific MCStreamer.
301     ///
302     /// \arg TT - The target triple.
303     /// \arg Ctx - The target context.
304     /// \arg TAB - The target assembler backend object. Takes ownership.
305     /// \arg _OS - The stream object.
306     /// \arg _Emitter - The target independent assembler object.Takes ownership.
307     /// \arg RelaxAll - Relax all fixups?
308     MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
309                                      TargetAsmBackend &TAB,
310                                      raw_ostream &_OS,
311                                      MCCodeEmitter *_Emitter,
312                                      bool RelaxAll) const {
313       if (!ObjectStreamerCtorFn)
314         return 0;
315       return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
316     }
317
318     /// createAsmStreamer - Create a target specific MCStreamer.
319     MCStreamer *createAsmStreamer(MCContext &Ctx,
320                                   formatted_raw_ostream &OS,
321                                   bool isLittleEndian,
322                                   bool isVerboseAsm,
323                                   MCInstPrinter *InstPrint,
324                                   MCCodeEmitter *CE,
325                                   bool ShowInst) const {
326       // AsmStreamerCtorFn is default to llvm::createAsmStreamer
327       return AsmStreamerCtorFn(Ctx, OS, isLittleEndian, isVerboseAsm,
328                                InstPrint, CE, ShowInst);
329     }
330
331     /// @}
332   };
333
334   /// TargetRegistry - Generic interface to target specific features.
335   struct TargetRegistry {
336     class iterator {
337       const Target *Current;
338       explicit iterator(Target *T) : Current(T) {}
339       friend struct TargetRegistry;
340     public:
341       iterator(const iterator &I) : Current(I.Current) {}
342       iterator() : Current(0) {}
343
344       bool operator==(const iterator &x) const {
345         return Current == x.Current;
346       }
347       bool operator!=(const iterator &x) const {
348         return !operator==(x);
349       }
350
351       // Iterator traversal: forward iteration only
352       iterator &operator++() {          // Preincrement
353         assert(Current && "Cannot increment end iterator!");
354         Current = Current->getNext();
355         return *this;
356       }
357       iterator operator++(int) {        // Postincrement
358         iterator tmp = *this;
359         ++*this;
360         return tmp;
361       }
362
363       const Target &operator*() const {
364         assert(Current && "Cannot dereference end iterator!");
365         return *Current;
366       }
367
368       const Target *operator->() const {
369         return &operator*();
370       }
371     };
372
373     /// @name Registry Access
374     /// @{
375
376     static iterator begin();
377
378     static iterator end() { return iterator(); }
379
380     /// lookupTarget - Lookup a target based on a target triple.
381     ///
382     /// \param Triple - The triple to use for finding a target.
383     /// \param Error - On failure, an error string describing why no target was
384     /// found.
385     static const Target *lookupTarget(const std::string &Triple,
386                                       std::string &Error);
387
388     /// getClosestTargetForJIT - Pick the best target that is compatible with
389     /// the current host.  If no close target can be found, this returns null
390     /// and sets the Error string to a reason.
391     ///
392     /// Maintained for compatibility through 2.6.
393     static const Target *getClosestTargetForJIT(std::string &Error);
394
395     /// @}
396     /// @name Target Registration
397     /// @{
398
399     /// RegisterTarget - Register the given target. Attempts to register a
400     /// target which has already been registered will be ignored.
401     ///
402     /// Clients are responsible for ensuring that registration doesn't occur
403     /// while another thread is attempting to access the registry. Typically
404     /// this is done by initializing all targets at program startup.
405     ///
406     /// @param T - The target being registered.
407     /// @param Name - The target name. This should be a static string.
408     /// @param ShortDesc - A short target description. This should be a static
409     /// string.
410     /// @param TQualityFn - The triple match quality computation function for
411     /// this target.
412     /// @param HasJIT - Whether the target supports JIT code
413     /// generation.
414     static void RegisterTarget(Target &T,
415                                const char *Name,
416                                const char *ShortDesc,
417                                Target::TripleMatchQualityFnTy TQualityFn,
418                                bool HasJIT = false);
419
420     /// RegisterAsmInfo - Register a MCAsmInfo implementation for the
421     /// given target.
422     ///
423     /// Clients are responsible for ensuring that registration doesn't occur
424     /// while another thread is attempting to access the registry. Typically
425     /// this is done by initializing all targets at program startup.
426     ///
427     /// @param T - The target being registered.
428     /// @param Fn - A function to construct a MCAsmInfo for the target.
429     static void RegisterAsmInfo(Target &T, Target::AsmInfoCtorFnTy Fn) {
430       // Ignore duplicate registration.
431       if (!T.AsmInfoCtorFn)
432         T.AsmInfoCtorFn = Fn;
433     }
434
435     /// RegisterTargetMachine - Register a TargetMachine implementation for the
436     /// given target.
437     ///
438     /// Clients are responsible for ensuring that registration doesn't occur
439     /// while another thread is attempting to access the registry. Typically
440     /// this is done by initializing all targets at program startup.
441     ///
442     /// @param T - The target being registered.
443     /// @param Fn - A function to construct a TargetMachine for the target.
444     static void RegisterTargetMachine(Target &T,
445                                       Target::TargetMachineCtorTy Fn) {
446       // Ignore duplicate registration.
447       if (!T.TargetMachineCtorFn)
448         T.TargetMachineCtorFn = Fn;
449     }
450
451     /// RegisterAsmBackend - Register a TargetAsmBackend implementation for the
452     /// given target.
453     ///
454     /// Clients are responsible for ensuring that registration doesn't occur
455     /// while another thread is attempting to access the registry. Typically
456     /// this is done by initializing all targets at program startup.
457     ///
458     /// @param T - The target being registered.
459     /// @param Fn - A function to construct an AsmBackend for the target.
460     static void RegisterAsmBackend(Target &T, Target::AsmBackendCtorTy Fn) {
461       if (!T.AsmBackendCtorFn)
462         T.AsmBackendCtorFn = Fn;
463     }
464
465     /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the
466     /// given target.
467     ///
468     /// Clients are responsible for ensuring that registration doesn't occur
469     /// while another thread is attempting to access the registry. Typically
470     /// this is done by initializing all targets at program startup.
471     ///
472     /// @param T - The target being registered.
473     /// @param Fn - A function to construct an AsmLexer for the target.
474     static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) {
475       if (!T.AsmLexerCtorFn)
476         T.AsmLexerCtorFn = Fn;
477     }
478
479     /// RegisterAsmParser - Register a TargetAsmParser implementation for the
480     /// given target.
481     ///
482     /// Clients are responsible for ensuring that registration doesn't occur
483     /// while another thread is attempting to access the registry. Typically
484     /// this is done by initializing all targets at program startup.
485     ///
486     /// @param T - The target being registered.
487     /// @param Fn - A function to construct an AsmParser for the target.
488     static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) {
489       if (!T.AsmParserCtorFn)
490         T.AsmParserCtorFn = Fn;
491     }
492
493     /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
494     /// target.
495     ///
496     /// Clients are responsible for ensuring that registration doesn't occur
497     /// while another thread is attempting to access the registry. Typically
498     /// this is done by initializing all targets at program startup.
499     ///
500     /// @param T - The target being registered.
501     /// @param Fn - A function to construct an AsmPrinter for the target.
502     static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
503       // Ignore duplicate registration.
504       if (!T.AsmPrinterCtorFn)
505         T.AsmPrinterCtorFn = Fn;
506     }
507
508     /// RegisterMCDisassembler - Register a MCDisassembler implementation for
509     /// the given target.
510     ///
511     /// Clients are responsible for ensuring that registration doesn't occur
512     /// while another thread is attempting to access the registry. Typically
513     /// this is done by initializing all targets at program startup.
514     ///
515     /// @param T - The target being registered.
516     /// @param Fn - A function to construct an MCDisassembler for the target.
517     static void RegisterMCDisassembler(Target &T,
518                                        Target::MCDisassemblerCtorTy Fn) {
519       if (!T.MCDisassemblerCtorFn)
520         T.MCDisassemblerCtorFn = Fn;
521     }
522
523     /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
524     /// given target.
525     ///
526     /// Clients are responsible for ensuring that registration doesn't occur
527     /// while another thread is attempting to access the registry. Typically
528     /// this is done by initializing all targets at program startup.
529     ///
530     /// @param T - The target being registered.
531     /// @param Fn - A function to construct an MCInstPrinter for the target.
532     static void RegisterMCInstPrinter(Target &T,
533                                       Target::MCInstPrinterCtorTy Fn) {
534       if (!T.MCInstPrinterCtorFn)
535         T.MCInstPrinterCtorFn = Fn;
536     }
537
538     /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
539     /// given target.
540     ///
541     /// Clients are responsible for ensuring that registration doesn't occur
542     /// while another thread is attempting to access the registry. Typically
543     /// this is done by initializing all targets at program startup.
544     ///
545     /// @param T - The target being registered.
546     /// @param Fn - A function to construct an MCCodeEmitter for the target.
547     static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) {
548       if (!T.CodeEmitterCtorFn)
549         T.CodeEmitterCtorFn = Fn;
550     }
551
552     /// RegisterObjectStreamer - Register a object code MCStreamer implementation
553     /// for the given target.
554     ///
555     /// Clients are responsible for ensuring that registration doesn't occur
556     /// while another thread is attempting to access the registry. Typically
557     /// this is done by initializing all targets at program startup.
558     ///
559     /// @param T - The target being registered.
560     /// @param Fn - A function to construct an MCStreamer for the target.
561     static void RegisterObjectStreamer(Target &T, Target::ObjectStreamerCtorTy Fn) {
562       if (!T.ObjectStreamerCtorFn)
563         T.ObjectStreamerCtorFn = Fn;
564     }
565
566     /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
567     /// for the given target.
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 Fn - A function to construct an MCStreamer for the target.
575     static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
576       if (T.AsmStreamerCtorFn == createAsmStreamer)
577         T.AsmStreamerCtorFn = Fn;
578     }
579
580     /// @}
581   };
582
583
584   //===--------------------------------------------------------------------===//
585
586   /// RegisterTarget - Helper template for registering a target, for use in the
587   /// target's initialization function. Usage:
588   ///
589   ///
590   /// Target TheFooTarget; // The global target instance.
591   ///
592   /// extern "C" void LLVMInitializeFooTargetInfo() {
593   ///   RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
594   /// }
595   template<Triple::ArchType TargetArchType = Triple::InvalidArch,
596            bool HasJIT = false>
597   struct RegisterTarget {
598     RegisterTarget(Target &T, const char *Name, const char *Desc) {
599       TargetRegistry::RegisterTarget(T, Name, Desc,
600                                      &getTripleMatchQuality,
601                                      HasJIT);
602     }
603
604     static unsigned getTripleMatchQuality(const std::string &TT) {
605       if (Triple(TT).getArch() == TargetArchType)
606         return 20;
607       return 0;
608     }
609   };
610
611   /// RegisterAsmInfo - Helper template for registering a target assembly info
612   /// implementation.  This invokes the static "Create" method on the class to
613   /// actually do the construction.  Usage:
614   ///
615   /// extern "C" void LLVMInitializeFooTarget() {
616   ///   extern Target TheFooTarget;
617   ///   RegisterAsmInfo<FooMCAsmInfo> X(TheFooTarget);
618   /// }
619   template<class MCAsmInfoImpl>
620   struct RegisterAsmInfo {
621     RegisterAsmInfo(Target &T) {
622       TargetRegistry::RegisterAsmInfo(T, &Allocator);
623     }
624   private:
625     static MCAsmInfo *Allocator(const Target &T, StringRef TT) {
626       return new MCAsmInfoImpl(T, TT);
627     }
628
629   };
630
631   /// RegisterAsmInfoFn - Helper template for registering a target assembly info
632   /// implementation.  This invokes the specified function to do the
633   /// construction.  Usage:
634   ///
635   /// extern "C" void LLVMInitializeFooTarget() {
636   ///   extern Target TheFooTarget;
637   ///   RegisterAsmInfoFn X(TheFooTarget, TheFunction);
638   /// }
639   struct RegisterAsmInfoFn {
640     RegisterAsmInfoFn(Target &T, Target::AsmInfoCtorFnTy Fn) {
641       TargetRegistry::RegisterAsmInfo(T, Fn);
642     }
643   };
644
645
646   /// RegisterTargetMachine - Helper template for registering a target machine
647   /// implementation, for use in the target machine initialization
648   /// function. Usage:
649   ///
650   /// extern "C" void LLVMInitializeFooTarget() {
651   ///   extern Target TheFooTarget;
652   ///   RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
653   /// }
654   template<class TargetMachineImpl>
655   struct RegisterTargetMachine {
656     RegisterTargetMachine(Target &T) {
657       TargetRegistry::RegisterTargetMachine(T, &Allocator);
658     }
659
660   private:
661     static TargetMachine *Allocator(const Target &T, const std::string &TT,
662                                     const std::string &FS) {
663       return new TargetMachineImpl(T, TT, FS);
664     }
665   };
666
667   /// RegisterAsmBackend - Helper template for registering a target specific
668   /// assembler backend. Usage:
669   ///
670   /// extern "C" void LLVMInitializeFooAsmBackend() {
671   ///   extern Target TheFooTarget;
672   ///   RegisterAsmBackend<FooAsmLexer> X(TheFooTarget);
673   /// }
674   template<class AsmBackendImpl>
675   struct RegisterAsmBackend {
676     RegisterAsmBackend(Target &T) {
677       TargetRegistry::RegisterAsmBackend(T, &Allocator);
678     }
679
680   private:
681     static TargetAsmBackend *Allocator(const Target &T,
682                                        const std::string &Triple) {
683       return new AsmBackendImpl(T, Triple);
684     }
685   };
686
687   /// RegisterAsmLexer - Helper template for registering a target specific
688   /// assembly lexer, for use in the target machine initialization
689   /// function. Usage:
690   ///
691   /// extern "C" void LLVMInitializeFooAsmLexer() {
692   ///   extern Target TheFooTarget;
693   ///   RegisterAsmLexer<FooAsmLexer> X(TheFooTarget);
694   /// }
695   template<class AsmLexerImpl>
696   struct RegisterAsmLexer {
697     RegisterAsmLexer(Target &T) {
698       TargetRegistry::RegisterAsmLexer(T, &Allocator);
699     }
700
701   private:
702     static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
703       return new AsmLexerImpl(T, MAI);
704     }
705   };
706
707   /// RegisterAsmParser - Helper template for registering a target specific
708   /// assembly parser, for use in the target machine initialization
709   /// function. Usage:
710   ///
711   /// extern "C" void LLVMInitializeFooAsmParser() {
712   ///   extern Target TheFooTarget;
713   ///   RegisterAsmParser<FooAsmParser> X(TheFooTarget);
714   /// }
715   template<class AsmParserImpl>
716   struct RegisterAsmParser {
717     RegisterAsmParser(Target &T) {
718       TargetRegistry::RegisterAsmParser(T, &Allocator);
719     }
720
721   private:
722     static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P,
723                                       TargetMachine &TM) {
724       return new AsmParserImpl(T, P, TM);
725     }
726   };
727
728   /// RegisterAsmPrinter - Helper template for registering a target specific
729   /// assembly printer, for use in the target machine initialization
730   /// function. Usage:
731   ///
732   /// extern "C" void LLVMInitializeFooAsmPrinter() {
733   ///   extern Target TheFooTarget;
734   ///   RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
735   /// }
736   template<class AsmPrinterImpl>
737   struct RegisterAsmPrinter {
738     RegisterAsmPrinter(Target &T) {
739       TargetRegistry::RegisterAsmPrinter(T, &Allocator);
740     }
741
742   private:
743     static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
744       return new AsmPrinterImpl(TM, Streamer);
745     }
746   };
747
748   /// RegisterCodeEmitter - Helper template for registering a target specific
749   /// machine code emitter, for use in the target initialization
750   /// function. Usage:
751   ///
752   /// extern "C" void LLVMInitializeFooCodeEmitter() {
753   ///   extern Target TheFooTarget;
754   ///   RegisterCodeEmitter<FooCodeEmitter> X(TheFooTarget);
755   /// }
756   template<class CodeEmitterImpl>
757   struct RegisterCodeEmitter {
758     RegisterCodeEmitter(Target &T) {
759       TargetRegistry::RegisterCodeEmitter(T, &Allocator);
760     }
761
762   private:
763     static MCCodeEmitter *Allocator(const Target &T, TargetMachine &TM,
764                                     MCContext &Ctx) {
765       return new CodeEmitterImpl(T, TM, Ctx);
766     }
767   };
768
769 }
770
771 #endif