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