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