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