TargetRegistry.h revision 37b74a387bb3993387029859c2d9d051c41c724e
1//===- TargetRegistry.h ---------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_SUPPORT_TARGETREGISTRY_H_
10#define MCLD_SUPPORT_TARGETREGISTRY_H_
11#include "mcld/Support/Target.h"
12
13#include <llvm/ADT/Triple.h>
14
15#include <list>
16#include <string>
17
18namespace llvm {
19class TargetMachine;
20class MCCodeEmitter;
21class MCContext;
22class AsmPrinter;
23}  // namespace llvm
24
25namespace mcld {
26
27/** \class TargetRegistry
28 *  \brief TargetRegistry is an object adapter of llvm::TargetRegistry
29 */
30class TargetRegistry {
31 public:
32  typedef std::list<mcld::Target*> TargetListTy;
33  typedef TargetListTy::iterator iterator;
34
35 private:
36  static TargetListTy s_TargetList;
37
38 public:
39  static iterator begin() { return s_TargetList.begin(); }
40  static iterator end() { return s_TargetList.end(); }
41
42  static size_t size() { return s_TargetList.size(); }
43  static bool empty() { return s_TargetList.empty(); }
44
45  /// RegisterTarget - Register the given target. Attempts to register a
46  /// target which has already been registered will be ignored.
47  ///
48  /// Clients are responsible for ensuring that registration doesn't occur
49  /// while another thread is attempting to access the registry. Typically
50  /// this is done by initializing all targets at program startup.
51  ///
52  /// @param T - The target being registered.
53  static void RegisterTarget(Target& pTarget,
54                             const char* pName,
55                             Target::TripleMatchQualityFnTy pQualityFn);
56
57  /// RegisterEmulation - Register a emulation function for the target.
58  /// target.
59  ///
60  /// @param T - the target being registered
61  /// @param Fn - A emulation function
62  static void RegisterEmulation(mcld::Target& T,
63                                mcld::Target::EmulationFnTy Fn) {
64    if (!T.EmulationFn)
65      T.EmulationFn = Fn;
66  }
67
68  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
69  /// the given target.
70  ///
71  /// @param T - The target being registered
72  /// @param Fn - A function to create TargetLDBackend for the target
73  static void RegisterTargetLDBackend(mcld::Target& T,
74                                      mcld::Target::TargetLDBackendCtorTy Fn) {
75    if (!T.TargetLDBackendCtorFn)
76      T.TargetLDBackendCtorFn = Fn;
77  }
78
79  /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo
80  /// implementation for the given target.
81  ///
82  /// @param T - The target being registered
83  /// @param Fn - A function to create DiagnosticLineInfo for the target
84  static void RegisterDiagnosticLineInfo(
85      mcld::Target& T,
86      mcld::Target::DiagnosticLineInfoCtorTy Fn) {
87    if (!T.DiagnosticLineInfoCtorFn)
88      T.DiagnosticLineInfoCtorFn = Fn;
89  }
90
91  /// lookupTarget - Look up MCLinker target
92  ///
93  /// @param Triple - The Triple string
94  /// @param Error  - The returned error message
95  static const mcld::Target* lookupTarget(const std::string& pTriple,
96                                          std::string& pError);
97
98  /// lookupTarget - Look up MCLinker target by an architecture name
99  /// and a triple. If the architecture name is not empty, then the
100  /// the lookup is done mainly by architecture. Otherwise, the target
101  /// triple is used.
102  ///
103  /// @param pArch   - The architecture name
104  /// @param pTriple - The target triple
105  /// @param pError  - The returned error message
106  static const mcld::Target* lookupTarget(const std::string& pArchName,
107                                          llvm::Triple& pTriple,
108                                          std::string& Error);
109};
110
111/// RegisterTarget - Helper function for registering a target, for use in the
112/// target's initialization function. Usage:
113///
114/// Target TheFooTarget; // The global target instance.
115///
116/// extern "C" void MCLDInitializeFooTargetInfo() {
117///   RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description");
118/// }
119template <llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch>
120struct RegisterTarget {
121 public:
122  RegisterTarget(mcld::Target& pTarget, const char* pName) {
123    // if we've registered one, then return immediately.
124    TargetRegistry::iterator target, ie = TargetRegistry::end();
125    for (target = TargetRegistry::begin(); target != ie; ++target) {
126      if (strcmp((*target)->name(), pName) == 0)
127        return;
128    }
129
130    TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality);
131  }
132
133  static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) {
134    if (pTriple.getArch() == TargetArchType)
135      return 20;
136    return 0;
137  }
138};
139
140}  // namespace mcld
141
142#endif  // MCLD_SUPPORT_TARGETREGISTRY_H_
143