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