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