]> sourceware.org Git - systemtap.git/blob - staptree.cxx
PR11566: embedded-c expressions
[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 // PR6954: regard as pure writes
2054 expression* last_lvalue = current_lvalue;
2055 current_lvalue = e->operand; // leave a mark for ::visit_symbol
2056 functioncall_traversing_visitor::visit_pre_crement (e);
2057 current_lvalue = last_lvalue;
2058 }
2059
2060 void
2061 varuse_collecting_visitor::visit_post_crement (post_crement *e)
2062 {
2063 // PR6954: regard as pure writes
2064 expression* last_lvalue = current_lvalue;
2065 current_lvalue = e->operand; // leave a mark for ::visit_symbol
2066 functioncall_traversing_visitor::visit_post_crement (e);
2067 current_lvalue = last_lvalue;
2068 }
2069
2070 void
2071 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2072 {
2073 // NB: we duplicate so don't bother call
2074 // functioncall_traversing_visitor::visit_foreach_loop (s);
2075
2076 symbol *array = NULL;
2077 hist_op *hist = NULL;
2078 classify_indexable (s->base, array, hist);
2079 if (array)
2080 array->visit(this);
2081 else
2082 hist->visit(this);
2083
2084 // If the collection is sorted, imply a "write" access to the
2085 // array in addition to the "read" one already noted above.
2086 if (s->sort_direction)
2087 {
2088 symbol *array = NULL;
2089 hist_op *hist = NULL;
2090 classify_indexable (s->base, array, hist);
2091 if (array) this->written.insert (array->referent);
2092 // XXX: Can hist_op iterations be sorted?
2093 }
2094
2095 // NB: don't forget to visit the index expressions, which are lvalues.
2096 for (unsigned i=0; i<s->indexes.size(); i++)
2097 {
2098 expression* last_lvalue = current_lvalue;
2099 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2100 s->indexes[i]->visit (this);
2101 current_lvalue = last_lvalue;
2102 }
2103
2104 // The value is an lvalue too
2105 if (s->value)
2106 {
2107 expression* last_lvalue = current_lvalue;
2108 current_lvalue = s->value; // leave a mark for ::visit_symbol
2109 s->value->visit (this);
2110 current_lvalue = last_lvalue;
2111 }
2112
2113 if (s->limit)
2114 s->limit->visit (this);
2115
2116 s->block->visit (this);
2117 }
2118
2119
2120 void
2121 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2122 {
2123 // Ideally, this would be treated like an assignment: a plain write
2124 // to the underlying value ("lvalue"). XXX: However, the
2125 // optimization pass is not smart enough to remove an unneeded
2126 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2127 // should protect the underlying value from optimizional mischief.
2128 expression* last_lrvalue = current_lrvalue;
2129 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2130 functioncall_traversing_visitor::visit_delete_statement (s);
2131 current_lrvalue = last_lrvalue;
2132 }
2133
2134 bool
2135 varuse_collecting_visitor::side_effect_free ()
2136 {
2137 return (written.empty() && !embedded_seen);
2138 }
2139
2140
2141 bool
2142 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2143 {
2144 // A looser notion of side-effect-freeness with respect to a given
2145 // list of variables.
2146
2147 // That's useful because the written list may consist of local
2148 // variables of called functions. But visible side-effects only
2149 // occur if the client's locals, or any globals are written-to.
2150
2151 set<vardecl*> intersection;
2152 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2153 set_intersection (written.begin(), written.end(),
2154 vars.begin(), vars.end(),
2155 int_it);
2156
2157 return (intersection.empty() && !embedded_seen);
2158 }
2159
2160
2161
2162
2163 // ------------------------------------------------------------------------
2164
2165
2166 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2167 throwing_visitor::throwing_visitor (): msg ("invalid element") {}
2168
2169
2170 void
2171 throwing_visitor::throwone (const token* t)
2172 {
2173 throw semantic_error (msg, t);
2174 }
2175
2176 void
2177 throwing_visitor::visit_block (block* s)
2178 {
2179 throwone (s->tok);
2180 }
2181
2182 void
2183 throwing_visitor::visit_try_block (try_block* s)
2184 {
2185 throwone (s->tok);
2186 }
2187
2188
2189 void
2190 throwing_visitor::visit_embeddedcode (embeddedcode* s)
2191 {
2192 throwone (s->tok);
2193 }
2194
2195 void
2196 throwing_visitor::visit_null_statement (null_statement* s)
2197 {
2198 throwone (s->tok);
2199 }
2200
2201 void
2202 throwing_visitor::visit_expr_statement (expr_statement* s)
2203 {
2204 throwone (s->tok);
2205 }
2206
2207 void
2208 throwing_visitor::visit_if_statement (if_statement* s)
2209 {
2210 throwone (s->tok);
2211 }
2212
2213 void
2214 throwing_visitor::visit_for_loop (for_loop* s)
2215 {
2216 throwone (s->tok);
2217 }
2218
2219 void
2220 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2221 {
2222 throwone (s->tok);
2223 }
2224
2225 void
2226 throwing_visitor::visit_return_statement (return_statement* s)
2227 {
2228 throwone (s->tok);
2229 }
2230
2231 void
2232 throwing_visitor::visit_delete_statement (delete_statement* s)
2233 {
2234 throwone (s->tok);
2235 }
2236
2237 void
2238 throwing_visitor::visit_next_statement (next_statement* s)
2239 {
2240 throwone (s->tok);
2241 }
2242
2243 void
2244 throwing_visitor::visit_break_statement (break_statement* s)
2245 {
2246 throwone (s->tok);
2247 }
2248
2249 void
2250 throwing_visitor::visit_continue_statement (continue_statement* s)
2251 {
2252 throwone (s->tok);
2253 }
2254
2255 void
2256 throwing_visitor::visit_literal_string (literal_string* e)
2257 {
2258 throwone (e->tok);
2259 }
2260
2261 void
2262 throwing_visitor::visit_literal_number (literal_number* e)
2263 {
2264 throwone (e->tok);
2265 }
2266
2267 void
2268 throwing_visitor::visit_embedded_expr (embedded_expr* e)
2269 {
2270 throwone (e->tok);
2271 }
2272
2273 void
2274 throwing_visitor::visit_binary_expression (binary_expression* e)
2275 {
2276 throwone (e->tok);
2277 }
2278
2279 void
2280 throwing_visitor::visit_unary_expression (unary_expression* e)
2281 {
2282 throwone (e->tok);
2283 }
2284
2285 void
2286 throwing_visitor::visit_pre_crement (pre_crement* e)
2287 {
2288 throwone (e->tok);
2289 }
2290
2291 void
2292 throwing_visitor::visit_post_crement (post_crement* e)
2293 {
2294 throwone (e->tok);
2295 }
2296
2297
2298 void
2299 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2300 {
2301 throwone (e->tok);
2302 }
2303
2304 void
2305 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2306 {
2307 throwone (e->tok);
2308 }
2309
2310 void
2311 throwing_visitor::visit_array_in (array_in* e)
2312 {
2313 throwone (e->tok);
2314 }
2315
2316 void
2317 throwing_visitor::visit_comparison (comparison* e)
2318 {
2319 throwone (e->tok);
2320 }
2321
2322 void
2323 throwing_visitor::visit_concatenation (concatenation* e)
2324 {
2325 throwone (e->tok);
2326 }
2327
2328 void
2329 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2330 {
2331 throwone (e->tok);
2332 }
2333
2334 void
2335 throwing_visitor::visit_assignment (assignment* e)
2336 {
2337 throwone (e->tok);
2338 }
2339
2340 void
2341 throwing_visitor::visit_symbol (symbol* e)
2342 {
2343 throwone (e->tok);
2344 }
2345
2346 void
2347 throwing_visitor::visit_target_symbol (target_symbol* e)
2348 {
2349 throwone (e->tok);
2350 }
2351
2352 void
2353 throwing_visitor::visit_cast_op (cast_op* e)
2354 {
2355 throwone (e->tok);
2356 }
2357
2358 void
2359 throwing_visitor::visit_defined_op (defined_op* e)
2360 {
2361 throwone (e->tok);
2362 }
2363
2364
2365 void
2366 throwing_visitor::visit_arrayindex (arrayindex* e)
2367 {
2368 throwone (e->tok);
2369 }
2370
2371 void
2372 throwing_visitor::visit_functioncall (functioncall* e)
2373 {
2374 throwone (e->tok);
2375 }
2376
2377 void
2378 throwing_visitor::visit_print_format (print_format* e)
2379 {
2380 throwone (e->tok);
2381 }
2382
2383 void
2384 throwing_visitor::visit_stat_op (stat_op* e)
2385 {
2386 throwone (e->tok);
2387 }
2388
2389 void
2390 throwing_visitor::visit_hist_op (hist_op* e)
2391 {
2392 throwone (e->tok);
2393 }
2394
2395
2396 // ------------------------------------------------------------------------
2397
2398
2399 void
2400 update_visitor::visit_block (block* s)
2401 {
2402 for (unsigned i = 0; i < s->statements.size(); ++i)
2403 replace (s->statements[i]);
2404 provide (s);
2405 }
2406
2407 void
2408 update_visitor::visit_try_block (try_block* s)
2409 {
2410 replace (s->try_block);
2411 replace (s->catch_error_var);
2412 replace (s->catch_block);
2413 provide (s);
2414 }
2415
2416 void
2417 update_visitor::visit_embeddedcode (embeddedcode* s)
2418 {
2419 provide (s);
2420 }
2421
2422 void
2423 update_visitor::visit_null_statement (null_statement* s)
2424 {
2425 provide (s);
2426 }
2427
2428 void
2429 update_visitor::visit_expr_statement (expr_statement* s)
2430 {
2431 replace (s->value);
2432 provide (s);
2433 }
2434
2435 void
2436 update_visitor::visit_if_statement (if_statement* s)
2437 {
2438 replace (s->condition);
2439 replace (s->thenblock);
2440 replace (s->elseblock);
2441 provide (s);
2442 }
2443
2444 void
2445 update_visitor::visit_for_loop (for_loop* s)
2446 {
2447 replace (s->init);
2448 replace (s->cond);
2449 replace (s->incr);
2450 replace (s->block);
2451 provide (s);
2452 }
2453
2454 void
2455 update_visitor::visit_foreach_loop (foreach_loop* s)
2456 {
2457 for (unsigned i = 0; i < s->indexes.size(); ++i)
2458 replace (s->indexes[i]);
2459 replace (s->base);
2460 replace (s->value);
2461 replace (s->limit);
2462 replace (s->block);
2463 provide (s);
2464 }
2465
2466 void
2467 update_visitor::visit_return_statement (return_statement* s)
2468 {
2469 replace (s->value);
2470 provide (s);
2471 }
2472
2473 void
2474 update_visitor::visit_delete_statement (delete_statement* s)
2475 {
2476 replace (s->value);
2477 provide (s);
2478 }
2479
2480 void
2481 update_visitor::visit_next_statement (next_statement* s)
2482 {
2483 provide (s);
2484 }
2485
2486 void
2487 update_visitor::visit_break_statement (break_statement* s)
2488 {
2489 provide (s);
2490 }
2491
2492 void
2493 update_visitor::visit_continue_statement (continue_statement* s)
2494 {
2495 provide (s);
2496 }
2497
2498 void
2499 update_visitor::visit_literal_string (literal_string* e)
2500 {
2501 provide (e);
2502 }
2503
2504 void
2505 update_visitor::visit_literal_number (literal_number* e)
2506 {
2507 provide (e);
2508 }
2509
2510 void
2511 update_visitor::visit_embedded_expr (embedded_expr* e)
2512 {
2513 provide (e);
2514 }
2515
2516 void
2517 update_visitor::visit_binary_expression (binary_expression* e)
2518 {
2519 replace (e->left);
2520 replace (e->right);
2521 provide (e);
2522 }
2523
2524 void
2525 update_visitor::visit_unary_expression (unary_expression* e)
2526 {
2527 replace (e->operand);
2528 provide (e);
2529 }
2530
2531 void
2532 update_visitor::visit_pre_crement (pre_crement* e)
2533 {
2534 replace (e->operand);
2535 provide (e);
2536 }
2537
2538 void
2539 update_visitor::visit_post_crement (post_crement* e)
2540 {
2541 replace (e->operand);
2542 provide (e);
2543 }
2544
2545
2546 void
2547 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2548 {
2549 replace (e->left);
2550 replace (e->right);
2551 provide (e);
2552 }
2553
2554 void
2555 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2556 {
2557 replace (e->left);
2558 replace (e->right);
2559 provide (e);
2560 }
2561
2562 void
2563 update_visitor::visit_array_in (array_in* e)
2564 {
2565 replace (e->operand);
2566 provide (e);
2567 }
2568
2569 void
2570 update_visitor::visit_comparison (comparison* e)
2571 {
2572 replace (e->left);
2573 replace (e->right);
2574 provide (e);
2575 }
2576
2577 void
2578 update_visitor::visit_concatenation (concatenation* e)
2579 {
2580 replace (e->left);
2581 replace (e->right);
2582 provide (e);
2583 }
2584
2585 void
2586 update_visitor::visit_ternary_expression (ternary_expression* e)
2587 {
2588 replace (e->cond);
2589 replace (e->truevalue);
2590 replace (e->falsevalue);
2591 provide (e);
2592 }
2593
2594 void
2595 update_visitor::visit_assignment (assignment* e)
2596 {
2597 replace (e->left);
2598 replace (e->right);
2599 provide (e);
2600 }
2601
2602 void
2603 update_visitor::visit_symbol (symbol* e)
2604 {
2605 provide (e);
2606 }
2607
2608 void
2609 update_visitor::visit_target_symbol (target_symbol* e)
2610 {
2611 e->visit_components (this);
2612 provide (e);
2613 }
2614
2615 void
2616 update_visitor::visit_cast_op (cast_op* e)
2617 {
2618 replace (e->operand);
2619 e->visit_components (this);
2620 provide (e);
2621 }
2622
2623 void
2624 update_visitor::visit_defined_op (defined_op* e)
2625 {
2626 replace (e->operand);
2627 provide (e);
2628 }
2629
2630 void
2631 update_visitor::visit_arrayindex (arrayindex* e)
2632 {
2633 replace (e->base);
2634 for (unsigned i = 0; i < e->indexes.size(); ++i)
2635 replace (e->indexes[i]);
2636 provide (e);
2637 }
2638
2639 void
2640 update_visitor::visit_functioncall (functioncall* e)
2641 {
2642 for (unsigned i = 0; i < e->args.size(); ++i)
2643 replace (e->args[i]);
2644 provide (e);
2645 }
2646
2647 void
2648 update_visitor::visit_print_format (print_format* e)
2649 {
2650 for (unsigned i = 0; i < e->args.size(); ++i)
2651 replace (e->args[i]);
2652 replace (e->hist);
2653 provide (e);
2654 }
2655
2656 void
2657 update_visitor::visit_stat_op (stat_op* e)
2658 {
2659 replace (e->stat);
2660 provide (e);
2661 }
2662
2663 void
2664 update_visitor::visit_hist_op (hist_op* e)
2665 {
2666 replace (e->stat);
2667 provide (e);
2668 }
2669
2670 template <> indexable*
2671 update_visitor::require <indexable> (indexable* src, bool clearok)
2672 {
2673 indexable *dst = NULL;
2674 if (src != NULL)
2675 {
2676 symbol *array_src=NULL;
2677 hist_op *hist_src=NULL;
2678
2679 classify_indexable(src, array_src, hist_src);
2680
2681 if (array_src)
2682 dst = require (array_src);
2683 else
2684 dst = require (hist_src);
2685 assert(clearok || dst);
2686 }
2687 return dst;
2688 }
2689
2690
2691 // ------------------------------------------------------------------------
2692
2693
2694 void
2695 deep_copy_visitor::visit_block (block* s)
2696 {
2697 update_visitor::visit_block(new block(*s));
2698 }
2699
2700 void
2701 deep_copy_visitor::visit_try_block (try_block* s)
2702 {
2703 update_visitor::visit_try_block(new try_block(*s));
2704 }
2705
2706 void
2707 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2708 {
2709 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2710 }
2711
2712 void
2713 deep_copy_visitor::visit_null_statement (null_statement* s)
2714 {
2715 update_visitor::visit_null_statement(new null_statement(*s));
2716 }
2717
2718 void
2719 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2720 {
2721 update_visitor::visit_expr_statement(new expr_statement(*s));
2722 }
2723
2724 void
2725 deep_copy_visitor::visit_if_statement (if_statement* s)
2726 {
2727 update_visitor::visit_if_statement(new if_statement(*s));
2728 }
2729
2730 void
2731 deep_copy_visitor::visit_for_loop (for_loop* s)
2732 {
2733 update_visitor::visit_for_loop(new for_loop(*s));
2734 }
2735
2736 void
2737 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2738 {
2739 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2740 }
2741
2742 void
2743 deep_copy_visitor::visit_return_statement (return_statement* s)
2744 {
2745 update_visitor::visit_return_statement(new return_statement(*s));
2746 }
2747
2748 void
2749 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2750 {
2751 update_visitor::visit_delete_statement(new delete_statement(*s));
2752 }
2753
2754 void
2755 deep_copy_visitor::visit_next_statement (next_statement* s)
2756 {
2757 update_visitor::visit_next_statement(new next_statement(*s));
2758 }
2759
2760 void
2761 deep_copy_visitor::visit_break_statement (break_statement* s)
2762 {
2763 update_visitor::visit_break_statement(new break_statement(*s));
2764 }
2765
2766 void
2767 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2768 {
2769 update_visitor::visit_continue_statement(new continue_statement(*s));
2770 }
2771
2772 void
2773 deep_copy_visitor::visit_literal_string (literal_string* e)
2774 {
2775 update_visitor::visit_literal_string(new literal_string(*e));
2776 }
2777
2778 void
2779 deep_copy_visitor::visit_literal_number (literal_number* e)
2780 {
2781 update_visitor::visit_literal_number(new literal_number(*e));
2782 }
2783
2784 void
2785 deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2786 {
2787 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2788 }
2789
2790 void
2791 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2792 {
2793 update_visitor::visit_binary_expression(new binary_expression(*e));
2794 }
2795
2796 void
2797 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2798 {
2799 update_visitor::visit_unary_expression(new unary_expression(*e));
2800 }
2801
2802 void
2803 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2804 {
2805 update_visitor::visit_pre_crement(new pre_crement(*e));
2806 }
2807
2808 void
2809 deep_copy_visitor::visit_post_crement (post_crement* e)
2810 {
2811 update_visitor::visit_post_crement(new post_crement(*e));
2812 }
2813
2814
2815 void
2816 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2817 {
2818 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2819 }
2820
2821 void
2822 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2823 {
2824 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2825 }
2826
2827 void
2828 deep_copy_visitor::visit_array_in (array_in* e)
2829 {
2830 update_visitor::visit_array_in(new array_in(*e));
2831 }
2832
2833 void
2834 deep_copy_visitor::visit_comparison (comparison* e)
2835 {
2836 update_visitor::visit_comparison(new comparison(*e));
2837 }
2838
2839 void
2840 deep_copy_visitor::visit_concatenation (concatenation* e)
2841 {
2842 update_visitor::visit_concatenation(new concatenation(*e));
2843 }
2844
2845 void
2846 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2847 {
2848 update_visitor::visit_ternary_expression(new ternary_expression(*e));
2849 }
2850
2851 void
2852 deep_copy_visitor::visit_assignment (assignment* e)
2853 {
2854 update_visitor::visit_assignment(new assignment(*e));
2855 }
2856
2857 void
2858 deep_copy_visitor::visit_symbol (symbol* e)
2859 {
2860 symbol* n = new symbol(*e);
2861 n->referent = NULL; // don't copy!
2862 update_visitor::visit_symbol(n);
2863 }
2864
2865 void
2866 deep_copy_visitor::visit_target_symbol (target_symbol* e)
2867 {
2868 target_symbol* n = new target_symbol(*e);
2869 n->referent = NULL; // don't copy!
2870 update_visitor::visit_target_symbol(n);
2871 }
2872
2873 void
2874 deep_copy_visitor::visit_cast_op (cast_op* e)
2875 {
2876 update_visitor::visit_cast_op(new cast_op(*e));
2877 }
2878
2879 void
2880 deep_copy_visitor::visit_defined_op (defined_op* e)
2881 {
2882 update_visitor::visit_defined_op(new defined_op(*e));
2883 }
2884
2885 void
2886 deep_copy_visitor::visit_arrayindex (arrayindex* e)
2887 {
2888 update_visitor::visit_arrayindex(new arrayindex(*e));
2889 }
2890
2891 void
2892 deep_copy_visitor::visit_functioncall (functioncall* e)
2893 {
2894 functioncall* n = new functioncall(*e);
2895 n->referent = NULL; // don't copy!
2896 update_visitor::visit_functioncall(n);
2897 }
2898
2899 void
2900 deep_copy_visitor::visit_print_format (print_format* e)
2901 {
2902 update_visitor::visit_print_format(new print_format(*e));
2903 }
2904
2905 void
2906 deep_copy_visitor::visit_stat_op (stat_op* e)
2907 {
2908 update_visitor::visit_stat_op(new stat_op(*e));
2909 }
2910
2911 void
2912 deep_copy_visitor::visit_hist_op (hist_op* e)
2913 {
2914 update_visitor::visit_hist_op(new hist_op(*e));
2915 }
2916
2917 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.153304 seconds and 6 git commands to generate.