]> sourceware.org Git - systemtap.git/blob - staptree.cxx
Merge branch 'master' of ssh://sourceware.org/git/systemtap
[systemtap.git] / staptree.cxx
1 // parse tree functions
2 // Copyright (C) 2005-2013 Red Hat Inc.
3 //
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
7 // later version.
8
9 #include "config.h"
10 #include "staptree.h"
11 #include "parse.h"
12 #include "util.h"
13 #include "session.h"
14
15 #include <iostream>
16 #include <typeinfo>
17 #include <sstream>
18 #include <cassert>
19 #include <cstring>
20 #include <vector>
21 #include <algorithm>
22 #include <cstring>
23
24 using namespace std;
25
26
27
28 visitable::~visitable ()
29 {
30 }
31
32
33 expression::expression ():
34 type (pe_unknown), tok (0)
35 {
36 }
37
38
39 expression::~expression ()
40 {
41 }
42
43
44 statement::statement ():
45 tok (0)
46 {
47 }
48
49
50 statement::statement (const token* tok):
51 tok (tok)
52 {
53 }
54
55
56 null_statement::null_statement (const token* tok):
57 statement(tok)
58 {
59 }
60
61
62 statement::~statement ()
63 {
64 }
65
66
67 symbol::symbol ():
68 referent (0)
69 {
70 }
71
72
73 arrayindex::arrayindex ():
74 base (0)
75 {
76 }
77
78
79 functioncall::functioncall ():
80 referent (0)
81 {
82 }
83
84
85 symboldecl::symboldecl ():
86 tok (0), systemtap_v_conditional (0),
87 type (pe_unknown)
88 {
89 }
90
91
92 symboldecl::~symboldecl ()
93 {
94 }
95
96 probe_point::probe_point (std::vector<component*> const & comps):
97 components(comps), optional (false), sufficient (false),
98 condition (0)
99 {
100 }
101
102 // NB: shallow-copy of compoonents & condition!
103 probe_point::probe_point (const probe_point& pp):
104 components(pp.components), optional (pp.optional), sufficient (pp.sufficient),
105 condition (pp.condition)
106 {
107 }
108
109
110 probe_point::probe_point ():
111 optional (false), sufficient (false), condition (0)
112 {
113 }
114
115
116 unsigned probe::last_probeidx = 0;
117
118 probe::probe ():
119 body (0), base (0), tok (0), systemtap_v_conditional (0), privileged (false)
120 {
121 this->name = string ("probe_") + lex_cast(last_probeidx ++);
122 }
123
124
125 // Copy constructor, but with overriding probe-point. To be used when
126 // mapping script-level probe points to another one, early during pass
127 // 2. There should be no symbol resolution done yet.
128 probe::probe(probe* p, probe_point* l)
129 {
130 this->base = p;
131 this->name = string ("probe_") + lex_cast(last_probeidx ++);
132 this->tok = p->tok;
133 this->locations.push_back(l);
134 this->body = deep_copy_visitor::deep_copy(p->body);
135 this->privileged = p->privileged;
136 this->systemtap_v_conditional = p->systemtap_v_conditional;
137 assert (p->locals.size() == 0);
138 assert (p->unused_locals.size() == 0);
139 }
140
141
142 probe_point::component::component ():
143 arg (0), tok(0)
144 {
145 }
146
147
148 probe_point::component::component (std::string const & f, literal * a):
149 functor(f), arg(a), tok(0)
150 {
151 }
152
153
154 vardecl::vardecl ():
155 arity_tok(0), arity (-1), maxsize(0), init(NULL), synthetic(false), wrap(false)
156 {
157 }
158
159
160 void
161 vardecl::set_arity (int a, const token* t)
162 {
163 if (a < 0)
164 return;
165
166 if (a == 0 && maxsize > 0)
167 throw SEMANTIC_ERROR (_("inconsistent arity"), tok);
168
169 if (arity != a && arity >= 0)
170 {
171 semantic_error err (ERR_SRC, _F("inconsistent arity (%s vs %d)",
172 lex_cast(arity).c_str(), a), t?:tok);
173 if (arity_tok)
174 err.chain = new SEMANTIC_ERROR (_F("arity %s first inferred here",
175 lex_cast(arity).c_str()), arity_tok);
176 throw err;
177 }
178
179 if (arity != a)
180 {
181 arity_tok = t;
182 arity = a;
183 index_types.resize (arity);
184 for (int i=0; i<arity; i++)
185 index_types[i] = pe_unknown;
186 }
187 }
188
189 bool
190 vardecl::compatible_arity (int a)
191 {
192 if (a == 0 && maxsize > 0)
193 return false;
194 if (arity == -1 || a == -1)
195 return true;
196 return arity == a;
197 }
198
199
200 functiondecl::functiondecl ():
201 body (0), synthetic (false), mangle_oldstyle (false)
202 {
203 }
204
205 void
206 functiondecl::join (systemtap_session& s)
207 {
208 if (!synthetic)
209 throw SEMANTIC_ERROR (_("internal error, joining a non-synthetic function"), tok);
210 if (!s.functions.insert (make_pair (name, this)).second)
211 throw SEMANTIC_ERROR (_F("synthetic function '%s' conflicts with an existing function",
212 name.c_str()), tok);
213 tok->location.file->functions.push_back (this);
214 }
215
216
217 literal_number::literal_number (int64_t v, bool hex)
218 {
219 value = v;
220 print_hex = hex;
221 type = pe_long;
222 }
223
224
225 literal_string::literal_string (const string& v)
226 {
227 value = v;
228 type = pe_string;
229 }
230
231
232 ostream&
233 operator << (ostream& o, const exp_type& e)
234 {
235 switch (e)
236 {
237 case pe_unknown: o << "unknown"; break;
238 case pe_long: o << "long"; break;
239 case pe_string: o << "string"; break;
240 case pe_stats: o << "stats"; break;
241 default: o << "???"; break;
242 }
243 return o;
244 }
245
246
247 void
248 target_symbol::assert_no_components(const std::string& tapset, bool pretty_ok)
249 {
250 if (components.empty())
251 return;
252
253 switch (components[0].type)
254 {
255 case comp_literal_array_index:
256 case comp_expression_array_index:
257 throw SEMANTIC_ERROR(_F("%s variable '%s' may not be used as array",
258 tapset.c_str(), name.c_str()), components[0].tok);
259 case comp_struct_member:
260 throw SEMANTIC_ERROR(_F("%s variable '%s' may not be used as a structure",
261 tapset.c_str(), name.c_str()), components[0].tok);
262 case comp_pretty_print:
263 if (!pretty_ok)
264 throw SEMANTIC_ERROR(_F("%s variable '%s' may not be pretty-printed",
265 tapset.c_str(), name.c_str()), components[0].tok);
266 return;
267 default:
268 throw SEMANTIC_ERROR (_F("invalid use of %s variable '%s'",
269 tapset.c_str(), name.c_str()), components[0].tok);
270 }
271 }
272
273
274 void target_symbol::chain (const semantic_error &er)
275 {
276 semantic_error* e = new semantic_error(er);
277 if (!e->tok1)
278 e->tok1 = this->tok;
279 assert (e->chain == 0);
280 e->chain = this->saved_conversion_error;
281 this->saved_conversion_error = e;
282 }
283
284
285 string target_symbol::sym_name ()
286 {
287 return name.substr(1);
288 }
289
290
291 string atvar_op::sym_name ()
292 {
293 if (cu_name == "")
294 return target_name;
295 else
296 return target_name.substr(0, target_name.length() - cu_name.length() - 1);
297 }
298
299
300 // ------------------------------------------------------------------------
301 // parse tree printing
302
303 ostream& operator << (ostream& o, const expression& k)
304 {
305 k.print (o);
306 return o;
307 }
308
309
310 void literal_string::print (ostream& o) const
311 {
312 o << '"';
313 for (unsigned i=0; i<value.size(); i++)
314 if (value[i] == '"') // or other escapeworthy characters?
315 o << '\\' << '"';
316 else
317 o << value[i];
318 o << '"';
319 }
320
321
322 void literal_number::print (ostream& o) const
323 {
324 if (print_hex)
325 o << hex << showbase;
326 o << value;
327 if (print_hex)
328 o << dec << noshowbase;
329 }
330
331
332 void embedded_expr::print (ostream& o) const
333 {
334 o << "%{ " << code << " %}";
335 }
336
337
338 void binary_expression::print (ostream& o) const
339 {
340 o << "(" << *left << ") "
341 << op
342 << " (" << *right << ")";
343 }
344
345 void regex_query::print (ostream& o) const
346 {
347 // NB: we need a custom printer, because the parser does not accept
348 // a parenthesized RHS.
349 o << "(" << *left << ") "
350 << op
351 << " " << *right;
352 }
353
354
355 void unary_expression::print (ostream& o) const
356 {
357 o << op << '(' << *operand << ")";
358 }
359
360 void array_in::print (ostream& o) const
361 {
362 o << "[";
363 for (unsigned i=0; i<operand->indexes.size(); i++)
364 {
365 if (i > 0) o << ", ";
366 operand->indexes[i]->print (o);
367 }
368 o << "] in ";
369 operand->base->print (o);
370 }
371
372 void post_crement::print (ostream& o) const
373 {
374 o << '(' << *operand << ")" << op;
375 }
376
377
378 void ternary_expression::print (ostream& o) const
379 {
380 o << "(" << *cond << ")?("
381 << *truevalue << "):("
382 << *falsevalue << ")";
383 }
384
385
386 void symbol::print (ostream& o) const
387 {
388 o << name;
389 }
390
391
392 void target_symbol::component::print (ostream& o) const
393 {
394 switch (type)
395 {
396 case comp_pretty_print:
397 case comp_struct_member:
398 o << "->" << member;
399 break;
400 case comp_literal_array_index:
401 o << '[' << num_index << ']';
402 break;
403 case comp_expression_array_index:
404 o << '[' << *expr_index << ']';
405 break;
406 }
407 }
408
409
410 std::ostream& operator << (std::ostream& o, const target_symbol::component& c)
411 {
412 c.print (o);
413 return o;
414 }
415
416
417 void target_symbol::print (ostream& o) const
418 {
419 if (addressof)
420 o << "&";
421 o << name;
422 for (unsigned i = 0; i < components.size(); ++i)
423 o << components[i];
424 }
425
426
427 void atvar_op::print (ostream& o) const
428 {
429 if (addressof)
430 o << "&";
431 o << name << "(\"" << target_name << "\")";
432 for (unsigned i = 0; i < components.size(); ++i)
433 o << components[i];
434 }
435
436
437 void cast_op::print (ostream& o) const
438 {
439 if (addressof)
440 o << "&";
441 o << name << '(' << *operand;
442 o << ", " << lex_cast_qstring (type_name);
443 if (module.length() > 0)
444 o << ", " << lex_cast_qstring (module);
445 o << ')';
446 for (unsigned i = 0; i < components.size(); ++i)
447 o << components[i];
448 }
449
450
451 void defined_op::print (ostream& o) const
452 {
453 o << "@defined(" << *operand << ")";
454 }
455
456
457 void entry_op::print (ostream& o) const
458 {
459 o << "@entry(" << *operand << ")";
460 }
461
462
463 void perf_op::print (ostream& o) const
464 {
465 o << "@perf(" << *operand << ")";
466 }
467
468
469 void vardecl::print (ostream& o) const
470 {
471 o << name;
472 if(wrap)
473 o << "%";
474 if (maxsize > 0)
475 o << "[" << maxsize << "]";
476 if (arity > 0 || index_types.size() > 0)
477 o << "[...]";
478 if (init)
479 {
480 o << " = ";
481 init->print(o);
482 }
483 }
484
485
486 void vardecl::printsig (ostream& o) const
487 {
488 o << name;
489 if(wrap)
490 o << "%";
491 if (maxsize > 0)
492 o << "[" << maxsize << "]";
493 o << ":" << type;
494 if (index_types.size() > 0)
495 {
496 o << " [";
497 for (unsigned i=0; i<index_types.size(); i++)
498 o << (i>0 ? ", " : "") << index_types[i];
499 o << "]";
500 }
501 }
502
503
504 void functiondecl::print (ostream& o) const
505 {
506 o << "function " << name << " (";
507 for (unsigned i=0; i<formal_args.size(); i++)
508 o << (i>0 ? ", " : "") << *formal_args[i];
509 o << ")" << endl;
510 body->print(o);
511 }
512
513
514 void functiondecl::printsig (ostream& o) const
515 {
516 o << name << ":" << type << " (";
517 for (unsigned i=0; i<formal_args.size(); i++)
518 o << (i>0 ? ", " : "")
519 << *formal_args[i]
520 << ":"
521 << formal_args[i]->type;
522 o << ")";
523 }
524
525
526 void arrayindex::print (ostream& o) const
527 {
528 base->print (o);
529 o << "[";
530 for (unsigned i=0; i<indexes.size(); i++)
531 o << (i>0 ? ", " : "") << *indexes[i];
532 o << "]";
533 }
534
535
536 void functioncall::print (ostream& o) const
537 {
538 o << function << "(";
539 for (unsigned i=0; i<args.size(); i++)
540 o << (i>0 ? ", " : "") << *args[i];
541 o << ")";
542 }
543
544
545 print_format*
546 print_format::create(const token *t, const char *n)
547 {
548 bool stream, format, delim, newline, _char;
549 if (n == NULL) n = t->content.c_str();
550 const char *o = n;
551
552 stream = true;
553 format = delim = newline = _char = false;
554
555 if (strcmp(n, "print_char") == 0)
556 _char = true;
557 else
558 {
559 if (*n == 's')
560 {
561 stream = false;
562 ++n;
563 }
564
565 if (0 != strncmp(n, "print", 5))
566 return NULL;
567 n += 5;
568
569 if (*n == 'f')
570 {
571 format = true;
572 ++n;
573 }
574 else
575 {
576 if (*n == 'd')
577 {
578 delim = true;
579 ++n;
580 }
581
582 if (*n == 'l' && *(n+1) == 'n')
583 {
584 newline = true;
585 n += 2;
586 }
587 }
588
589 if (*n != '\0')
590 return NULL;
591 }
592
593 print_format *pf = new print_format(stream, format, delim, newline, _char, o);
594 pf->tok = t;
595 return pf;
596 }
597
598
599 string
600 print_format::components_to_string(vector<format_component> const & components)
601 {
602 ostringstream oss;
603
604 for (vector<format_component>::const_iterator i = components.begin();
605 i != components.end(); ++i)
606 {
607
608 assert (i->type != conv_unspecified);
609
610 if (i->type == conv_literal)
611 {
612 assert(!i->literal_string.empty());
613 for (string::const_iterator j = i->literal_string.begin();
614 j != i->literal_string.end(); ++j)
615 {
616 // See also: c_unparser::visit_literal_string and lex_cast_qstring
617 if (*j == '%')
618 oss << '%';
619 else if(*j == '"')
620 oss << '\\';
621 oss << *j;
622 }
623 }
624 else
625 {
626 oss << '%';
627
628 if (i->test_flag (fmt_flag_zeropad))
629 oss << '0';
630
631 if (i->test_flag (fmt_flag_plus))
632 oss << '+';
633
634 if (i->test_flag (fmt_flag_space))
635 oss << ' ';
636
637 if (i->test_flag (fmt_flag_left))
638 oss << '-';
639
640 if (i->test_flag (fmt_flag_special))
641 oss << '#';
642
643 if (i->widthtype == width_dynamic)
644 oss << '*';
645 else if (i->widthtype != width_unspecified && i->width > 0)
646 oss << i->width;
647
648 if (i->prectype == prec_dynamic)
649 oss << ".*";
650 else if (i->prectype != prec_unspecified && i->precision > 0)
651 oss << '.' << i->precision;
652
653 switch (i->type)
654 {
655 case conv_binary:
656 oss << "b";
657 break;
658
659 case conv_char:
660 oss << "llc";
661 break;
662
663 case conv_number:
664 if (i->base == 16)
665 {
666 if (i->test_flag (fmt_flag_large))
667 oss << "llX";
668 else
669 oss << "llx";
670 }
671 else if (i->base == 8)
672 oss << "llo";
673 else if (i->test_flag (fmt_flag_sign))
674 oss << "lld";
675 else
676 oss << "llu";
677 break;
678
679 case conv_pointer:
680 oss << "p";
681 break;
682
683 case conv_string:
684 oss << 's';
685 break;
686
687 case conv_memory:
688 oss << 'm';
689 break;
690
691 case conv_memory_hex:
692 oss << 'M';
693 break;
694
695 default:
696 break;
697 }
698 }
699 }
700 return oss.str ();
701 }
702
703 vector<print_format::format_component>
704 print_format::string_to_components(string const & str)
705 {
706 format_component curr;
707 vector<format_component> res;
708
709 curr.clear();
710
711 string::const_iterator i = str.begin();
712
713 while (i != str.end())
714 {
715 if (*i != '%')
716 {
717 assert (curr.type == conv_unspecified || curr.type == conv_literal);
718 curr.type = conv_literal;
719 curr.literal_string += *i;
720 ++i;
721 continue;
722 }
723 else if (i+1 == str.end() || *(i+1) == '%')
724 {
725 assert(*i == '%');
726 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
727 assert (curr.type == conv_unspecified || curr.type == conv_literal);
728 curr.type = conv_literal;
729 curr.literal_string += '%';
730 i += 2;
731 continue;
732 }
733 else
734 {
735 assert(*i == '%');
736 if (curr.type != conv_unspecified)
737 {
738 // Flush any component we were previously accumulating
739 assert (curr.type == conv_literal);
740 res.push_back(curr);
741 curr.clear();
742 }
743 }
744 ++i;
745
746 if (i == str.end())
747 break;
748
749 // Now we are definitely parsing a conversion.
750 // Begin by parsing flags (which are optional).
751
752 switch (*i)
753 {
754 case '0':
755 curr.set_flag (fmt_flag_zeropad);
756 ++i;
757 break;
758
759 case '+':
760 curr.set_flag (fmt_flag_plus);
761 ++i;
762 break;
763
764 case '-':
765 curr.set_flag (fmt_flag_left);
766 ++i;
767 break;
768
769 case ' ':
770 curr.set_flag (fmt_flag_space);
771 ++i;
772 break;
773
774 case '#':
775 curr.set_flag (fmt_flag_special);
776 ++i;
777 break;
778
779 default:
780 break;
781 }
782
783 if (i == str.end())
784 break;
785
786 // Parse optional width
787 if (*i == '*')
788 {
789 curr.widthtype = width_dynamic;
790 ++i;
791 }
792 else if (isdigit(*i))
793 {
794 curr.widthtype = width_static;
795 curr.width = 0;
796 do
797 {
798 curr.width *= 10;
799 curr.width += (*i - '0');
800 ++i;
801 }
802 while (i != str.end() && isdigit(*i));
803 }
804
805 if (i == str.end())
806 break;
807
808 // Parse optional precision
809 if (*i == '.')
810 {
811 ++i;
812 if (i == str.end())
813 break;
814 if (*i == '*')
815 {
816 curr.prectype = prec_dynamic;
817 ++i;
818 }
819 else if (isdigit(*i))
820 {
821 curr.prectype = prec_static;
822 curr.precision = 0;
823 do
824 {
825 curr.precision *= 10;
826 curr.precision += (*i - '0');
827 ++i;
828 }
829 while (i != str.end() && isdigit(*i));
830 }
831 }
832
833 if (i == str.end())
834 break;
835
836 // Parse the type modifier
837 switch (*i)
838 {
839 case 'l':
840 ++i;
841 break;
842 }
843
844 if (i == str.end())
845 break;
846
847 // Parse the actual conversion specifier (bcsmdioupxXn)
848 switch (*i)
849 {
850 // Valid conversion types
851 case 'b':
852 curr.type = conv_binary;
853 break;
854
855 case 'c':
856 curr.type = conv_char;
857 break;
858
859 case 's':
860 curr.type = conv_string;
861 break;
862
863 case 'm':
864 curr.type = conv_memory;
865 break;
866
867 case 'M':
868 curr.type = conv_memory_hex;
869 break;
870
871 case 'd':
872 case 'i':
873 curr.set_flag (fmt_flag_sign);
874 case 'u':
875 curr.type = conv_number;
876 curr.base = 10;
877 break;
878
879 case 'o':
880 curr.type = conv_number;
881 curr.base = 8;
882 break;
883
884 case 'X':
885 curr.set_flag (fmt_flag_large);
886 case 'x':
887 curr.type = conv_number;
888 curr.base = 16;
889 break;
890
891 case 'p':
892 // Since stap 1.3, %p == %#x.
893 curr.set_flag (fmt_flag_special);
894 curr.type = conv_pointer;
895 curr.base = 16;
896 // Oddness for stap < 1.3 is handled in translation
897 break;
898
899 default:
900 break;
901 }
902
903 if (curr.type == conv_unspecified)
904 throw PARSE_ERROR(_("invalid or missing conversion specifier"));
905
906 ++i;
907 res.push_back(curr);
908 curr.clear();
909 }
910
911 // If there's a remaining partly-composed conversion, fail.
912 if (!curr.is_empty())
913 {
914 if (curr.type == conv_literal)
915 res.push_back(curr);
916 else
917 throw PARSE_ERROR(_("trailing incomplete print format conversion"));
918 }
919
920 return res;
921 }
922
923
924 void print_format::print (ostream& o) const
925 {
926 o << print_format_type << "(";
927 if (print_with_format)
928 o << lex_cast_qstring (raw_components);
929 if (print_with_delim)
930 o << lex_cast_qstring (delimiter.literal_string);
931 if (hist)
932 hist->print(o);
933 for (vector<expression*>::const_iterator i = args.begin();
934 i != args.end(); ++i)
935 {
936 if (i != args.begin() || print_with_format || print_with_delim)
937 o << ", ";
938 (*i)->print(o);
939 }
940 o << ")";
941 }
942
943 void stat_op::print (ostream& o) const
944 {
945 o << '@';
946 switch (ctype)
947 {
948 case sc_average:
949 o << "avg(";
950 break;
951
952 case sc_count:
953 o << "count(";
954 break;
955
956 case sc_sum:
957 o << "sum(";
958 break;
959
960 case sc_min:
961 o << "min(";
962 break;
963
964 case sc_max:
965 o << "max(";
966 break;
967
968 case sc_none:
969 assert (0); // should not happen, as sc_none is only used in foreach sorts
970 break;
971 }
972 stat->print(o);
973 o << ")";
974 }
975
976 void
977 hist_op::print (ostream& o) const
978 {
979 o << '@';
980 switch (htype)
981 {
982 case hist_linear:
983 assert(params.size() == 3);
984 o << "hist_linear(";
985 stat->print(o);
986 for (size_t i = 0; i < params.size(); ++i)
987 {
988 o << ", " << params[i];
989 }
990 o << ")";
991 break;
992
993 case hist_log:
994 assert(params.size() == 0);
995 o << "hist_log(";
996 stat->print(o);
997 o << ")";
998 break;
999 }
1000 }
1001
1002 ostream& operator << (ostream& o, const statement& k)
1003 {
1004 k.print (o);
1005 return o;
1006 }
1007
1008
1009 void embeddedcode::print (ostream &o) const
1010 {
1011 o << "%{";
1012 o << code;
1013 o << "%}";
1014 }
1015
1016 void block::print (ostream& o) const
1017 {
1018 o << "{" << endl;
1019 for (unsigned i=0; i<statements.size(); i++)
1020 o << *statements [i] << endl;
1021 o << "}";
1022 }
1023
1024 block::block (statement* car, statement* cdr)
1025 {
1026 statements.push_back(car);
1027 statements.push_back(cdr);
1028 this->tok = car->tok;
1029 }
1030
1031
1032
1033 void try_block::print (ostream& o) const
1034 {
1035 o << "try {" << endl;
1036 if (try_block) o << *try_block << endl;
1037 o << "} catch ";
1038 if (catch_error_var) o << "(" << *catch_error_var << ") ";
1039 o << "{" << endl;
1040 if (catch_block) o << *catch_block << endl;
1041 o << "}" << endl;
1042 }
1043
1044
1045 void for_loop::print (ostream& o) const
1046 {
1047 o << "for (";
1048 if (init) init->print (o);
1049 o << "; ";
1050 cond->print (o);
1051 o << "; ";
1052 if (incr) incr->print (o);
1053 o << ") ";
1054 block->print (o);
1055 }
1056
1057
1058 void foreach_loop::print (ostream& o) const
1059 {
1060 o << "foreach (";
1061 if (value)
1062 {
1063 value->print (o);
1064 o << " = ";
1065 }
1066 o << "[";
1067 for (unsigned i=0; i<indexes.size(); i++)
1068 {
1069 if (i > 0) o << ", ";
1070 indexes[i]->print (o);
1071 if (sort_direction != 0 && sort_column == i+1)
1072 o << (sort_direction > 0 ? "+" : "-");
1073 }
1074 o << "] in ";
1075 base->print (o);
1076 if (sort_direction != 0 && sort_column == 0)
1077 {
1078 switch (sort_aggr)
1079 {
1080 case sc_count: o << " @count"; break;
1081 case sc_average: o << " @avg"; break;
1082 case sc_min: o << " @min"; break;
1083 case sc_max: o << " @max"; break;
1084 case sc_sum: o << " @sum"; break;
1085 case sc_none:
1086 default:
1087 ;
1088 }
1089
1090 o << (sort_direction > 0 ? "+" : "-");
1091 }
1092 if (limit)
1093 {
1094 o << " limit ";
1095 limit->print (o);
1096 }
1097 o << ") ";
1098 block->print (o);
1099 }
1100
1101
1102 void null_statement::print (ostream& o) const
1103 {
1104 o << ";";
1105 }
1106
1107
1108 void expr_statement::print (ostream& o) const
1109 {
1110 o << *value;
1111 }
1112
1113
1114 void return_statement::print (ostream& o) const
1115 {
1116 o << "return " << *value;
1117 }
1118
1119
1120 void delete_statement::print (ostream& o) const
1121 {
1122 o << "delete " << *value;
1123 }
1124
1125 void next_statement::print (ostream& o) const
1126 {
1127 o << "next";
1128 }
1129
1130 void break_statement::print (ostream& o) const
1131 {
1132 o << "break";
1133 }
1134
1135 void continue_statement::print (ostream& o) const
1136 {
1137 o << "continue";
1138 }
1139
1140 void if_statement::print (ostream& o) const
1141 {
1142 o << "if (" << *condition << ") "
1143 << *thenblock << endl;
1144 if (elseblock)
1145 o << "else " << *elseblock << endl;
1146 }
1147
1148
1149 void stapfile::print (ostream& o) const
1150 {
1151 o << "# file " << name << endl;
1152
1153 for (unsigned i=0; i<embeds.size(); i++)
1154 embeds[i]->print (o);
1155
1156 for (unsigned i=0; i<globals.size(); i++)
1157 {
1158 o << "global ";
1159 globals[i]->print (o);
1160 o << endl;
1161 }
1162
1163 for (unsigned i=0; i<aliases.size(); i++)
1164 {
1165 aliases[i]->print (o);
1166 o << endl;
1167 }
1168
1169 for (unsigned i=0; i<probes.size(); i++)
1170 {
1171 probes[i]->print (o);
1172 o << endl;
1173 }
1174
1175 for (unsigned j = 0; j < functions.size(); j++)
1176 {
1177 functions[j]->print (o);
1178 o << endl;
1179 }
1180 }
1181
1182
1183 void probe::print (ostream& o) const
1184 {
1185 o << "probe ";
1186 printsig (o);
1187 o << *body;
1188 }
1189
1190
1191 void probe::printsig (ostream& o) const
1192 {
1193 const probe_alias *alias = get_alias ();
1194 if (alias)
1195 {
1196 alias->printsig (o);
1197 return;
1198 }
1199
1200 for (unsigned i=0; i<locations.size(); i++)
1201 {
1202 if (i > 0) o << ",";
1203 locations[i]->print (o);
1204 }
1205 }
1206
1207
1208 void
1209 probe::collect_derivation_chain (std::vector<probe*> &probes_list) const
1210 {
1211 probes_list.push_back(const_cast<probe*>(this));
1212 if (base)
1213 base->collect_derivation_chain(probes_list);
1214 }
1215
1216
1217 void
1218 probe::collect_derivation_pp_chain (std::vector<probe_point*> &pp_list) const
1219 {
1220 pp_list.push_back(const_cast<probe_point*>(this->locations[0]));
1221 if (base)
1222 base->collect_derivation_pp_chain(pp_list);
1223 }
1224
1225
1226
1227 void probe_point::print (ostream& o, bool print_extras) const
1228 {
1229 for (unsigned i=0; i<components.size(); i++)
1230 {
1231 if (i>0) o << ".";
1232 probe_point::component* c = components[i];
1233 o << c->functor;
1234 if (c->arg)
1235 o << "(" << *c->arg << ")";
1236 }
1237 if (!print_extras)
1238 return;
1239 if (sufficient)
1240 o << "!";
1241 else if (optional) // sufficient implies optional
1242 o << "?";
1243 if (condition)
1244 o<< " if (" << *condition << ")";
1245 }
1246
1247 string probe_point::str (bool print_extras) const
1248 {
1249 ostringstream o;
1250 print(o, print_extras);
1251 return o.str();
1252 }
1253
1254
1255 probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
1256 probe (), alias_names (aliases), epilogue_style(false)
1257 {
1258 }
1259
1260 void probe_alias::printsig (ostream& o) const
1261 {
1262 for (unsigned i=0; i<alias_names.size(); i++)
1263 {
1264 o << (i>0 ? " = " : "");
1265 alias_names[i]->print (o);
1266 }
1267 o << " = ";
1268 for (unsigned i=0; i<locations.size(); i++)
1269 {
1270 if (i > 0) o << ", ";
1271 locations[i]->print (o);
1272 }
1273 }
1274
1275
1276 ostream& operator << (ostream& o, const probe_point& k)
1277 {
1278 k.print (o);
1279 return o;
1280 }
1281
1282
1283 ostream& operator << (ostream& o, const symboldecl& k)
1284 {
1285 k.print (o);
1286 return o;
1287 }
1288
1289
1290
1291 // ------------------------------------------------------------------------
1292 // visitors
1293
1294
1295 void
1296 block::visit (visitor* u)
1297 {
1298 u->visit_block (this);
1299 }
1300
1301
1302 void
1303 try_block::visit (visitor* u)
1304 {
1305 u->visit_try_block (this);
1306 }
1307
1308
1309 void
1310 embeddedcode::visit (visitor* u)
1311 {
1312 u->visit_embeddedcode (this);
1313 }
1314
1315
1316 void
1317 for_loop::visit (visitor* u)
1318 {
1319 u->visit_for_loop (this);
1320 }
1321
1322 void
1323 foreach_loop::visit (visitor* u)
1324 {
1325 u->visit_foreach_loop (this);
1326 }
1327
1328 void
1329 null_statement::visit (visitor* u)
1330 {
1331 u->visit_null_statement (this);
1332 }
1333
1334 void
1335 expr_statement::visit (visitor* u)
1336 {
1337 u->visit_expr_statement (this);
1338 }
1339
1340 void
1341 return_statement::visit (visitor* u)
1342 {
1343 u->visit_return_statement (this);
1344 }
1345
1346 void
1347 delete_statement::visit (visitor* u)
1348 {
1349 u->push_active_lvalue (this->value);
1350 u->visit_delete_statement (this);
1351 u->pop_active_lvalue ();
1352 }
1353
1354 void
1355 if_statement::visit (visitor* u)
1356 {
1357 u->visit_if_statement (this);
1358 }
1359
1360 void
1361 next_statement::visit (visitor* u)
1362 {
1363 u->visit_next_statement (this);
1364 }
1365
1366 void
1367 break_statement::visit (visitor* u)
1368 {
1369 u->visit_break_statement (this);
1370 }
1371
1372 void
1373 continue_statement::visit (visitor* u)
1374 {
1375 u->visit_continue_statement (this);
1376 }
1377
1378 void
1379 literal_string::visit(visitor* u)
1380 {
1381 u->visit_literal_string (this);
1382 }
1383
1384 void
1385 literal_number::visit(visitor* u)
1386 {
1387 u->visit_literal_number (this);
1388 }
1389
1390 void
1391 binary_expression::visit (visitor* u)
1392 {
1393 u->visit_binary_expression (this);
1394 }
1395
1396 void
1397 embedded_expr::visit (visitor* u)
1398 {
1399 u->visit_embedded_expr (this);
1400 }
1401
1402 void
1403 unary_expression::visit (visitor* u)
1404 {
1405 u->visit_unary_expression (this);
1406 }
1407
1408 void
1409 pre_crement::visit (visitor* u)
1410 {
1411 u->push_active_lvalue (this->operand);
1412 u->visit_pre_crement (this);
1413 u->pop_active_lvalue ();
1414 }
1415
1416 void
1417 post_crement::visit (visitor* u)
1418 {
1419 u->push_active_lvalue (this->operand);
1420 u->visit_post_crement (this);
1421 u->pop_active_lvalue ();
1422 }
1423
1424 void
1425 logical_or_expr::visit (visitor* u)
1426 {
1427 u->visit_logical_or_expr (this);
1428 }
1429
1430 void
1431 logical_and_expr::visit (visitor* u)
1432 {
1433 u->visit_logical_and_expr (this);
1434 }
1435
1436 void
1437 array_in::visit (visitor* u)
1438 {
1439 u->visit_array_in (this);
1440 }
1441
1442 void
1443 regex_query::visit (visitor* u)
1444 {
1445 u->visit_regex_query (this);
1446 }
1447
1448 void
1449 comparison::visit (visitor* u)
1450 {
1451 u->visit_comparison (this);
1452 }
1453
1454 void
1455 concatenation::visit (visitor* u)
1456 {
1457 u->visit_concatenation (this);
1458 }
1459
1460 void
1461 ternary_expression::visit (visitor* u)
1462 {
1463 u->visit_ternary_expression (this);
1464 }
1465
1466 void
1467 assignment::visit (visitor* u)
1468 {
1469 u->push_active_lvalue (this->left);
1470 u->visit_assignment (this);
1471 u->pop_active_lvalue ();
1472 }
1473
1474 void
1475 symbol::visit (visitor* u)
1476 {
1477 u->visit_symbol (this);
1478 }
1479
1480 void
1481 target_symbol::visit (visitor* u)
1482 {
1483 u->visit_target_symbol(this);
1484 }
1485
1486 void
1487 target_symbol::visit_components (visitor* u)
1488 {
1489 for (unsigned i = 0; i < components.size(); ++i)
1490 if (components[i].type == comp_expression_array_index)
1491 components[i].expr_index->visit (u);
1492 }
1493
1494 void
1495 target_symbol::visit_components (update_visitor* u)
1496 {
1497 for (unsigned i = 0; i < components.size(); ++i)
1498 if (components[i].type == comp_expression_array_index)
1499 u->replace (components[i].expr_index);
1500 }
1501
1502 void
1503 cast_op::visit (visitor* u)
1504 {
1505 u->visit_cast_op(this);
1506 }
1507
1508
1509 void
1510 atvar_op::visit (visitor* u)
1511 {
1512 u->visit_atvar_op(this);
1513 }
1514
1515
1516 void
1517 defined_op::visit (visitor* u)
1518 {
1519 u->visit_defined_op(this);
1520 }
1521
1522
1523 void
1524 entry_op::visit (visitor* u)
1525 {
1526 u->visit_entry_op(this);
1527 }
1528
1529
1530 void
1531 perf_op::visit (visitor* u)
1532 {
1533 u->visit_perf_op(this);
1534 }
1535
1536
1537 void
1538 arrayindex::visit (visitor* u)
1539 {
1540 u->visit_arrayindex (this);
1541 }
1542
1543 void
1544 functioncall::visit (visitor* u)
1545 {
1546 u->visit_functioncall (this);
1547 }
1548
1549 void
1550 print_format::visit (visitor *u)
1551 {
1552 u->visit_print_format (this);
1553 }
1554
1555 void
1556 stat_op::visit (visitor *u)
1557 {
1558 u->visit_stat_op (this);
1559 }
1560
1561 void
1562 hist_op::visit (visitor *u)
1563 {
1564 u->visit_hist_op (this);
1565 }
1566
1567
1568 bool
1569 indexable::is_symbol(symbol *& sym_out)
1570 {
1571 sym_out = NULL;
1572 return false;
1573 }
1574
1575 bool
1576 indexable::is_hist_op(hist_op *& hist_out)
1577 {
1578 hist_out = NULL;
1579 return false;
1580 }
1581
1582 bool
1583 symbol::is_symbol(symbol *& sym_out)
1584 {
1585 sym_out = this;
1586 return true;
1587 }
1588
1589 bool
1590 hist_op::is_hist_op(hist_op *& hist_out)
1591 {
1592 hist_out = this;
1593 return true;
1594 }
1595
1596 void
1597 classify_indexable(indexable* ix,
1598 symbol *& array_out,
1599 hist_op *& hist_out)
1600 {
1601 array_out = NULL;
1602 hist_out = NULL;
1603 assert(ix != NULL);
1604 if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1605 throw SEMANTIC_ERROR(_("Expecting symbol or histogram operator"), ix->tok);
1606 if (!(hist_out || array_out))
1607 throw SEMANTIC_ERROR(_("Failed to classify indexable"), ix->tok);
1608 }
1609
1610
1611 // ------------------------------------------------------------------------
1612
1613 bool
1614 visitor::is_active_lvalue(expression *e)
1615 {
1616 for (unsigned i = 0; i < active_lvalues.size(); ++i)
1617 {
1618 if (active_lvalues[i] == e)
1619 return true;
1620 }
1621 return false;
1622 }
1623
1624 void
1625 visitor::push_active_lvalue(expression *e)
1626 {
1627 active_lvalues.push_back(e);
1628 }
1629
1630 void
1631 visitor::pop_active_lvalue()
1632 {
1633 assert(!active_lvalues.empty());
1634 active_lvalues.pop_back();
1635 }
1636
1637
1638
1639 // ------------------------------------------------------------------------
1640
1641 void
1642 traversing_visitor::visit_block (block* s)
1643 {
1644 for (unsigned i=0; i<s->statements.size(); i++)
1645 s->statements[i]->visit (this);
1646 }
1647
1648 void
1649 traversing_visitor::visit_try_block (try_block* s)
1650 {
1651 if (s->try_block)
1652 s->try_block->visit (this);
1653 if (s->catch_error_var)
1654 s->catch_error_var->visit (this);
1655 if (s->catch_block)
1656 s->catch_block->visit (this);
1657 }
1658
1659 void
1660 traversing_visitor::visit_embeddedcode (embeddedcode*)
1661 {
1662 }
1663
1664 void
1665 traversing_visitor::visit_null_statement (null_statement*)
1666 {
1667 }
1668
1669 void
1670 traversing_visitor::visit_expr_statement (expr_statement* s)
1671 {
1672 s->value->visit (this);
1673 }
1674
1675 void
1676 traversing_visitor::visit_if_statement (if_statement* s)
1677 {
1678 s->condition->visit (this);
1679 s->thenblock->visit (this);
1680 if (s->elseblock)
1681 s->elseblock->visit (this);
1682 }
1683
1684 void
1685 traversing_visitor::visit_for_loop (for_loop* s)
1686 {
1687 if (s->init) s->init->visit (this);
1688 s->cond->visit (this);
1689 if (s->incr) s->incr->visit (this);
1690 s->block->visit (this);
1691 }
1692
1693 void
1694 traversing_visitor::visit_foreach_loop (foreach_loop* s)
1695 {
1696 s->base->visit(this);
1697
1698 for (unsigned i=0; i<s->indexes.size(); i++)
1699 s->indexes[i]->visit (this);
1700
1701 if (s->value)
1702 s->value->visit (this);
1703
1704 if (s->limit)
1705 s->limit->visit (this);
1706
1707 s->block->visit (this);
1708 }
1709
1710 void
1711 traversing_visitor::visit_return_statement (return_statement* s)
1712 {
1713 s->value->visit (this);
1714 }
1715
1716 void
1717 traversing_visitor::visit_delete_statement (delete_statement* s)
1718 {
1719 s->value->visit (this);
1720 }
1721
1722 void
1723 traversing_visitor::visit_next_statement (next_statement*)
1724 {
1725 }
1726
1727 void
1728 traversing_visitor::visit_break_statement (break_statement*)
1729 {
1730 }
1731
1732 void
1733 traversing_visitor::visit_continue_statement (continue_statement*)
1734 {
1735 }
1736
1737 void
1738 traversing_visitor::visit_literal_string (literal_string*)
1739 {
1740 }
1741
1742 void
1743 traversing_visitor::visit_literal_number (literal_number*)
1744 {
1745 }
1746
1747 void
1748 traversing_visitor::visit_embedded_expr (embedded_expr*)
1749 {
1750 }
1751
1752 void
1753 traversing_visitor::visit_binary_expression (binary_expression* e)
1754 {
1755 e->left->visit (this);
1756 e->right->visit (this);
1757 }
1758
1759 void
1760 traversing_visitor::visit_unary_expression (unary_expression* e)
1761 {
1762 e->operand->visit (this);
1763 }
1764
1765 void
1766 traversing_visitor::visit_pre_crement (pre_crement* e)
1767 {
1768 e->operand->visit (this);
1769 }
1770
1771 void
1772 traversing_visitor::visit_post_crement (post_crement* e)
1773 {
1774 e->operand->visit (this);
1775 }
1776
1777
1778 void
1779 traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1780 {
1781 e->left->visit (this);
1782 e->right->visit (this);
1783 }
1784
1785 void
1786 traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1787 {
1788 e->left->visit (this);
1789 e->right->visit (this);
1790 }
1791
1792 void
1793 traversing_visitor::visit_array_in (array_in* e)
1794 {
1795 e->operand->visit (this);
1796 }
1797
1798 void
1799 traversing_visitor::visit_regex_query (regex_query* e)
1800 {
1801 e->left->visit (this);
1802 e->right->visit (this);
1803 }
1804
1805 void
1806 traversing_visitor::visit_comparison (comparison* e)
1807 {
1808 e->left->visit (this);
1809 e->right->visit (this);
1810 }
1811
1812 void
1813 traversing_visitor::visit_concatenation (concatenation* e)
1814 {
1815 e->left->visit (this);
1816 e->right->visit (this);
1817 }
1818
1819 void
1820 traversing_visitor::visit_ternary_expression (ternary_expression* e)
1821 {
1822 e->cond->visit (this);
1823 e->truevalue->visit (this);
1824 e->falsevalue->visit (this);
1825 }
1826
1827 void
1828 traversing_visitor::visit_assignment (assignment* e)
1829 {
1830 e->left->visit (this);
1831 e->right->visit (this);
1832 }
1833
1834 void
1835 traversing_visitor::visit_symbol (symbol*)
1836 {
1837 }
1838
1839 void
1840 traversing_visitor::visit_target_symbol (target_symbol* e)
1841 {
1842 e->visit_components (this);
1843 }
1844
1845 void
1846 traversing_visitor::visit_cast_op (cast_op* e)
1847 {
1848 e->operand->visit (this);
1849 e->visit_components (this);
1850 }
1851
1852 void
1853 traversing_visitor::visit_atvar_op (atvar_op* e)
1854 {
1855 e->visit_components (this);
1856 }
1857
1858 void
1859 traversing_visitor::visit_defined_op (defined_op* e)
1860 {
1861 e->operand->visit (this);
1862 }
1863
1864 void
1865 traversing_visitor::visit_entry_op (entry_op* e)
1866 {
1867 e->operand->visit (this);
1868 }
1869
1870
1871 void
1872 traversing_visitor::visit_perf_op (perf_op* e)
1873 {
1874 e->operand->visit (this);
1875 }
1876
1877
1878 void
1879 traversing_visitor::visit_arrayindex (arrayindex* e)
1880 {
1881 for (unsigned i=0; i<e->indexes.size(); i++)
1882 e->indexes[i]->visit (this);
1883
1884 e->base->visit(this);
1885 }
1886
1887 void
1888 traversing_visitor::visit_functioncall (functioncall* e)
1889 {
1890 for (unsigned i=0; i<e->args.size(); i++)
1891 e->args[i]->visit (this);
1892 }
1893
1894 void
1895 traversing_visitor::visit_print_format (print_format* e)
1896 {
1897 for (unsigned i=0; i<e->args.size(); i++)
1898 e->args[i]->visit (this);
1899 if (e->hist)
1900 e->hist->visit(this);
1901 }
1902
1903 void
1904 traversing_visitor::visit_stat_op (stat_op* e)
1905 {
1906 e->stat->visit (this);
1907 }
1908
1909 void
1910 traversing_visitor::visit_hist_op (hist_op* e)
1911 {
1912 e->stat->visit (this);
1913 }
1914
1915
1916 void
1917 functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1918 {
1919 traversing_visitor::visit_functioncall (e);
1920
1921 // prevent infinite recursion
1922 if (traversed.find (e->referent) == traversed.end ())
1923 {
1924 traversed.insert (e->referent);
1925 // recurse
1926 functiondecl* last_current_function = current_function;
1927 current_function = e->referent;
1928 e->referent->body->visit (this);
1929 current_function = last_current_function;
1930 }
1931 }
1932
1933
1934 void
1935 varuse_collecting_visitor::visit_try_block (try_block *s)
1936 {
1937 if (s->try_block)
1938 s->try_block->visit (this);
1939 if (s->catch_error_var)
1940 written.insert (s->catch_error_var->referent);
1941 if (s->catch_block)
1942 s->catch_block->visit (this);
1943
1944 // NB: don't functioncall_traversing_visitor::visit_try_block (s);
1945 // since that would count s->catch_error_var as a read also.
1946 }
1947
1948
1949 void
1950 varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1951 {
1952 assert (current_function); // only they get embedded code
1953
1954 // Don't allow embedded C functions in unprivileged mode unless
1955 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1956 // or we're in a usermode runtime.
1957 if (! pr_contains (session.privilege, pr_stapdev) &&
1958 ! pr_contains (session.privilege, pr_stapsys) &&
1959 ! session.runtime_usermode_p () &&
1960 s->code.find ("/* unprivileged */") == string::npos &&
1961 s->code.find ("/* myproc-unprivileged */") == string::npos)
1962 throw SEMANTIC_ERROR (_F("function may not be used when --privilege=%s is specified",
1963 pr_name (session.privilege)),
1964 current_function->tok);
1965
1966 // Don't allow /* guru */ functions unless -g is active.
1967 if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
1968 throw SEMANTIC_ERROR (_("function may not be used unless -g is specified"),
1969 current_function->tok);
1970
1971 // PR14524: Support old-style THIS->local syntax on per-function basis.
1972 if (s->code.find ("/* unmangled */") != string::npos)
1973 current_function->mangle_oldstyle = true;
1974
1975 // We want to elide embedded-C functions when possible. For
1976 // example, each $target variable access is expanded to an
1977 // embedded-C function call. Yet, for safety reasons, we should
1978 // presume that embedded-C functions have intentional side-effects.
1979 //
1980 // To tell these two types of functions apart, we apply a
1981 // Kludge(tm): we look for a magic string within the function body.
1982 // $target variables as rvalues will have this; lvalues won't.
1983 // Also, explicit side-effect-free tapset functions will have this.
1984
1985 if (s->code.find ("/* pure */") != string::npos)
1986 return;
1987
1988 embedded_seen = true;
1989 }
1990
1991
1992 // About the same case as above.
1993 void
1994 varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1995 {
1996 // Don't allow embedded C expressions in unprivileged mode unless
1997 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1998 // or we're in a usermode runtime.
1999 if (! pr_contains (session.privilege, pr_stapdev) &&
2000 ! pr_contains (session.privilege, pr_stapsys) &&
2001 ! session.runtime_usermode_p () &&
2002 e->code.find ("/* unprivileged */") == string::npos &&
2003 e->code.find ("/* myproc-unprivileged */") == string::npos)
2004 throw SEMANTIC_ERROR (_F("embedded expression may not be used when --privilege=%s is specified",
2005 pr_name (session.privilege)),
2006 e->tok);
2007
2008 // Don't allow /* guru */ functions unless -g is active.
2009 if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
2010 throw SEMANTIC_ERROR (_("embedded expression may not be used unless -g is specified"),
2011 e->tok);
2012
2013 // We want to elide embedded-C functions when possible. For
2014 // example, each $target variable access is expanded to an
2015 // embedded-C function call. Yet, for safety reasons, we should
2016 // presume that embedded-C functions have intentional side-effects.
2017 //
2018 // To tell these two types of functions apart, we apply a
2019 // Kludge(tm): we look for a magic string within the function body.
2020 // $target variables as rvalues will have this; lvalues won't.
2021 // Also, explicit side-effect-free tapset functions will have this.
2022
2023 if (e->code.find ("/* pure */") != string::npos)
2024 return;
2025
2026 embedded_seen = true;
2027 }
2028
2029
2030 void
2031 varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
2032 {
2033 // Still-unresolved target symbol assignments get treated as
2034 // generating side-effects like embedded-C, to prevent premature
2035 // elision and later error message suppression (PR5516). rvalue use
2036 // of unresolved target symbols is OTOH not considered a side-effect.
2037
2038 if (is_active_lvalue (e))
2039 embedded_seen = true;
2040
2041 functioncall_traversing_visitor::visit_target_symbol (e);
2042 }
2043
2044
2045 void
2046 varuse_collecting_visitor::visit_atvar_op (atvar_op *e)
2047 {
2048 // Similar to visit_target_symbol
2049
2050 if (is_active_lvalue (e))
2051 embedded_seen = true;
2052
2053 functioncall_traversing_visitor::visit_atvar_op (e);
2054 }
2055
2056
2057 void
2058 varuse_collecting_visitor::visit_cast_op (cast_op *e)
2059 {
2060 // As with target_symbols, unresolved cast assignments need to preserved
2061 // for later error handling.
2062 if (is_active_lvalue (e))
2063 embedded_seen = true;
2064
2065 functioncall_traversing_visitor::visit_cast_op (e);
2066 }
2067
2068 void
2069 varuse_collecting_visitor::visit_defined_op (defined_op *e)
2070 {
2071 // XXX
2072 functioncall_traversing_visitor::visit_defined_op (e);
2073 }
2074
2075 void
2076 varuse_collecting_visitor::visit_entry_op (entry_op *e)
2077 {
2078 // XXX
2079 functioncall_traversing_visitor::visit_entry_op (e);
2080 }
2081
2082
2083 void
2084 varuse_collecting_visitor::visit_perf_op (perf_op *e)
2085 {
2086 functioncall_traversing_visitor::visit_perf_op (e);
2087 }
2088
2089
2090 void
2091 varuse_collecting_visitor::visit_print_format (print_format* e)
2092 {
2093 // NB: Instead of being top-level statements, "print" and "printf"
2094 // are implemented as statement-expressions containing a
2095 // print_format. They have side-effects, but not via the
2096 // embedded-code detection method above.
2097 //
2098 // But sprint and sprintf don't have side-effects.
2099
2100 bool last_lvalue_read = current_lvalue_read;
2101 current_lvalue_read = true;
2102 if (e->print_to_stream)
2103 embedded_seen = true; // a proxy for "has unknown side-effects"
2104
2105 functioncall_traversing_visitor::visit_print_format (e);
2106 current_lvalue_read = last_lvalue_read;
2107 }
2108
2109
2110 void
2111 varuse_collecting_visitor::visit_assignment (assignment *e)
2112 {
2113 if (e->op == "=" || e->op == "<<<") // pure writes
2114 {
2115 expression* last_lvalue = current_lvalue;
2116 bool last_lvalue_read = current_lvalue_read;
2117 current_lvalue = e->left; // leave a mark for ::visit_symbol
2118 current_lvalue_read = true;
2119 functioncall_traversing_visitor::visit_assignment (e);
2120 current_lvalue = last_lvalue;
2121 current_lvalue_read = last_lvalue_read;
2122 }
2123 else // read-modify-writes
2124 {
2125 expression* last_lrvalue = current_lrvalue;
2126 current_lrvalue = e->left; // leave a mark for ::visit_symbol
2127 functioncall_traversing_visitor::visit_assignment (e);
2128 current_lrvalue = last_lrvalue;
2129 }
2130 }
2131
2132 void
2133 varuse_collecting_visitor::visit_symbol (symbol *e)
2134 {
2135 if (e->referent == 0)
2136 throw SEMANTIC_ERROR (_("symbol without referent"), e->tok);
2137
2138 // We could handle initialized globals by marking them as "written".
2139 // However, this current visitor may be called for a function or
2140 // probe body, from the point of view of which this global is
2141 // already initialized, so not written.
2142 /*
2143 if (e->referent->init)
2144 written.insert (e->referent);
2145 */
2146
2147 if (current_lvalue == e || current_lrvalue == e)
2148 {
2149 written.insert (e->referent);
2150 }
2151 if (current_lvalue != e || current_lrvalue == e)
2152 {
2153 read.insert (e->referent);
2154 }
2155
2156 if (current_lrvalue == e)
2157 {
2158 if (current_lvalue_read)
2159 used.insert (e->referent);
2160 }
2161 else if (current_lvalue != e)
2162 used.insert (e->referent);
2163 }
2164
2165 // NB: stat_op need not be overridden, since it will get to
2166 // visit_symbol and only as a possible rvalue.
2167
2168
2169 void
2170 varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2171 {
2172 // Hooking this callback is necessary because of the hacky
2173 // statistics representation. For the expression "i[4] = 5", the
2174 // incoming lvalue will point to this arrayindex. However, the
2175 // symbol corresponding to the "i[4]" is multiply inherited with
2176 // arrayindex. If the symbol base part of this object is not at
2177 // offset 0, then static_cast<symbol*>(e) may result in a different
2178 // address, and not match lvalue by number when we recurse that way.
2179 // So we explicitly override the incoming lvalue/lrvalue values to
2180 // point at the embedded objects' actual base addresses.
2181
2182 expression* last_lrvalue = current_lrvalue;
2183 expression* last_lvalue = current_lvalue;
2184
2185 symbol *array = NULL;
2186 hist_op *hist = NULL;
2187 classify_indexable(e->base, array, hist);
2188 expression *value = array ?: hist->stat;
2189
2190 if (current_lrvalue == e) current_lrvalue = value;
2191 if (current_lvalue == e) current_lvalue = value;
2192 functioncall_traversing_visitor::visit_arrayindex (e);
2193
2194 current_lrvalue = last_lrvalue;
2195 current_lvalue = last_lvalue;
2196 }
2197
2198
2199 void
2200 varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2201 {
2202 expression* last_lrvalue = current_lrvalue;
2203 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2204 functioncall_traversing_visitor::visit_pre_crement (e);
2205 current_lrvalue = last_lrvalue;
2206 }
2207
2208 void
2209 varuse_collecting_visitor::visit_post_crement (post_crement *e)
2210 {
2211 expression* last_lrvalue = current_lrvalue;
2212 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2213 functioncall_traversing_visitor::visit_post_crement (e);
2214 current_lrvalue = last_lrvalue;
2215 }
2216
2217 void
2218 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2219 {
2220 // NB: we duplicate so don't bother call
2221 // functioncall_traversing_visitor::visit_foreach_loop (s);
2222
2223 s->base->visit(this);
2224
2225 // If the collection is sorted, imply a "write" access to the
2226 // array in addition to the "read" one already noted above.
2227 if (s->sort_direction)
2228 {
2229 symbol *array = NULL;
2230 hist_op *hist = NULL;
2231 classify_indexable (s->base, array, hist);
2232 if (array) this->written.insert (array->referent);
2233 // XXX: Can hist_op iterations be sorted?
2234 }
2235
2236 // NB: don't forget to visit the index expressions, which are lvalues.
2237 for (unsigned i=0; i<s->indexes.size(); i++)
2238 {
2239 expression* last_lvalue = current_lvalue;
2240 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2241 s->indexes[i]->visit (this);
2242 current_lvalue = last_lvalue;
2243 }
2244
2245 // The value is an lvalue too
2246 if (s->value)
2247 {
2248 expression* last_lvalue = current_lvalue;
2249 current_lvalue = s->value; // leave a mark for ::visit_symbol
2250 s->value->visit (this);
2251 current_lvalue = last_lvalue;
2252 }
2253
2254 if (s->limit)
2255 s->limit->visit (this);
2256
2257 s->block->visit (this);
2258 }
2259
2260
2261 void
2262 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2263 {
2264 // Ideally, this would be treated like an assignment: a plain write
2265 // to the underlying value ("lvalue"). XXX: However, the
2266 // optimization pass is not smart enough to remove an unneeded
2267 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2268 // should protect the underlying value from optimizional mischief.
2269 expression* last_lrvalue = current_lrvalue;
2270 bool last_lvalue_read = current_lvalue_read;
2271 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2272 current_lvalue_read = true;
2273 functioncall_traversing_visitor::visit_delete_statement (s);
2274 current_lrvalue = last_lrvalue;
2275 current_lvalue_read = last_lvalue_read;
2276 }
2277
2278 bool
2279 varuse_collecting_visitor::side_effect_free ()
2280 {
2281 return (written.empty() && !embedded_seen);
2282 }
2283
2284
2285 bool
2286 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2287 {
2288 // A looser notion of side-effect-freeness with respect to a given
2289 // list of variables.
2290
2291 // That's useful because the written list may consist of local
2292 // variables of called functions. But visible side-effects only
2293 // occur if the client's locals, or any globals are written-to.
2294
2295 set<vardecl*> intersection;
2296 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2297 set_intersection (written.begin(), written.end(),
2298 vars.begin(), vars.end(),
2299 int_it);
2300
2301 return (intersection.empty() && !embedded_seen);
2302 }
2303
2304
2305
2306
2307 // ------------------------------------------------------------------------
2308
2309
2310 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2311 throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2312
2313
2314 void
2315 throwing_visitor::throwone (const token* t)
2316 {
2317 throw SEMANTIC_ERROR (msg, t);
2318 }
2319
2320 void
2321 throwing_visitor::visit_block (block* s)
2322 {
2323 throwone (s->tok);
2324 }
2325
2326 void
2327 throwing_visitor::visit_try_block (try_block* s)
2328 {
2329 throwone (s->tok);
2330 }
2331
2332
2333 void
2334 throwing_visitor::visit_embeddedcode (embeddedcode* s)
2335 {
2336 throwone (s->tok);
2337 }
2338
2339 void
2340 throwing_visitor::visit_null_statement (null_statement* s)
2341 {
2342 throwone (s->tok);
2343 }
2344
2345 void
2346 throwing_visitor::visit_expr_statement (expr_statement* s)
2347 {
2348 throwone (s->tok);
2349 }
2350
2351 void
2352 throwing_visitor::visit_if_statement (if_statement* s)
2353 {
2354 throwone (s->tok);
2355 }
2356
2357 void
2358 throwing_visitor::visit_for_loop (for_loop* s)
2359 {
2360 throwone (s->tok);
2361 }
2362
2363 void
2364 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2365 {
2366 throwone (s->tok);
2367 }
2368
2369 void
2370 throwing_visitor::visit_return_statement (return_statement* s)
2371 {
2372 throwone (s->tok);
2373 }
2374
2375 void
2376 throwing_visitor::visit_delete_statement (delete_statement* s)
2377 {
2378 throwone (s->tok);
2379 }
2380
2381 void
2382 throwing_visitor::visit_next_statement (next_statement* s)
2383 {
2384 throwone (s->tok);
2385 }
2386
2387 void
2388 throwing_visitor::visit_break_statement (break_statement* s)
2389 {
2390 throwone (s->tok);
2391 }
2392
2393 void
2394 throwing_visitor::visit_continue_statement (continue_statement* s)
2395 {
2396 throwone (s->tok);
2397 }
2398
2399 void
2400 throwing_visitor::visit_literal_string (literal_string* e)
2401 {
2402 throwone (e->tok);
2403 }
2404
2405 void
2406 throwing_visitor::visit_literal_number (literal_number* e)
2407 {
2408 throwone (e->tok);
2409 }
2410
2411 void
2412 throwing_visitor::visit_embedded_expr (embedded_expr* e)
2413 {
2414 throwone (e->tok);
2415 }
2416
2417 void
2418 throwing_visitor::visit_binary_expression (binary_expression* e)
2419 {
2420 throwone (e->tok);
2421 }
2422
2423 void
2424 throwing_visitor::visit_unary_expression (unary_expression* e)
2425 {
2426 throwone (e->tok);
2427 }
2428
2429 void
2430 throwing_visitor::visit_pre_crement (pre_crement* e)
2431 {
2432 throwone (e->tok);
2433 }
2434
2435 void
2436 throwing_visitor::visit_post_crement (post_crement* e)
2437 {
2438 throwone (e->tok);
2439 }
2440
2441
2442 void
2443 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2444 {
2445 throwone (e->tok);
2446 }
2447
2448 void
2449 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2450 {
2451 throwone (e->tok);
2452 }
2453
2454 void
2455 throwing_visitor::visit_array_in (array_in* e)
2456 {
2457 throwone (e->tok);
2458 }
2459
2460 void
2461 throwing_visitor::visit_regex_query (regex_query* e)
2462 {
2463 throwone (e->tok);
2464 }
2465
2466 void
2467 throwing_visitor::visit_comparison (comparison* e)
2468 {
2469 throwone (e->tok);
2470 }
2471
2472 void
2473 throwing_visitor::visit_concatenation (concatenation* e)
2474 {
2475 throwone (e->tok);
2476 }
2477
2478 void
2479 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2480 {
2481 throwone (e->tok);
2482 }
2483
2484 void
2485 throwing_visitor::visit_assignment (assignment* e)
2486 {
2487 throwone (e->tok);
2488 }
2489
2490 void
2491 throwing_visitor::visit_symbol (symbol* e)
2492 {
2493 throwone (e->tok);
2494 }
2495
2496 void
2497 throwing_visitor::visit_target_symbol (target_symbol* e)
2498 {
2499 throwone (e->tok);
2500 }
2501
2502 void
2503 throwing_visitor::visit_atvar_op (atvar_op* e)
2504 {
2505 throwone (e->tok);
2506 }
2507
2508 void
2509 throwing_visitor::visit_cast_op (cast_op* e)
2510 {
2511 throwone (e->tok);
2512 }
2513
2514 void
2515 throwing_visitor::visit_defined_op (defined_op* e)
2516 {
2517 throwone (e->tok);
2518 }
2519
2520 void
2521 throwing_visitor::visit_entry_op (entry_op* e)
2522 {
2523 throwone (e->tok);
2524 }
2525
2526
2527 void
2528 throwing_visitor::visit_perf_op (perf_op* e)
2529 {
2530 throwone (e->tok);
2531 }
2532
2533
2534 void
2535 throwing_visitor::visit_arrayindex (arrayindex* e)
2536 {
2537 throwone (e->tok);
2538 }
2539
2540 void
2541 throwing_visitor::visit_functioncall (functioncall* e)
2542 {
2543 throwone (e->tok);
2544 }
2545
2546 void
2547 throwing_visitor::visit_print_format (print_format* e)
2548 {
2549 throwone (e->tok);
2550 }
2551
2552 void
2553 throwing_visitor::visit_stat_op (stat_op* e)
2554 {
2555 throwone (e->tok);
2556 }
2557
2558 void
2559 throwing_visitor::visit_hist_op (hist_op* e)
2560 {
2561 throwone (e->tok);
2562 }
2563
2564
2565 // ------------------------------------------------------------------------
2566
2567
2568 void
2569 update_visitor::visit_block (block* s)
2570 {
2571 for (unsigned i = 0; i < s->statements.size(); ++i)
2572 replace (s->statements[i]);
2573 provide (s);
2574 }
2575
2576 void
2577 update_visitor::visit_try_block (try_block* s)
2578 {
2579 replace (s->try_block);
2580 replace (s->catch_error_var);
2581 replace (s->catch_block);
2582 provide (s);
2583 }
2584
2585 void
2586 update_visitor::visit_embeddedcode (embeddedcode* s)
2587 {
2588 provide (s);
2589 }
2590
2591 void
2592 update_visitor::visit_null_statement (null_statement* s)
2593 {
2594 provide (s);
2595 }
2596
2597 void
2598 update_visitor::visit_expr_statement (expr_statement* s)
2599 {
2600 replace (s->value);
2601 provide (s);
2602 }
2603
2604 void
2605 update_visitor::visit_if_statement (if_statement* s)
2606 {
2607 replace (s->condition);
2608 replace (s->thenblock);
2609 replace (s->elseblock);
2610 provide (s);
2611 }
2612
2613 void
2614 update_visitor::visit_for_loop (for_loop* s)
2615 {
2616 replace (s->init);
2617 replace (s->cond);
2618 replace (s->incr);
2619 replace (s->block);
2620 provide (s);
2621 }
2622
2623 void
2624 update_visitor::visit_foreach_loop (foreach_loop* s)
2625 {
2626 for (unsigned i = 0; i < s->indexes.size(); ++i)
2627 replace (s->indexes[i]);
2628 replace (s->base);
2629 replace (s->value);
2630 replace (s->limit);
2631 replace (s->block);
2632 provide (s);
2633 }
2634
2635 void
2636 update_visitor::visit_return_statement (return_statement* s)
2637 {
2638 replace (s->value);
2639 provide (s);
2640 }
2641
2642 void
2643 update_visitor::visit_delete_statement (delete_statement* s)
2644 {
2645 replace (s->value);
2646 provide (s);
2647 }
2648
2649 void
2650 update_visitor::visit_next_statement (next_statement* s)
2651 {
2652 provide (s);
2653 }
2654
2655 void
2656 update_visitor::visit_break_statement (break_statement* s)
2657 {
2658 provide (s);
2659 }
2660
2661 void
2662 update_visitor::visit_continue_statement (continue_statement* s)
2663 {
2664 provide (s);
2665 }
2666
2667 void
2668 update_visitor::visit_literal_string (literal_string* e)
2669 {
2670 provide (e);
2671 }
2672
2673 void
2674 update_visitor::visit_literal_number (literal_number* e)
2675 {
2676 provide (e);
2677 }
2678
2679 void
2680 update_visitor::visit_embedded_expr (embedded_expr* e)
2681 {
2682 provide (e);
2683 }
2684
2685 void
2686 update_visitor::visit_binary_expression (binary_expression* e)
2687 {
2688 replace (e->left);
2689 replace (e->right);
2690 provide (e);
2691 }
2692
2693 void
2694 update_visitor::visit_unary_expression (unary_expression* e)
2695 {
2696 replace (e->operand);
2697 provide (e);
2698 }
2699
2700 void
2701 update_visitor::visit_pre_crement (pre_crement* e)
2702 {
2703 replace (e->operand);
2704 provide (e);
2705 }
2706
2707 void
2708 update_visitor::visit_post_crement (post_crement* e)
2709 {
2710 replace (e->operand);
2711 provide (e);
2712 }
2713
2714
2715 void
2716 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2717 {
2718 replace (e->left);
2719 replace (e->right);
2720 provide (e);
2721 }
2722
2723 void
2724 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2725 {
2726 replace (e->left);
2727 replace (e->right);
2728 provide (e);
2729 }
2730
2731 void
2732 update_visitor::visit_array_in (array_in* e)
2733 {
2734 replace (e->operand);
2735 provide (e);
2736 }
2737
2738 void
2739 update_visitor::visit_regex_query (regex_query* e)
2740 {
2741 replace (e->left);
2742 replace (e->right); // XXX: do we *need* to replace literal in RHS?
2743 provide (e);
2744 }
2745
2746 void
2747 update_visitor::visit_comparison (comparison* e)
2748 {
2749 replace (e->left);
2750 replace (e->right);
2751 provide (e);
2752 }
2753
2754 void
2755 update_visitor::visit_concatenation (concatenation* e)
2756 {
2757 replace (e->left);
2758 replace (e->right);
2759 provide (e);
2760 }
2761
2762 void
2763 update_visitor::visit_ternary_expression (ternary_expression* e)
2764 {
2765 replace (e->cond);
2766 replace (e->truevalue);
2767 replace (e->falsevalue);
2768 provide (e);
2769 }
2770
2771 void
2772 update_visitor::visit_assignment (assignment* e)
2773 {
2774 replace (e->left);
2775 replace (e->right);
2776 provide (e);
2777 }
2778
2779 void
2780 update_visitor::visit_symbol (symbol* e)
2781 {
2782 provide (e);
2783 }
2784
2785 void
2786 update_visitor::visit_target_symbol (target_symbol* e)
2787 {
2788 e->visit_components (this);
2789 provide (e);
2790 }
2791
2792 void
2793 update_visitor::visit_cast_op (cast_op* e)
2794 {
2795 replace (e->operand);
2796 e->visit_components (this);
2797 provide (e);
2798 }
2799
2800 void
2801 update_visitor::visit_atvar_op (atvar_op* e)
2802 {
2803 e->visit_components (this);
2804 provide (e);
2805 }
2806
2807 void
2808 update_visitor::visit_defined_op (defined_op* e)
2809 {
2810 replace (e->operand);
2811 provide (e);
2812 }
2813
2814 void
2815 update_visitor::visit_entry_op (entry_op* e)
2816 {
2817 replace (e->operand);
2818 provide (e);
2819 }
2820
2821 void
2822 update_visitor::visit_perf_op (perf_op* e)
2823 {
2824 replace (e->operand);
2825 provide (e);
2826 }
2827
2828 void
2829 update_visitor::visit_arrayindex (arrayindex* e)
2830 {
2831 replace (e->base);
2832 for (unsigned i = 0; i < e->indexes.size(); ++i)
2833 replace (e->indexes[i]);
2834 provide (e);
2835 }
2836
2837 void
2838 update_visitor::visit_functioncall (functioncall* e)
2839 {
2840 for (unsigned i = 0; i < e->args.size(); ++i)
2841 replace (e->args[i]);
2842 provide (e);
2843 }
2844
2845 void
2846 update_visitor::visit_print_format (print_format* e)
2847 {
2848 for (unsigned i = 0; i < e->args.size(); ++i)
2849 replace (e->args[i]);
2850 replace (e->hist);
2851 provide (e);
2852 }
2853
2854 void
2855 update_visitor::visit_stat_op (stat_op* e)
2856 {
2857 replace (e->stat);
2858 provide (e);
2859 }
2860
2861 void
2862 update_visitor::visit_hist_op (hist_op* e)
2863 {
2864 replace (e->stat);
2865 provide (e);
2866 }
2867
2868
2869 // ------------------------------------------------------------------------
2870
2871
2872 void
2873 deep_copy_visitor::visit_block (block* s)
2874 {
2875 update_visitor::visit_block(new block(*s));
2876 }
2877
2878 void
2879 deep_copy_visitor::visit_try_block (try_block* s)
2880 {
2881 update_visitor::visit_try_block(new try_block(*s));
2882 }
2883
2884 void
2885 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2886 {
2887 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2888 }
2889
2890 void
2891 deep_copy_visitor::visit_null_statement (null_statement* s)
2892 {
2893 update_visitor::visit_null_statement(new null_statement(*s));
2894 }
2895
2896 void
2897 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2898 {
2899 update_visitor::visit_expr_statement(new expr_statement(*s));
2900 }
2901
2902 void
2903 deep_copy_visitor::visit_if_statement (if_statement* s)
2904 {
2905 update_visitor::visit_if_statement(new if_statement(*s));
2906 }
2907
2908 void
2909 deep_copy_visitor::visit_for_loop (for_loop* s)
2910 {
2911 update_visitor::visit_for_loop(new for_loop(*s));
2912 }
2913
2914 void
2915 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2916 {
2917 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2918 }
2919
2920 void
2921 deep_copy_visitor::visit_return_statement (return_statement* s)
2922 {
2923 update_visitor::visit_return_statement(new return_statement(*s));
2924 }
2925
2926 void
2927 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2928 {
2929 update_visitor::visit_delete_statement(new delete_statement(*s));
2930 }
2931
2932 void
2933 deep_copy_visitor::visit_next_statement (next_statement* s)
2934 {
2935 update_visitor::visit_next_statement(new next_statement(*s));
2936 }
2937
2938 void
2939 deep_copy_visitor::visit_break_statement (break_statement* s)
2940 {
2941 update_visitor::visit_break_statement(new break_statement(*s));
2942 }
2943
2944 void
2945 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2946 {
2947 update_visitor::visit_continue_statement(new continue_statement(*s));
2948 }
2949
2950 void
2951 deep_copy_visitor::visit_literal_string (literal_string* e)
2952 {
2953 update_visitor::visit_literal_string(new literal_string(*e));
2954 }
2955
2956 void
2957 deep_copy_visitor::visit_literal_number (literal_number* e)
2958 {
2959 update_visitor::visit_literal_number(new literal_number(*e));
2960 }
2961
2962 void
2963 deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2964 {
2965 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2966 }
2967
2968 void
2969 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2970 {
2971 update_visitor::visit_binary_expression(new binary_expression(*e));
2972 }
2973
2974 void
2975 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2976 {
2977 update_visitor::visit_unary_expression(new unary_expression(*e));
2978 }
2979
2980 void
2981 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2982 {
2983 update_visitor::visit_pre_crement(new pre_crement(*e));
2984 }
2985
2986 void
2987 deep_copy_visitor::visit_post_crement (post_crement* e)
2988 {
2989 update_visitor::visit_post_crement(new post_crement(*e));
2990 }
2991
2992
2993 void
2994 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2995 {
2996 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2997 }
2998
2999 void
3000 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
3001 {
3002 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
3003 }
3004
3005 void
3006 deep_copy_visitor::visit_array_in (array_in* e)
3007 {
3008 update_visitor::visit_array_in(new array_in(*e));
3009 }
3010
3011 void
3012 deep_copy_visitor::visit_regex_query (regex_query* e)
3013 {
3014 update_visitor::visit_regex_query(new regex_query(*e));
3015 }
3016
3017 void
3018 deep_copy_visitor::visit_comparison (comparison* e)
3019 {
3020 update_visitor::visit_comparison(new comparison(*e));
3021 }
3022
3023 void
3024 deep_copy_visitor::visit_concatenation (concatenation* e)
3025 {
3026 update_visitor::visit_concatenation(new concatenation(*e));
3027 }
3028
3029 void
3030 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
3031 {
3032 update_visitor::visit_ternary_expression(new ternary_expression(*e));
3033 }
3034
3035 void
3036 deep_copy_visitor::visit_assignment (assignment* e)
3037 {
3038 update_visitor::visit_assignment(new assignment(*e));
3039 }
3040
3041 void
3042 deep_copy_visitor::visit_symbol (symbol* e)
3043 {
3044 symbol* n = new symbol(*e);
3045 n->referent = NULL; // don't copy!
3046 update_visitor::visit_symbol(n);
3047 }
3048
3049 void
3050 deep_copy_visitor::visit_target_symbol (target_symbol* e)
3051 {
3052 target_symbol* n = new target_symbol(*e);
3053 n->referent = NULL; // don't copy!
3054 update_visitor::visit_target_symbol(n);
3055 }
3056
3057 void
3058 deep_copy_visitor::visit_cast_op (cast_op* e)
3059 {
3060 update_visitor::visit_cast_op(new cast_op(*e));
3061 }
3062
3063 void
3064 deep_copy_visitor::visit_atvar_op (atvar_op* e)
3065 {
3066 update_visitor::visit_atvar_op(new atvar_op(*e));
3067 }
3068
3069 void
3070 deep_copy_visitor::visit_defined_op (defined_op* e)
3071 {
3072 update_visitor::visit_defined_op(new defined_op(*e));
3073 }
3074
3075 void
3076 deep_copy_visitor::visit_entry_op (entry_op* e)
3077 {
3078 update_visitor::visit_entry_op(new entry_op(*e));
3079 }
3080
3081 void
3082 deep_copy_visitor::visit_perf_op (perf_op* e)
3083 {
3084 update_visitor::visit_perf_op(new perf_op(*e));
3085 }
3086
3087 void
3088 deep_copy_visitor::visit_arrayindex (arrayindex* e)
3089 {
3090 update_visitor::visit_arrayindex(new arrayindex(*e));
3091 }
3092
3093 void
3094 deep_copy_visitor::visit_functioncall (functioncall* e)
3095 {
3096 functioncall* n = new functioncall(*e);
3097 n->referent = NULL; // don't copy!
3098 update_visitor::visit_functioncall(n);
3099 }
3100
3101 void
3102 deep_copy_visitor::visit_print_format (print_format* e)
3103 {
3104 update_visitor::visit_print_format(new print_format(*e));
3105 }
3106
3107 void
3108 deep_copy_visitor::visit_stat_op (stat_op* e)
3109 {
3110 update_visitor::visit_stat_op(new stat_op(*e));
3111 }
3112
3113 void
3114 deep_copy_visitor::visit_hist_op (hist_op* e)
3115 {
3116 update_visitor::visit_hist_op(new hist_op(*e));
3117 }
3118
3119 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.158934 seconds and 6 git commands to generate.