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