//===- Linker.h -----------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_LINKER_H
#define MCLD_LINKER_H

#include <string>

namespace mcld {

class Module;
class LinkerConfig;
class LinkerScript;

class Target;
class TargetLDBackend;

class IRBuilder;
class ObjectLinker;

class FileHandle;
class FileOutputBuffer;

/** \class Linker
*  \brief Linker is a modular linker.
*/
class Linker
{
public:
  Linker();

  ~Linker();

  /// emulate - To set up target-dependent options and default linker script.
  bool emulate(LinkerScript& pScript, LinkerConfig& pConfig);

  /// normalize - To normalize the command line language into mcld::Module.
  bool normalize(Module& pModule, IRBuilder& pBuilder);

  /// resolve - To build up the topology of mcld::Module.
  bool resolve(Module& pModule);

  /// layout - To serialize the final result of the output mcld::Module.
  bool layout();

  /// link - A convenient way to resolve and to layout the output mcld::Module.
  bool link(Module& pModule, IRBuilder& pBuilder);

  /// emit - To emit output mcld::Module to a FileOutputBuffer.
  bool emit(FileOutputBuffer& pOutput);

  /// emit - To open a file for output in pPath and to emit output mcld::Module
  /// to the file.
  bool emit(const Module& pModule, const std::string& pPath);

  /// emit - To emit output mcld::Module in the pFileDescriptor.
  bool emit(const Module& pModule, int pFileDescriptor);

  bool reset();

private:
  bool initTarget();

  bool initBackend();

  bool initOStream();

  bool initEmulator(LinkerScript& pScript);

private:
  LinkerConfig* m_pConfig;
  IRBuilder* m_pIRBuilder;

  const Target* m_pTarget;
  TargetLDBackend* m_pBackend;
  ObjectLinker* m_pObjLinker;
};

} // namespace of MC Linker

#endif