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