//===- Operand.cpp --------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "mcld/Script/Operand.h"
#include "mcld/Fragment/Fragment.h"
#include "mcld/LD/LDSection.h"
#include "mcld/LD/SectionData.h"
#include "mcld/Support/GCFactory.h"
#include "mcld/Support/raw_ostream.h"
#include <llvm/Support/ManagedStatic.h>
namespace mcld {
//===----------------------------------------------------------------------===//
// Operand
//===----------------------------------------------------------------------===//
Operand::Operand(Type pType) : ExprToken(ExprToken::OPERAND), m_Type(pType) {
}
Operand::~Operand() {
}
//===----------------------------------------------------------------------===//
// SymOperand
//===----------------------------------------------------------------------===//
typedef GCFactory<SymOperand, MCLD_SYMBOLS_PER_INPUT> SymOperandFactory;
static llvm::ManagedStatic<SymOperandFactory> g_SymOperandFactory;
SymOperand::SymOperand() : Operand(Operand::SYMBOL), m_Value(0) {
}
SymOperand::SymOperand(const std::string& pName)
: Operand(Operand::SYMBOL), m_Name(pName), m_Value(0) {
}
void SymOperand::dump() const {
mcld::outs() << m_Name;
}
bool SymOperand::isDot() const {
assert(!m_Name.empty());
return m_Name.size() == 1 && m_Name[0] == '.';
}
SymOperand* SymOperand::create(const std::string& pName) {
SymOperand* result = g_SymOperandFactory->allocate();
new (result) SymOperand(pName);
return result;
}
void SymOperand::destroy(SymOperand*& pOperand) {
g_SymOperandFactory->destroy(pOperand);
g_SymOperandFactory->deallocate(pOperand);
pOperand = NULL;
}
void SymOperand::clear() {
g_SymOperandFactory->clear();
}
//===----------------------------------------------------------------------===//
// IntOperand
//===----------------------------------------------------------------------===//
typedef GCFactory<IntOperand, MCLD_SYMBOLS_PER_INPUT> IntOperandFactory;
static llvm::ManagedStatic<IntOperandFactory> g_IntOperandFactory;
IntOperand::IntOperand() : Operand(Operand::INTEGER), m_Value(0) {
}
IntOperand::IntOperand(uint64_t pValue)
: Operand(Operand::INTEGER), m_Value(pValue) {
}
void IntOperand::dump() const {
mcld::outs() << m_Value;
}
IntOperand* IntOperand::create(uint64_t pValue) {
IntOperand* result = g_IntOperandFactory->allocate();
new (result) IntOperand(pValue);
return result;
}
void IntOperand::destroy(IntOperand*& pOperand) {
g_IntOperandFactory->destroy(pOperand);
g_IntOperandFactory->deallocate(pOperand);
pOperand = NULL;
}
void IntOperand::clear() {
g_IntOperandFactory->clear();
}
//===----------------------------------------------------------------------===//
// SectOperand
//===----------------------------------------------------------------------===//
typedef GCFactory<SectOperand, MCLD_SECTIONS_PER_INPUT> SectOperandFactory;
static llvm::ManagedStatic<SectOperandFactory> g_SectOperandFactory;
SectOperand::SectOperand() : Operand(Operand::SECTION) {
}
SectOperand::SectOperand(const std::string& pName)
: Operand(Operand::SECTION), m_Name(pName) {
}
void SectOperand::dump() const {
mcld::outs() << m_Name;
}
SectOperand* SectOperand::create(const std::string& pName) {
SectOperand* result = g_SectOperandFactory->allocate();
new (result) SectOperand(pName);
return result;
}
void SectOperand::destroy(SectOperand*& pOperand) {
g_SectOperandFactory->destroy(pOperand);
g_SectOperandFactory->deallocate(pOperand);
pOperand = NULL;
}
void SectOperand::clear() {
g_SectOperandFactory->clear();
}
//===----------------------------------------------------------------------===//
// SectDescOperand
//===----------------------------------------------------------------------===//
typedef GCFactory<SectDescOperand, MCLD_SECTIONS_PER_INPUT>
SectDescOperandFactory;
static llvm::ManagedStatic<SectDescOperandFactory> g_SectDescOperandFactory;
SectDescOperand::SectDescOperand()
: Operand(Operand::SECTION_DESC), m_pOutputDesc(NULL) {
}
SectDescOperand::SectDescOperand(const SectionMap::Output* pOutputDesc)
: Operand(Operand::SECTION_DESC), m_pOutputDesc(pOutputDesc) {
}
void SectDescOperand::dump() const {
assert(m_pOutputDesc != NULL);
mcld::outs() << m_pOutputDesc->getSection()->name();
}
SectDescOperand* SectDescOperand::create(
const SectionMap::Output* pOutputDesc) {
SectDescOperand* result = g_SectDescOperandFactory->allocate();
new (result) SectDescOperand(pOutputDesc);
return result;
}
void SectDescOperand::destroy(SectDescOperand*& pOperand) {
g_SectDescOperandFactory->destroy(pOperand);
g_SectDescOperandFactory->deallocate(pOperand);
pOperand = NULL;
}
void SectDescOperand::clear() {
g_SectDescOperandFactory->clear();
}
//===----------------------------------------------------------------------===//
// FragOperand
//===----------------------------------------------------------------------===//
typedef GCFactory<FragOperand, MCLD_SYMBOLS_PER_INPUT> FragOperandFactory;
static llvm::ManagedStatic<FragOperandFactory> g_FragOperandFactory;
FragOperand::FragOperand() : Operand(Operand::FRAGMENT), m_pFragment(NULL) {
}
FragOperand::FragOperand(Fragment& pFragment)
: Operand(Operand::FRAGMENT), m_pFragment(&pFragment) {
}
void FragOperand::dump() const {
mcld::outs() << "fragment";
}
uint64_t FragOperand::value() const {
return m_pFragment->getOffset() +
m_pFragment->getParent()->getSection().addr();
}
FragOperand* FragOperand::create(Fragment& pFragment) {
FragOperand* result = g_FragOperandFactory->allocate();
new (result) FragOperand(pFragment);
return result;
}
void FragOperand::destroy(FragOperand*& pOperand) {
g_FragOperandFactory->destroy(pOperand);
g_FragOperandFactory->deallocate(pOperand);
pOperand = NULL;
}
void FragOperand::clear() {
g_FragOperandFactory->clear();
}
} // namespace mcld