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