]> sourceware.org Git - systemtap.git/blob - staptree.cxx
Unify no-component assertions on target variables
[systemtap.git] / staptree.cxx
1 // parse tree functions
2 // Copyright (C) 2005-2009 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
14 #include <iostream>
15 #include <typeinfo>
16 #include <sstream>
17 #include <cassert>
18 #include <cstring>
19 #include <vector>
20 #include <algorithm>
21 #include <cstring>
22
23 using namespace std;
24
25
26
27 expression::expression ():
28 type (pe_unknown), tok (0)
29 {
30 }
31
32
33 expression::~expression ()
34 {
35 }
36
37
38 statement::statement ():
39 tok (0)
40 {
41 }
42
43
44 statement::~statement ()
45 {
46 }
47
48
49 symbol::symbol ():
50 referent (0)
51 {
52 }
53
54
55 arrayindex::arrayindex ():
56 base (0)
57 {
58 }
59
60
61 functioncall::functioncall ():
62 referent (0)
63 {
64 }
65
66
67 symboldecl::symboldecl ():
68 tok (0),
69 type (pe_unknown)
70 {
71 }
72
73
74 symboldecl::~symboldecl ()
75 {
76 }
77
78 probe_point::probe_point (std::vector<component*> const & comps,
79 const token * t):
80 components(comps), tok(t), optional (false), sufficient (false),
81 condition (0)
82 {
83 }
84
85 // NB: shallow-copy of compoonents & condition!
86 probe_point::probe_point (const probe_point& pp):
87 components(pp.components), tok(pp.tok), optional (pp.optional), sufficient (pp.sufficient),
88 condition (pp.condition)
89 {
90 }
91
92
93 probe_point::probe_point ():
94 tok (0), optional (false), sufficient (false), condition (0)
95 {
96 }
97
98
99 unsigned probe::last_probeidx = 0;
100 probe::probe ():
101 body (0), tok (0)
102 {
103 this->name = string ("probe_") + lex_cast<string>(last_probeidx ++);
104 }
105
106
107 probe_point::component::component ():
108 arg (0)
109 {
110 }
111
112
113 probe_point::component::component (std::string const & f, literal * a):
114 functor(f), arg(a)
115 {
116 }
117
118
119 vardecl::vardecl ():
120 arity (-1), maxsize(0), init(NULL)
121 {
122 }
123
124
125 void
126 vardecl::set_arity (int a)
127 {
128 if (a < 0)
129 return;
130
131 if ((arity != a && arity >= 0) || (a == 0 && maxsize > 0))
132 throw semantic_error ("inconsistent arity", tok);
133
134 if (arity != a)
135 {
136 arity = a;
137 index_types.resize (arity);
138 for (int i=0; i<arity; i++)
139 index_types[i] = pe_unknown;
140 }
141 }
142
143 bool
144 vardecl::compatible_arity (int a)
145 {
146 if (a == 0 && maxsize > 0)
147 return false;
148 if (arity == -1 || a == -1)
149 return true;
150 return arity == a;
151 }
152
153
154 functiondecl::functiondecl ():
155 body (0)
156 {
157 }
158
159
160 literal_number::literal_number (int64_t v)
161 {
162 value = v;
163 type = pe_long;
164 }
165
166
167 literal_string::literal_string (const string& v)
168 {
169 value = v;
170 type = pe_string;
171 }
172
173
174 ostream&
175 operator << (ostream& o, const exp_type& e)
176 {
177 switch (e)
178 {
179 case pe_unknown: o << "unknown"; break;
180 case pe_long: o << "long"; break;
181 case pe_string: o << "string"; break;
182 case pe_stats: o << "stats"; break;
183 default: o << "???"; break;
184 }
185 return o;
186 }
187
188
189 void
190 target_symbol::assert_no_components(const std::string& tapset)
191 {
192 if (components.empty())
193 return;
194
195 switch (components[0].type)
196 {
197 case target_symbol::comp_literal_array_index:
198 throw semantic_error(tapset + " variable '" + base_name +
199 "' may not be used as array",
200 components[0].tok);
201 case target_symbol::comp_struct_member:
202 throw semantic_error(tapset + " variable '" + base_name +
203 "' may not be used as a structure",
204 components[0].tok);
205 default:
206 throw semantic_error ("invalid use of " + tapset +
207 " variable '" + base_name + "'",
208 components[0].tok);
209 }
210 }
211
212
213 // ------------------------------------------------------------------------
214 // parse tree printing
215
216 ostream& operator << (ostream& o, const expression& k)
217 {
218 k.print (o);
219 return o;
220 }
221
222
223 void literal_string::print (ostream& o) const
224 {
225 o << '"';
226 for (unsigned i=0; i<value.size(); i++)
227 if (value[i] == '"') // or other escapeworthy characters?
228 o << '\\' << '"';
229 else
230 o << value[i];
231 o << '"';
232 }
233
234
235 void literal_number::print (ostream& o) const
236 {
237 o << value;
238 }
239
240
241 void binary_expression::print (ostream& o) const
242 {
243 o << "(" << *left << ") "
244 << op
245 << " (" << *right << ")";
246 }
247
248
249 void unary_expression::print (ostream& o) const
250 {
251 o << op << '(' << *operand << ")";
252 }
253
254 void array_in::print (ostream& o) const
255 {
256 o << "[";
257 for (unsigned i=0; i<operand->indexes.size(); i++)
258 {
259 if (i > 0) o << ", ";
260 operand->indexes[i]->print (o);
261 }
262 o << "] in ";
263 operand->base->print_indexable (o);
264 }
265
266 void post_crement::print (ostream& o) const
267 {
268 o << '(' << *operand << ")" << op;
269 }
270
271
272 void ternary_expression::print (ostream& o) const
273 {
274 o << "(" << *cond << ")?("
275 << *truevalue << "):("
276 << *falsevalue << ")";
277 }
278
279
280 void symbol::print (ostream& o) const
281 {
282 o << name;
283 }
284
285
286 void target_symbol::component::print (ostream& o) const
287 {
288 switch (type)
289 {
290 case comp_struct_member:
291 o << "->" << member;
292 break;
293 case comp_literal_array_index:
294 o << '[' << num_index << ']';
295 break;
296 }
297 }
298
299
300 std::ostream& operator << (std::ostream& o, const target_symbol::component& c)
301 {
302 c.print (o);
303 return o;
304 }
305
306
307 void target_symbol::print (ostream& o) const
308 {
309 if (addressof)
310 o << "&";
311 o << base_name;
312 for (unsigned i = 0; i < components.size(); ++i)
313 o << components[i];
314 }
315
316
317 void cast_op::print (ostream& o) const
318 {
319 if (addressof)
320 o << "&";
321 o << base_name << '(' << *operand;
322 o << ", " << lex_cast_qstring (type);
323 if (module.length() > 0)
324 o << ", " << lex_cast_qstring (module);
325 o << ')';
326 for (unsigned i = 0; i < components.size(); ++i)
327 o << components[i];
328 }
329
330
331 void vardecl::print (ostream& o) const
332 {
333 o << name;
334 if (maxsize > 0)
335 o << "[" << maxsize << "]";
336 if (arity > 0 || index_types.size() > 0)
337 o << "[...]";
338 if (init)
339 {
340 o << " = ";
341 init->print(o);
342 }
343 }
344
345
346 void vardecl::printsig (ostream& o) const
347 {
348 o << name;
349 if (maxsize > 0)
350 o << "[" << maxsize << "]";
351 o << ":" << type;
352 if (index_types.size() > 0)
353 {
354 o << " [";
355 for (unsigned i=0; i<index_types.size(); i++)
356 o << (i>0 ? ", " : "") << index_types[i];
357 o << "]";
358 }
359 }
360
361
362 void functiondecl::print (ostream& o) const
363 {
364 o << "function " << name << " (";
365 for (unsigned i=0; i<formal_args.size(); i++)
366 o << (i>0 ? ", " : "") << *formal_args[i];
367 o << ")" << endl;
368 body->print(o);
369 }
370
371
372 void functiondecl::printsig (ostream& o) const
373 {
374 o << name << ":" << type << " (";
375 for (unsigned i=0; i<formal_args.size(); i++)
376 o << (i>0 ? ", " : "")
377 << *formal_args[i]
378 << ":"
379 << formal_args[i]->type;
380 o << ")";
381 }
382
383
384 void arrayindex::print (ostream& o) const
385 {
386 base->print_indexable (o);
387 o << "[";
388 for (unsigned i=0; i<indexes.size(); i++)
389 o << (i>0 ? ", " : "") << *indexes[i];
390 o << "]";
391 }
392
393
394 void functioncall::print (ostream& o) const
395 {
396 o << function << "(";
397 for (unsigned i=0; i<args.size(); i++)
398 o << (i>0 ? ", " : "") << *args[i];
399 o << ")";
400 }
401
402
403 bool
404 print_format::parse_print(const std::string &name,
405 bool &stream, bool &format, bool &delim, bool &newline, bool &_char)
406 {
407 const char *n = name.c_str();
408
409 stream = true;
410 format = delim = newline = _char = false;
411
412 if (strcmp(n, "print_char") == 0)
413 {
414 _char = true;
415 return true;
416 }
417
418 if (*n == 's')
419 {
420 stream = false;
421 ++n;
422 }
423
424 if (0 != strncmp(n, "print", 5))
425 return false;
426 n += 5;
427
428 if (*n == 'f')
429 {
430 format = true;
431 ++n;
432 }
433 else
434 {
435 if (*n == 'd')
436 {
437 delim = true;
438 ++n;
439 }
440
441 if (*n == 'l' && *(n+1) == 'n')
442 {
443 newline = true;
444 n += 2;
445 }
446 }
447
448 return (*n == '\0');
449 }
450
451
452 string
453 print_format::components_to_string(vector<format_component> const & components)
454 {
455 ostringstream oss;
456
457 for (vector<format_component>::const_iterator i = components.begin();
458 i != components.end(); ++i)
459 {
460
461 assert (i->type != conv_unspecified);
462
463 if (i->type == conv_literal)
464 {
465 assert(!i->literal_string.empty());
466 for (string::const_iterator j = i->literal_string.begin();
467 j != i->literal_string.end(); ++j)
468 {
469 // See also: c_unparser::visit_literal_string and lex_cast_qstring
470 if (*j == '%')
471 oss << '%';
472 else if(*j == '"')
473 oss << '\\';
474 oss << *j;
475 }
476 }
477 else
478 {
479 oss << '%';
480
481 if (i->flags & static_cast<unsigned long>(fmt_flag_zeropad))
482 oss << '0';
483
484 if (i->flags & static_cast<unsigned long>(fmt_flag_plus))
485 oss << '+';
486
487 if (i->flags & static_cast<unsigned long>(fmt_flag_space))
488 oss << ' ';
489
490 if (i->flags & static_cast<unsigned long>(fmt_flag_left))
491 oss << '-';
492
493 if (i->flags & static_cast<unsigned long>(fmt_flag_special))
494 oss << '#';
495
496 if (i->widthtype == width_dynamic)
497 oss << '*';
498 else if (i->widthtype != width_unspecified && i->width > 0)
499 oss << i->width;
500
501 if (i->prectype == prec_dynamic)
502 oss << ".*";
503 else if (i->prectype != prec_unspecified && i->precision > 0)
504 oss << '.' << i->precision;
505
506 switch (i->type)
507 {
508 case conv_binary:
509 oss << "b";
510 break;
511
512 case conv_char:
513 oss << "llc";
514 break;
515
516 case conv_signed_decimal:
517 oss << "lld";
518 break;
519
520 case conv_unsigned_decimal:
521 oss << "llu";
522 break;
523
524 case conv_unsigned_octal:
525 oss << "llo";
526 break;
527
528 case conv_unsigned_ptr:
529 oss << "p";
530 break;
531
532 case conv_unsigned_uppercase_hex:
533 oss << "llX";
534 break;
535
536 case conv_unsigned_lowercase_hex:
537 oss << "llx";
538 break;
539
540 case conv_string:
541 oss << 's';
542 break;
543
544 case conv_memory:
545 oss << 'm';
546 break;
547
548 case conv_memory_hex:
549 oss << 'M';
550 break;
551
552 default:
553 break;
554 }
555 }
556 }
557 return oss.str ();
558 }
559
560 vector<print_format::format_component>
561 print_format::string_to_components(string const & str)
562 {
563 format_component curr;
564 vector<format_component> res;
565
566 curr.clear();
567
568 string::const_iterator i = str.begin();
569
570 while (i != str.end())
571 {
572 if (*i != '%')
573 {
574 assert (curr.type == conv_unspecified || curr.type == conv_literal);
575 curr.type = conv_literal;
576 curr.literal_string += *i;
577 ++i;
578 continue;
579 }
580 else if (i+1 == str.end() || *(i+1) == '%')
581 {
582 assert(*i == '%');
583 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
584 assert (curr.type == conv_unspecified || curr.type == conv_literal);
585 curr.type = conv_literal;
586 curr.literal_string += '%';
587 i += 2;
588 continue;
589 }
590 else
591 {
592 assert(*i == '%');
593 if (curr.type != conv_unspecified)
594 {
595 // Flush any component we were previously accumulating
596 assert (curr.type == conv_literal);
597 res.push_back(curr);
598 curr.clear();
599 }
600 }
601 ++i;
602
603 if (i == str.end())
604 break;
605
606 // Now we are definitely parsing a conversion.
607 // Begin by parsing flags (which are optional).
608
609 switch (*i)
610 {
611 case '0':
612 curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
613 ++i;
614 break;
615
616 case '+':
617 curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
618 ++i;
619 break;
620
621 case '-':
622 curr.flags |= static_cast<unsigned long>(fmt_flag_left);
623 ++i;
624 break;
625
626 case ' ':
627 curr.flags |= static_cast<unsigned long>(fmt_flag_space);
628 ++i;
629 break;
630
631 case '#':
632 curr.flags |= static_cast<unsigned long>(fmt_flag_special);
633 ++i;
634 break;
635
636 default:
637 break;
638 }
639
640 if (i == str.end())
641 break;
642
643 // Parse optional width
644 if (*i == '*')
645 {
646 curr.widthtype = width_dynamic;
647 ++i;
648 }
649 else if (isdigit(*i))
650 {
651 curr.widthtype = width_static;
652 curr.width = 0;
653 do
654 {
655 curr.width *= 10;
656 curr.width += (*i - '0');
657 ++i;
658 }
659 while (i != str.end() && isdigit(*i));
660 }
661
662 if (i == str.end())
663 break;
664
665 // Parse optional precision
666 if (*i == '.')
667 {
668 ++i;
669 if (i == str.end())
670 break;
671 if (*i == '*')
672 {
673 curr.prectype = prec_dynamic;
674 ++i;
675 }
676 else if (isdigit(*i))
677 {
678 curr.prectype = prec_static;
679 curr.precision = 0;
680 do
681 {
682 curr.precision *= 10;
683 curr.precision += (*i - '0');
684 ++i;
685 }
686 while (i != str.end() && isdigit(*i));
687 }
688 }
689
690 if (i == str.end())
691 break;
692
693 // Parse the actual conversion specifier (bcsmdioupxXn)
694 switch (*i)
695 {
696 // Valid conversion types
697 case 'b':
698 curr.type = conv_binary;
699 break;
700
701 case 'c':
702 curr.type = conv_char;
703 break;
704
705 case 's':
706 curr.type = conv_string;
707 break;
708
709 case 'm':
710 curr.type = conv_memory;
711 break;
712
713 case 'M':
714 curr.type = conv_memory_hex;
715 break;
716
717 case 'd':
718 case 'i':
719 curr.type = conv_signed_decimal;
720 break;
721
722 case 'o':
723 curr.type = conv_unsigned_octal;
724 break;
725
726 case 'u':
727 curr.type = conv_unsigned_decimal;
728 break;
729
730 case 'p':
731 curr.type = conv_unsigned_ptr;
732 break;
733
734 case 'X':
735 curr.type = conv_unsigned_uppercase_hex;
736 break;
737
738 case 'x':
739 curr.type = conv_unsigned_lowercase_hex;
740 break;
741
742 default:
743 break;
744 }
745
746 if (curr.type == conv_unspecified)
747 throw parse_error("invalid or missing conversion specifier");
748
749 ++i;
750 res.push_back(curr);
751 curr.clear();
752 }
753
754 // If there's a remaining partly-composed conversion, fail.
755 if (!curr.is_empty())
756 {
757 if (curr.type == conv_literal)
758 res.push_back(curr);
759 else
760 throw parse_error("trailing incomplete print format conversion");
761 }
762
763 return res;
764 }
765
766
767 void print_format::print (ostream& o) const
768 {
769 o << tok->content << "(";
770 if (print_with_format)
771 o << lex_cast_qstring (raw_components);
772 if (print_with_delim)
773 o << lex_cast_qstring (delimiter.literal_string);
774 if (hist)
775 hist->print(o);
776 for (vector<expression*>::const_iterator i = args.begin();
777 i != args.end(); ++i)
778 {
779 if (i != args.begin() || print_with_format || print_with_delim)
780 o << ", ";
781 (*i)->print(o);
782 }
783 o << ")";
784 }
785
786 void stat_op::print (ostream& o) const
787 {
788 o << '@';
789 switch (ctype)
790 {
791 case sc_average:
792 o << "avg(";
793 break;
794
795 case sc_count:
796 o << "count(";
797 break;
798
799 case sc_sum:
800 o << "sum(";
801 break;
802
803 case sc_min:
804 o << "min(";
805 break;
806
807 case sc_max:
808 o << "max(";
809 break;
810 }
811 stat->print(o);
812 o << ")";
813 }
814
815 void
816 hist_op::print (ostream& o) const
817 {
818 o << '@';
819 switch (htype)
820 {
821 case hist_linear:
822 assert(params.size() == 3);
823 o << "hist_linear(";
824 stat->print(o);
825 for (size_t i = 0; i < params.size(); ++i)
826 {
827 o << ", " << params[i];
828 }
829 o << ")";
830 break;
831
832 case hist_log:
833 assert(params.size() == 0);
834 o << "hist_log(";
835 stat->print(o);
836 o << ")";
837 break;
838 }
839 }
840
841 ostream& operator << (ostream& o, const statement& k)
842 {
843 k.print (o);
844 return o;
845 }
846
847
848 void embeddedcode::print (ostream &o) const
849 {
850 o << "%{";
851 o << code;
852 o << "%}";
853 }
854
855 void block::print (ostream& o) const
856 {
857 o << "{" << endl;
858 for (unsigned i=0; i<statements.size(); i++)
859 o << *statements [i] << endl;
860 o << "}";
861 }
862
863 block::block (statement* car, statement* cdr)
864 {
865 statements.push_back(car);
866 statements.push_back(cdr);
867 this->tok = car->tok;
868 }
869
870
871
872 void for_loop::print (ostream& o) const
873 {
874 o << "for (";
875 if (init) init->print (o);
876 o << "; ";
877 cond->print (o);
878 o << "; ";
879 if (incr) incr->print (o);
880 o << ") ";
881 block->print (o);
882 }
883
884
885 void foreach_loop::print (ostream& o) const
886 {
887 o << "foreach ([";
888 for (unsigned i=0; i<indexes.size(); i++)
889 {
890 if (i > 0) o << ", ";
891 indexes[i]->print (o);
892 if (sort_direction != 0 && sort_column == i+1)
893 o << (sort_direction > 0 ? "+" : "-");
894 }
895 o << "] in ";
896 base->print_indexable (o);
897 if (sort_direction != 0 && sort_column == 0)
898 o << (sort_direction > 0 ? "+" : "-");
899 if (limit)
900 {
901 o << " limit ";
902 limit->print (o);
903 }
904 o << ") ";
905 block->print (o);
906 }
907
908
909 void null_statement::print (ostream& o) const
910 {
911 o << ";";
912 }
913
914
915 void expr_statement::print (ostream& o) const
916 {
917 o << *value;
918 }
919
920
921 void return_statement::print (ostream& o) const
922 {
923 o << "return " << *value;
924 }
925
926
927 void delete_statement::print (ostream& o) const
928 {
929 o << "delete " << *value;
930 }
931
932 void next_statement::print (ostream& o) const
933 {
934 o << "next";
935 }
936
937 void break_statement::print (ostream& o) const
938 {
939 o << "break";
940 }
941
942 void continue_statement::print (ostream& o) const
943 {
944 o << "continue";
945 }
946
947 void if_statement::print (ostream& o) const
948 {
949 o << "if (" << *condition << ") "
950 << *thenblock << endl;
951 if (elseblock)
952 o << "else " << *elseblock << endl;
953 }
954
955
956 void stapfile::print (ostream& o) const
957 {
958 o << "# file " << name << endl;
959
960 for (unsigned i=0; i<embeds.size(); i++)
961 embeds[i]->print (o);
962
963 for (unsigned i=0; i<globals.size(); i++)
964 {
965 o << "global ";
966 globals[i]->print (o);
967 o << endl;
968 }
969
970 for (unsigned i=0; i<aliases.size(); i++)
971 {
972 aliases[i]->print (o);
973 o << endl;
974 }
975
976 for (unsigned i=0; i<probes.size(); i++)
977 {
978 probes[i]->print (o);
979 o << endl;
980 }
981
982 for (unsigned j = 0; j < functions.size(); j++)
983 {
984 functions[j]->print (o);
985 o << endl;
986 }
987 }
988
989
990 void probe::print (ostream& o) const
991 {
992 o << "probe ";
993 printsig (o);
994 o << *body;
995 }
996
997
998 void probe::printsig (ostream& o) const
999 {
1000 const probe_alias *alias = get_alias ();
1001 if (alias)
1002 {
1003 alias->printsig (o);
1004 return;
1005 }
1006
1007 for (unsigned i=0; i<locations.size(); i++)
1008 {
1009 if (i > 0) o << ",";
1010 locations[i]->print (o);
1011 }
1012 }
1013
1014
1015 void
1016 probe::collect_derivation_chain (std::vector<probe*> &probes_list)
1017 {
1018 probes_list.push_back(this);
1019 }
1020
1021
1022 void probe_point::print (ostream& o) const
1023 {
1024 for (unsigned i=0; i<components.size(); i++)
1025 {
1026 if (i>0) o << ".";
1027 probe_point::component* c = components[i];
1028 o << c->functor;
1029 if (c->arg)
1030 o << "(" << *c->arg << ")";
1031 }
1032 if (sufficient)
1033 o << "!";
1034 else if (optional) // sufficient implies optional
1035 o << "?";
1036 if (condition)
1037 o<< " if (" << *condition << ")";
1038 }
1039
1040 string probe_point::str ()
1041 {
1042 ostringstream o;
1043 for (unsigned i=0; i<components.size(); i++)
1044 {
1045 if (i>0) o << ".";
1046 probe_point::component* c = components[i];
1047 o << c->functor;
1048 if (c->arg)
1049 o << "(" << *c->arg << ")";
1050 }
1051 if (sufficient)
1052 o << "!";
1053 else if (optional) // sufficient implies optional
1054 o << "?";
1055 if (condition)
1056 o<< " if (" << *condition << ")";
1057 return o.str();
1058 }
1059
1060
1061 probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
1062 probe (), alias_names (aliases)
1063 {
1064 }
1065
1066 void probe_alias::printsig (ostream& o) const
1067 {
1068 for (unsigned i=0; i<alias_names.size(); i++)
1069 {
1070 o << (i>0 ? " = " : "");
1071 alias_names[i]->print (o);
1072 }
1073 o << " = ";
1074 for (unsigned i=0; i<locations.size(); i++)
1075 {
1076 if (i > 0) o << ", ";
1077 locations[i]->print (o);
1078 }
1079 }
1080
1081
1082 ostream& operator << (ostream& o, const probe_point& k)
1083 {
1084 k.print (o);
1085 return o;
1086 }
1087
1088
1089 ostream& operator << (ostream& o, const symboldecl& k)
1090 {
1091 k.print (o);
1092 return o;
1093 }
1094
1095
1096
1097 // ------------------------------------------------------------------------
1098 // visitors
1099
1100
1101 void
1102 block::visit (visitor* u)
1103 {
1104 u->visit_block (this);
1105 }
1106
1107
1108 void
1109 embeddedcode::visit (visitor* u)
1110 {
1111 u->visit_embeddedcode (this);
1112 }
1113
1114
1115 void
1116 for_loop::visit (visitor* u)
1117 {
1118 u->visit_for_loop (this);
1119 }
1120
1121 void
1122 foreach_loop::visit (visitor* u)
1123 {
1124 u->visit_foreach_loop (this);
1125 }
1126
1127 void
1128 null_statement::visit (visitor* u)
1129 {
1130 u->visit_null_statement (this);
1131 }
1132
1133 void
1134 expr_statement::visit (visitor* u)
1135 {
1136 u->visit_expr_statement (this);
1137 }
1138
1139 void
1140 return_statement::visit (visitor* u)
1141 {
1142 u->visit_return_statement (this);
1143 }
1144
1145 void
1146 delete_statement::visit (visitor* u)
1147 {
1148 u->push_active_lvalue (this->value);
1149 u->visit_delete_statement (this);
1150 u->pop_active_lvalue ();
1151 }
1152
1153 void
1154 if_statement::visit (visitor* u)
1155 {
1156 u->visit_if_statement (this);
1157 }
1158
1159 void
1160 next_statement::visit (visitor* u)
1161 {
1162 u->visit_next_statement (this);
1163 }
1164
1165 void
1166 break_statement::visit (visitor* u)
1167 {
1168 u->visit_break_statement (this);
1169 }
1170
1171 void
1172 continue_statement::visit (visitor* u)
1173 {
1174 u->visit_continue_statement (this);
1175 }
1176
1177 void
1178 literal_string::visit(visitor* u)
1179 {
1180 u->visit_literal_string (this);
1181 }
1182
1183 void
1184 literal_number::visit(visitor* u)
1185 {
1186 u->visit_literal_number (this);
1187 }
1188
1189 void
1190 binary_expression::visit (visitor* u)
1191 {
1192 u->visit_binary_expression (this);
1193 }
1194
1195 void
1196 unary_expression::visit (visitor* u)
1197 {
1198 u->visit_unary_expression (this);
1199 }
1200
1201 void
1202 pre_crement::visit (visitor* u)
1203 {
1204 u->push_active_lvalue (this->operand);
1205 u->visit_pre_crement (this);
1206 u->pop_active_lvalue ();
1207 }
1208
1209 void
1210 post_crement::visit (visitor* u)
1211 {
1212 u->push_active_lvalue (this->operand);
1213 u->visit_post_crement (this);
1214 u->pop_active_lvalue ();
1215 }
1216
1217 void
1218 logical_or_expr::visit (visitor* u)
1219 {
1220 u->visit_logical_or_expr (this);
1221 }
1222
1223 void
1224 logical_and_expr::visit (visitor* u)
1225 {
1226 u->visit_logical_and_expr (this);
1227 }
1228
1229 void
1230 array_in::visit (visitor* u)
1231 {
1232 u->visit_array_in (this);
1233 }
1234
1235 void
1236 comparison::visit (visitor* u)
1237 {
1238 u->visit_comparison (this);
1239 }
1240
1241 void
1242 concatenation::visit (visitor* u)
1243 {
1244 u->visit_concatenation (this);
1245 }
1246
1247 void
1248 ternary_expression::visit (visitor* u)
1249 {
1250 u->visit_ternary_expression (this);
1251 }
1252
1253 void
1254 assignment::visit (visitor* u)
1255 {
1256 u->push_active_lvalue (this->left);
1257 u->visit_assignment (this);
1258 u->pop_active_lvalue ();
1259 }
1260
1261 void
1262 symbol::visit (visitor* u)
1263 {
1264 u->visit_symbol (this);
1265 }
1266
1267 void
1268 target_symbol::visit (visitor* u)
1269 {
1270 u->visit_target_symbol(this);
1271 }
1272
1273 void
1274 cast_op::visit (visitor* u)
1275 {
1276 u->visit_cast_op(this);
1277 }
1278
1279 void
1280 arrayindex::visit (visitor* u)
1281 {
1282 u->visit_arrayindex (this);
1283 }
1284
1285 void
1286 functioncall::visit (visitor* u)
1287 {
1288 u->visit_functioncall (this);
1289 }
1290
1291 void
1292 print_format::visit (visitor *u)
1293 {
1294 u->visit_print_format (this);
1295 }
1296
1297 void
1298 stat_op::visit (visitor *u)
1299 {
1300 u->visit_stat_op (this);
1301 }
1302
1303 void
1304 hist_op::visit (visitor *u)
1305 {
1306 u->visit_hist_op (this);
1307 }
1308
1309 void
1310 indexable::print_indexable (std::ostream& o) const
1311 {
1312 const symbol *sym;
1313 const hist_op *hist;
1314 classify_const_indexable(this, sym, hist);
1315 if (sym)
1316 sym->print (o);
1317 else
1318 {
1319 assert (hist);
1320 hist->print (o);
1321 }
1322 }
1323
1324 void
1325 indexable::visit_indexable (visitor* u)
1326 {
1327 symbol *sym;
1328 hist_op *hist;
1329 classify_indexable(this, sym, hist);
1330 if (sym)
1331 sym->visit (u);
1332 else
1333 {
1334 assert (hist);
1335 hist->visit (u);
1336 }
1337 }
1338
1339
1340 bool
1341 indexable::is_symbol(symbol *& sym_out)
1342 {
1343 sym_out = NULL;
1344 return false;
1345 }
1346
1347 bool
1348 indexable::is_hist_op(hist_op *& hist_out)
1349 {
1350 hist_out = NULL;
1351 return false;
1352 }
1353
1354 bool
1355 indexable::is_const_symbol(const symbol *& sym_out) const
1356 {
1357 sym_out = NULL;
1358 return false;
1359 }
1360
1361 bool
1362 indexable::is_const_hist_op(const hist_op *& hist_out) const
1363 {
1364 hist_out = NULL;
1365 return false;
1366 }
1367
1368 bool
1369 symbol::is_symbol(symbol *& sym_out)
1370 {
1371 sym_out = this;
1372 return true;
1373 }
1374
1375 bool
1376 symbol::is_const_symbol(const symbol *& sym_out) const
1377 {
1378 sym_out = this;
1379 return true;
1380 }
1381
1382 const token *
1383 symbol::get_tok() const
1384 {
1385 return tok;
1386 }
1387
1388 bool
1389 hist_op::is_hist_op(hist_op *& hist_out)
1390 {
1391 hist_out = this;
1392 return true;
1393 }
1394
1395 bool
1396 hist_op::is_const_hist_op(const hist_op *& hist_out) const
1397 {
1398 hist_out = this;
1399 return true;
1400 }
1401
1402 const token *
1403 hist_op::get_tok() const
1404 {
1405 return tok;
1406 }
1407
1408 void
1409 classify_indexable(indexable* ix,
1410 symbol *& array_out,
1411 hist_op *& hist_out)
1412 {
1413 array_out = NULL;
1414 hist_out = NULL;
1415 if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1416 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1417 if (ix && !(hist_out || array_out))
1418 throw semantic_error("Failed to classify indexable", ix->get_tok());
1419 }
1420
1421 void
1422 classify_const_indexable(const indexable* ix,
1423 const symbol *& array_out,
1424 const hist_op *& hist_out)
1425 {
1426 array_out = NULL;
1427 hist_out = NULL;
1428 if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
1429 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1430 }
1431
1432 // ------------------------------------------------------------------------
1433
1434 bool
1435 visitor::is_active_lvalue(expression *e)
1436 {
1437 for (unsigned i = 0; i < active_lvalues.size(); ++i)
1438 {
1439 if (active_lvalues[i] == e)
1440 return true;
1441 }
1442 return false;
1443 }
1444
1445 void
1446 visitor::push_active_lvalue(expression *e)
1447 {
1448 active_lvalues.push_back(e);
1449 }
1450
1451 void
1452 visitor::pop_active_lvalue()
1453 {
1454 assert(!active_lvalues.empty());
1455 active_lvalues.pop_back();
1456 }
1457
1458
1459
1460 // ------------------------------------------------------------------------
1461
1462 void
1463 traversing_visitor::visit_block (block* s)
1464 {
1465 for (unsigned i=0; i<s->statements.size(); i++)
1466 s->statements[i]->visit (this);
1467 }
1468
1469 void
1470 traversing_visitor::visit_embeddedcode (embeddedcode*)
1471 {
1472 }
1473
1474 void
1475 traversing_visitor::visit_null_statement (null_statement*)
1476 {
1477 }
1478
1479 void
1480 traversing_visitor::visit_expr_statement (expr_statement* s)
1481 {
1482 s->value->visit (this);
1483 }
1484
1485 void
1486 traversing_visitor::visit_if_statement (if_statement* s)
1487 {
1488 s->condition->visit (this);
1489 s->thenblock->visit (this);
1490 if (s->elseblock)
1491 s->elseblock->visit (this);
1492 }
1493
1494 void
1495 traversing_visitor::visit_for_loop (for_loop* s)
1496 {
1497 if (s->init) s->init->visit (this);
1498 s->cond->visit (this);
1499 if (s->incr) s->incr->visit (this);
1500 s->block->visit (this);
1501 }
1502
1503 void
1504 traversing_visitor::visit_foreach_loop (foreach_loop* s)
1505 {
1506 symbol *array = NULL;
1507 hist_op *hist = NULL;
1508 classify_indexable (s->base, array, hist);
1509 if (array)
1510 array->visit(this);
1511 else
1512 hist->visit(this);
1513
1514 for (unsigned i=0; i<s->indexes.size(); i++)
1515 s->indexes[i]->visit (this);
1516
1517 if (s->limit)
1518 s->limit->visit (this);
1519
1520 s->block->visit (this);
1521 }
1522
1523 void
1524 traversing_visitor::visit_return_statement (return_statement* s)
1525 {
1526 s->value->visit (this);
1527 }
1528
1529 void
1530 traversing_visitor::visit_delete_statement (delete_statement* s)
1531 {
1532 s->value->visit (this);
1533 }
1534
1535 void
1536 traversing_visitor::visit_next_statement (next_statement*)
1537 {
1538 }
1539
1540 void
1541 traversing_visitor::visit_break_statement (break_statement*)
1542 {
1543 }
1544
1545 void
1546 traversing_visitor::visit_continue_statement (continue_statement*)
1547 {
1548 }
1549
1550 void
1551 traversing_visitor::visit_literal_string (literal_string*)
1552 {
1553 }
1554
1555 void
1556 traversing_visitor::visit_literal_number (literal_number*)
1557 {
1558 }
1559
1560 void
1561 traversing_visitor::visit_binary_expression (binary_expression* e)
1562 {
1563 e->left->visit (this);
1564 e->right->visit (this);
1565 }
1566
1567 void
1568 traversing_visitor::visit_unary_expression (unary_expression* e)
1569 {
1570 e->operand->visit (this);
1571 }
1572
1573 void
1574 traversing_visitor::visit_pre_crement (pre_crement* e)
1575 {
1576 e->operand->visit (this);
1577 }
1578
1579 void
1580 traversing_visitor::visit_post_crement (post_crement* e)
1581 {
1582 e->operand->visit (this);
1583 }
1584
1585
1586 void
1587 traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1588 {
1589 e->left->visit (this);
1590 e->right->visit (this);
1591 }
1592
1593 void
1594 traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1595 {
1596 e->left->visit (this);
1597 e->right->visit (this);
1598 }
1599
1600 void
1601 traversing_visitor::visit_array_in (array_in* e)
1602 {
1603 e->operand->visit (this);
1604 }
1605
1606 void
1607 traversing_visitor::visit_comparison (comparison* e)
1608 {
1609 e->left->visit (this);
1610 e->right->visit (this);
1611 }
1612
1613 void
1614 traversing_visitor::visit_concatenation (concatenation* e)
1615 {
1616 e->left->visit (this);
1617 e->right->visit (this);
1618 }
1619
1620 void
1621 traversing_visitor::visit_ternary_expression (ternary_expression* e)
1622 {
1623 e->cond->visit (this);
1624 e->truevalue->visit (this);
1625 e->falsevalue->visit (this);
1626 }
1627
1628 void
1629 traversing_visitor::visit_assignment (assignment* e)
1630 {
1631 e->left->visit (this);
1632 e->right->visit (this);
1633 }
1634
1635 void
1636 traversing_visitor::visit_symbol (symbol*)
1637 {
1638 }
1639
1640 void
1641 traversing_visitor::visit_target_symbol (target_symbol*)
1642 {
1643 }
1644
1645 void
1646 traversing_visitor::visit_cast_op (cast_op* e)
1647 {
1648 e->operand->visit (this);
1649 }
1650
1651 void
1652 traversing_visitor::visit_arrayindex (arrayindex* e)
1653 {
1654 for (unsigned i=0; i<e->indexes.size(); i++)
1655 e->indexes[i]->visit (this);
1656
1657 symbol *array = NULL;
1658 hist_op *hist = NULL;
1659 classify_indexable(e->base, array, hist);
1660 if (array)
1661 return array->visit(this);
1662 else
1663 return hist->visit(this);
1664 }
1665
1666 void
1667 traversing_visitor::visit_functioncall (functioncall* e)
1668 {
1669 for (unsigned i=0; i<e->args.size(); i++)
1670 e->args[i]->visit (this);
1671 }
1672
1673 void
1674 traversing_visitor::visit_print_format (print_format* e)
1675 {
1676 for (unsigned i=0; i<e->args.size(); i++)
1677 e->args[i]->visit (this);
1678 if (e->hist)
1679 e->hist->visit(this);
1680 }
1681
1682 void
1683 traversing_visitor::visit_stat_op (stat_op* e)
1684 {
1685 e->stat->visit (this);
1686 }
1687
1688 void
1689 traversing_visitor::visit_hist_op (hist_op* e)
1690 {
1691 e->stat->visit (this);
1692 }
1693
1694
1695 void
1696 functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1697 {
1698 traversing_visitor::visit_functioncall (e);
1699
1700 // prevent infinite recursion
1701 if (traversed.find (e->referent) == traversed.end ())
1702 {
1703 traversed.insert (e->referent);
1704 // recurse
1705 functiondecl* last_current_function = current_function;
1706 current_function = e->referent;
1707 e->referent->body->visit (this);
1708 current_function = last_current_function;
1709 }
1710 }
1711
1712
1713 void
1714 varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1715 {
1716 // We want to elide embedded-C functions when possible. For
1717 // example, each $target variable access is expanded to an
1718 // embedded-C function call. Yet, for safety reasons, we should
1719 // presume that embedded-C functions have intentional side-effects.
1720 //
1721 // To tell these two types of functions apart, we apply a
1722 // Kludge(tm): we look for a magic string within the function body.
1723 // $target variables as rvalues will have this; lvalues won't.
1724 // Also, explicit side-effect-free tapset functions will have this.
1725
1726 assert (current_function); // only they get embedded code
1727 if (s->code.find ("/* pure */") != string::npos)
1728 return;
1729
1730 embedded_seen = true;
1731 }
1732
1733 void
1734 varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1735 {
1736 // Still-unresolved target symbol assignments get treated as
1737 // generating side-effects like embedded-C, to prevent premature
1738 // elision and later error message suppression (PR5516). rvalue use
1739 // of unresolved target symbols is OTOH not considered a side-effect.
1740
1741 if (is_active_lvalue (e))
1742 embedded_seen = true;
1743 }
1744
1745 void
1746 varuse_collecting_visitor::visit_cast_op (cast_op *e)
1747 {
1748 // As with target_symbols, unresolved cast assignments need to preserved
1749 // for later error handling.
1750 if (is_active_lvalue (e))
1751 embedded_seen = true;
1752
1753 functioncall_traversing_visitor::visit_cast_op (e);
1754 }
1755
1756 void
1757 varuse_collecting_visitor::visit_print_format (print_format* e)
1758 {
1759 // NB: Instead of being top-level statements, "print" and "printf"
1760 // are implemented as statement-expressions containing a
1761 // print_format. They have side-effects, but not via the
1762 // embedded-code detection method above.
1763 //
1764 // But sprint and sprintf don't have side-effects.
1765
1766 if (e->print_to_stream)
1767 embedded_seen = true; // a proxy for "has unknown side-effects"
1768
1769 functioncall_traversing_visitor::visit_print_format (e);
1770 }
1771
1772
1773 void
1774 varuse_collecting_visitor::visit_assignment (assignment *e)
1775 {
1776 if (e->op == "=" || e->op == "<<<") // pure writes
1777 {
1778 expression* last_lvalue = current_lvalue;
1779 current_lvalue = e->left; // leave a mark for ::visit_symbol
1780 functioncall_traversing_visitor::visit_assignment (e);
1781 current_lvalue = last_lvalue;
1782 }
1783 else // read-modify-writes
1784 {
1785 expression* last_lrvalue = current_lrvalue;
1786 current_lrvalue = e->left; // leave a mark for ::visit_symbol
1787 functioncall_traversing_visitor::visit_assignment (e);
1788 current_lrvalue = last_lrvalue;
1789 }
1790 }
1791
1792 void
1793 varuse_collecting_visitor::visit_symbol (symbol *e)
1794 {
1795 if (e->referent == 0)
1796 throw semantic_error ("symbol without referent", e->tok);
1797
1798 // We could handle initialized globals by marking them as "written".
1799 // However, this current visitor may be called for a function or
1800 // probe body, from the point of view of which this global is
1801 // already initialized, so not written.
1802 /*
1803 if (e->referent->init)
1804 written.insert (e->referent);
1805 */
1806
1807 if (current_lvalue == e || current_lrvalue == e)
1808 {
1809 written.insert (e->referent);
1810 // clog << "write ";
1811 }
1812 if (current_lvalue != e || current_lrvalue == e)
1813 {
1814 read.insert (e->referent);
1815 // clog << "read ";
1816 }
1817 // clog << *e->tok << endl;
1818 }
1819
1820 // NB: stat_op need not be overridden, since it will get to
1821 // visit_symbol and only as a possible rvalue.
1822
1823
1824 void
1825 varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
1826 {
1827 // Hooking this callback is necessary because of the hacky
1828 // statistics representation. For the expression "i[4] = 5", the
1829 // incoming lvalue will point to this arrayindex. However, the
1830 // symbol corresponding to the "i[4]" is multiply inherited with
1831 // arrayindex. If the symbol base part of this object is not at
1832 // offset 0, then static_cast<symbol*>(e) may result in a different
1833 // address, and not match lvalue by number when we recurse that way.
1834 // So we explicitly override the incoming lvalue/lrvalue values to
1835 // point at the embedded objects' actual base addresses.
1836
1837 expression* last_lrvalue = current_lrvalue;
1838 expression* last_lvalue = current_lvalue;
1839
1840 symbol *array = NULL;
1841 hist_op *hist = NULL;
1842 classify_indexable(e->base, array, hist);
1843
1844 if (array)
1845 {
1846 if (current_lrvalue == e) current_lrvalue = array;
1847 if (current_lvalue == e) current_lvalue = array;
1848 functioncall_traversing_visitor::visit_arrayindex (e);
1849 }
1850 else // if (hist)
1851 {
1852 if (current_lrvalue == e) current_lrvalue = hist->stat;
1853 if (current_lvalue == e) current_lvalue = hist->stat;
1854 functioncall_traversing_visitor::visit_arrayindex (e);
1855 }
1856
1857 current_lrvalue = last_lrvalue;
1858 current_lvalue = last_lvalue;
1859 }
1860
1861
1862 void
1863 varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
1864 {
1865 expression* last_lrvalue = current_lrvalue;
1866 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1867 functioncall_traversing_visitor::visit_pre_crement (e);
1868 current_lrvalue = last_lrvalue;
1869 }
1870
1871 void
1872 varuse_collecting_visitor::visit_post_crement (post_crement *e)
1873 {
1874 expression* last_lrvalue = current_lrvalue;
1875 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1876 functioncall_traversing_visitor::visit_post_crement (e);
1877 current_lrvalue = last_lrvalue;
1878 }
1879
1880 void
1881 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
1882 {
1883 // NB: we duplicate so don't bother call
1884 // functioncall_traversing_visitor::visit_foreach_loop (s);
1885
1886 symbol *array = NULL;
1887 hist_op *hist = NULL;
1888 classify_indexable (s->base, array, hist);
1889 if (array)
1890 array->visit(this);
1891 else
1892 hist->visit(this);
1893
1894 // If the collection is sorted, imply a "write" access to the
1895 // array in addition to the "read" one already noted above.
1896 if (s->sort_direction)
1897 {
1898 symbol *array = NULL;
1899 hist_op *hist = NULL;
1900 classify_indexable (s->base, array, hist);
1901 if (array) this->written.insert (array->referent);
1902 // XXX: Can hist_op iterations be sorted?
1903 }
1904
1905 // NB: don't forget to visit the index expressions, which are lvalues.
1906 for (unsigned i=0; i<s->indexes.size(); i++)
1907 {
1908 expression* last_lvalue = current_lvalue;
1909 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
1910 s->indexes[i]->visit (this);
1911 current_lvalue = last_lvalue;
1912 }
1913
1914 if (s->limit)
1915 s->limit->visit (this);
1916
1917 s->block->visit (this);
1918 }
1919
1920
1921 void
1922 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
1923 {
1924 // Ideally, this would be treated like an assignment: a plain write
1925 // to the underlying value ("lvalue"). XXX: However, the
1926 // optimization pass is not smart enough to remove an unneeded
1927 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
1928 // should protect the underlying value from optimizional mischief.
1929 expression* last_lrvalue = current_lrvalue;
1930 current_lrvalue = s->value; // leave a mark for ::visit_symbol
1931 functioncall_traversing_visitor::visit_delete_statement (s);
1932 current_lrvalue = last_lrvalue;
1933 }
1934
1935 bool
1936 varuse_collecting_visitor::side_effect_free ()
1937 {
1938 return (written.empty() && !embedded_seen);
1939 }
1940
1941
1942 bool
1943 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
1944 {
1945 // A looser notion of side-effect-freeness with respect to a given
1946 // list of variables.
1947
1948 // That's useful because the written list may consist of local
1949 // variables of called functions. But visible side-effects only
1950 // occur if the client's locals, or any globals are written-to.
1951
1952 set<vardecl*> intersection;
1953 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
1954 set_intersection (written.begin(), written.end(),
1955 vars.begin(), vars.end(),
1956 int_it);
1957
1958 return (intersection.empty() && !embedded_seen);
1959 }
1960
1961
1962
1963
1964 // ------------------------------------------------------------------------
1965
1966
1967 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
1968 throwing_visitor::throwing_visitor (): msg ("invalid element") {}
1969
1970
1971 void
1972 throwing_visitor::throwone (const token* t)
1973 {
1974 throw semantic_error (msg, t);
1975 }
1976
1977 void
1978 throwing_visitor::visit_block (block* s)
1979 {
1980 throwone (s->tok);
1981 }
1982
1983 void
1984 throwing_visitor::visit_embeddedcode (embeddedcode* s)
1985 {
1986 throwone (s->tok);
1987 }
1988
1989 void
1990 throwing_visitor::visit_null_statement (null_statement* s)
1991 {
1992 throwone (s->tok);
1993 }
1994
1995 void
1996 throwing_visitor::visit_expr_statement (expr_statement* s)
1997 {
1998 throwone (s->tok);
1999 }
2000
2001 void
2002 throwing_visitor::visit_if_statement (if_statement* s)
2003 {
2004 throwone (s->tok);
2005 }
2006
2007 void
2008 throwing_visitor::visit_for_loop (for_loop* s)
2009 {
2010 throwone (s->tok);
2011 }
2012
2013 void
2014 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2015 {
2016 throwone (s->tok);
2017 }
2018
2019 void
2020 throwing_visitor::visit_return_statement (return_statement* s)
2021 {
2022 throwone (s->tok);
2023 }
2024
2025 void
2026 throwing_visitor::visit_delete_statement (delete_statement* s)
2027 {
2028 throwone (s->tok);
2029 }
2030
2031 void
2032 throwing_visitor::visit_next_statement (next_statement* s)
2033 {
2034 throwone (s->tok);
2035 }
2036
2037 void
2038 throwing_visitor::visit_break_statement (break_statement* s)
2039 {
2040 throwone (s->tok);
2041 }
2042
2043 void
2044 throwing_visitor::visit_continue_statement (continue_statement* s)
2045 {
2046 throwone (s->tok);
2047 }
2048
2049 void
2050 throwing_visitor::visit_literal_string (literal_string* e)
2051 {
2052 throwone (e->tok);
2053 }
2054
2055 void
2056 throwing_visitor::visit_literal_number (literal_number* e)
2057 {
2058 throwone (e->tok);
2059 }
2060
2061 void
2062 throwing_visitor::visit_binary_expression (binary_expression* e)
2063 {
2064 throwone (e->tok);
2065 }
2066
2067 void
2068 throwing_visitor::visit_unary_expression (unary_expression* e)
2069 {
2070 throwone (e->tok);
2071 }
2072
2073 void
2074 throwing_visitor::visit_pre_crement (pre_crement* e)
2075 {
2076 throwone (e->tok);
2077 }
2078
2079 void
2080 throwing_visitor::visit_post_crement (post_crement* e)
2081 {
2082 throwone (e->tok);
2083 }
2084
2085
2086 void
2087 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2088 {
2089 throwone (e->tok);
2090 }
2091
2092 void
2093 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2094 {
2095 throwone (e->tok);
2096 }
2097
2098 void
2099 throwing_visitor::visit_array_in (array_in* e)
2100 {
2101 throwone (e->tok);
2102 }
2103
2104 void
2105 throwing_visitor::visit_comparison (comparison* e)
2106 {
2107 throwone (e->tok);
2108 }
2109
2110 void
2111 throwing_visitor::visit_concatenation (concatenation* e)
2112 {
2113 throwone (e->tok);
2114 }
2115
2116 void
2117 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2118 {
2119 throwone (e->tok);
2120 }
2121
2122 void
2123 throwing_visitor::visit_assignment (assignment* e)
2124 {
2125 throwone (e->tok);
2126 }
2127
2128 void
2129 throwing_visitor::visit_symbol (symbol* e)
2130 {
2131 throwone (e->tok);
2132 }
2133
2134 void
2135 throwing_visitor::visit_target_symbol (target_symbol* e)
2136 {
2137 throwone (e->tok);
2138 }
2139
2140 void
2141 throwing_visitor::visit_cast_op (cast_op* e)
2142 {
2143 throwone (e->tok);
2144 }
2145
2146 void
2147 throwing_visitor::visit_arrayindex (arrayindex* e)
2148 {
2149 throwone (e->tok);
2150 }
2151
2152 void
2153 throwing_visitor::visit_functioncall (functioncall* e)
2154 {
2155 throwone (e->tok);
2156 }
2157
2158 void
2159 throwing_visitor::visit_print_format (print_format* e)
2160 {
2161 throwone (e->tok);
2162 }
2163
2164 void
2165 throwing_visitor::visit_stat_op (stat_op* e)
2166 {
2167 throwone (e->tok);
2168 }
2169
2170 void
2171 throwing_visitor::visit_hist_op (hist_op* e)
2172 {
2173 throwone (e->tok);
2174 }
2175
2176
2177 // ------------------------------------------------------------------------
2178
2179
2180 void
2181 update_visitor::visit_block (block* s)
2182 {
2183 for (unsigned i = 0; i < s->statements.size(); ++i)
2184 s->statements[i] = require (s->statements[i]);
2185 provide (s);
2186 }
2187
2188 void
2189 update_visitor::visit_embeddedcode (embeddedcode* s)
2190 {
2191 provide (s);
2192 }
2193
2194 void
2195 update_visitor::visit_null_statement (null_statement* s)
2196 {
2197 provide (s);
2198 }
2199
2200 void
2201 update_visitor::visit_expr_statement (expr_statement* s)
2202 {
2203 s->value = require (s->value);
2204 provide (s);
2205 }
2206
2207 void
2208 update_visitor::visit_if_statement (if_statement* s)
2209 {
2210 s->condition = require (s->condition);
2211 s->thenblock = require (s->thenblock);
2212 s->elseblock = require (s->elseblock);
2213 provide (s);
2214 }
2215
2216 void
2217 update_visitor::visit_for_loop (for_loop* s)
2218 {
2219 s->init = require (s->init);
2220 s->cond = require (s->cond);
2221 s->incr = require (s->incr);
2222 s->block = require (s->block);
2223 provide (s);
2224 }
2225
2226 void
2227 update_visitor::visit_foreach_loop (foreach_loop* s)
2228 {
2229 for (unsigned i = 0; i < s->indexes.size(); ++i)
2230 s->indexes[i] = require (s->indexes[i]);
2231 s->base = require (s->base);
2232 s->limit = require (s->limit);
2233 s->block = require (s->block);
2234 provide (s);
2235 }
2236
2237 void
2238 update_visitor::visit_return_statement (return_statement* s)
2239 {
2240 s->value = require (s->value);
2241 provide (s);
2242 }
2243
2244 void
2245 update_visitor::visit_delete_statement (delete_statement* s)
2246 {
2247 s->value = require (s->value);
2248 provide (s);
2249 }
2250
2251 void
2252 update_visitor::visit_next_statement (next_statement* s)
2253 {
2254 provide (s);
2255 }
2256
2257 void
2258 update_visitor::visit_break_statement (break_statement* s)
2259 {
2260 provide (s);
2261 }
2262
2263 void
2264 update_visitor::visit_continue_statement (continue_statement* s)
2265 {
2266 provide (s);
2267 }
2268
2269 void
2270 update_visitor::visit_literal_string (literal_string* e)
2271 {
2272 provide (e);
2273 }
2274
2275 void
2276 update_visitor::visit_literal_number (literal_number* e)
2277 {
2278 provide (e);
2279 }
2280
2281 void
2282 update_visitor::visit_binary_expression (binary_expression* e)
2283 {
2284 e->left = require (e->left);
2285 e->right = require (e->right);
2286 provide (e);
2287 }
2288
2289 void
2290 update_visitor::visit_unary_expression (unary_expression* e)
2291 {
2292 e->operand = require (e->operand);
2293 provide (e);
2294 }
2295
2296 void
2297 update_visitor::visit_pre_crement (pre_crement* e)
2298 {
2299 e->operand = require (e->operand);
2300 provide (e);
2301 }
2302
2303 void
2304 update_visitor::visit_post_crement (post_crement* e)
2305 {
2306 e->operand = require (e->operand);
2307 provide (e);
2308 }
2309
2310
2311 void
2312 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2313 {
2314 e->left = require (e->left);
2315 e->right = require (e->right);
2316 provide (e);
2317 }
2318
2319 void
2320 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2321 {
2322 e->left = require (e->left);
2323 e->right = require (e->right);
2324 provide (e);
2325 }
2326
2327 void
2328 update_visitor::visit_array_in (array_in* e)
2329 {
2330 e->operand = require (e->operand);
2331 provide (e);
2332 }
2333
2334 void
2335 update_visitor::visit_comparison (comparison* e)
2336 {
2337 e->left = require (e->left);
2338 e->right = require (e->right);
2339 provide (e);
2340 }
2341
2342 void
2343 update_visitor::visit_concatenation (concatenation* e)
2344 {
2345 e->left = require (e->left);
2346 e->right = require (e->right);
2347 provide (e);
2348 }
2349
2350 void
2351 update_visitor::visit_ternary_expression (ternary_expression* e)
2352 {
2353 e->cond = require (e->cond);
2354 e->truevalue = require (e->truevalue);
2355 e->falsevalue = require (e->falsevalue);
2356 provide (e);
2357 }
2358
2359 void
2360 update_visitor::visit_assignment (assignment* e)
2361 {
2362 e->left = require (e->left);
2363 e->right = require (e->right);
2364 provide (e);
2365 }
2366
2367 void
2368 update_visitor::visit_symbol (symbol* e)
2369 {
2370 provide (e);
2371 }
2372
2373 void
2374 update_visitor::visit_target_symbol (target_symbol* e)
2375 {
2376 provide (e);
2377 }
2378
2379 void
2380 update_visitor::visit_cast_op (cast_op* e)
2381 {
2382 e->operand = require (e->operand);
2383 provide (e);
2384 }
2385
2386 void
2387 update_visitor::visit_arrayindex (arrayindex* e)
2388 {
2389 e->base = require (e->base);
2390 for (unsigned i = 0; i < e->indexes.size(); ++i)
2391 e->indexes[i] = require (e->indexes[i]);
2392 provide (e);
2393 }
2394
2395 void
2396 update_visitor::visit_functioncall (functioncall* e)
2397 {
2398 for (unsigned i = 0; i < e->args.size(); ++i)
2399 e->args[i] = require (e->args[i]);
2400 provide (e);
2401 }
2402
2403 void
2404 update_visitor::visit_print_format (print_format* e)
2405 {
2406 for (unsigned i = 0; i < e->args.size(); ++i)
2407 e->args[i] = require (e->args[i]);
2408 e->hist = require (e->hist);
2409 provide (e);
2410 }
2411
2412 void
2413 update_visitor::visit_stat_op (stat_op* e)
2414 {
2415 e->stat = require (e->stat);
2416 provide (e);
2417 }
2418
2419 void
2420 update_visitor::visit_hist_op (hist_op* e)
2421 {
2422 e->stat = require (e->stat);
2423 provide (e);
2424 }
2425
2426 template <> indexable*
2427 update_visitor::require <indexable*> (indexable* src, bool clearok)
2428 {
2429 indexable *dst = NULL;
2430 if (src != NULL)
2431 {
2432 symbol *array_src=NULL;
2433 hist_op *hist_src=NULL;
2434
2435 classify_indexable(src, array_src, hist_src);
2436
2437 if (array_src)
2438 dst = require (array_src);
2439 else
2440 dst = require (hist_src);
2441 assert(clearok || dst);
2442 }
2443 return dst;
2444 }
2445
2446
2447 // ------------------------------------------------------------------------
2448
2449
2450 void
2451 deep_copy_visitor::visit_block (block* s)
2452 {
2453 update_visitor::visit_block(new block(*s));
2454 }
2455
2456 void
2457 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2458 {
2459 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2460 }
2461
2462 void
2463 deep_copy_visitor::visit_null_statement (null_statement* s)
2464 {
2465 update_visitor::visit_null_statement(new null_statement(*s));
2466 }
2467
2468 void
2469 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2470 {
2471 update_visitor::visit_expr_statement(new expr_statement(*s));
2472 }
2473
2474 void
2475 deep_copy_visitor::visit_if_statement (if_statement* s)
2476 {
2477 update_visitor::visit_if_statement(new if_statement(*s));
2478 }
2479
2480 void
2481 deep_copy_visitor::visit_for_loop (for_loop* s)
2482 {
2483 update_visitor::visit_for_loop(new for_loop(*s));
2484 }
2485
2486 void
2487 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2488 {
2489 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2490 }
2491
2492 void
2493 deep_copy_visitor::visit_return_statement (return_statement* s)
2494 {
2495 update_visitor::visit_return_statement(new return_statement(*s));
2496 }
2497
2498 void
2499 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2500 {
2501 update_visitor::visit_delete_statement(new delete_statement(*s));
2502 }
2503
2504 void
2505 deep_copy_visitor::visit_next_statement (next_statement* s)
2506 {
2507 update_visitor::visit_next_statement(new next_statement(*s));
2508 }
2509
2510 void
2511 deep_copy_visitor::visit_break_statement (break_statement* s)
2512 {
2513 update_visitor::visit_break_statement(new break_statement(*s));
2514 }
2515
2516 void
2517 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2518 {
2519 update_visitor::visit_continue_statement(new continue_statement(*s));
2520 }
2521
2522 void
2523 deep_copy_visitor::visit_literal_string (literal_string* e)
2524 {
2525 update_visitor::visit_literal_string(new literal_string(*e));
2526 }
2527
2528 void
2529 deep_copy_visitor::visit_literal_number (literal_number* e)
2530 {
2531 update_visitor::visit_literal_number(new literal_number(*e));
2532 }
2533
2534 void
2535 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2536 {
2537 update_visitor::visit_binary_expression(new binary_expression(*e));
2538 }
2539
2540 void
2541 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2542 {
2543 update_visitor::visit_unary_expression(new unary_expression(*e));
2544 }
2545
2546 void
2547 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2548 {
2549 update_visitor::visit_pre_crement(new pre_crement(*e));
2550 }
2551
2552 void
2553 deep_copy_visitor::visit_post_crement (post_crement* e)
2554 {
2555 update_visitor::visit_post_crement(new post_crement(*e));
2556 }
2557
2558
2559 void
2560 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2561 {
2562 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2563 }
2564
2565 void
2566 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2567 {
2568 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2569 }
2570
2571 void
2572 deep_copy_visitor::visit_array_in (array_in* e)
2573 {
2574 update_visitor::visit_array_in(new array_in(*e));
2575 }
2576
2577 void
2578 deep_copy_visitor::visit_comparison (comparison* e)
2579 {
2580 update_visitor::visit_comparison(new comparison(*e));
2581 }
2582
2583 void
2584 deep_copy_visitor::visit_concatenation (concatenation* e)
2585 {
2586 update_visitor::visit_concatenation(new concatenation(*e));
2587 }
2588
2589 void
2590 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2591 {
2592 update_visitor::visit_ternary_expression(new ternary_expression(*e));
2593 }
2594
2595 void
2596 deep_copy_visitor::visit_assignment (assignment* e)
2597 {
2598 update_visitor::visit_assignment(new assignment(*e));
2599 }
2600
2601 void
2602 deep_copy_visitor::visit_symbol (symbol* e)
2603 {
2604 symbol* n = new symbol(*e);
2605 n->referent = NULL; // don't copy!
2606 update_visitor::visit_symbol(n);
2607 }
2608
2609 void
2610 deep_copy_visitor::visit_target_symbol (target_symbol* e)
2611 {
2612 target_symbol* n = new target_symbol(*e);
2613 n->referent = NULL; // don't copy!
2614 update_visitor::visit_target_symbol(n);
2615 }
2616
2617 void
2618 deep_copy_visitor::visit_cast_op (cast_op* e)
2619 {
2620 update_visitor::visit_cast_op(new cast_op(*e));
2621 }
2622
2623 void
2624 deep_copy_visitor::visit_arrayindex (arrayindex* e)
2625 {
2626 update_visitor::visit_arrayindex(new arrayindex(*e));
2627 }
2628
2629 void
2630 deep_copy_visitor::visit_functioncall (functioncall* e)
2631 {
2632 functioncall* n = new functioncall(*e);
2633 n->referent = NULL; // don't copy!
2634 update_visitor::visit_functioncall(n);
2635 }
2636
2637 void
2638 deep_copy_visitor::visit_print_format (print_format* e)
2639 {
2640 update_visitor::visit_print_format(new print_format(*e));
2641 }
2642
2643 void
2644 deep_copy_visitor::visit_stat_op (stat_op* e)
2645 {
2646 update_visitor::visit_stat_op(new stat_op(*e));
2647 }
2648
2649 void
2650 deep_copy_visitor::visit_hist_op (hist_op* e)
2651 {
2652 update_visitor::visit_hist_op(new hist_op(*e));
2653 }
2654
2655 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.152684 seconds and 6 git commands to generate.