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