//===- MCLDFile.h ---------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// MCLDFile represents a file, the content of the file is stored in LDContext.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_LD_FILE_H
#define MCLD_LD_FILE_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif
#include "mcld/ADT/Uncopyable.h"
#include "mcld/LD/LDContext.h"
#include "mcld/Support/Path.h"
#include "mcld/Support/FileSystem.h"
#include "mcld/Support/GCFactory.h"
#include "mcld/Support/MemoryArea.h"
#include <llvm/ADT/StringRef.h>
#include <string>
#include <sys/stat.h>
namespace mcld
{
class MemoryArea;
/** \class MCLDFile
* \brief MCLDFile represents the file being linked or produced.
*
* MCLDFile is the storage of name, path and type
* A MCLDFile just refers to LDContext, not owns it.
*
* @see mcld::sys::fs::Path LDContext
*/
class MCLDFile : private Uncopyable
{
public:
enum Type {
Unknown,
Object,
Exec,
DynObj,
CoreFile,
Script,
Archive,
External
};
public:
MCLDFile();
MCLDFile(llvm::StringRef pName);
MCLDFile(llvm::StringRef pName,
const sys::fs::Path& pPath,
unsigned int pType = Unknown);
virtual ~MCLDFile();
// ----- modifiers ----- //
void setType(unsigned int pType)
{ m_Type = pType; }
void setContext(LDContext* pContext)
{ m_pContext = pContext; }
void setPath(const sys::fs::Path& pPath)
{ m_Path = pPath; }
void setMemArea(MemoryArea* pMemArea)
{
m_pMemArea = pMemArea;
}
/// setSOName - set the name of the shared object.
/// In ELF, this will be written in DT_SONAME
void setSOName(const std::string& pName);
// ----- observers ----- //
unsigned int type() const
{ return m_Type; }
const std::string& name() const
{ return m_Name; }
const sys::fs::Path& path() const
{ return m_Path; }
bool hasContext() const
{ return (0 != m_pContext); }
LDContext* context()
{ return m_pContext; }
const LDContext* context() const
{ return m_pContext; }
bool hasMemArea() const
{ return (0 != m_pMemArea); }
MemoryArea* memArea()
{ return m_pMemArea; }
const MemoryArea* memArea() const
{ return m_pMemArea; }
protected:
unsigned int m_Type;
LDContext *m_pContext;
sys::fs::Path m_Path;
std::string m_Name;
MemoryArea* m_pMemArea;
};
/** \class MCLDFileFactory
* \brief MCLDFileFactory controls the production and destruction of
* MCLDFiles.
*
* All MCLDFiles created by MCLDFileFactory are guaranteed to be destructed
* while MCLDFileFactory is destructed.
*
* MCLDFileFactory also provides the MCLCContextFactory to MCLDFile.
* MCLDFile is responsed for the life of LDContext, therefore, the best
* idea is let MCLDFile control the life of LDContext. Since SectLinker
* has the need to count the number of LDContext, we give a central factory
* for LDContext.
*
* \see llvm::sys::Path
*/
template<size_t NUM>
class MCLDFileFactory : public GCFactory<MCLDFile, NUM>
{
public:
typedef GCFactory<MCLDFile, NUM> Alloc;
public:
// ----- production ----- //
MCLDFile* produce(llvm::StringRef pName,
const sys::fs::Path& pPath,
unsigned int pType = MCLDFile::Unknown);
MCLDFile* produce();
};
} // namespace of mcld
//===----------------------------------------------------------------------===//
// MCLDFileFactory
template<size_t NUM>
mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce(llvm::StringRef pName,
const mcld::sys::fs::Path& pPath,
unsigned int pType)
{
mcld::MCLDFile* result = Alloc::allocate();
new (result) mcld::MCLDFile(pName, pPath, pType);
return result;
}
template<size_t NUM>
mcld::MCLDFile* mcld::MCLDFileFactory<NUM>::produce()
{
mcld::MCLDFile* result = Alloc::allocate();
new (result) mcld::MCLDFile();
return result;
}
#endif