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