blob: 88ad34a7bb23ef8cb798badb9e8397175381b918 [file] [log] [blame]
Zonr Changaffc1502012-07-16 14:28:23 +08001//===- InputTree.h --------------------------------------------------------===//
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07002//
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//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -08009#ifndef MCLD_INPUTTREE_H_
10#define MCLD_INPUTTREE_H_
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070011
Stephen Hines37b74a32014-11-26 18:48:20 -080012#include "mcld/ADT/BinTree.h"
13#include "mcld/ADT/TypeTraits.h"
14#include "mcld/MC/Input.h"
15#include "mcld/Support/Path.h"
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070016
17#include <string>
18
Shih-wei Liao22add6f2012-12-15 17:21:00 -080019namespace mcld {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070020
Stephen Hines37b74a32014-11-26 18:48:20 -080021/** \class template<typename Traits, typename Iterator>
22 * PolicyIterator<mcld::Input>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070023 * \brief PolicyIterator<mcld::Input> is a partially specific PolicyIterator
24 */
Stephen Hines37b74a32014-11-26 18:48:20 -080025template <typename Traits, typename IteratorType>
26class PolicyIterator<mcld::Input, Traits, IteratorType>
27 : public PolicyIteratorBase<Input, Traits, IteratorType> {
28 public:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070029 typedef PolicyIterator<Input, Traits, IteratorType> Self;
30 typedef PolicyIteratorBase<Input, Traits, IteratorType> Base;
Stephen Hines37b74a32014-11-26 18:48:20 -080031 typedef PolicyIterator<Input, typename Traits::nonconst_traits, IteratorType>
32 iterator;
33 typedef PolicyIterator<Input, typename Traits::const_traits, IteratorType>
34 const_iterator;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070035
Stephen Hines37b74a32014-11-26 18:48:20 -080036 public:
37 PolicyIterator() : Base() {}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070038
Stephen Hines37b74a32014-11-26 18:48:20 -080039 PolicyIterator(const iterator& X) : Base(X.m_pNode) {}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070040
Stephen Hines37b74a32014-11-26 18:48:20 -080041 explicit PolicyIterator(NodeBase* X) : Base(X) {}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070042
43 virtual ~PolicyIterator() {}
44
Stephen Hines37b74a32014-11-26 18:48:20 -080045 bool isGroup() const { return !Base::hasData() && !Base::isRoot(); }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070046
47 Self& operator++() {
48 IteratorType::advance();
Shih-wei Liao22add6f2012-12-15 17:21:00 -080049 // skip the Group node
50 while (isGroup())
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070051 IteratorType::advance();
52 return *this;
53 }
54
55 Self operator++(int) {
56 Self tmp(*this);
57 IteratorType::advance();
Shih-wei Liao22add6f2012-12-15 17:21:00 -080058 // skip the Group node
59 while (isGroup())
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070060 IteratorType::advance();
61 return tmp;
62 }
63};
64
Stephen Hines37b74a32014-11-26 18:48:20 -080065template <>
66class BinaryTree<Input> : public BinaryTreeBase<Input> {
67 public:
68 typedef size_t size_type;
69 typedef ptrdiff_t difference_type;
70 typedef Input value_type;
71 typedef value_type* pointer;
72 typedef value_type& reference;
73 typedef const value_type* const_pointer;
74 typedef const value_type& const_reference;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070075
Stephen Hines37b74a32014-11-26 18:48:20 -080076 typedef BinaryTree<Input> Self;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070077 typedef TreeIterator<value_type, NonConstTraits<value_type> > iterator;
Stephen Hines37b74a32014-11-26 18:48:20 -080078 typedef TreeIterator<value_type, ConstTraits<value_type> > const_iterator;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070079
Stephen Hines37b74a32014-11-26 18:48:20 -080080 typedef PolicyIterator<value_type, NonConstTraits<value_type>, DFSIterator>
81 dfs_iterator;
82 typedef PolicyIterator<value_type, ConstTraits<value_type>, DFSIterator>
83 const_dfs_iterator;
84 typedef PolicyIterator<value_type, NonConstTraits<value_type>, BFSIterator>
85 bfs_iterator;
86 typedef PolicyIterator<value_type, ConstTraits<value_type>, BFSIterator>
87 const_bfs_iterator;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070088
Stephen Hines37b74a32014-11-26 18:48:20 -080089 protected:
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070090 typedef Node<value_type> node_type;
91
Stephen Hines37b74a32014-11-26 18:48:20 -080092 public:
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070093 // ----- constructors and destructor ----- //
Stephen Hines37b74a32014-11-26 18:48:20 -080094 BinaryTree() : BinaryTreeBase<Input>() {}
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070095
Stephen Hines37b74a32014-11-26 18:48:20 -080096 ~BinaryTree() {}
Stephen Hinesf7ac0f12013-05-03 19:09:24 -070097
98 // ----- iterators ----- //
Stephen Hines37b74a32014-11-26 18:48:20 -080099 bfs_iterator bfs_begin() {
100 bfs_iterator it = bfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
101 if (it.isGroup())
102 ++it;
103 return it;
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700104 }
105
Stephen Hines37b74a32014-11-26 18:48:20 -0800106 bfs_iterator bfs_end() {
107 return bfs_iterator(BinaryTreeBase<Input>::m_Root.node.right);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700108 }
109
Stephen Hines37b74a32014-11-26 18:48:20 -0800110 const_bfs_iterator bfs_begin() const {
111 const_bfs_iterator it =
112 const_bfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
113 if (it.isGroup())
114 ++it;
115 return it;
116 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700117
Stephen Hines37b74a32014-11-26 18:48:20 -0800118 const_bfs_iterator bfs_end() const {
119 return const_bfs_iterator(BinaryTreeBase<Input>::m_Root.node.right);
120 }
121
122 dfs_iterator dfs_begin() {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700123 dfs_iterator it = dfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
124 if (it.isGroup())
125 ++it;
126 return it;
127 }
128
Stephen Hines37b74a32014-11-26 18:48:20 -0800129 dfs_iterator dfs_end() {
130 return dfs_iterator(BinaryTreeBase<Input>::m_Root.node.right);
131 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700132
Stephen Hines37b74a32014-11-26 18:48:20 -0800133 const_dfs_iterator dfs_begin() const {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700134 const_dfs_iterator it =
Stephen Hines37b74a32014-11-26 18:48:20 -0800135 const_dfs_iterator(BinaryTreeBase<Input>::m_Root.node.left);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700136 if (it.isGroup())
137 ++it;
138 return it;
139 }
140
Stephen Hines37b74a32014-11-26 18:48:20 -0800141 const_dfs_iterator dfs_end() const {
142 return const_dfs_iterator(BinaryTreeBase<Input>::m_Root.node.right);
143 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700144
Stephen Hines37b74a32014-11-26 18:48:20 -0800145 iterator root() { return iterator(&(BinaryTreeBase<Input>::m_Root.node)); }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700146
Stephen Hines37b74a32014-11-26 18:48:20 -0800147 const_iterator root() const {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700148 // FIXME: provide the iterater constructors for constant NodeBase instead of
149 // using const_cast
150 return const_iterator(
Stephen Hines37b74a32014-11-26 18:48:20 -0800151 const_cast<NodeBase*>(&BinaryTreeBase<Input>::m_Root.node));
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700152 }
153
Stephen Hines37b74a32014-11-26 18:48:20 -0800154 iterator begin() {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700155 iterator it = iterator(BinaryTreeBase<Input>::m_Root.node.left);
156 return it;
157 }
158
Stephen Hines37b74a32014-11-26 18:48:20 -0800159 iterator end() { return iterator(BinaryTreeBase<Input>::m_Root.node.right); }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700160
Stephen Hines37b74a32014-11-26 18:48:20 -0800161 const_iterator begin() const {
162 return const_iterator(BinaryTreeBase<Input>::m_Root.node.left);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700163 }
164
Stephen Hines37b74a32014-11-26 18:48:20 -0800165 const_iterator end() const {
166 return const_iterator(BinaryTreeBase<Input>::m_Root.node.right);
167 }
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700168
169 // ----- modifiers ----- //
170 /// join - create a leaf node and merge it in the tree.
171 // This version of join determines the direction on compilation time.
172 // @param DIRECT the direction of the connecting edge of the parent node.
173 // @param position the parent node
174 // @param value the value being pushed.
Stephen Hines37b74a32014-11-26 18:48:20 -0800175 template <size_t DIRECT>
Stephen Hines87f34652014-02-14 18:00:16 -0800176 BinaryTree& join(TreeIteratorBase& pPosition, const Input& value) {
Stephen Hines37b74a32014-11-26 18:48:20 -0800177 node_type* node = BinaryTreeBase<Input>::createNode();
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700178 node->data = const_cast<Input*>(&value);
Stephen Hines87f34652014-02-14 18:00:16 -0800179
180 if (pPosition.isRoot())
181 pPosition.hook<TreeIteratorBase::Leftward>(node);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700182 else
Stephen Hines87f34652014-02-14 18:00:16 -0800183 pPosition.hook<DIRECT>(node);
184
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700185 return *this;
186 }
187
188 /// merge - merge the tree
189 // @param DIRECT the direction of the connecting edge of the parent node.
190 // @param position the parent node
191 // @param the tree being joined.
192 // @return the joined tree
Stephen Hines37b74a32014-11-26 18:48:20 -0800193 template <size_t DIRECT>
Stephen Hines87f34652014-02-14 18:00:16 -0800194 BinaryTree& merge(TreeIteratorBase& pPosition, BinaryTree& pTree) {
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700195 if (this == &pTree)
196 return *this;
197
198 if (!pTree.empty()) {
Stephen Hines87f34652014-02-14 18:00:16 -0800199 pPosition.hook<DIRECT>(pTree.m_Root.node.left);
Stephen Hines37b74a32014-11-26 18:48:20 -0800200 BinaryTreeBase<Input>::m_Root.summon(pTree.BinaryTreeBase<Input>::m_Root);
Stephen Hinesf7ac0f12013-05-03 19:09:24 -0700201 BinaryTreeBase<Input>::m_Root.delegate(pTree.m_Root);
202 pTree.m_Root.node.left = pTree.m_Root.node.right = &pTree.m_Root.node;
203 }
204 return *this;
205 }
206};
207
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700208/** \class InputTree
209 * \brief InputTree is the input tree to contains all inputs from the
210 * command line.
211 *
212 * InputTree, of course, is uncopyable.
213 *
214 * @see Input
215 */
Stephen Hines37b74a32014-11-26 18:48:20 -0800216class InputTree : public BinaryTree<Input> {
217 private:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700218 typedef BinaryTree<Input> BinTreeTy;
219
Stephen Hines37b74a32014-11-26 18:48:20 -0800220 public:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700221 enum Direction {
Stephen Hines37b74a32014-11-26 18:48:20 -0800222 Inclusive = TreeIteratorBase::Leftward,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700223 Positional = TreeIteratorBase::Rightward
224 };
225
Stephen Hines37b74a32014-11-26 18:48:20 -0800226 typedef BinaryTree<Input>::iterator iterator;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700227 typedef BinaryTree<Input>::const_iterator const_iterator;
228
Stephen Hines37b74a32014-11-26 18:48:20 -0800229 public:
Zonr Changaffc1502012-07-16 14:28:23 +0800230 /** \class Mover
231 * \brief Mover provides the interface for moving iterator forward.
232 *
233 * Mover is a function object (functor). @ref Mover::move moves
234 * iterator forward in certain direction. @ref Mover::connect
235 * connects two nodes of the given iterators togather.
236 */
237 struct Mover {
Stephen Hines87f34652014-02-14 18:00:16 -0800238 virtual void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const = 0;
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700239 virtual void move(TreeIteratorBase& pNode) const = 0;
Stephen Hines37b74a32014-11-26 18:48:20 -0800240 virtual ~Mover() {}
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700241 };
242
Zonr Changaffc1502012-07-16 14:28:23 +0800243 /** \class Succeeder
244 * \brief class Succeeder moves the iterator afterward.
245 */
246 struct Succeeder : public Mover {
Stephen Hines87f34652014-02-14 18:00:16 -0800247 void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const {
248 pFrom.hook<Positional>(pTo);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700249 }
250
Stephen Hines37b74a32014-11-26 18:48:20 -0800251 void move(TreeIteratorBase& pNode) const { pNode.move<Positional>(); }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700252 };
253
Zonr Changaffc1502012-07-16 14:28:23 +0800254 /** \class Includer
255 * \brief class Includer moves the iterator downward.
256 */
257 struct Includer : public Mover {
Stephen Hines87f34652014-02-14 18:00:16 -0800258 void connect(TreeIteratorBase& pFrom, NodeBase* pTo) const {
259 pFrom.hook<Inclusive>(pTo);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700260 }
261
Stephen Hines37b74a32014-11-26 18:48:20 -0800262 void move(TreeIteratorBase& pNode) const { pNode.move<Inclusive>(); }
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700263 };
264
Stephen Hines37b74a32014-11-26 18:48:20 -0800265 public:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700266 static Succeeder Afterward;
Stephen Hines37b74a32014-11-26 18:48:20 -0800267 static Includer Downward;
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700268
Stephen Hines37b74a32014-11-26 18:48:20 -0800269 public:
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700270 using BinTreeTy::merge;
271
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700272 // ----- modify ----- //
Stephen Hines37b74a32014-11-26 18:48:20 -0800273 template <size_t DIRECT>
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700274 InputTree& enterGroup(TreeIteratorBase pRoot);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700275
Stephen Hines37b74a32014-11-26 18:48:20 -0800276 template <size_t DIRECT>
277 InputTree& insert(TreeIteratorBase pRoot, Input& pInput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700278
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800279 InputTree& merge(TreeIteratorBase pRoot,
Zonr Changaffc1502012-07-16 14:28:23 +0800280 const Mover& pMover,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700281 InputTree& pTree);
282
Stephen Hines37b74a32014-11-26 18:48:20 -0800283 InputTree& insert(TreeIteratorBase pRoot, const Mover& pMover, Input& pInput);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700284
Stephen Hines37b74a32014-11-26 18:48:20 -0800285 InputTree& enterGroup(TreeIteratorBase pRoot, const Mover& pMover);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700286};
287
288bool isGroup(const InputTree::iterator& pos);
289bool isGroup(const InputTree::const_iterator& pos);
290bool isGroup(const InputTree::dfs_iterator& pos);
291bool isGroup(const InputTree::const_dfs_iterator& pos);
292bool isGroup(const InputTree::bfs_iterator& pos);
293bool isGroup(const InputTree::const_bfs_iterator& pos);
294
Stephen Hines37b74a32014-11-26 18:48:20 -0800295} // namespace mcld
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700296
297//===----------------------------------------------------------------------===//
298// template member functions
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800299//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -0800300template <size_t DIRECT>
301mcld::InputTree& mcld::InputTree::enterGroup(mcld::TreeIteratorBase pRoot) {
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800302 BinTreeTy::node_type* node = createNode();
Stephen Hines87f34652014-02-14 18:00:16 -0800303
Zonr Changaffc1502012-07-16 14:28:23 +0800304 if (pRoot.isRoot())
Stephen Hines87f34652014-02-14 18:00:16 -0800305 pRoot.hook<TreeIteratorBase::Leftward>(node);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700306 else
Stephen Hines87f34652014-02-14 18:00:16 -0800307 pRoot.hook<DIRECT>(node);
308
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700309 return *this;
310}
311
Stephen Hines37b74a32014-11-26 18:48:20 -0800312template <size_t DIRECT>
Shih-wei Liao67e37f12012-07-27 03:50:34 -0700313mcld::InputTree& mcld::InputTree::insert(mcld::TreeIteratorBase pRoot,
Stephen Hines37b74a32014-11-26 18:48:20 -0800314 mcld::Input& pInput) {
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700315 BinTreeTy::node_type* node = createNode();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800316 node->data = &pInput;
Stephen Hines87f34652014-02-14 18:00:16 -0800317
Zonr Changaffc1502012-07-16 14:28:23 +0800318 if (pRoot.isRoot())
Stephen Hines87f34652014-02-14 18:00:16 -0800319 pRoot.hook<TreeIteratorBase::Leftward>(node);
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700320 else
Stephen Hines87f34652014-02-14 18:00:16 -0800321 pRoot.hook<DIRECT>(node);
322
Shih-wei Liao5460a1f2012-03-16 22:41:16 -0700323 return *this;
324}
325
Stephen Hines37b74a32014-11-26 18:48:20 -0800326#endif // MCLD_INPUTTREE_H_