1//===- RPNExpr.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/RpnExpr.h>
10#include <mcld/Script/ExprToken.h>
11#include <mcld/Script/Operand.h>
12#include <mcld/Script/Operator.h>
13#include <mcld/Support/GCFactory.h>
14#include <mcld/Support/raw_ostream.h>
15#include <llvm/Support/ManagedStatic.h>
16#include <llvm/Support/Casting.h>
17
18using namespace mcld;
19
20typedef GCFactory<RpnExpr, MCLD_SYMBOLS_PER_INPUT> ExprFactory;
21static llvm::ManagedStatic<ExprFactory> g_ExprFactory;
22
23//===----------------------------------------------------------------------===//
24// RpnExpr
25//===----------------------------------------------------------------------===//
26RpnExpr::RpnExpr()
27{
28}
29
30RpnExpr::~RpnExpr()
31{
32}
33
34bool RpnExpr::hasDot() const
35{
36  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
37    if ((*it)->kind() == ExprToken::OPERAND &&
38        llvm::cast<Operand>(*it)->isDot())
39      return true;
40  }
41  return false;
42}
43
44void RpnExpr::dump() const
45{
46  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
47    (*it)->dump();
48    mcld::outs() << " ";
49  }
50}
51
52void RpnExpr::push_back(ExprToken* pToken)
53{
54  m_TokenQueue.push_back(pToken);
55}
56
57RpnExpr* RpnExpr::create()
58{
59  RpnExpr* result = g_ExprFactory->allocate();
60  new (result) RpnExpr();
61  return result;
62}
63
64void RpnExpr::destroy(RpnExpr*& pRpnExpr)
65{
66  g_ExprFactory->destroy(pRpnExpr);
67  g_ExprFactory->deallocate(pRpnExpr);
68  pRpnExpr = NULL;
69}
70
71void RpnExpr::clear()
72{
73  g_ExprFactory->clear();
74}
75
76RpnExpr::iterator RpnExpr::insert(iterator pPosition, ExprToken* pToken)
77{
78  return m_TokenQueue.insert(pPosition, pToken);
79}
80
81void RpnExpr::erase(iterator pPosition)
82{
83  m_TokenQueue.erase(pPosition);
84}
85
86// buildHelperExpr - build the helper expr:
87//                   ADDR ( `output_sect' ) + SIZEOF ( `output_sect' )
88RpnExpr* RpnExpr::buildHelperExpr(SectionMap::iterator pIter)
89{
90  RpnExpr* expr = RpnExpr::create();
91  expr->push_back(SectDescOperand::create(*pIter));
92  expr->push_back(&Operator::create<Operator::ADDR>());
93  expr->push_back(SectDescOperand::create(*pIter));
94  expr->push_back(&Operator::create<Operator::SIZEOF>());
95  expr->push_back(&Operator::create<Operator::ADD>());
96  return expr;
97}
98
99// buildHelperExpr - build the helper expr: `fragment'
100RpnExpr* RpnExpr::buildHelperExpr(Fragment& pFrag)
101{
102  RpnExpr* expr = RpnExpr::create();
103  expr->push_back(FragOperand::create(pFrag));
104  return expr;
105}
106