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