]> sourceware.org Git - systemtap.git/blob - staptree.h
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
[systemtap.git] / staptree.h
1 // -*- C++ -*-
2 // Copyright (C) 2005-2009 Red Hat Inc.
3 // Copyright (C) 2006 Intel Corporation.
4 //
5 // This file is part of systemtap, and is free software. You can
6 // redistribute it and/or modify it under the terms of the GNU General
7 // Public License (GPL); either version 2, or (at your option) any
8 // later version.
9
10 #ifndef STAPTREE_H
11 #define STAPTREE_H
12
13 #include <map>
14 #include <stack>
15 #include <set>
16 #include <string>
17 #include <vector>
18 #include <iostream>
19 #include <stdexcept>
20 #include <cassert>
21 extern "C" {
22 #include <stdint.h>
23 }
24
25 struct token; // parse.h
26 struct systemtap_session; // session.h
27
28 struct semantic_error: public std::runtime_error
29 {
30 const token* tok1;
31 std::string msg2;
32 const token* tok2;
33 semantic_error *chain;
34
35 ~semantic_error () throw () {}
36 semantic_error (const std::string& msg):
37 runtime_error (msg), tok1 (0), tok2 (0), chain (0) {}
38 semantic_error (const std::string& msg, const token* t1):
39 runtime_error (msg), tok1 (t1), tok2 (0), chain (0) {}
40 semantic_error (const std::string& msg, const token* t1,
41 const std::string& m2, const token* t2):
42 runtime_error (msg), tok1 (t1), msg2 (m2), tok2 (t2), chain (0) {}
43 };
44
45 // ------------------------------------------------------------------------
46
47 /* struct statistic_decl moved to session.h */
48
49 // ------------------------------------------------------------------------
50
51 enum exp_type
52 {
53 pe_unknown,
54 pe_long, // int64_t
55 pe_string, // std::string
56 pe_stats
57 };
58
59 std::ostream& operator << (std::ostream& o, const exp_type& e);
60
61 struct token;
62 struct visitor;
63 struct update_visitor;
64
65 struct expression
66 {
67 exp_type type;
68 const token* tok;
69 expression ();
70 virtual ~expression ();
71 virtual void print (std::ostream& o) const = 0;
72 virtual void visit (visitor* u) = 0;
73 };
74
75 std::ostream& operator << (std::ostream& o, const expression& k);
76
77
78 struct literal: public expression
79 {
80 };
81
82
83 struct literal_string: public literal
84 {
85 std::string value;
86 literal_string (const std::string& v);
87 void print (std::ostream& o) const;
88 void visit (visitor* u);
89 };
90
91
92 struct literal_number: public literal
93 {
94 int64_t value;
95 literal_number (int64_t v);
96 void print (std::ostream& o) const;
97 void visit (visitor* u);
98 };
99
100
101 struct binary_expression: public expression
102 {
103 expression* left;
104 std::string op;
105 expression* right;
106 void print (std::ostream& o) const;
107 void visit (visitor* u);
108 };
109
110
111 struct unary_expression: public expression
112 {
113 std::string op;
114 expression* operand;
115 void print (std::ostream& o) const;
116 void visit (visitor* u);
117 };
118
119
120 struct pre_crement: public unary_expression
121 {
122 void visit (visitor* u);
123 };
124
125
126 struct post_crement: public unary_expression
127 {
128 void print (std::ostream& o) const;
129 void visit (visitor* u);
130 };
131
132
133 struct logical_or_expr: public binary_expression
134 {
135 void visit (visitor* u);
136 };
137
138
139 struct logical_and_expr: public binary_expression
140 {
141 void visit (visitor* u);
142 };
143
144
145 struct arrayindex;
146 struct array_in: public expression
147 {
148 arrayindex* operand;
149 void print (std::ostream& o) const;
150 void visit (visitor* u);
151 };
152
153
154 struct comparison: public binary_expression
155 {
156 void visit (visitor* u);
157 };
158
159
160 struct concatenation: public binary_expression
161 {
162 void visit (visitor* u);
163 };
164
165
166 struct ternary_expression: public expression
167 {
168 expression* cond;
169 expression* truevalue;
170 expression* falsevalue;
171 void print (std::ostream& o) const;
172 void visit (visitor* u);
173 };
174
175
176 struct assignment: public binary_expression
177 {
178 void visit (visitor* u);
179 };
180
181 struct symbol;
182 struct hist_op;
183 struct indexable
184 {
185 // This is a helper class which, type-wise, acts as a disjoint union
186 // of symbols and histograms. You can ask it whether it's a
187 // histogram or a symbol, and downcast accordingly.
188 void print_indexable (std::ostream& o) const;
189 void visit_indexable (visitor* u);
190 virtual bool is_symbol(symbol *& sym_out);
191 virtual bool is_hist_op(hist_op *& hist_out);
192 virtual bool is_const_symbol(const symbol *& sym_out) const;
193 virtual bool is_const_hist_op(const hist_op *& hist_out) const;
194 virtual const token *get_tok() const = 0;
195 virtual ~indexable() {}
196 };
197
198 // Perform a downcast to one out-value and NULL the other, throwing an
199 // exception if neither downcast succeeds. This is (sadly) about the
200 // best we can accomplish in C++.
201 void
202 classify_indexable(indexable* ix,
203 symbol *& array_out,
204 hist_op *& hist_out);
205
206 void
207 classify_const_indexable(const indexable* ix,
208 symbol const *& array_out,
209 hist_op const *& hist_out);
210
211 class vardecl;
212 struct symbol:
213 public expression,
214 public indexable
215 {
216 std::string name;
217 vardecl *referent;
218 symbol ();
219 void print (std::ostream& o) const;
220 void visit (visitor* u);
221 // overrides of type 'indexable'
222 const token *get_tok() const;
223 bool is_const_symbol(const symbol *& sym_out) const;
224 bool is_symbol(symbol *& sym_out);
225 };
226
227
228 struct target_symbol: public symbol
229 {
230 enum component_type
231 {
232 comp_struct_member,
233 comp_literal_array_index,
234 comp_expression_array_index,
235 };
236
237 struct component
238 {
239 const token* tok;
240 component_type type;
241 std::string member; // comp_struct_member
242 int64_t num_index; // comp_literal_array_index
243 expression* expr_index; // comp_expression_array_index
244
245 component(const token* t, const std::string& m):
246 tok(t), type(comp_struct_member), member(m) {}
247 component(const token* t, int64_t n):
248 tok(t), type(comp_literal_array_index), num_index(n) {}
249 component(const token* t, expression* e):
250 tok(t), type(comp_expression_array_index), expr_index(e) {}
251 void print (std::ostream& o) const;
252 };
253
254 bool addressof;
255 std::string base_name;
256 std::vector<component> components;
257 std::string probe_context_var;
258 semantic_error* saved_conversion_error;
259 target_symbol(): addressof(false), saved_conversion_error (0) {}
260 void print (std::ostream& o) const;
261 void visit (visitor* u);
262 void visit_components (visitor* u);
263 void visit_components (update_visitor* u);
264 void assert_no_components(const std::string& tapset);
265 };
266
267 std::ostream& operator << (std::ostream& o, const target_symbol::component& c);
268
269
270 struct cast_op: public target_symbol
271 {
272 expression *operand;
273 std::string type, module;
274 void print (std::ostream& o) const;
275 void visit (visitor* u);
276 };
277
278
279 struct arrayindex: public expression
280 {
281 std::vector<expression*> indexes;
282 indexable *base;
283 arrayindex ();
284 void print (std::ostream& o) const;
285 void visit (visitor* u);
286 };
287
288
289 class functiondecl;
290 struct functioncall: public expression
291 {
292 std::string function;
293 std::vector<expression*> args;
294 functiondecl *referent;
295 functioncall ();
296 void print (std::ostream& o) const;
297 void visit (visitor* u);
298 };
299
300
301 struct print_format: public expression
302 {
303 bool print_to_stream;
304 bool print_with_format;
305 bool print_with_delim;
306 bool print_with_newline;
307 bool print_char;
308
309 enum format_flag
310 {
311 fmt_flag_zeropad = 1,
312 fmt_flag_plus = 2,
313 fmt_flag_space = 4,
314 fmt_flag_left = 8,
315 fmt_flag_special = 16
316 };
317
318 enum conversion_type
319 {
320 conv_unspecified,
321 conv_signed_decimal,
322 conv_unsigned_decimal,
323 conv_unsigned_octal,
324 conv_unsigned_ptr,
325 conv_unsigned_uppercase_hex,
326 conv_unsigned_lowercase_hex,
327 conv_string,
328 conv_char,
329 conv_memory,
330 conv_memory_hex,
331 conv_literal,
332 conv_binary
333 };
334
335 enum width_type
336 {
337 width_unspecified,
338 width_static,
339 width_dynamic
340 };
341
342 enum precision_type
343 {
344 prec_unspecified,
345 prec_static,
346 prec_dynamic
347 };
348
349 struct format_component
350 {
351 unsigned long flags;
352 unsigned width;
353 unsigned precision;
354 width_type widthtype;
355 precision_type prectype;
356 conversion_type type;
357 std::string literal_string;
358 bool is_empty() const
359 {
360 return flags == 0
361 && widthtype == width_unspecified
362 && prectype == prec_unspecified
363 && type == conv_unspecified
364 && literal_string.empty();
365 }
366 void clear()
367 {
368 flags = 0;
369 widthtype = width_unspecified;
370 prectype = prec_unspecified;
371 type = conv_unspecified;
372 literal_string.clear();
373 }
374 };
375
376 std::string raw_components;
377 std::vector<format_component> components;
378 format_component delimiter;
379 std::vector<expression*> args;
380 hist_op *hist;
381
382 static std::string components_to_string(std::vector<format_component> const & components);
383 static std::vector<format_component> string_to_components(std::string const & str);
384 static print_format* create(const token *t);
385
386 void print (std::ostream& o) const;
387 void visit (visitor* u);
388
389 private:
390 print_format(bool stream, bool format, bool delim, bool newline, bool _char):
391 print_to_stream(stream), print_with_format(format),
392 print_with_delim(delim), print_with_newline(newline),
393 print_char(_char), hist(NULL)
394 {}
395 };
396
397
398 enum stat_component_type
399 {
400 sc_average,
401 sc_count,
402 sc_sum,
403 sc_min,
404 sc_max,
405 };
406
407 struct stat_op: public expression
408 {
409 stat_component_type ctype;
410 expression* stat;
411 void print (std::ostream& o) const;
412 void visit (visitor* u);
413 };
414
415 enum histogram_type
416 {
417 hist_linear,
418 hist_log
419 };
420
421 struct hist_op: public indexable
422 {
423 const token* tok;
424 histogram_type htype;
425 expression* stat;
426 std::vector<int64_t> params;
427 void print (std::ostream& o) const;
428 void visit (visitor* u);
429 // overrides of type 'indexable'
430 const token *get_tok() const;
431 bool is_const_hist_op(const hist_op *& hist_out) const;
432 bool is_hist_op(hist_op *& hist_out);
433 };
434
435 // ------------------------------------------------------------------------
436
437
438 struct symboldecl // unique object per (possibly implicit)
439 // symbol declaration
440 {
441 const token* tok;
442 std::string name;
443 exp_type type;
444 symboldecl ();
445 virtual ~symboldecl ();
446 virtual void print (std::ostream &o) const = 0;
447 virtual void printsig (std::ostream &o) const = 0;
448 };
449
450
451 std::ostream& operator << (std::ostream& o, const symboldecl& k);
452
453
454 struct vardecl: public symboldecl
455 {
456 void print (std::ostream& o) const;
457 void printsig (std::ostream& o) const;
458 vardecl ();
459 void set_arity (int arity);
460 bool compatible_arity (int a);
461 int arity; // -1: unknown; 0: scalar; >0: array
462 int maxsize; // upperbound on size for arrays
463 std::vector<exp_type> index_types; // for arrays only
464 literal *init; // for global scalars only
465 };
466
467
468 struct vardecl_builtin: public vardecl
469 {
470 };
471
472
473 struct statement;
474 struct functiondecl: public symboldecl
475 {
476 std::vector<vardecl*> formal_args;
477 std::vector<vardecl*> locals;
478 std::vector<vardecl*> unused_locals;
479 statement* body;
480 functiondecl ();
481 void print (std::ostream& o) const;
482 void printsig (std::ostream& o) const;
483 };
484
485
486 // ------------------------------------------------------------------------
487
488
489 struct statement
490 {
491 virtual void print (std::ostream& o) const = 0;
492 virtual void visit (visitor* u) = 0;
493 const token* tok;
494 statement ();
495 virtual ~statement ();
496 };
497
498 std::ostream& operator << (std::ostream& o, const statement& k);
499
500
501 struct embeddedcode: public statement
502 {
503 std::string code;
504 void print (std::ostream& o) const;
505 void visit (visitor* u);
506 };
507
508
509 struct block: public statement
510 {
511 std::vector<statement*> statements;
512 void print (std::ostream& o) const;
513 void visit (visitor* u);
514 block () {}
515 block (statement* car, statement* cdr);
516 };
517
518
519 struct expr_statement;
520 struct for_loop: public statement
521 {
522 expr_statement* init; // may be 0
523 expression* cond;
524 expr_statement* incr; // may be 0
525 statement* block;
526 void print (std::ostream& o) const;
527 void visit (visitor* u);
528 };
529
530
531 struct foreach_loop: public statement
532 {
533 // this part is a specialization of arrayindex
534 std::vector<symbol*> indexes;
535 indexable *base;
536 int sort_direction; // -1: decreasing, 0: none, 1: increasing
537 unsigned sort_column; // 0: value, 1..N: index
538 expression* limit; // optional iteration limit
539
540 statement* block;
541 void print (std::ostream& o) const;
542 void visit (visitor* u);
543 };
544
545
546 struct null_statement: public statement
547 {
548 void print (std::ostream& o) const;
549 void visit (visitor* u);
550 };
551
552
553 struct expr_statement: public statement
554 {
555 expression* value; // executed for side-effects
556 void print (std::ostream& o) const;
557 void visit (visitor* u);
558 };
559
560
561 struct if_statement: public statement
562 {
563 expression* condition;
564 statement* thenblock;
565 statement* elseblock; // may be 0
566 void print (std::ostream& o) const;
567 void visit (visitor* u);
568 };
569
570
571 struct return_statement: public expr_statement
572 {
573 void print (std::ostream& o) const;
574 void visit (visitor* u);
575 };
576
577
578 struct delete_statement: public expr_statement
579 {
580 void print (std::ostream& o) const;
581 void visit (visitor* u);
582 };
583
584
585 struct break_statement: public statement
586 {
587 void print (std::ostream& o) const;
588 void visit (visitor* u);
589 };
590
591
592 struct continue_statement: public statement
593 {
594 void print (std::ostream& o) const;
595 void visit (visitor* u);
596 };
597
598
599 struct next_statement: public statement
600 {
601 void print (std::ostream& o) const;
602 void visit (visitor* u);
603 };
604
605
606 struct probe;
607 struct derived_probe;
608 struct probe_alias;
609 struct embeddedcode;
610 struct stapfile
611 {
612 std::string name;
613 std::vector<probe*> probes;
614 std::vector<probe_alias*> aliases;
615 std::vector<functiondecl*> functions;
616 std::vector<vardecl*> globals;
617 std::vector<embeddedcode*> embeds;
618 std::string file_contents;
619 bool privileged;
620 stapfile (): file_contents (""),
621 privileged (false) {}
622 void print (std::ostream& o) const;
623 };
624
625
626 struct probe_point
627 {
628 struct component // XXX: sort of a restricted functioncall
629 {
630 std::string functor;
631 literal* arg; // optional
632 component ();
633 component(std::string const & f, literal * a = NULL);
634 };
635 std::vector<component*> components;
636 const token* tok; // points to first component's functor
637 bool optional;
638 bool sufficient;
639 expression* condition;
640 void print (std::ostream& o) const;
641 probe_point ();
642 probe_point(const probe_point& pp);
643 probe_point(std::vector<component*> const & comps,const token * t);
644 std::string str();
645 };
646
647 std::ostream& operator << (std::ostream& o, const probe_point& k);
648
649
650 struct probe
651 {
652 std::vector<probe_point*> locations;
653 statement* body;
654 const token* tok;
655 std::vector<vardecl*> locals;
656 std::vector<vardecl*> unused_locals;
657 probe ();
658 void print (std::ostream& o) const;
659 virtual void printsig (std::ostream &o) const;
660 virtual void collect_derivation_chain (std::vector<probe*> &probes_list);
661 virtual const probe_alias *get_alias () const { return 0; }
662 virtual probe* basest () { return this; }
663 virtual ~probe() {}
664 bool privileged;
665 std::string name;
666 };
667
668 struct probe_alias: public probe
669 {
670 probe_alias(std::vector<probe_point*> const & aliases);
671 std::vector<probe_point*> alias_names;
672 virtual void printsig (std::ostream &o) const;
673 bool epilogue_style;
674 };
675
676
677 // A derived visitor instance is used to visit the entire
678 // statement/expression tree.
679 struct visitor
680 {
681 // Machinery for differentiating lvalue visits from non-lvalue.
682 std::vector<expression *> active_lvalues;
683 bool is_active_lvalue(expression *e);
684 void push_active_lvalue(expression *e);
685 void pop_active_lvalue();
686
687 virtual ~visitor () {}
688 virtual void visit_block (block *s) = 0;
689 virtual void visit_embeddedcode (embeddedcode *s) = 0;
690 virtual void visit_null_statement (null_statement *s) = 0;
691 virtual void visit_expr_statement (expr_statement *s) = 0;
692 virtual void visit_if_statement (if_statement* s) = 0;
693 virtual void visit_for_loop (for_loop* s) = 0;
694 virtual void visit_foreach_loop (foreach_loop* s) = 0;
695 virtual void visit_return_statement (return_statement* s) = 0;
696 virtual void visit_delete_statement (delete_statement* s) = 0;
697 virtual void visit_next_statement (next_statement* s) = 0;
698 virtual void visit_break_statement (break_statement* s) = 0;
699 virtual void visit_continue_statement (continue_statement* s) = 0;
700 virtual void visit_literal_string (literal_string* e) = 0;
701 virtual void visit_literal_number (literal_number* e) = 0;
702 virtual void visit_binary_expression (binary_expression* e) = 0;
703 virtual void visit_unary_expression (unary_expression* e) = 0;
704 virtual void visit_pre_crement (pre_crement* e) = 0;
705 virtual void visit_post_crement (post_crement* e) = 0;
706 virtual void visit_logical_or_expr (logical_or_expr* e) = 0;
707 virtual void visit_logical_and_expr (logical_and_expr* e) = 0;
708 virtual void visit_array_in (array_in* e) = 0;
709 virtual void visit_comparison (comparison* e) = 0;
710 virtual void visit_concatenation (concatenation* e) = 0;
711 virtual void visit_ternary_expression (ternary_expression* e) = 0;
712 virtual void visit_assignment (assignment* e) = 0;
713 virtual void visit_symbol (symbol* e) = 0;
714 virtual void visit_target_symbol (target_symbol* e) = 0;
715 virtual void visit_arrayindex (arrayindex* e) = 0;
716 virtual void visit_functioncall (functioncall* e) = 0;
717 virtual void visit_print_format (print_format* e) = 0;
718 virtual void visit_stat_op (stat_op* e) = 0;
719 virtual void visit_hist_op (hist_op* e) = 0;
720 virtual void visit_cast_op (cast_op* e) = 0;
721 };
722
723
724 // A simple kind of visitor, which travels down to the leaves of the
725 // statement/expression tree, up to but excluding following vardecls
726 // and functioncalls.
727 struct traversing_visitor: public visitor
728 {
729 void visit_block (block *s);
730 void visit_embeddedcode (embeddedcode *s);
731 void visit_null_statement (null_statement *s);
732 void visit_expr_statement (expr_statement *s);
733 void visit_if_statement (if_statement* s);
734 void visit_for_loop (for_loop* s);
735 void visit_foreach_loop (foreach_loop* s);
736 void visit_return_statement (return_statement* s);
737 void visit_delete_statement (delete_statement* s);
738 void visit_next_statement (next_statement* s);
739 void visit_break_statement (break_statement* s);
740 void visit_continue_statement (continue_statement* s);
741 void visit_literal_string (literal_string* e);
742 void visit_literal_number (literal_number* e);
743 void visit_binary_expression (binary_expression* e);
744 void visit_unary_expression (unary_expression* e);
745 void visit_pre_crement (pre_crement* e);
746 void visit_post_crement (post_crement* e);
747 void visit_logical_or_expr (logical_or_expr* e);
748 void visit_logical_and_expr (logical_and_expr* e);
749 void visit_array_in (array_in* e);
750 void visit_comparison (comparison* e);
751 void visit_concatenation (concatenation* e);
752 void visit_ternary_expression (ternary_expression* e);
753 void visit_assignment (assignment* e);
754 void visit_symbol (symbol* e);
755 void visit_target_symbol (target_symbol* e);
756 void visit_arrayindex (arrayindex* e);
757 void visit_functioncall (functioncall* e);
758 void visit_print_format (print_format* e);
759 void visit_stat_op (stat_op* e);
760 void visit_hist_op (hist_op* e);
761 void visit_cast_op (cast_op* e);
762 };
763
764
765 // A kind of traversing visitor, which also follows function calls.
766 // It uses an internal set object to prevent infinite recursion.
767 struct functioncall_traversing_visitor: public traversing_visitor
768 {
769 std::set<functiondecl*> traversed;
770 functiondecl* current_function;
771 functioncall_traversing_visitor(): current_function(0) {}
772 void visit_functioncall (functioncall* e);
773 };
774
775
776 // A kind of traversing visitor, which also follows function calls,
777 // and stores the vardecl* referent of each variable read and/or
778 // written and other such sundry side-effect data. It's used by
779 // the elaboration-time optimizer pass.
780 struct varuse_collecting_visitor: public functioncall_traversing_visitor
781 {
782 systemtap_session& session;
783 std::set<vardecl*> read;
784 std::set<vardecl*> written;
785 bool embedded_seen;
786 expression* current_lvalue;
787 expression* current_lrvalue;
788 varuse_collecting_visitor(systemtap_session& s):
789 session (s),
790 embedded_seen (false),
791 current_lvalue(0),
792 current_lrvalue(0) {}
793 void visit_embeddedcode (embeddedcode *s);
794 void visit_delete_statement (delete_statement *s);
795 void visit_print_format (print_format *e);
796 void visit_assignment (assignment *e);
797 void visit_arrayindex (arrayindex *e);
798 void visit_target_symbol (target_symbol *e);
799 void visit_symbol (symbol *e);
800 void visit_pre_crement (pre_crement *e);
801 void visit_post_crement (post_crement *e);
802 void visit_foreach_loop (foreach_loop *s);
803 void visit_cast_op (cast_op* e);
804
805 bool side_effect_free ();
806 bool side_effect_free_wrt (const std::set<vardecl*>& vars);
807 };
808
809
810
811 // A kind of visitor that throws an semantic_error exception
812 // whenever a non-overridden method is called.
813 struct throwing_visitor: public visitor
814 {
815 std::string msg;
816 throwing_visitor (const std::string& m);
817 throwing_visitor ();
818
819 virtual void throwone (const token* t);
820
821 void visit_block (block *s);
822 void visit_embeddedcode (embeddedcode *s);
823 void visit_null_statement (null_statement *s);
824 void visit_expr_statement (expr_statement *s);
825 void visit_if_statement (if_statement* s);
826 void visit_for_loop (for_loop* s);
827 void visit_foreach_loop (foreach_loop* s);
828 void visit_return_statement (return_statement* s);
829 void visit_delete_statement (delete_statement* s);
830 void visit_next_statement (next_statement* s);
831 void visit_break_statement (break_statement* s);
832 void visit_continue_statement (continue_statement* s);
833 void visit_literal_string (literal_string* e);
834 void visit_literal_number (literal_number* e);
835 void visit_binary_expression (binary_expression* e);
836 void visit_unary_expression (unary_expression* e);
837 void visit_pre_crement (pre_crement* e);
838 void visit_post_crement (post_crement* e);
839 void visit_logical_or_expr (logical_or_expr* e);
840 void visit_logical_and_expr (logical_and_expr* e);
841 void visit_array_in (array_in* e);
842 void visit_comparison (comparison* e);
843 void visit_concatenation (concatenation* e);
844 void visit_ternary_expression (ternary_expression* e);
845 void visit_assignment (assignment* e);
846 void visit_symbol (symbol* e);
847 void visit_target_symbol (target_symbol* e);
848 void visit_arrayindex (arrayindex* e);
849 void visit_functioncall (functioncall* e);
850 void visit_print_format (print_format* e);
851 void visit_stat_op (stat_op* e);
852 void visit_hist_op (hist_op* e);
853 void visit_cast_op (cast_op* e);
854 };
855
856 // A visitor similar to a traversing_visitor, but with the ability to rewrite
857 // parts of the tree through require/provide.
858
859 struct update_visitor: public visitor
860 {
861 template <typename T> T* require (T* src, bool clearok=false)
862 {
863 T* dst = NULL;
864 if (src != NULL)
865 {
866 src->visit(this);
867 assert(!targets.empty());
868 dst = static_cast<T*>(targets.top());
869 targets.pop();
870 assert(clearok || dst);
871 }
872 return dst;
873 }
874
875 template <typename T> void provide (T* src)
876 {
877 targets.push(static_cast<void*>(src));
878 }
879
880 template <typename T> void replace (T*& src, bool clearok=false)
881 {
882 src = require(src, clearok);
883 }
884
885 virtual ~update_visitor() { assert(targets.empty()); }
886
887 virtual void visit_block (block *s);
888 virtual void visit_embeddedcode (embeddedcode *s);
889 virtual void visit_null_statement (null_statement *s);
890 virtual void visit_expr_statement (expr_statement *s);
891 virtual void visit_if_statement (if_statement* s);
892 virtual void visit_for_loop (for_loop* s);
893 virtual void visit_foreach_loop (foreach_loop* s);
894 virtual void visit_return_statement (return_statement* s);
895 virtual void visit_delete_statement (delete_statement* s);
896 virtual void visit_next_statement (next_statement* s);
897 virtual void visit_break_statement (break_statement* s);
898 virtual void visit_continue_statement (continue_statement* s);
899 virtual void visit_literal_string (literal_string* e);
900 virtual void visit_literal_number (literal_number* e);
901 virtual void visit_binary_expression (binary_expression* e);
902 virtual void visit_unary_expression (unary_expression* e);
903 virtual void visit_pre_crement (pre_crement* e);
904 virtual void visit_post_crement (post_crement* e);
905 virtual void visit_logical_or_expr (logical_or_expr* e);
906 virtual void visit_logical_and_expr (logical_and_expr* e);
907 virtual void visit_array_in (array_in* e);
908 virtual void visit_comparison (comparison* e);
909 virtual void visit_concatenation (concatenation* e);
910 virtual void visit_ternary_expression (ternary_expression* e);
911 virtual void visit_assignment (assignment* e);
912 virtual void visit_symbol (symbol* e);
913 virtual void visit_target_symbol (target_symbol* e);
914 virtual void visit_arrayindex (arrayindex* e);
915 virtual void visit_functioncall (functioncall* e);
916 virtual void visit_print_format (print_format* e);
917 virtual void visit_stat_op (stat_op* e);
918 virtual void visit_hist_op (hist_op* e);
919 virtual void visit_cast_op (cast_op* e);
920
921 private:
922 std::stack<void *> targets;
923 };
924
925 template <> indexable*
926 update_visitor::require <indexable> (indexable* src, bool clearok);
927
928 // A visitor which performs a deep copy of the root node it's applied
929 // to. NB: It does not copy any of the variable or function
930 // declarations; those fields are set to NULL, assuming you want to
931 // re-infer the declarations in a new context (the one you're copying
932 // to).
933
934 struct deep_copy_visitor: public update_visitor
935 {
936 template <typename T> static T* deep_copy (T* e)
937 {
938 deep_copy_visitor v;
939 return v.require (e);
940 }
941
942 virtual void visit_block (block *s);
943 virtual void visit_embeddedcode (embeddedcode *s);
944 virtual void visit_null_statement (null_statement *s);
945 virtual void visit_expr_statement (expr_statement *s);
946 virtual void visit_if_statement (if_statement* s);
947 virtual void visit_for_loop (for_loop* s);
948 virtual void visit_foreach_loop (foreach_loop* s);
949 virtual void visit_return_statement (return_statement* s);
950 virtual void visit_delete_statement (delete_statement* s);
951 virtual void visit_next_statement (next_statement* s);
952 virtual void visit_break_statement (break_statement* s);
953 virtual void visit_continue_statement (continue_statement* s);
954 virtual void visit_literal_string (literal_string* e);
955 virtual void visit_literal_number (literal_number* e);
956 virtual void visit_binary_expression (binary_expression* e);
957 virtual void visit_unary_expression (unary_expression* e);
958 virtual void visit_pre_crement (pre_crement* e);
959 virtual void visit_post_crement (post_crement* e);
960 virtual void visit_logical_or_expr (logical_or_expr* e);
961 virtual void visit_logical_and_expr (logical_and_expr* e);
962 virtual void visit_array_in (array_in* e);
963 virtual void visit_comparison (comparison* e);
964 virtual void visit_concatenation (concatenation* e);
965 virtual void visit_ternary_expression (ternary_expression* e);
966 virtual void visit_assignment (assignment* e);
967 virtual void visit_symbol (symbol* e);
968 virtual void visit_target_symbol (target_symbol* e);
969 virtual void visit_arrayindex (arrayindex* e);
970 virtual void visit_functioncall (functioncall* e);
971 virtual void visit_print_format (print_format* e);
972 virtual void visit_stat_op (stat_op* e);
973 virtual void visit_hist_op (hist_op* e);
974 virtual void visit_cast_op (cast_op* e);
975 };
976
977 #endif // STAPTREE_H
978
979 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.077153 seconds and 5 git commands to generate.