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