Home | History | Annotate | Download | only in MC
      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 
     22 namespace mcld {
     23 
     24 class LinkerConfig;
     25 class InputFactory;
     26 class ContextFactory;
     27 class MemoryAreaFactory;
     28 class AttrConstraint;
     29 class 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  */
     36 class InputBuilder
     37 {
     38 public:
     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 
     89 private:
     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 //===----------------------------------------------------------------------===//
    108 template<> inline InputTree&
    109 InputBuilder::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 
    123 template<> inline InputTree&
    124 InputBuilder::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