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