1//===- Operand.cpp --------------------------------------------------------===//
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#include <mcld/Script/Operand.h>
10#include <mcld/Support/raw_ostream.h>
11#include <mcld/Support/GCFactory.h>
12#include <mcld/LD/LDSection.h>
13#include <mcld/LD/SectionData.h>
14#include <mcld/Fragment/Fragment.h>
15#include <llvm/Support/ManagedStatic.h>
16
17using namespace mcld;
18
19//===----------------------------------------------------------------------===//
20// Operand
21//===----------------------------------------------------------------------===//
22Operand::Operand(Type pType)
23  : ExprToken(ExprToken::OPERAND), m_Type(pType)
24{
25}
26
27Operand::~Operand()
28{
29}
30
31//===----------------------------------------------------------------------===//
32// SymOperand
33//===----------------------------------------------------------------------===//
34typedef GCFactory<SymOperand, MCLD_SYMBOLS_PER_INPUT> SymOperandFactory;
35static llvm::ManagedStatic<SymOperandFactory> g_SymOperandFactory;
36
37SymOperand::SymOperand()
38  : Operand(Operand::SYMBOL), m_Value(0)
39{
40}
41
42SymOperand::SymOperand(const std::string& pName)
43  : Operand(Operand::SYMBOL), m_Name(pName), m_Value(0)
44{
45}
46
47void SymOperand::dump() const
48{
49  mcld::outs() << m_Name;
50}
51
52bool SymOperand::isDot() const
53{
54  assert(!m_Name.empty());
55  return m_Name.size() == 1 && m_Name[0] == '.';
56}
57
58SymOperand* SymOperand::create(const std::string& pName)
59{
60  SymOperand* result = g_SymOperandFactory->allocate();
61  new (result) SymOperand(pName);
62  return result;
63}
64
65void SymOperand::destroy(SymOperand*& pOperand)
66{
67  g_SymOperandFactory->destroy(pOperand);
68  g_SymOperandFactory->deallocate(pOperand);
69  pOperand = NULL;
70}
71
72void SymOperand::clear()
73{
74  g_SymOperandFactory->clear();
75}
76
77//===----------------------------------------------------------------------===//
78// IntOperand
79//===----------------------------------------------------------------------===//
80typedef GCFactory<IntOperand, MCLD_SYMBOLS_PER_INPUT> IntOperandFactory;
81static llvm::ManagedStatic<IntOperandFactory> g_IntOperandFactory;
82
83IntOperand::IntOperand()
84  : Operand(Operand::INTEGER), m_Value(0)
85{
86}
87
88IntOperand::IntOperand(uint64_t pValue)
89  : Operand(Operand::INTEGER), m_Value(pValue)
90{
91}
92
93void IntOperand::dump() const
94{
95  mcld::outs() << m_Value;
96}
97
98IntOperand* IntOperand::create(uint64_t pValue)
99{
100  IntOperand* result = g_IntOperandFactory->allocate();
101  new (result) IntOperand(pValue);
102  return result;
103}
104
105void IntOperand::destroy(IntOperand*& pOperand)
106{
107  g_IntOperandFactory->destroy(pOperand);
108  g_IntOperandFactory->deallocate(pOperand);
109  pOperand = NULL;
110}
111
112void IntOperand::clear()
113{
114  g_IntOperandFactory->clear();
115}
116
117//===----------------------------------------------------------------------===//
118// SectOperand
119//===----------------------------------------------------------------------===//
120typedef GCFactory<SectOperand, MCLD_SECTIONS_PER_INPUT> SectOperandFactory;
121static llvm::ManagedStatic<SectOperandFactory> g_SectOperandFactory;
122SectOperand::SectOperand()
123  : Operand(Operand::SECTION)
124{
125}
126
127SectOperand::SectOperand(const std::string& pName)
128  : Operand(Operand::SECTION), m_Name(pName)
129{
130}
131
132void SectOperand::dump() const
133{
134  mcld::outs() << m_Name;
135}
136
137SectOperand* SectOperand::create(const std::string& pName)
138{
139  SectOperand* result = g_SectOperandFactory->allocate();
140  new (result) SectOperand(pName);
141  return result;
142}
143
144void SectOperand::destroy(SectOperand*& pOperand)
145{
146  g_SectOperandFactory->destroy(pOperand);
147  g_SectOperandFactory->deallocate(pOperand);
148  pOperand = NULL;
149}
150
151void SectOperand::clear()
152{
153  g_SectOperandFactory->clear();
154}
155
156//===----------------------------------------------------------------------===//
157// SectDescOperand
158//===----------------------------------------------------------------------===//
159typedef GCFactory<SectDescOperand,
160                  MCLD_SECTIONS_PER_INPUT> SectDescOperandFactory;
161static llvm::ManagedStatic<SectDescOperandFactory> g_SectDescOperandFactory;
162SectDescOperand::SectDescOperand()
163  : Operand(Operand::SECTION_DESC), m_pOutputDesc(NULL)
164{
165}
166
167SectDescOperand::SectDescOperand(const SectionMap::Output* pOutputDesc)
168  : Operand(Operand::SECTION_DESC), m_pOutputDesc(pOutputDesc)
169{
170}
171
172void SectDescOperand::dump() const
173{
174  assert(m_pOutputDesc != NULL);
175  mcld::outs() << m_pOutputDesc->getSection()->name();
176}
177
178SectDescOperand* SectDescOperand::create(const SectionMap::Output* pOutputDesc)
179{
180  SectDescOperand* result = g_SectDescOperandFactory->allocate();
181  new (result) SectDescOperand(pOutputDesc);
182  return result;
183}
184
185void SectDescOperand::destroy(SectDescOperand*& pOperand)
186{
187  g_SectDescOperandFactory->destroy(pOperand);
188  g_SectDescOperandFactory->deallocate(pOperand);
189  pOperand = NULL;
190}
191
192void SectDescOperand::clear()
193{
194  g_SectDescOperandFactory->clear();
195}
196
197//===----------------------------------------------------------------------===//
198// FragOperand
199//===----------------------------------------------------------------------===//
200typedef GCFactory<FragOperand, MCLD_SYMBOLS_PER_INPUT> FragOperandFactory;
201static llvm::ManagedStatic<FragOperandFactory> g_FragOperandFactory;
202
203FragOperand::FragOperand()
204  : Operand(Operand::FRAGMENT), m_pFragment(NULL)
205{
206}
207
208FragOperand::FragOperand(Fragment& pFragment)
209  : Operand(Operand::FRAGMENT), m_pFragment(&pFragment)
210{
211}
212
213void FragOperand::dump() const
214{
215  mcld::outs() << "fragment";
216}
217
218uint64_t FragOperand::value() const
219{
220  return m_pFragment->getOffset() +
221         m_pFragment->getParent()->getSection().addr();
222}
223
224FragOperand* FragOperand::create(Fragment& pFragment)
225{
226  FragOperand* result = g_FragOperandFactory->allocate();
227  new (result) FragOperand(pFragment);
228  return result;
229}
230
231void FragOperand::destroy(FragOperand*& pOperand)
232{
233  g_FragOperandFactory->destroy(pOperand);
234  g_FragOperandFactory->deallocate(pOperand);
235  pOperand = NULL;
236}
237
238void FragOperand::clear()
239{
240  g_FragOperandFactory->clear();
241}
242