//===- TargetRegistry.h ---------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef TARGET_REGISTRY_H
#define TARGET_REGISTRY_H
#include <llvm/Support/TargetRegistry.h>
#include <string>
#include <list>

namespace llvm {
class TargetMachine;
class MCCodeEmitter;
class MCContext;
class AsmPrinter;
} // namespace of llvm

namespace mcld {
class LLVMTargetMachine;
class TargetRegistry;
class SectLinker;
class SectLinkerOption;
class TargetLDBackend;
class AttributeFactory;
class InputFactory;
class ContextFactory;

//===----------------------------------------------------------------------===//
/// Target - mcld::Target is an object adapter of llvm::Target
///
class Target
{
  friend class mcld::LLVMTargetMachine;
  friend class mcld::TargetRegistry;
public:
  typedef mcld::LLVMTargetMachine *(*TargetMachineCtorTy)(const mcld::Target &,
                                                          llvm::TargetMachine &,
                                                          const std::string&);

  typedef SectLinker *(*SectLinkerCtorTy)(const std::string& pTriple,
                                          SectLinkerOption &,
                                          TargetLDBackend&);

  typedef TargetLDBackend  *(*TargetLDBackendCtorTy)(const llvm::Target&,
                                                     const std::string&);

private:
  TargetMachineCtorTy TargetMachineCtorFn;
  SectLinkerCtorTy SectLinkerCtorFn;
  TargetLDBackendCtorTy TargetLDBackendCtorFn;

public:
  Target();

  void setTarget(const llvm::Target& pTarget) {
    m_pT = &pTarget;
  }

  mcld::LLVMTargetMachine *createTargetMachine(const std::string &pTriple,
                          const std::string &pCPU, const std::string &pFeatures,
                          const llvm::TargetOptions &Options,
                          llvm::Reloc::Model RM = llvm::Reloc::Default,
                          llvm::CodeModel::Model CM = llvm::CodeModel::Default,
                          llvm::CodeGenOpt::Level OL = llvm::CodeGenOpt::Default) const {
    if (TargetMachineCtorFn && m_pT) {
      llvm::TargetMachine *tm = m_pT->createTargetMachine(pTriple, pCPU, pFeatures, Options, RM, CM, OL);
      if (tm)
        return TargetMachineCtorFn(*this, *tm, pTriple);
    }
    return 0;
  }

  /// createSectLinker - create target-specific SectLinker
  ///
  /// @return created SectLinker
  SectLinker *createSectLinker(const std::string &pTriple,
                               SectLinkerOption &pOption,
                               TargetLDBackend &pLDBackend) const {
    if (!SectLinkerCtorFn)
      return 0;
    return SectLinkerCtorFn(pTriple,
                            pOption,
                            pLDBackend);
  }

  /// createLDBackend - create target-specific LDBackend
  ///
  /// @return created TargetLDBackend
  TargetLDBackend *createLDBackend(const llvm::Target& T, const std::string& Triple) const {
    if (!TargetLDBackendCtorFn)
      return 0;
    return TargetLDBackendCtorFn(T, Triple);
  }

  const llvm::Target* get() const {
    return m_pT;
  }

private:
  const llvm::Target* m_pT;
};

//===----------------------------------------------------------------------===//
/// TargetRegistry - mcld::TargetRegistry is an object adapter of
/// llvm::TargetRegistry
///
class TargetRegistry
{
public:
  typedef std::list<mcld::Target*> TargetListTy;
  typedef TargetListTy::iterator iterator;

private:
  static TargetListTy s_TargetList;

public:
  static iterator begin() { return s_TargetList.begin(); }
  static iterator end() { return s_TargetList.end(); }

  static size_t size() { return s_TargetList.size(); }
  static bool empty() { return s_TargetList.empty(); }

  /// RegisterTarget - Register the given target. Attempts to register a
  /// target which has already been registered will be ignored.
  ///
  /// Clients are responsible for ensuring that registration doesn't occur
  /// while another thread is attempting to access the registry. Typically
  /// this is done by initializing all targets at program startup.
  ///
  /// @param T - The target being registered.
  static void RegisterTarget(mcld::Target &T);

  /// RegisterTargetMachine - Register a TargetMachine implementation for the
  /// given target.
  ///
  /// @param T - The target being registered.
  /// @param Fn - A function to construct a TargetMachine for the target.
  static void RegisterTargetMachine(mcld::Target &T, mcld::Target::TargetMachineCtorTy Fn) {
    // Ignore duplicate registration.
    if (!T.TargetMachineCtorFn)
      T.TargetMachineCtorFn = Fn;
  }

  /// RegisterSectLinker - Register a SectLinker implementation for the given
  /// target.
  ///
  /// @param T - the target being registered
  /// @param Fn - A function to create SectLinker for the target
  static void RegisterSectLinker(mcld::Target &T, mcld::Target::SectLinkerCtorTy Fn) {
    if (!T.SectLinkerCtorFn)
      T.SectLinkerCtorFn = Fn;
  }

  /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for
  /// the given target.
  ///
  /// @param T - The target being registered
  /// @param Fn - A function to create TargetLDBackend for the target
  static void RegisterTargetLDBackend(mcld::Target &T, mcld::Target::TargetLDBackendCtorTy Fn) {
    if (!T.TargetLDBackendCtorFn)
      T.TargetLDBackendCtorFn = Fn;
  }

  /// lookupTarget - Lookup a target based on a llvm::Target.
  ///
  /// @param T - The llvm::Target to find
  static const mcld::Target *lookupTarget(const llvm::Target& T);

  /// lookupTarget - function wrapper of llvm::TargetRegistry::lookupTarget
  ///
  /// @param Triple - The Triple string
  /// @param Error  - The returned error message
  static const mcld::Target *lookupTarget(const std::string &Triple,
                                          std::string &Error);
};

/// RegisterTarget - Helper function for registering a target, for use in the
/// target's initialization function. Usage:
///
/// Target TheFooTarget; // The global target instance.
///
/// extern "C" void LLVMInitializeFooTargetInfo() {
///   RegisterTarget X(TheFooTarget, "foo", "Foo description");
/// }
struct RegisterTarget
{
  RegisterTarget(mcld::Target &T, const char *Name) {
    llvm::TargetRegistry::iterator TIter, TEnd = llvm::TargetRegistry::end();
    // lookup llvm::Target
    for( TIter=llvm::TargetRegistry::begin(); TIter!=TEnd; ++TIter ) {
      if( 0==strcmp(TIter->getName(), Name) )
        break;
    }
    T.setTarget(*TIter);

    TargetRegistry::RegisterTarget(T);
  }
};

/// RegisterTargetMachine - Helper template for registering a target machine
/// implementation, for use in the target machine initialization
/// function. Usage:
///
/// extern "C" void LLVMInitializeFooTarget() {
///   extern mcld::Target TheFooTarget;
///   RegisterTargetMachine<mcld::FooTargetMachine> X(TheFooTarget);
/// }
template<class TargetMachineImpl>
struct RegisterTargetMachine
{
  RegisterTargetMachine(mcld::Target &T) {
    TargetRegistry::RegisterTargetMachine(T, &Allocator);
  }

private:
  static mcld::LLVMTargetMachine *Allocator(const mcld::Target &T,
                                            llvm::TargetMachine& TM,
                                            const std::string &Triple) {
    return new TargetMachineImpl(TM, T, Triple);
  }
};

} //end namespace mcld

#endif

