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