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