| //===- 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 |