Operand.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- Operand.h ----------------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_SCRIPT_OPERAND_H
10#define MCLD_SCRIPT_OPERAND_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <mcld/Script/ExprToken.h>
16#include <mcld/Object/SectionMap.h>
17#include <mcld/Support/Allocators.h>
18#include <mcld/Config/Config.h>
19#include <llvm/Support/DataTypes.h>
20#include <string>
21#include <cassert>
22
23namespace mcld
24{
25
26/** \class Operand
27 *  \brief This class defines the interfaces to an operand token.
28 */
29
30class Operand : public ExprToken
31{
32public:
33  enum Type {
34    SYMBOL,
35    INTEGER,
36    SECTION,
37    SECTION_DESC,
38    FRAGMENT
39  };
40
41protected:
42  Operand(Type pType);
43  virtual ~Operand();
44
45public:
46  Type type() const { return m_Type; }
47
48  virtual bool isDot() const { return false; }
49
50  virtual uint64_t value() const = 0;
51
52  static bool classof(const ExprToken* pToken)
53  {
54    return pToken->kind() == ExprToken::OPERAND;
55  }
56
57private:
58  Type m_Type;
59};
60
61/** \class SymOperand
62 *  \brief This class defines the interfaces to a symbol operand.
63 */
64
65class SymOperand : public Operand
66{
67private:
68  friend class Chunk<SymOperand, MCLD_SYMBOLS_PER_INPUT>;
69  SymOperand();
70  SymOperand(const std::string& pName);
71
72public:
73  void dump() const;
74
75  const std::string& name() const { return m_Name; }
76
77  bool isDot() const;
78
79  uint64_t value() const { return m_Value; }
80
81  void setValue(uint64_t pValue) { m_Value = pValue; }
82
83  static bool classof(const Operand* pOperand)
84  {
85    return pOperand->type() == Operand::SYMBOL;
86  }
87
88  /* factory method */
89  static SymOperand* create(const std::string& pName);
90  static void destroy(SymOperand*& pOperand);
91  static void clear();
92
93private:
94  std::string m_Name;
95  uint64_t m_Value;
96};
97
98/** \class IntOperand
99 *  \brief This class defines the interfaces to an integer operand.
100 */
101
102class IntOperand : public Operand
103{
104private:
105  friend class Chunk<IntOperand, MCLD_SYMBOLS_PER_INPUT>;
106  IntOperand();
107  IntOperand(uint64_t pValue);
108
109public:
110  void dump() const;
111
112  uint64_t value() const { return m_Value; }
113
114  void setValue(uint64_t pValue) { m_Value = pValue; }
115
116  static bool classof(const Operand* pOperand)
117  {
118    return pOperand->type() == Operand::INTEGER;
119  }
120
121  /* factory method */
122  static IntOperand* create(uint64_t pValue);
123  static void destroy(IntOperand*& pOperand);
124  static void clear();
125
126private:
127  uint64_t m_Value;
128};
129
130/** \class SectOperand
131 *  \brief This class defines the interfaces to an section name operand.
132 */
133class LDSection;
134
135class SectOperand : public Operand
136{
137private:
138  friend class Chunk<SectOperand, MCLD_SECTIONS_PER_INPUT>;
139  SectOperand();
140  SectOperand(const std::string& pName);
141
142public:
143  void dump() const;
144
145  const std::string& name() const { return m_Name; }
146
147  uint64_t value() const
148  {
149    assert(0);
150    return 0;
151  }
152
153  static bool classof(const Operand* pOperand)
154  {
155    return pOperand->type() == Operand::SECTION;
156  }
157
158  /* factory method */
159  static SectOperand* create(const std::string& pName);
160  static void destroy(SectOperand*& pOperand);
161  static void clear();
162
163private:
164  std::string m_Name;
165};
166
167/** \class SectDescOperand
168 *  \brief This class defines the interfaces to an section name operand.
169 */
170
171class SectDescOperand : public Operand
172{
173private:
174  friend class Chunk<SectDescOperand, MCLD_SECTIONS_PER_INPUT>;
175  SectDescOperand();
176  SectDescOperand(const SectionMap::Output* pOutputDesc);
177
178public:
179  void dump() const;
180
181  const SectionMap::Output* outputDesc() const { return m_pOutputDesc; }
182
183  uint64_t value() const
184  {
185    assert(0);
186    return 0;
187  }
188
189  static bool classof(const Operand* pOperand)
190  {
191    return pOperand->type() == Operand::SECTION_DESC;
192  }
193
194  /* factory method */
195  static SectDescOperand* create(const SectionMap::Output* pOutputDesc);
196  static void destroy(SectDescOperand*& pOperand);
197  static void clear();
198
199private:
200  const SectionMap::Output* m_pOutputDesc;
201};
202
203/** \class FragOperand
204 *  \brief This class defines the interfaces to a fragment operand.
205 */
206
207class Fragment;
208
209class FragOperand : public Operand
210{
211private:
212  friend class Chunk<FragOperand, MCLD_SYMBOLS_PER_INPUT>;
213  FragOperand();
214  FragOperand(Fragment& pFragment);
215
216public:
217  void dump() const;
218
219  const Fragment* frag() const { return m_pFragment; }
220  Fragment*       frag()       { return m_pFragment; }
221
222  uint64_t value() const;
223
224  static bool classof(const Operand* pOperand)
225  {
226    return pOperand->type() == Operand::FRAGMENT;
227  }
228
229  /* factory method */
230  static FragOperand* create(Fragment& pFragment);
231  static void destroy(FragOperand*& pOperand);
232  static void clear();
233
234private:
235  Fragment* m_pFragment;
236};
237
238} // namespace of mcld
239
240#endif
241
242