systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
Tree.h
Go to the documentation of this file.
1#ifndef VECTOR_TREE_H_
2#define VECTOR_TREE_H_
3
4#include <map>
5#include <queue>
6#include <stack>
7#include <string>
8#include <vector>
9
10#include "llvm/Support/raw_ostream.h"
11
12namespace systemc_clang {
13//
15//
16//
17template <typename T>
18class TreeNode {
19 private:
23
24 public:
26 TreeNode(T data) : data_{data}, discovered_{false}, parent_{this} {};
27
28 TreeNode(const TreeNode &from) {
29 data_ = from.data_;
31 parent_ = from.parent_;
32 }
33
34 virtual ~TreeNode() {
35 // parent_ = nullptr;
36 }
37
38 T getData() const { return data_; }
39 const T *getDataPtr() { return &data_; }
40 std::string toString() const { return data_.toString(); }
41
42 bool isDiscovered() const { return discovered_; }
43 void setDiscovered() { discovered_ = true; }
44 void resetDiscovered() { discovered_ = false; }
45
46 void setParent(TreeNode *from) { parent_ = from; }
47
48 TreeNode *getParent() const { return parent_; }
49
50 void dump(llvm::raw_ostream &outstream = llvm::outs()) {
51 outstream << "[" << toString() << "] ";
52 }
53
54 virtual void visit(llvm::raw_ostream &outstream = llvm::outs()) {
55 outstream << "(" << parent_->toString() << ")"
56 << " " << toString() << " ";
57 }
58};
59
61// class Tree
62//
63//
64template <typename T>
65class Tree {
66 public:
68 typedef std::vector<TreeNodePtr> VectorTreePtr;
69
70 private:
71 // Adjacency list.
72 // This is a reasonable structure since types are
73 // typically going to be of small depth.
74 std::map<TreeNodePtr, std::vector<TreeNodePtr> > adj_list_;
76
79 std::vector<TreeNodePtr> nodes_bft_;
80 std::vector<TreeNodePtr> nodes_dft_;
81
82 public:
83 Tree() : root_{nullptr}, run_dft_{false}, run_bft_{false} {}
84
85 Tree(const Tree &from) {
86 adj_list_ = from.adj_list_;
87 root_ = from.root_;
88 run_dft_ = from.run_dft_;
89 run_bft_ = from.run_bft_;
92 }
93
95 for (auto &node : adj_list_) {
96 delete node.first;
97 node.second.clear();
98 }
99 adj_list_.clear();
100 nodes_dft_.clear();
101 nodes_bft_.clear();
102 root_ = nullptr;
103 }
104
105 void dump(llvm::raw_ostream &outstream = llvm::outs()) {
106 for (auto const &entry : adj_list_) {
107 auto node{entry.first};
108 auto edges{entry.second};
109 outstream << node->toString() << " => size: " << edges.size() << "\n";
110 for (auto const &edge_node : edges) {
111 outstream << " " << edge_node->toString();
112 }
113 outstream << "\n";
114 }
115 }
116
117 std::size_t size() const { return adj_list_.size(); }
118
119 void setRoot(const TreeNodePtr from) { root_ = from; }
120
121 const TreeNodePtr getRoot() const { return root_; }
122
123 bool foundNode(TreeNodePtr node) const {
124 auto found_node{adj_list_.find(node)};
125 if (found_node == adj_list_.end()) {
126 return false;
127 }
128 return true;
129 }
130
132 if (!foundNode(node)) {
133 return false;
134 }
135
136 return (adj_list_[node].size() > 0);
137 }
138
139 const VectorTreePtr &getChildren(TreeNodePtr node) { return adj_list_[node]; }
140
142 TreeNodePtr new_node{new TreeNode<T>(data)};
143 VectorTreePtr empty_edges{};
144 adj_list_.insert(adj_list_.begin(), std::make_pair(new_node, empty_edges));
145 return new_node;
146 }
147
148 void addEdge(const TreeNodePtr from, const TreeNodePtr to) {
149 auto source{adj_list_.find(from)};
150
151 if (source == adj_list_.end()) {
152 return;
153 }
154
155 auto &edges{source->second};
156 // Insert it into the beginning of the vector.
157 //
158 // Clang parses the template arguments in left-to-right manner. Inserting
159 // these types at the beginning works to represent this correctly for the
160 // DFT. This is because the DFT algorithm picks up from begin() to end()
161 // the edges, and inserts them into a queue by pushing them on.
162 edges.insert(edges.begin(), to);
163 to->setParent(from);
164 }
165
167 for (auto const &node : adj_list_) {
168 node.first->resetDiscovered();
169 }
170 }
171
172 std::string bft(TreeNodePtr root) {
174 std::string return_string{};
175
176 std::queue<TreeNodePtr> que{};
177 root->setDiscovered();
178 que.push(root);
179
180 while (!que.empty()) {
181 auto node{que.front()};
182 node->visit();
183 nodes_bft_.push_back(node);
184 return_string += " ";
185 return_string += node->toString();
186 que.pop();
187
188 auto source{adj_list_.find(node)};
189
190 if (source == adj_list_.end()) {
191 return "";
192 }
193
194 auto const &edges{source->second};
195 for (auto const &edge_node : edges) {
196 if (!edge_node->isDiscovered()) {
197 edge_node->setDiscovered();
198 que.push(edge_node);
199 }
200 }
201 }
202 return return_string;
203 }
204
205 std::string dft(TreeNodePtr root = nullptr) {
207 std::string return_string;
208
209 // If the argument is not specified, then just use the root.
210 if (root == nullptr) {
211 root = root_;
212 }
213
214 // If the root itself is not found then we can't run DFT.
215 if (root == nullptr) {
216 return return_string;
217 }
218
219 std::stack<TreeNodePtr> visit{};
220 visit.push(root);
221
222 while (!visit.empty()) {
223 auto &node{visit.top()};
224 node->visit();
225 return_string += node->toString();
226 return_string += " ";
227
228 // llvm::outs() << "@@ " << node->toString() << "\n";
229 // For repeated calls to dft...
230 // Check if node is already in there
231 if (!run_dft_) {
232 nodes_dft_.push_back(node);
233 }
234
235 // Call back function.
236 visit.pop();
237
238 if (!node->isDiscovered()) {
239 node->setDiscovered();
240
241 auto source{adj_list_.find(node)};
242 if (source == adj_list_.end()) {
243 return "";
244 }
245
246 auto const &edges{source->second};
247 for (auto &node : edges) {
248 visit.push(node);
249 }
250 }
251 }
252 if (!run_dft_) {
253 run_dft_ = true;
254 }
255 return return_string;
256 }
257
258 public:
260 //
261 //
262 //
264 //
266 public:
267 typedef std::vector<TreeNodePtr> *TreeDFTPtr;
268
269 private:
272 std::size_t pos_;
273
274 public:
275 const_dft_iterator(Tree<T> *tree, std::size_t pos)
276 : tree_{tree}, nodes_dft_{&tree->nodes_dft_}, pos_{pos} {
277 tree->dft();
278 }
279
280 const TreeNodePtr &operator*() { return (nodes_dft_)->operator[](pos_); }
281
283 ++pos_;
284 return *this;
285 }
286
288 pos_ = 0;
289 return *this;
290 }
291
293 pos_ = nodes_dft_->size();
294 return *this;
295 }
296
297 bool operator!=(const const_dft_iterator &it) { return pos_ != it.pos_; }
298 };
299
300 const_dft_iterator begin() const { return const_dft_iterator{this, 0}; }
301
303 return const_dft_iterator{this, nodes_dft_.size()};
304 }
305
306 //
310 public:
311 typedef std::vector<TreeNodePtr> *TreeDFTPtr;
312
313 private:
316 std::size_t pos_;
317
318 public:
319 dft_iterator(Tree<T> *tree, std::size_t pos)
320 : tree_{tree}, nodes_dft_{&tree->nodes_dft_}, pos_{pos} {
321 tree_->dft();
322 }
323
324 TreeNodePtr &operator*() { return (nodes_dft_)->operator[](pos_); }
325
327 ++pos_;
328 return *this;
329 }
330
332 pos_ = 0;
333 return *this;
334 }
335
337 pos_ = nodes_dft_->size();
338 return *this;
339 }
340
341 bool operator!=(const dft_iterator &it) { return pos_ != it.pos_; }
342 };
343
344 dft_iterator begin() { return dft_iterator{this, 0}; }
345
346 dft_iterator end() { return dft_iterator{this, nodes_dft_.size()}; }
347};
348}; // namespace systemc_clang
349#endif
class TreeNode<T>
Definition Tree.h:18
bool isDiscovered() const
Definition Tree.h:42
void dump(llvm::raw_ostream &outstream=llvm::outs())
Definition Tree.h:50
T getData() const
Definition Tree.h:38
virtual void visit(llvm::raw_ostream &outstream=llvm::outs())
Definition Tree.h:54
TreeNode * getParent() const
Definition Tree.h:48
TreeNode * parent_
Whether this node was discovered or not.
Definition Tree.h:22
void setParent(TreeNode *from)
Definition Tree.h:46
virtual ~TreeNode()
Definition Tree.h:34
void resetDiscovered()
Definition Tree.h:44
bool discovered_
Data item.
Definition Tree.h:21
TreeNode(const TreeNode &from)
Definition Tree.h:28
std::string toString() const
Definition Tree.h:40
TreeNode(T data)
Parent node.
Definition Tree.h:26
const T * getDataPtr()
Definition Tree.h:39
const_dft_iterator(Tree< T > *tree, std::size_t pos)
Definition Tree.h:275
const_dft_iterator & operator++()
Definition Tree.h:282
std::vector< TreeNodePtr > * TreeDFTPtr
Definition Tree.h:267
bool operator!=(const const_dft_iterator &it)
Definition Tree.h:297
const TreeNodePtr & operator*()
Definition Tree.h:280
dft_iterator & operator++()
Definition Tree.h:326
std::vector< TreeNodePtr > * TreeDFTPtr
Definition Tree.h:311
bool operator!=(const dft_iterator &it)
Definition Tree.h:341
dft_iterator(Tree< T > *tree, std::size_t pos)
Definition Tree.h:319
TreeNodePtr & operator*()
Definition Tree.h:324
void addEdge(const TreeNodePtr from, const TreeNodePtr to)
Definition Tree.h:148
dft_iterator begin()
Definition Tree.h:344
std::size_t size() const
Definition Tree.h:117
std::vector< TreeNodePtr > nodes_dft_
Definition Tree.h:80
void dump(llvm::raw_ostream &outstream=llvm::outs())
Definition Tree.h:105
const_dft_iterator end() const
Definition Tree.h:302
dft_iterator end()
Definition Tree.h:346
const_dft_iterator begin() const
Definition Tree.h:300
std::vector< TreeNodePtr > nodes_bft_
Definition Tree.h:79
std::string bft(TreeNodePtr root)
Definition Tree.h:172
TreeNodePtr addNode(T data)
Definition Tree.h:141
TreeNodePtr root_
Definition Tree.h:75
const TreeNodePtr getRoot() const
Definition Tree.h:121
const VectorTreePtr & getChildren(TreeNodePtr node)
Definition Tree.h:139
void resetDiscovered()
Definition Tree.h:166
Tree(const Tree &from)
Definition Tree.h:85
void setRoot(const TreeNodePtr from)
Definition Tree.h:119
bool foundNode(TreeNodePtr node) const
Definition Tree.h:123
TreeNode< T > * TreeNodePtr
Definition Tree.h:67
std::vector< TreeNodePtr > VectorTreePtr
Definition Tree.h:68
std::string dft(TreeNodePtr root=nullptr)
Definition Tree.h:205
std::map< TreeNodePtr, std::vector< TreeNodePtr > > adj_list_
Definition Tree.h:74
bool hasChildren(TreeNodePtr node)
Definition Tree.h:131