summaryrefslogtreecommitdiff
path: root/include/mcld/InputTree.h
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2012-12-15 17:21:00 -0800
committerShih-wei Liao <sliao@google.com>2012-12-15 17:21:00 -0800
commit22add6ff3426df1a85089fe6a6e1597ee3b6f300 (patch)
treec58763780e7b965179d9cdce45f1fc5a5268932d /include/mcld/InputTree.h
parentc842fe71ef087c982cc03d0ea73eeaf455d932d3 (diff)
downloadmclinker-22add6ff3426df1a85089fe6a6e1597ee3b6f300.tar.gz
MCLinker upstream commit 0459e386785c.
Change-Id: Ide6790f5a354b7fcc03d812d6c8cf43b1e309ba3
Diffstat (limited to 'include/mcld/InputTree.h')
-rw-r--r--include/mcld/InputTree.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/include/mcld/InputTree.h b/include/mcld/InputTree.h
new file mode 100644
index 0000000..2981ebe
--- /dev/null
+++ b/include/mcld/InputTree.h
@@ -0,0 +1,203 @@
+//===- InputTree.h --------------------------------------------------------===//
+//
+// The MCLinker Project
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCLD_MC_INPUT_TREE_H
+#define MCLD_MC_INPUT_TREE_H
+#ifdef ENABLE_UNITTEST
+#include <gtest.h>
+#endif
+
+#include <mcld/ADT/BinTree.h>
+#include <mcld/ADT/TypeTraits.h>
+#include <mcld/MC/MCLDInput.h>
+#include <mcld/Support/Path.h>
+
+#include <string>
+
+
+namespace mcld {
+
+/** \class template<typename Traits, typename Iterator> PolicyIterator<mcld::Input>
+ * \brief PolicyIterator<mcld::Input> is a partially specific PolicyIterator
+ */
+template<typename Traits, typename IteratorType>
+class PolicyIterator<mcld::Input, Traits, IteratorType> : public PolicyIteratorBase<Input, Traits, IteratorType>
+{
+public:
+ typedef PolicyIterator<Input, Traits, IteratorType> Self;
+ typedef PolicyIteratorBase<Input, Traits, IteratorType> Base;
+ typedef PolicyIterator<Input, typename Traits::nonconst_traits, IteratorType> iterator;
+ typedef PolicyIterator<Input, typename Traits::const_traits, IteratorType> const_iterator;
+
+public:
+ PolicyIterator()
+ : Base() {}
+
+ PolicyIterator(const iterator &X)
+ : Base(X.m_pNode) {}
+
+ explicit PolicyIterator(NodeBase* X)
+ : Base(X) {}
+
+ virtual ~PolicyIterator() {}
+
+ bool isGroup() const
+ { return !Base::hasData() && !Base::isRoot(); }
+
+ Self& operator++() {
+ IteratorType::advance();
+ // skip the Group node
+ while (isGroup())
+ IteratorType::advance();
+ return *this;
+ }
+
+ Self operator++(int) {
+ Self tmp(*this);
+ IteratorType::advance();
+ // skip the Group node
+ while (isGroup())
+ IteratorType::advance();
+ return tmp;
+ }
+};
+
+/** \class InputTree
+ * \brief InputTree is the input tree to contains all inputs from the
+ * command line.
+ *
+ * InputTree, of course, is uncopyable.
+ *
+ * @see Input
+ */
+class InputTree : public BinaryTree<Input>
+{
+private:
+ typedef BinaryTree<Input> BinTreeTy;
+
+public:
+ enum Direction {
+ Inclusive = TreeIteratorBase::Leftward,
+ Positional = TreeIteratorBase::Rightward
+ };
+
+ typedef BinaryTree<Input>::iterator iterator;
+ typedef BinaryTree<Input>::const_iterator const_iterator;
+
+public:
+ /** \class Mover
+ * \brief Mover provides the interface for moving iterator forward.
+ *
+ * Mover is a function object (functor). @ref Mover::move moves
+ * iterator forward in certain direction. @ref Mover::connect
+ * connects two nodes of the given iterators togather.
+ */
+ struct Mover {
+ virtual ~Mover() {}
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const = 0;
+ virtual void move(TreeIteratorBase& pNode) const = 0;
+ };
+
+ /** \class Succeeder
+ * \brief class Succeeder moves the iterator afterward.
+ */
+ struct Succeeder : public Mover {
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
+ proxy::hook<Positional>(pFrom.m_pNode, pTo.m_pNode);
+ }
+
+ virtual void move(TreeIteratorBase& pNode) const {
+ pNode.move<Positional>();
+ }
+ };
+
+ /** \class Includer
+ * \brief class Includer moves the iterator downward.
+ */
+ struct Includer : public Mover {
+ virtual void connect(TreeIteratorBase& pFrom, const TreeIteratorBase& pTo) const {
+ proxy::hook<Inclusive>(pFrom.m_pNode, pTo.m_pNode);
+ }
+
+ virtual void move(TreeIteratorBase& pNode) const {
+ pNode.move<Inclusive>();
+ }
+ };
+
+public:
+ static Succeeder Afterward;
+ static Includer Downward;
+
+public:
+
+ using BinTreeTy::merge;
+
+ // ----- modify ----- //
+ template<size_t DIRECT>
+ InputTree& enterGroup(TreeIteratorBase pRoot);
+
+ template<size_t DIRECT>
+ InputTree& insert(TreeIteratorBase pRoot,
+ Input& pInput);
+
+ InputTree& merge(TreeIteratorBase pRoot,
+ const Mover& pMover,
+ InputTree& pTree);
+
+ InputTree& insert(TreeIteratorBase pRoot,
+ const Mover& pMover,
+ Input& pInput);
+
+ InputTree& enterGroup(TreeIteratorBase pRoot,
+ const Mover& pMover);
+
+};
+
+bool isGroup(const InputTree::iterator& pos);
+bool isGroup(const InputTree::const_iterator& pos);
+bool isGroup(const InputTree::dfs_iterator& pos);
+bool isGroup(const InputTree::const_dfs_iterator& pos);
+bool isGroup(const InputTree::bfs_iterator& pos);
+bool isGroup(const InputTree::const_bfs_iterator& pos);
+
+} // namespace of mcld
+
+//===----------------------------------------------------------------------===//
+// template member functions
+//===----------------------------------------------------------------------===//
+template<size_t DIRECT>
+mcld::InputTree&
+mcld::InputTree::enterGroup(mcld::TreeIteratorBase pRoot)
+{
+ BinTreeTy::node_type* node = createNode();
+ if (pRoot.isRoot())
+ proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
+ const_cast<const node_type*>(node));
+ else
+ proxy::hook<DIRECT>(pRoot.m_pNode,
+ const_cast<const node_type*>(node));
+ return *this;
+}
+
+template<size_t DIRECT>
+mcld::InputTree& mcld::InputTree::insert(mcld::TreeIteratorBase pRoot,
+ mcld::Input& pInput)
+{
+ BinTreeTy::node_type* node = createNode();
+ node->data = &pInput;
+ if (pRoot.isRoot())
+ proxy::hook<TreeIteratorBase::Leftward>(pRoot.m_pNode,
+ const_cast<const node_type*>(node));
+ else
+ proxy::hook<DIRECT>(pRoot.m_pNode,
+ const_cast<const node_type*>(node));
+ return *this;
+}
+
+#endif
+