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