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