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