//===- Module.h -----------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Module contains the intermediate representation (LDIR) of MCLinker.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_MODULE_H
#define MCLD_MODULE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include <vector>
#include <string>
#include <map>
#include <mcld/LinkerScript.h>
#include <mcld/InputTree.h>
#include <mcld/ADT/HashTable.h>
#include <mcld/ADT/HashEntry.h>
#include <mcld/Support/GCFactoryListTraits.h>
#include <mcld/Fragment/Fragment.h>
#include <mcld/LD/NamePool.h>
#include <mcld/LD/SectionSymbolSet.h>
#include <mcld/MC/SymbolCategory.h>
#include <mcld/MC/MCLDInput.h>
#include <llvm/ADT/ilist.h>
namespace mcld {
class LDSection;
class LDSymbol;
/** \class Module
* \brief Module provides the intermediate representation for linking.
*/
class Module
{
public:
typedef std::vector<Input*> ObjectList;
typedef ObjectList::iterator obj_iterator;
typedef ObjectList::const_iterator const_obj_iterator;
typedef std::vector<Input*> LibraryList;
typedef LibraryList::iterator lib_iterator;
typedef LibraryList::const_iterator const_lib_iterator;
typedef InputTree::iterator input_iterator;
typedef InputTree::const_iterator const_input_iterator;
typedef std::vector<LDSection*> SectionTable;
typedef SectionTable::iterator iterator;
typedef SectionTable::const_iterator const_iterator;
typedef SymbolCategory SymbolTable;
typedef SymbolTable::iterator sym_iterator;
typedef SymbolTable::const_iterator const_sym_iterator;
typedef std::vector<const ResolveInfo*> AliasList;
typedef AliasList::iterator alias_iterator;
typedef AliasList::const_iterator const_alias_iterator;
public:
explicit Module(LinkerScript& pScript);
Module(const std::string& pName, LinkerScript& pScript);
~Module();
const std::string& name() const { return m_Name; }
void setName(const std::string& pName) { m_Name = pName; }
const LinkerScript& getScript() const { return m_Script; }
LinkerScript& getScript() { return m_Script; }
// ----- link-in objects ----- //
const ObjectList& getObjectList() const { return m_ObjectList; }
ObjectList& getObjectList() { return m_ObjectList; }
const_obj_iterator obj_begin() const { return m_ObjectList.begin(); }
obj_iterator obj_begin() { return m_ObjectList.begin(); }
const_obj_iterator obj_end () const { return m_ObjectList.end(); }
obj_iterator obj_end () { return m_ObjectList.end(); }
// ----- link-in libraries ----- //
const LibraryList& getLibraryList() const { return m_LibraryList; }
LibraryList& getLibraryList() { return m_LibraryList; }
const_lib_iterator lib_begin() const { return m_LibraryList.begin(); }
lib_iterator lib_begin() { return m_LibraryList.begin(); }
const_lib_iterator lib_end () const { return m_LibraryList.end(); }
lib_iterator lib_end () { return m_LibraryList.end(); }
// ----- link-in inputs ----- //
const InputTree& getInputTree() const { return m_MainTree; }
InputTree& getInputTree() { return m_MainTree; }
const_input_iterator input_begin() const { return m_MainTree.begin(); }
input_iterator input_begin() { return m_MainTree.begin(); }
const_input_iterator input_end () const { return m_MainTree.end(); }
input_iterator input_end () { return m_MainTree.end(); }
/// @}
/// @name Section Accessors
/// @{
// ----- sections ----- //
const SectionTable& getSectionTable() const { return m_SectionTable; }
SectionTable& getSectionTable() { return m_SectionTable; }
iterator begin() { return m_SectionTable.begin(); }
const_iterator begin() const { return m_SectionTable.begin(); }
iterator end () { return m_SectionTable.end(); }
const_iterator end () const { return m_SectionTable.end(); }
LDSection* front() { return m_SectionTable.front(); }
const LDSection* front() const { return m_SectionTable.front(); }
LDSection* back () { return m_SectionTable.back(); }
const LDSection* back () const { return m_SectionTable.back(); }
size_t size () const { return m_SectionTable.size(); }
bool empty() const { return m_SectionTable.empty(); }
LDSection* getSection(const std::string& pName);
const LDSection* getSection(const std::string& pName) const;
/// @}
/// @name Symbol Accessors
/// @{
// ----- symbols ----- //
const SymbolTable& getSymbolTable() const { return m_SymbolTable; }
SymbolTable& getSymbolTable() { return m_SymbolTable; }
sym_iterator sym_begin() { return m_SymbolTable.begin(); }
const_sym_iterator sym_begin() const { return m_SymbolTable.begin(); }
sym_iterator sym_end () { return m_SymbolTable.end(); }
const_sym_iterator sym_end () const { return m_SymbolTable.end(); }
size_t sym_size () const { return m_SymbolTable.numOfSymbols(); }
// ----- section symbols ----- //
const LDSymbol* getSectionSymbol(const LDSection& pSection) const
{ return m_SectSymbolSet.get(pSection); }
LDSymbol* getSectionSymbol(const LDSection& pSection)
{ return m_SectSymbolSet.get(pSection); }
const SectionSymbolSet& getSectionSymbolSet() const
{ return m_SectSymbolSet; }
SectionSymbolSet& getSectionSymbolSet()
{ return m_SectSymbolSet; }
// ----- names ----- //
const NamePool& getNamePool() const { return m_NamePool; }
NamePool& getNamePool() { return m_NamePool; }
// ----- Aliases ----- //
// create an alias list for pSym, the aliases of pSym
// can be added into the list by calling addAlias
void CreateAliasList(const ResolveInfo& pSym);
// add pAlias into the newly created alias list
void addAlias(const ResolveInfo& pAlias);
AliasList* getAliasList(const ResolveInfo& pSym);
private:
std::string m_Name;
LinkerScript& m_Script;
ObjectList m_ObjectList;
LibraryList m_LibraryList;
InputTree m_MainTree;
SectionTable m_SectionTable;
SymbolTable m_SymbolTable;
NamePool m_NamePool;
SectionSymbolSet m_SectSymbolSet;
std::vector<AliasList*> m_AliasLists;
};
} // namespace of mcld
#endif