C++程序  |  242行  |  5.97 KB

//===- 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/Support/raw_ostream.h>
#include <mcld/Support/GCFactory.h>
#include <mcld/LD/LDSection.h>
#include <mcld/LD/SectionData.h>
#include <mcld/Fragment/Fragment.h>
#include <llvm/Support/ManagedStatic.h>

using 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();
}