//===- Operand.h ----------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_SCRIPT_OPERAND_H
#define MCLD_SCRIPT_OPERAND_H
#include <mcld/Script/ExprToken.h>
#include <mcld/Object/SectionMap.h>
#include <mcld/Support/Allocators.h>
#include <mcld/Config/Config.h>
#include <llvm/Support/DataTypes.h>
#include <string>
#include <cassert>
namespace mcld
{
/** \class Operand
* \brief This class defines the interfaces to an operand token.
*/
class Operand : public ExprToken
{
public:
enum Type {
SYMBOL,
INTEGER,
SECTION,
SECTION_DESC,
FRAGMENT
};
protected:
Operand(Type pType);
virtual ~Operand();
public:
Type type() const { return m_Type; }
virtual bool isDot() const { return false; }
virtual uint64_t value() const = 0;
static bool classof(const ExprToken* pToken)
{
return pToken->kind() == ExprToken::OPERAND;
}
private:
Type m_Type;
};
/** \class SymOperand
* \brief This class defines the interfaces to a symbol operand.
*/
class SymOperand : public Operand
{
private:
friend class Chunk<SymOperand, MCLD_SYMBOLS_PER_INPUT>;
SymOperand();
SymOperand(const std::string& pName);
public:
void dump() const;
const std::string& name() const { return m_Name; }
bool isDot() const;
uint64_t value() const { return m_Value; }
void setValue(uint64_t pValue) { m_Value = pValue; }
static bool classof(const Operand* pOperand)
{
return pOperand->type() == Operand::SYMBOL;
}
/* factory method */
static SymOperand* create(const std::string& pName);
static void destroy(SymOperand*& pOperand);
static void clear();
private:
std::string m_Name;
uint64_t m_Value;
};
/** \class IntOperand
* \brief This class defines the interfaces to an integer operand.
*/
class IntOperand : public Operand
{
private:
friend class Chunk<IntOperand, MCLD_SYMBOLS_PER_INPUT>;
IntOperand();
IntOperand(uint64_t pValue);
public:
void dump() const;
uint64_t value() const { return m_Value; }
void setValue(uint64_t pValue) { m_Value = pValue; }
static bool classof(const Operand* pOperand)
{
return pOperand->type() == Operand::INTEGER;
}
/* factory method */
static IntOperand* create(uint64_t pValue);
static void destroy(IntOperand*& pOperand);
static void clear();
private:
uint64_t m_Value;
};
/** \class SectOperand
* \brief This class defines the interfaces to an section name operand.
*/
class LDSection;
class SectOperand : public Operand
{
private:
friend class Chunk<SectOperand, MCLD_SECTIONS_PER_INPUT>;
SectOperand();
SectOperand(const std::string& pName);
public:
void dump() const;
const std::string& name() const { return m_Name; }
uint64_t value() const
{
assert(0);
return 0;
}
static bool classof(const Operand* pOperand)
{
return pOperand->type() == Operand::SECTION;
}
/* factory method */
static SectOperand* create(const std::string& pName);
static void destroy(SectOperand*& pOperand);
static void clear();
private:
std::string m_Name;
};
/** \class SectDescOperand
* \brief This class defines the interfaces to an section name operand.
*/
class SectDescOperand : public Operand
{
private:
friend class Chunk<SectDescOperand, MCLD_SECTIONS_PER_INPUT>;
SectDescOperand();
SectDescOperand(const SectionMap::Output* pOutputDesc);
public:
void dump() const;
const SectionMap::Output* outputDesc() const { return m_pOutputDesc; }
uint64_t value() const
{
assert(0);
return 0;
}
static bool classof(const Operand* pOperand)
{
return pOperand->type() == Operand::SECTION_DESC;
}
/* factory method */
static SectDescOperand* create(const SectionMap::Output* pOutputDesc);
static void destroy(SectDescOperand*& pOperand);
static void clear();
private:
const SectionMap::Output* m_pOutputDesc;
};
/** \class FragOperand
* \brief This class defines the interfaces to a fragment operand.
*/
class Fragment;
class FragOperand : public Operand
{
private:
friend class Chunk<FragOperand, MCLD_SYMBOLS_PER_INPUT>;
FragOperand();
FragOperand(Fragment& pFragment);
public:
void dump() const;
const Fragment* frag() const { return m_pFragment; }
Fragment* frag() { return m_pFragment; }
uint64_t value() const;
static bool classof(const Operand* pOperand)
{
return pOperand->type() == Operand::FRAGMENT;
}
/* factory method */
static FragOperand* create(Fragment& pFragment);
static void destroy(FragOperand*& pOperand);
static void clear();
private:
Fragment* m_pFragment;
};
} // namespace of mcld
#endif