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 
19 namespace mcld {
20 
21 class AttrConstraint;
22 class ContextFactory;
23 class InputFactory;
24 class LinkerConfig;
25 class MemoryAreaFactory;
26 
27 /** \class InputBuilder
28  *  \brief InputBuilder recieves InputActions and build the InputTree.
29  *
30  *  InputBuilder build input tree and inputs.
31  */
32 class 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  ----- //
getCurrentNode()51   const InputTree::iterator& getCurrentNode() const { return m_Root; }
getCurrentNode()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 //===----------------------------------------------------------------------===//
102 template <>
103 inline 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 
117 template <>
118 inline 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