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