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