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