//===- InputBuilder.h -----------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_MC_INPUTBUILDER_H_
#define MCLD_MC_INPUTBUILDER_H_
#include "mcld/InputTree.h"
#include "mcld/MC/Input.h"
#include "mcld/Support/FileHandle.h"
#include <stack>
#include <string>
namespace mcld {
class AttrConstraint;
class ContextFactory;
class InputFactory;
class LinkerConfig;
class MemoryAreaFactory;
/** \class InputBuilder
* \brief InputBuilder recieves InputActions and build the InputTree.
*
* InputBuilder build input tree and inputs.
*/
class InputBuilder {
public:
explicit InputBuilder(const LinkerConfig& pConfig);
InputBuilder(const LinkerConfig& pConfig,
InputFactory& pInputFactory,
ContextFactory& pContextFactory,
MemoryAreaFactory& pMemoryFactory,
bool pDelegate = true);
virtual ~InputBuilder();
// ----- input tree operations ----- //
const InputTree& getCurrentTree() const;
InputTree& getCurrentTree();
void setCurrentTree(InputTree& pInputTree);
// ----- root of input tree ----- //
const InputTree::iterator& getCurrentNode() const { return m_Root; }
InputTree::iterator& getCurrentNode() { return m_Root; }
template <InputTree::Direction DIRECTION>
InputTree& createNode(const std::string& pName,
const sys::fs::Path& pPath,
unsigned int pType = Input::Unknown);
// ----- input operations ----- //
Input* createInput(const std::string& pName,
const sys::fs::Path& pPath,
unsigned int pType = Input::Unknown,
off_t pFileOffset = 0);
bool setContext(Input& pInput, bool pCheck = true);
bool setMemory(Input& pInput,
FileHandle::OpenMode pMode,
FileHandle::Permission pPerm);
bool setMemory(Input& pInput, void* pMemBuffer, size_t pSize);
InputTree& enterGroup();
InputTree& exitGroup();
bool isInGroup() const;
const AttrConstraint& getConstraint() const;
const AttributeProxy& getAttributes() const;
AttributeProxy& getAttributes();
private:
const LinkerConfig& m_Config;
InputFactory* m_pInputFactory;
MemoryAreaFactory* m_pMemFactory;
ContextFactory* m_pContextFactory;
InputTree* m_pCurrentTree;
InputTree::Mover* m_pMove;
InputTree::iterator m_Root;
std::stack<InputTree::iterator> m_ReturnStack;
bool m_bOwnFactory;
};
//===----------------------------------------------------------------------===//
// Template implement
//===----------------------------------------------------------------------===//
template <>
inline InputTree& InputBuilder::createNode<InputTree::Inclusive>(
const std::string& pName,
const sys::fs::Path& pPath,
unsigned int pType) {
assert(m_pCurrentTree != NULL && m_pMove != NULL);
Input* input = createInput(pName, pPath, pType);
m_pCurrentTree->insert(m_Root, *m_pMove, *input);
m_pMove->move(m_Root);
m_pMove = &InputTree::Downward;
return *m_pCurrentTree;
}
template <>
inline InputTree& InputBuilder::createNode<InputTree::Positional>(
const std::string& pName,
const sys::fs::Path& pPath,
unsigned int pType) {
assert(m_pCurrentTree != NULL && m_pMove != NULL);
Input* input = createInput(pName, pPath, pType);
m_pCurrentTree->insert(m_Root, *m_pMove, *input);
m_pMove->move(m_Root);
m_pMove = &InputTree::Afterward;
return *m_pCurrentTree;
}
} // namespace mcld
#endif // MCLD_MC_INPUTBUILDER_H_