InputBuilder.h revision 533eae20118036f425f27bf0536ef0ccbb090b65
1//===- InputBuilder.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_MC_INPUTBUILDER_H
10#define MCLD_MC_INPUTBUILDER_H
11
12#include <string>
13#include <stack>
14
15#include <mcld/InputTree.h>
16#include <mcld/MC/Input.h>
17#include <mcld/Support/FileHandle.h>
18
19namespace mcld {
20
21class LinkerConfig;
22class InputFactory;
23class ContextFactory;
24class MemoryAreaFactory;
25class AttrConstraint;
26
27/** \class InputBuilder
28 *  \brief InputBuilder recieves InputActions and build the InputTree.
29 *
30 *  InputBuilder build input tree and inputs.
31 */
32class InputBuilder
33{
34public:
35  explicit InputBuilder(const LinkerConfig& pConfig);
36
37  InputBuilder(const LinkerConfig& pConfig,
38               InputFactory& pInputFactory,
39               ContextFactory& pContextFactory,
40               MemoryAreaFactory& pMemoryFactory,
41               bool pDelegate = true);
42
43  virtual ~InputBuilder();
44
45  // -----  input tree operations  ----- //
46  const InputTree& getCurrentTree() const;
47  InputTree&       getCurrentTree();
48
49  void setCurrentTree(InputTree& pInputTree);
50
51  // -----  root of input tree  ----- //
52  const InputTree::iterator& getCurrentNode() const { return m_Root; }
53  InputTree::iterator&       getCurrentNode()       { return m_Root; }
54
55  template<InputTree::Direction DIRECTION>
56  InputTree& createNode(const std::string& pName,
57                        const sys::fs::Path& pPath,
58                        unsigned int pType = Input::Unknown);
59
60  // -----  input operations  ----- //
61  Input* createInput(const std::string& pName,
62                     const sys::fs::Path& pPath,
63                     unsigned int pType = Input::Unknown,
64                     off_t pFileOffset = 0);
65
66  bool setContext(Input& pInput, bool pCheck = true);
67
68  bool setMemory(Input& pInput,
69                 FileHandle::OpenMode pMode,
70		 FileHandle::Permission pPerm = FileHandle::System);
71
72  bool setMemory(Input& pInput, void* pMemBuffer, size_t pSize);
73
74  InputTree& enterGroup();
75
76  InputTree& exitGroup();
77
78  bool isInGroup() const;
79
80  const AttrConstraint& getConstraint() const;
81
82  const AttributeProxy& getAttributes() const;
83  AttributeProxy&       getAttributes();
84
85private:
86  const LinkerConfig& m_Config;
87
88  InputFactory* m_pInputFactory;
89  MemoryAreaFactory* m_pMemFactory;
90  ContextFactory* m_pContextFactory;
91
92  InputTree* m_pCurrentTree;
93  InputTree::Mover* m_pMove;
94  InputTree::iterator m_Root;
95  std::stack<InputTree::iterator> m_ReturnStack;
96
97  bool m_bOwnFactory;
98
99};
100
101//===----------------------------------------------------------------------===//
102// Template implement
103//===----------------------------------------------------------------------===//
104template<> inline InputTree&
105InputBuilder::createNode<InputTree::Inclusive>(const std::string& pName,
106                                               const sys::fs::Path& pPath,
107                                               unsigned int pType)
108{
109  assert(NULL != m_pCurrentTree && NULL != m_pMove);
110
111  Input* input = createInput(pName, pPath, pType);
112  m_pCurrentTree->insert(m_Root, *m_pMove, *input);
113  m_pMove->move(m_Root);
114  m_pMove = &InputTree::Downward;
115
116  return *m_pCurrentTree;
117}
118
119template<> inline InputTree&
120InputBuilder::createNode<InputTree::Positional>(const std::string& pName,
121                                               const sys::fs::Path& pPath,
122                                               unsigned int pType)
123{
124  assert(NULL != m_pCurrentTree && NULL != m_pMove);
125
126  Input* input = createInput(pName, pPath, pType);
127  m_pCurrentTree->insert(m_Root, *m_pMove, *input);
128  m_pMove->move(m_Root);
129  m_pMove = &InputTree::Afterward;
130
131  return *m_pCurrentTree;
132}
133
134} // end of namespace mcld
135
136#endif
137
138