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