]> sourceware.org Git - systemtap.git/blob - staptree.cxx
PR3823: Adding gettext functionality to several base files
[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 (_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)
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 if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1574 throw semantic_error(_("Expecting symbol or histogram operator"), ix->get_tok());
1575 if (ix && !(hist_out || array_out))
1576 throw semantic_error(_("Failed to classify indexable"), ix->get_tok());
1577 }
1578
1579 void
1580 classify_const_indexable(const indexable* ix,
1581 const symbol *& array_out,
1582 const hist_op *& hist_out)
1583 {
1584 array_out = NULL;
1585 hist_out = NULL;
1586 if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
1587 throw semantic_error(_("Expecting symbol or histogram operator"), ix->get_tok());
1588 }
1589
1590 // ------------------------------------------------------------------------
1591
1592 bool
1593 visitor::is_active_lvalue(expression *e)
1594 {
1595 for (unsigned i = 0; i < active_lvalues.size(); ++i)
1596 {
1597 if (active_lvalues[i] == e)
1598 return true;
1599 }
1600 return false;
1601 }
1602
1603 void
1604 visitor::push_active_lvalue(expression *e)
1605 {
1606 active_lvalues.push_back(e);
1607 }
1608
1609 void
1610 visitor::pop_active_lvalue()
1611 {
1612 assert(!active_lvalues.empty());
1613 active_lvalues.pop_back();
1614 }
1615
1616
1617
1618 // ------------------------------------------------------------------------
1619
1620 void
1621 traversing_visitor::visit_block (block* s)
1622 {
1623 for (unsigned i=0; i<s->statements.size(); i++)
1624 s->statements[i]->visit (this);
1625 }
1626
1627 void
1628 traversing_visitor::visit_try_block (try_block* s)
1629 {
1630 if (s->try_block)
1631 s->try_block->visit (this);
1632 if (s->catch_error_var)
1633 s->catch_error_var->visit (this);
1634 if (s->catch_block)
1635 s->catch_block->visit (this);
1636 }
1637
1638 void
1639 traversing_visitor::visit_embeddedcode (embeddedcode*)
1640 {
1641 }
1642
1643 void
1644 traversing_visitor::visit_null_statement (null_statement*)
1645 {
1646 }
1647
1648 void
1649 traversing_visitor::visit_expr_statement (expr_statement* s)
1650 {
1651 s->value->visit (this);
1652 }
1653
1654 void
1655 traversing_visitor::visit_if_statement (if_statement* s)
1656 {
1657 s->condition->visit (this);
1658 s->thenblock->visit (this);
1659 if (s->elseblock)
1660 s->elseblock->visit (this);
1661 }
1662
1663 void
1664 traversing_visitor::visit_for_loop (for_loop* s)
1665 {
1666 if (s->init) s->init->visit (this);
1667 s->cond->visit (this);
1668 if (s->incr) s->incr->visit (this);
1669 s->block->visit (this);
1670 }
1671
1672 void
1673 traversing_visitor::visit_foreach_loop (foreach_loop* s)
1674 {
1675 symbol *array = NULL;
1676 hist_op *hist = NULL;
1677 classify_indexable (s->base, array, hist);
1678 if (array)
1679 array->visit(this);
1680 else
1681 hist->visit(this);
1682
1683 for (unsigned i=0; i<s->indexes.size(); i++)
1684 s->indexes[i]->visit (this);
1685
1686 if (s->value)
1687 s->value->visit (this);
1688
1689 if (s->limit)
1690 s->limit->visit (this);
1691
1692 s->block->visit (this);
1693 }
1694
1695 void
1696 traversing_visitor::visit_return_statement (return_statement* s)
1697 {
1698 s->value->visit (this);
1699 }
1700
1701 void
1702 traversing_visitor::visit_delete_statement (delete_statement* s)
1703 {
1704 s->value->visit (this);
1705 }
1706
1707 void
1708 traversing_visitor::visit_next_statement (next_statement*)
1709 {
1710 }
1711
1712 void
1713 traversing_visitor::visit_break_statement (break_statement*)
1714 {
1715 }
1716
1717 void
1718 traversing_visitor::visit_continue_statement (continue_statement*)
1719 {
1720 }
1721
1722 void
1723 traversing_visitor::visit_literal_string (literal_string*)
1724 {
1725 }
1726
1727 void
1728 traversing_visitor::visit_literal_number (literal_number*)
1729 {
1730 }
1731
1732 void
1733 traversing_visitor::visit_embedded_expr (embedded_expr*)
1734 {
1735 }
1736
1737 void
1738 traversing_visitor::visit_binary_expression (binary_expression* e)
1739 {
1740 e->left->visit (this);
1741 e->right->visit (this);
1742 }
1743
1744 void
1745 traversing_visitor::visit_unary_expression (unary_expression* e)
1746 {
1747 e->operand->visit (this);
1748 }
1749
1750 void
1751 traversing_visitor::visit_pre_crement (pre_crement* e)
1752 {
1753 e->operand->visit (this);
1754 }
1755
1756 void
1757 traversing_visitor::visit_post_crement (post_crement* e)
1758 {
1759 e->operand->visit (this);
1760 }
1761
1762
1763 void
1764 traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1765 {
1766 e->left->visit (this);
1767 e->right->visit (this);
1768 }
1769
1770 void
1771 traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1772 {
1773 e->left->visit (this);
1774 e->right->visit (this);
1775 }
1776
1777 void
1778 traversing_visitor::visit_array_in (array_in* e)
1779 {
1780 e->operand->visit (this);
1781 }
1782
1783 void
1784 traversing_visitor::visit_comparison (comparison* e)
1785 {
1786 e->left->visit (this);
1787 e->right->visit (this);
1788 }
1789
1790 void
1791 traversing_visitor::visit_concatenation (concatenation* e)
1792 {
1793 e->left->visit (this);
1794 e->right->visit (this);
1795 }
1796
1797 void
1798 traversing_visitor::visit_ternary_expression (ternary_expression* e)
1799 {
1800 e->cond->visit (this);
1801 e->truevalue->visit (this);
1802 e->falsevalue->visit (this);
1803 }
1804
1805 void
1806 traversing_visitor::visit_assignment (assignment* e)
1807 {
1808 e->left->visit (this);
1809 e->right->visit (this);
1810 }
1811
1812 void
1813 traversing_visitor::visit_symbol (symbol*)
1814 {
1815 }
1816
1817 void
1818 traversing_visitor::visit_target_symbol (target_symbol* e)
1819 {
1820 e->visit_components (this);
1821 }
1822
1823 void
1824 traversing_visitor::visit_cast_op (cast_op* e)
1825 {
1826 e->operand->visit (this);
1827 e->visit_components (this);
1828 }
1829
1830 void
1831 traversing_visitor::visit_defined_op (defined_op* e)
1832 {
1833 e->operand->visit (this);
1834 }
1835
1836 void
1837 traversing_visitor::visit_entry_op (entry_op* e)
1838 {
1839 e->operand->visit (this);
1840 }
1841
1842
1843 void
1844 traversing_visitor::visit_arrayindex (arrayindex* e)
1845 {
1846 for (unsigned i=0; i<e->indexes.size(); i++)
1847 e->indexes[i]->visit (this);
1848
1849 symbol *array = NULL;
1850 hist_op *hist = NULL;
1851 classify_indexable(e->base, array, hist);
1852 if (array)
1853 return array->visit(this);
1854 else
1855 return hist->visit(this);
1856 }
1857
1858 void
1859 traversing_visitor::visit_functioncall (functioncall* e)
1860 {
1861 for (unsigned i=0; i<e->args.size(); i++)
1862 e->args[i]->visit (this);
1863 }
1864
1865 void
1866 traversing_visitor::visit_print_format (print_format* e)
1867 {
1868 for (unsigned i=0; i<e->args.size(); i++)
1869 e->args[i]->visit (this);
1870 if (e->hist)
1871 e->hist->visit(this);
1872 }
1873
1874 void
1875 traversing_visitor::visit_stat_op (stat_op* e)
1876 {
1877 e->stat->visit (this);
1878 }
1879
1880 void
1881 traversing_visitor::visit_hist_op (hist_op* e)
1882 {
1883 e->stat->visit (this);
1884 }
1885
1886
1887 void
1888 functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1889 {
1890 traversing_visitor::visit_functioncall (e);
1891
1892 // prevent infinite recursion
1893 if (traversed.find (e->referent) == traversed.end ())
1894 {
1895 traversed.insert (e->referent);
1896 // recurse
1897 functiondecl* last_current_function = current_function;
1898 current_function = e->referent;
1899 e->referent->body->visit (this);
1900 current_function = last_current_function;
1901 }
1902 }
1903
1904
1905 void
1906 varuse_collecting_visitor::visit_try_block (try_block *s)
1907 {
1908 if (s->try_block)
1909 s->try_block->visit (this);
1910 if (s->catch_error_var)
1911 written.insert (s->catch_error_var->referent);
1912 if (s->catch_block)
1913 s->catch_block->visit (this);
1914
1915 // NB: don't functioncall_traversing_visitor::visit_try_block (s);
1916 // since that would count s->catch_error_var as a read also.
1917 }
1918
1919
1920 void
1921 varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1922 {
1923 assert (current_function); // only they get embedded code
1924
1925 // Don't allow embedded C functions in unprivileged mode unless
1926 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1927 if (session.unprivileged &&
1928 s->code.find ("/* unprivileged */") == string::npos &&
1929 s->code.find ("/* myproc-unprivileged */") == string::npos)
1930 throw semantic_error (_("function may not be used when --unprivileged is specified"),
1931 current_function->tok);
1932
1933 // Don't allow /* guru */ functions unless -g is active.
1934 if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
1935 throw semantic_error (_("function may not be used unless -g is specified"),
1936 current_function->tok);
1937
1938 // We want to elide embedded-C functions when possible. For
1939 // example, each $target variable access is expanded to an
1940 // embedded-C function call. Yet, for safety reasons, we should
1941 // presume that embedded-C functions have intentional side-effects.
1942 //
1943 // To tell these two types of functions apart, we apply a
1944 // Kludge(tm): we look for a magic string within the function body.
1945 // $target variables as rvalues will have this; lvalues won't.
1946 // Also, explicit side-effect-free tapset functions will have this.
1947
1948 if (s->code.find ("/* pure */") != string::npos)
1949 return;
1950
1951 embedded_seen = true;
1952 }
1953
1954
1955 // About the same case as above.
1956 void
1957 varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1958 {
1959 // Don't allow embedded C functions in unprivileged mode unless
1960 // they are tagged with /* unprivileged */
1961 if (session.unprivileged &&
1962 e->code.find ("/* unprivileged */") == string::npos &&
1963 e->code.find ("/* myproc-unprivileged */") == string::npos)
1964 throw semantic_error (_("embedded expression may not be used when --unprivileged is specified"),
1965 e->tok);
1966
1967 // Don't allow /* guru */ functions unless -g is active.
1968 if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
1969 throw semantic_error (_("embedded expression may not be used unless -g is specified"),
1970 e->tok);
1971
1972 // We want to elide embedded-C functions when possible. For
1973 // example, each $target variable access is expanded to an
1974 // embedded-C function call. Yet, for safety reasons, we should
1975 // presume that embedded-C functions have intentional side-effects.
1976 //
1977 // To tell these two types of functions apart, we apply a
1978 // Kludge(tm): we look for a magic string within the function body.
1979 // $target variables as rvalues will have this; lvalues won't.
1980 // Also, explicit side-effect-free tapset functions will have this.
1981
1982 if (e->code.find ("/* pure */") != string::npos)
1983 return;
1984
1985 embedded_seen = true;
1986 }
1987
1988
1989 void
1990 varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1991 {
1992 // Still-unresolved target symbol assignments get treated as
1993 // generating side-effects like embedded-C, to prevent premature
1994 // elision and later error message suppression (PR5516). rvalue use
1995 // of unresolved target symbols is OTOH not considered a side-effect.
1996
1997 if (is_active_lvalue (e))
1998 embedded_seen = true;
1999
2000 functioncall_traversing_visitor::visit_target_symbol (e);
2001 }
2002
2003 void
2004 varuse_collecting_visitor::visit_cast_op (cast_op *e)
2005 {
2006 // As with target_symbols, unresolved cast assignments need to preserved
2007 // for later error handling.
2008 if (is_active_lvalue (e))
2009 embedded_seen = true;
2010
2011 functioncall_traversing_visitor::visit_cast_op (e);
2012 }
2013
2014 void
2015 varuse_collecting_visitor::visit_defined_op (defined_op *e)
2016 {
2017 // XXX
2018 functioncall_traversing_visitor::visit_defined_op (e);
2019 }
2020
2021 void
2022 varuse_collecting_visitor::visit_entry_op (entry_op *e)
2023 {
2024 // XXX
2025 functioncall_traversing_visitor::visit_entry_op (e);
2026 }
2027
2028
2029 void
2030 varuse_collecting_visitor::visit_print_format (print_format* e)
2031 {
2032 // NB: Instead of being top-level statements, "print" and "printf"
2033 // are implemented as statement-expressions containing a
2034 // print_format. They have side-effects, but not via the
2035 // embedded-code detection method above.
2036 //
2037 // But sprint and sprintf don't have side-effects.
2038
2039 if (e->print_to_stream)
2040 embedded_seen = true; // a proxy for "has unknown side-effects"
2041
2042 functioncall_traversing_visitor::visit_print_format (e);
2043 }
2044
2045
2046 void
2047 varuse_collecting_visitor::visit_assignment (assignment *e)
2048 {
2049 if (e->op == "=" || e->op == "<<<") // pure writes
2050 {
2051 expression* last_lvalue = current_lvalue;
2052 current_lvalue = e->left; // leave a mark for ::visit_symbol
2053 functioncall_traversing_visitor::visit_assignment (e);
2054 current_lvalue = last_lvalue;
2055 }
2056 else // read-modify-writes
2057 {
2058 expression* last_lrvalue = current_lrvalue;
2059 current_lrvalue = e->left; // leave a mark for ::visit_symbol
2060 functioncall_traversing_visitor::visit_assignment (e);
2061 current_lrvalue = last_lrvalue;
2062 }
2063 }
2064
2065 void
2066 varuse_collecting_visitor::visit_symbol (symbol *e)
2067 {
2068 if (e->referent == 0)
2069 throw semantic_error (_("symbol without referent"), e->tok);
2070
2071 // We could handle initialized globals by marking them as "written".
2072 // However, this current visitor may be called for a function or
2073 // probe body, from the point of view of which this global is
2074 // already initialized, so not written.
2075 /*
2076 if (e->referent->init)
2077 written.insert (e->referent);
2078 */
2079
2080 if (current_lvalue == e || current_lrvalue == e)
2081 {
2082 written.insert (e->referent);
2083 // clog << "write ";
2084 }
2085 if (current_lvalue != e || current_lrvalue == e)
2086 {
2087 read.insert (e->referent);
2088 // clog << "read ";
2089 }
2090 // clog << *e->tok << endl;
2091 }
2092
2093 // NB: stat_op need not be overridden, since it will get to
2094 // visit_symbol and only as a possible rvalue.
2095
2096
2097 void
2098 varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2099 {
2100 // Hooking this callback is necessary because of the hacky
2101 // statistics representation. For the expression "i[4] = 5", the
2102 // incoming lvalue will point to this arrayindex. However, the
2103 // symbol corresponding to the "i[4]" is multiply inherited with
2104 // arrayindex. If the symbol base part of this object is not at
2105 // offset 0, then static_cast<symbol*>(e) may result in a different
2106 // address, and not match lvalue by number when we recurse that way.
2107 // So we explicitly override the incoming lvalue/lrvalue values to
2108 // point at the embedded objects' actual base addresses.
2109
2110 expression* last_lrvalue = current_lrvalue;
2111 expression* last_lvalue = current_lvalue;
2112
2113 symbol *array = NULL;
2114 hist_op *hist = NULL;
2115 classify_indexable(e->base, array, hist);
2116
2117 if (array)
2118 {
2119 if (current_lrvalue == e) current_lrvalue = array;
2120 if (current_lvalue == e) current_lvalue = array;
2121 functioncall_traversing_visitor::visit_arrayindex (e);
2122 }
2123 else // if (hist)
2124 {
2125 if (current_lrvalue == e) current_lrvalue = hist->stat;
2126 if (current_lvalue == e) current_lvalue = hist->stat;
2127 functioncall_traversing_visitor::visit_arrayindex (e);
2128 }
2129
2130 current_lrvalue = last_lrvalue;
2131 current_lvalue = last_lvalue;
2132 }
2133
2134
2135 void
2136 varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2137 {
2138 expression* last_lrvalue = current_lrvalue;
2139 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2140 functioncall_traversing_visitor::visit_pre_crement (e);
2141 current_lrvalue = last_lrvalue;
2142 }
2143
2144 void
2145 varuse_collecting_visitor::visit_post_crement (post_crement *e)
2146 {
2147 expression* last_lrvalue = current_lrvalue;
2148 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2149 functioncall_traversing_visitor::visit_post_crement (e);
2150 current_lrvalue = last_lrvalue;
2151 }
2152
2153 void
2154 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2155 {
2156 // NB: we duplicate so don't bother call
2157 // functioncall_traversing_visitor::visit_foreach_loop (s);
2158
2159 symbol *array = NULL;
2160 hist_op *hist = NULL;
2161 classify_indexable (s->base, array, hist);
2162 if (array)
2163 array->visit(this);
2164 else
2165 hist->visit(this);
2166
2167 // If the collection is sorted, imply a "write" access to the
2168 // array in addition to the "read" one already noted above.
2169 if (s->sort_direction)
2170 {
2171 symbol *array = NULL;
2172 hist_op *hist = NULL;
2173 classify_indexable (s->base, array, hist);
2174 if (array) this->written.insert (array->referent);
2175 // XXX: Can hist_op iterations be sorted?
2176 }
2177
2178 // NB: don't forget to visit the index expressions, which are lvalues.
2179 for (unsigned i=0; i<s->indexes.size(); i++)
2180 {
2181 expression* last_lvalue = current_lvalue;
2182 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2183 s->indexes[i]->visit (this);
2184 current_lvalue = last_lvalue;
2185 }
2186
2187 // The value is an lvalue too
2188 if (s->value)
2189 {
2190 expression* last_lvalue = current_lvalue;
2191 current_lvalue = s->value; // leave a mark for ::visit_symbol
2192 s->value->visit (this);
2193 current_lvalue = last_lvalue;
2194 }
2195
2196 if (s->limit)
2197 s->limit->visit (this);
2198
2199 s->block->visit (this);
2200 }
2201
2202
2203 void
2204 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2205 {
2206 // Ideally, this would be treated like an assignment: a plain write
2207 // to the underlying value ("lvalue"). XXX: However, the
2208 // optimization pass is not smart enough to remove an unneeded
2209 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2210 // should protect the underlying value from optimizional mischief.
2211 expression* last_lrvalue = current_lrvalue;
2212 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2213 functioncall_traversing_visitor::visit_delete_statement (s);
2214 current_lrvalue = last_lrvalue;
2215 }
2216
2217 bool
2218 varuse_collecting_visitor::side_effect_free ()
2219 {
2220 return (written.empty() && !embedded_seen);
2221 }
2222
2223
2224 bool
2225 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2226 {
2227 // A looser notion of side-effect-freeness with respect to a given
2228 // list of variables.
2229
2230 // That's useful because the written list may consist of local
2231 // variables of called functions. But visible side-effects only
2232 // occur if the client's locals, or any globals are written-to.
2233
2234 set<vardecl*> intersection;
2235 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2236 set_intersection (written.begin(), written.end(),
2237 vars.begin(), vars.end(),
2238 int_it);
2239
2240 return (intersection.empty() && !embedded_seen);
2241 }
2242
2243
2244
2245
2246 // ------------------------------------------------------------------------
2247
2248
2249 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2250 throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2251
2252
2253 void
2254 throwing_visitor::throwone (const token* t)
2255 {
2256 throw semantic_error (msg, t);
2257 }
2258
2259 void
2260 throwing_visitor::visit_block (block* s)
2261 {
2262 throwone (s->tok);
2263 }
2264
2265 void
2266 throwing_visitor::visit_try_block (try_block* s)
2267 {
2268 throwone (s->tok);
2269 }
2270
2271
2272 void
2273 throwing_visitor::visit_embeddedcode (embeddedcode* s)
2274 {
2275 throwone (s->tok);
2276 }
2277
2278 void
2279 throwing_visitor::visit_null_statement (null_statement* s)
2280 {
2281 throwone (s->tok);
2282 }
2283
2284 void
2285 throwing_visitor::visit_expr_statement (expr_statement* s)
2286 {
2287 throwone (s->tok);
2288 }
2289
2290 void
2291 throwing_visitor::visit_if_statement (if_statement* s)
2292 {
2293 throwone (s->tok);
2294 }
2295
2296 void
2297 throwing_visitor::visit_for_loop (for_loop* s)
2298 {
2299 throwone (s->tok);
2300 }
2301
2302 void
2303 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2304 {
2305 throwone (s->tok);
2306 }
2307
2308 void
2309 throwing_visitor::visit_return_statement (return_statement* s)
2310 {
2311 throwone (s->tok);
2312 }
2313
2314 void
2315 throwing_visitor::visit_delete_statement (delete_statement* s)
2316 {
2317 throwone (s->tok);
2318 }
2319
2320 void
2321 throwing_visitor::visit_next_statement (next_statement* s)
2322 {
2323 throwone (s->tok);
2324 }
2325
2326 void
2327 throwing_visitor::visit_break_statement (break_statement* s)
2328 {
2329 throwone (s->tok);
2330 }
2331
2332 void
2333 throwing_visitor::visit_continue_statement (continue_statement* s)
2334 {
2335 throwone (s->tok);
2336 }
2337
2338 void
2339 throwing_visitor::visit_literal_string (literal_string* e)
2340 {
2341 throwone (e->tok);
2342 }
2343
2344 void
2345 throwing_visitor::visit_literal_number (literal_number* e)
2346 {
2347 throwone (e->tok);
2348 }
2349
2350 void
2351 throwing_visitor::visit_embedded_expr (embedded_expr* e)
2352 {
2353 throwone (e->tok);
2354 }
2355
2356 void
2357 throwing_visitor::visit_binary_expression (binary_expression* e)
2358 {
2359 throwone (e->tok);
2360 }
2361
2362 void
2363 throwing_visitor::visit_unary_expression (unary_expression* e)
2364 {
2365 throwone (e->tok);
2366 }
2367
2368 void
2369 throwing_visitor::visit_pre_crement (pre_crement* e)
2370 {
2371 throwone (e->tok);
2372 }
2373
2374 void
2375 throwing_visitor::visit_post_crement (post_crement* e)
2376 {
2377 throwone (e->tok);
2378 }
2379
2380
2381 void
2382 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2383 {
2384 throwone (e->tok);
2385 }
2386
2387 void
2388 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2389 {
2390 throwone (e->tok);
2391 }
2392
2393 void
2394 throwing_visitor::visit_array_in (array_in* e)
2395 {
2396 throwone (e->tok);
2397 }
2398
2399 void
2400 throwing_visitor::visit_comparison (comparison* e)
2401 {
2402 throwone (e->tok);
2403 }
2404
2405 void
2406 throwing_visitor::visit_concatenation (concatenation* e)
2407 {
2408 throwone (e->tok);
2409 }
2410
2411 void
2412 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2413 {
2414 throwone (e->tok);
2415 }
2416
2417 void
2418 throwing_visitor::visit_assignment (assignment* e)
2419 {
2420 throwone (e->tok);
2421 }
2422
2423 void
2424 throwing_visitor::visit_symbol (symbol* e)
2425 {
2426 throwone (e->tok);
2427 }
2428
2429 void
2430 throwing_visitor::visit_target_symbol (target_symbol* e)
2431 {
2432 throwone (e->tok);
2433 }
2434
2435 void
2436 throwing_visitor::visit_cast_op (cast_op* e)
2437 {
2438 throwone (e->tok);
2439 }
2440
2441 void
2442 throwing_visitor::visit_defined_op (defined_op* e)
2443 {
2444 throwone (e->tok);
2445 }
2446
2447 void
2448 throwing_visitor::visit_entry_op (entry_op* e)
2449 {
2450 throwone (e->tok);
2451 }
2452
2453
2454 void
2455 throwing_visitor::visit_arrayindex (arrayindex* e)
2456 {
2457 throwone (e->tok);
2458 }
2459
2460 void
2461 throwing_visitor::visit_functioncall (functioncall* e)
2462 {
2463 throwone (e->tok);
2464 }
2465
2466 void
2467 throwing_visitor::visit_print_format (print_format* e)
2468 {
2469 throwone (e->tok);
2470 }
2471
2472 void
2473 throwing_visitor::visit_stat_op (stat_op* e)
2474 {
2475 throwone (e->tok);
2476 }
2477
2478 void
2479 throwing_visitor::visit_hist_op (hist_op* e)
2480 {
2481 throwone (e->tok);
2482 }
2483
2484
2485 // ------------------------------------------------------------------------
2486
2487
2488 void
2489 update_visitor::visit_block (block* s)
2490 {
2491 for (unsigned i = 0; i < s->statements.size(); ++i)
2492 replace (s->statements[i]);
2493 provide (s);
2494 }
2495
2496 void
2497 update_visitor::visit_try_block (try_block* s)
2498 {
2499 replace (s->try_block);
2500 replace (s->catch_error_var);
2501 replace (s->catch_block);
2502 provide (s);
2503 }
2504
2505 void
2506 update_visitor::visit_embeddedcode (embeddedcode* s)
2507 {
2508 provide (s);
2509 }
2510
2511 void
2512 update_visitor::visit_null_statement (null_statement* s)
2513 {
2514 provide (s);
2515 }
2516
2517 void
2518 update_visitor::visit_expr_statement (expr_statement* s)
2519 {
2520 replace (s->value);
2521 provide (s);
2522 }
2523
2524 void
2525 update_visitor::visit_if_statement (if_statement* s)
2526 {
2527 replace (s->condition);
2528 replace (s->thenblock);
2529 replace (s->elseblock);
2530 provide (s);
2531 }
2532
2533 void
2534 update_visitor::visit_for_loop (for_loop* s)
2535 {
2536 replace (s->init);
2537 replace (s->cond);
2538 replace (s->incr);
2539 replace (s->block);
2540 provide (s);
2541 }
2542
2543 void
2544 update_visitor::visit_foreach_loop (foreach_loop* s)
2545 {
2546 for (unsigned i = 0; i < s->indexes.size(); ++i)
2547 replace (s->indexes[i]);
2548 replace (s->base);
2549 replace (s->value);
2550 replace (s->limit);
2551 replace (s->block);
2552 provide (s);
2553 }
2554
2555 void
2556 update_visitor::visit_return_statement (return_statement* s)
2557 {
2558 replace (s->value);
2559 provide (s);
2560 }
2561
2562 void
2563 update_visitor::visit_delete_statement (delete_statement* s)
2564 {
2565 replace (s->value);
2566 provide (s);
2567 }
2568
2569 void
2570 update_visitor::visit_next_statement (next_statement* s)
2571 {
2572 provide (s);
2573 }
2574
2575 void
2576 update_visitor::visit_break_statement (break_statement* s)
2577 {
2578 provide (s);
2579 }
2580
2581 void
2582 update_visitor::visit_continue_statement (continue_statement* s)
2583 {
2584 provide (s);
2585 }
2586
2587 void
2588 update_visitor::visit_literal_string (literal_string* e)
2589 {
2590 provide (e);
2591 }
2592
2593 void
2594 update_visitor::visit_literal_number (literal_number* e)
2595 {
2596 provide (e);
2597 }
2598
2599 void
2600 update_visitor::visit_embedded_expr (embedded_expr* e)
2601 {
2602 provide (e);
2603 }
2604
2605 void
2606 update_visitor::visit_binary_expression (binary_expression* e)
2607 {
2608 replace (e->left);
2609 replace (e->right);
2610 provide (e);
2611 }
2612
2613 void
2614 update_visitor::visit_unary_expression (unary_expression* e)
2615 {
2616 replace (e->operand);
2617 provide (e);
2618 }
2619
2620 void
2621 update_visitor::visit_pre_crement (pre_crement* e)
2622 {
2623 replace (e->operand);
2624 provide (e);
2625 }
2626
2627 void
2628 update_visitor::visit_post_crement (post_crement* e)
2629 {
2630 replace (e->operand);
2631 provide (e);
2632 }
2633
2634
2635 void
2636 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2637 {
2638 replace (e->left);
2639 replace (e->right);
2640 provide (e);
2641 }
2642
2643 void
2644 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2645 {
2646 replace (e->left);
2647 replace (e->right);
2648 provide (e);
2649 }
2650
2651 void
2652 update_visitor::visit_array_in (array_in* e)
2653 {
2654 replace (e->operand);
2655 provide (e);
2656 }
2657
2658 void
2659 update_visitor::visit_comparison (comparison* e)
2660 {
2661 replace (e->left);
2662 replace (e->right);
2663 provide (e);
2664 }
2665
2666 void
2667 update_visitor::visit_concatenation (concatenation* e)
2668 {
2669 replace (e->left);
2670 replace (e->right);
2671 provide (e);
2672 }
2673
2674 void
2675 update_visitor::visit_ternary_expression (ternary_expression* e)
2676 {
2677 replace (e->cond);
2678 replace (e->truevalue);
2679 replace (e->falsevalue);
2680 provide (e);
2681 }
2682
2683 void
2684 update_visitor::visit_assignment (assignment* e)
2685 {
2686 replace (e->left);
2687 replace (e->right);
2688 provide (e);
2689 }
2690
2691 void
2692 update_visitor::visit_symbol (symbol* e)
2693 {
2694 provide (e);
2695 }
2696
2697 void
2698 update_visitor::visit_target_symbol (target_symbol* e)
2699 {
2700 e->visit_components (this);
2701 provide (e);
2702 }
2703
2704 void
2705 update_visitor::visit_cast_op (cast_op* e)
2706 {
2707 replace (e->operand);
2708 e->visit_components (this);
2709 provide (e);
2710 }
2711
2712 void
2713 update_visitor::visit_defined_op (defined_op* e)
2714 {
2715 replace (e->operand);
2716 provide (e);
2717 }
2718
2719 void
2720 update_visitor::visit_entry_op (entry_op* e)
2721 {
2722 replace (e->operand);
2723 provide (e);
2724 }
2725
2726 void
2727 update_visitor::visit_arrayindex (arrayindex* e)
2728 {
2729 replace (e->base);
2730 for (unsigned i = 0; i < e->indexes.size(); ++i)
2731 replace (e->indexes[i]);
2732 provide (e);
2733 }
2734
2735 void
2736 update_visitor::visit_functioncall (functioncall* e)
2737 {
2738 for (unsigned i = 0; i < e->args.size(); ++i)
2739 replace (e->args[i]);
2740 provide (e);
2741 }
2742
2743 void
2744 update_visitor::visit_print_format (print_format* e)
2745 {
2746 for (unsigned i = 0; i < e->args.size(); ++i)
2747 replace (e->args[i]);
2748 replace (e->hist);
2749 provide (e);
2750 }
2751
2752 void
2753 update_visitor::visit_stat_op (stat_op* e)
2754 {
2755 replace (e->stat);
2756 provide (e);
2757 }
2758
2759 void
2760 update_visitor::visit_hist_op (hist_op* e)
2761 {
2762 replace (e->stat);
2763 provide (e);
2764 }
2765
2766 template <> indexable*
2767 update_visitor::require <indexable> (indexable* src, bool clearok)
2768 {
2769 indexable *dst = NULL;
2770 if (src != NULL)
2771 {
2772 symbol *array_src=NULL;
2773 hist_op *hist_src=NULL;
2774
2775 classify_indexable(src, array_src, hist_src);
2776
2777 if (array_src)
2778 dst = require (array_src);
2779 else
2780 dst = require (hist_src);
2781 assert(clearok || dst);
2782 }
2783 return dst;
2784 }
2785
2786
2787 // ------------------------------------------------------------------------
2788
2789
2790 void
2791 deep_copy_visitor::visit_block (block* s)
2792 {
2793 update_visitor::visit_block(new block(*s));
2794 }
2795
2796 void
2797 deep_copy_visitor::visit_try_block (try_block* s)
2798 {
2799 update_visitor::visit_try_block(new try_block(*s));
2800 }
2801
2802 void
2803 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2804 {
2805 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2806 }
2807
2808 void
2809 deep_copy_visitor::visit_null_statement (null_statement* s)
2810 {
2811 update_visitor::visit_null_statement(new null_statement(*s));
2812 }
2813
2814 void
2815 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2816 {
2817 update_visitor::visit_expr_statement(new expr_statement(*s));
2818 }
2819
2820 void
2821 deep_copy_visitor::visit_if_statement (if_statement* s)
2822 {
2823 update_visitor::visit_if_statement(new if_statement(*s));
2824 }
2825
2826 void
2827 deep_copy_visitor::visit_for_loop (for_loop* s)
2828 {
2829 update_visitor::visit_for_loop(new for_loop(*s));
2830 }
2831
2832 void
2833 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2834 {
2835 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2836 }
2837
2838 void
2839 deep_copy_visitor::visit_return_statement (return_statement* s)
2840 {
2841 update_visitor::visit_return_statement(new return_statement(*s));
2842 }
2843
2844 void
2845 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2846 {
2847 update_visitor::visit_delete_statement(new delete_statement(*s));
2848 }
2849
2850 void
2851 deep_copy_visitor::visit_next_statement (next_statement* s)
2852 {
2853 update_visitor::visit_next_statement(new next_statement(*s));
2854 }
2855
2856 void
2857 deep_copy_visitor::visit_break_statement (break_statement* s)
2858 {
2859 update_visitor::visit_break_statement(new break_statement(*s));
2860 }
2861
2862 void
2863 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2864 {
2865 update_visitor::visit_continue_statement(new continue_statement(*s));
2866 }
2867
2868 void
2869 deep_copy_visitor::visit_literal_string (literal_string* e)
2870 {
2871 update_visitor::visit_literal_string(new literal_string(*e));
2872 }
2873
2874 void
2875 deep_copy_visitor::visit_literal_number (literal_number* e)
2876 {
2877 update_visitor::visit_literal_number(new literal_number(*e));
2878 }
2879
2880 void
2881 deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2882 {
2883 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2884 }
2885
2886 void
2887 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2888 {
2889 update_visitor::visit_binary_expression(new binary_expression(*e));
2890 }
2891
2892 void
2893 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2894 {
2895 update_visitor::visit_unary_expression(new unary_expression(*e));
2896 }
2897
2898 void
2899 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2900 {
2901 update_visitor::visit_pre_crement(new pre_crement(*e));
2902 }
2903
2904 void
2905 deep_copy_visitor::visit_post_crement (post_crement* e)
2906 {
2907 update_visitor::visit_post_crement(new post_crement(*e));
2908 }
2909
2910
2911 void
2912 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2913 {
2914 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2915 }
2916
2917 void
2918 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2919 {
2920 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2921 }
2922
2923 void
2924 deep_copy_visitor::visit_array_in (array_in* e)
2925 {
2926 update_visitor::visit_array_in(new array_in(*e));
2927 }
2928
2929 void
2930 deep_copy_visitor::visit_comparison (comparison* e)
2931 {
2932 update_visitor::visit_comparison(new comparison(*e));
2933 }
2934
2935 void
2936 deep_copy_visitor::visit_concatenation (concatenation* e)
2937 {
2938 update_visitor::visit_concatenation(new concatenation(*e));
2939 }
2940
2941 void
2942 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2943 {
2944 update_visitor::visit_ternary_expression(new ternary_expression(*e));
2945 }
2946
2947 void
2948 deep_copy_visitor::visit_assignment (assignment* e)
2949 {
2950 update_visitor::visit_assignment(new assignment(*e));
2951 }
2952
2953 void
2954 deep_copy_visitor::visit_symbol (symbol* e)
2955 {
2956 symbol* n = new symbol(*e);
2957 n->referent = NULL; // don't copy!
2958 update_visitor::visit_symbol(n);
2959 }
2960
2961 void
2962 deep_copy_visitor::visit_target_symbol (target_symbol* e)
2963 {
2964 target_symbol* n = new target_symbol(*e);
2965 n->referent = NULL; // don't copy!
2966 update_visitor::visit_target_symbol(n);
2967 }
2968
2969 void
2970 deep_copy_visitor::visit_cast_op (cast_op* e)
2971 {
2972 update_visitor::visit_cast_op(new cast_op(*e));
2973 }
2974
2975 void
2976 deep_copy_visitor::visit_defined_op (defined_op* e)
2977 {
2978 update_visitor::visit_defined_op(new defined_op(*e));
2979 }
2980
2981 void
2982 deep_copy_visitor::visit_entry_op (entry_op* e)
2983 {
2984 update_visitor::visit_entry_op(new entry_op(*e));
2985 }
2986
2987 void
2988 deep_copy_visitor::visit_arrayindex (arrayindex* e)
2989 {
2990 update_visitor::visit_arrayindex(new arrayindex(*e));
2991 }
2992
2993 void
2994 deep_copy_visitor::visit_functioncall (functioncall* e)
2995 {
2996 functioncall* n = new functioncall(*e);
2997 n->referent = NULL; // don't copy!
2998 update_visitor::visit_functioncall(n);
2999 }
3000
3001 void
3002 deep_copy_visitor::visit_print_format (print_format* e)
3003 {
3004 update_visitor::visit_print_format(new print_format(*e));
3005 }
3006
3007 void
3008 deep_copy_visitor::visit_stat_op (stat_op* e)
3009 {
3010 update_visitor::visit_stat_op(new stat_op(*e));
3011 }
3012
3013 void
3014 deep_copy_visitor::visit_hist_op (hist_op* e)
3015 {
3016 update_visitor::visit_hist_op(new hist_op(*e));
3017 }
3018
3019 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.164184 seconds and 6 git commands to generate.