]> sourceware.org Git - systemtap.git/blob - staptree.cxx
PR13313 cont'd, fix regexp for [+-]D[+-]D[+-]D(...) operand case
[systemtap.git] / staptree.cxx
1 // parse tree functions
2 // Copyright (C) 2005-2011 Red Hat Inc.
3 //
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
7 // later version.
8
9 #include "config.h"
10 #include "staptree.h"
11 #include "parse.h"
12 #include "util.h"
13 #include "session.h"
14
15 #include <iostream>
16 #include <typeinfo>
17 #include <sstream>
18 #include <cassert>
19 #include <cstring>
20 #include <vector>
21 #include <algorithm>
22 #include <cstring>
23
24 using namespace std;
25
26
27
28 expression::expression ():
29 type (pe_unknown), tok (0)
30 {
31 }
32
33
34 expression::~expression ()
35 {
36 }
37
38
39 statement::statement ():
40 tok (0)
41 {
42 }
43
44
45 statement::statement (const token* tok):
46 tok (tok)
47 {
48 }
49
50
51 null_statement::null_statement (const token* tok):
52 statement(tok)
53 {
54 }
55
56
57 statement::~statement ()
58 {
59 }
60
61
62 symbol::symbol ():
63 referent (0)
64 {
65 }
66
67
68 arrayindex::arrayindex ():
69 base (0)
70 {
71 }
72
73
74 functioncall::functioncall ():
75 referent (0)
76 {
77 }
78
79
80 symboldecl::symboldecl ():
81 tok (0), systemtap_v_conditional (0),
82 type (pe_unknown)
83 {
84 }
85
86
87 symboldecl::~symboldecl ()
88 {
89 }
90
91 probe_point::probe_point (std::vector<component*> const & comps):
92 components(comps), optional (false), sufficient (false),
93 condition (0)
94 {
95 }
96
97 // NB: shallow-copy of compoonents & condition!
98 probe_point::probe_point (const probe_point& pp):
99 components(pp.components), optional (pp.optional), sufficient (pp.sufficient),
100 condition (pp.condition)
101 {
102 }
103
104
105 probe_point::probe_point ():
106 optional (false), sufficient (false), condition (0)
107 {
108 }
109
110
111 unsigned probe::last_probeidx = 0;
112
113 probe::probe ():
114 body (0), tok (0), systemtap_v_conditional (0), privileged (false)
115 {
116 this->name = string ("probe_") + lex_cast(last_probeidx ++);
117 }
118
119
120 // Copy constructor, but with overriding probe-point. To be used when
121 // mapping script-level probe points to another one, early during pass
122 // 2. There should be no symbol resolution done yet.
123 probe::probe(const probe& p, probe_point* l)
124 {
125 this->name = string ("probe_") + lex_cast(last_probeidx ++);
126 this->tok = p.tok;
127 this->locations.push_back(l);
128 this->body = p.body; // NB: not needed to be copied yet; a later derived_probe will
129 this->privileged = p.privileged;
130 this->systemtap_v_conditional = p.systemtap_v_conditional;
131 assert (p.locals.size() == 0);
132 assert (p.unused_locals.size() == 0);
133 }
134
135
136 probe_point::component::component ():
137 arg (0), tok(0)
138 {
139 }
140
141
142 probe_point::component::component (std::string const & f, literal * a):
143 functor(f), arg(a), tok(0)
144 {
145 }
146
147
148 vardecl::vardecl ():
149 arity_tok(0), arity (-1), maxsize(0), init(NULL), skip_init(false), wrap(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(wrap)
427 o << "%";
428 if (maxsize > 0)
429 o << "[" << maxsize << "]";
430 if (arity > 0 || index_types.size() > 0)
431 o << "[...]";
432 if (init)
433 {
434 o << " = ";
435 init->print(o);
436 }
437 }
438
439
440 void vardecl::printsig (ostream& o) const
441 {
442 o << name;
443 if(wrap)
444 o << "%";
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->test_flag (fmt_flag_zeropad))
582 oss << '0';
583
584 if (i->test_flag (fmt_flag_plus))
585 oss << '+';
586
587 if (i->test_flag (fmt_flag_space))
588 oss << ' ';
589
590 if (i->test_flag (fmt_flag_left))
591 oss << '-';
592
593 if (i->test_flag (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_number:
617 if (i->base == 16)
618 {
619 if (i->test_flag (fmt_flag_large))
620 oss << "llX";
621 else
622 oss << "llx";
623 }
624 else if (i->base == 8)
625 oss << "llo";
626 else if (i->test_flag (fmt_flag_sign))
627 oss << "lld";
628 else
629 oss << "llu";
630 break;
631
632 case conv_pointer:
633 oss << "p";
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.set_flag (fmt_flag_zeropad);
709 ++i;
710 break;
711
712 case '+':
713 curr.set_flag (fmt_flag_plus);
714 ++i;
715 break;
716
717 case '-':
718 curr.set_flag (fmt_flag_left);
719 ++i;
720 break;
721
722 case ' ':
723 curr.set_flag (fmt_flag_space);
724 ++i;
725 break;
726
727 case '#':
728 curr.set_flag (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.set_flag (fmt_flag_sign);
827 case 'u':
828 curr.type = conv_number;
829 curr.base = 10;
830 break;
831
832 case 'o':
833 curr.type = conv_number;
834 curr.base = 8;
835 break;
836
837 case 'X':
838 curr.set_flag (fmt_flag_large);
839 case 'x':
840 curr.type = conv_number;
841 curr.base = 16;
842 break;
843
844 case 'p':
845 // Since stap 1.3, %p == %#x.
846 curr.set_flag (fmt_flag_special);
847 curr.type = conv_pointer;
848 curr.base = 16;
849 // Oddness for stap < 1.3 is handled in translation
850 break;
851
852 default:
853 break;
854 }
855
856 if (curr.type == conv_unspecified)
857 throw parse_error(_("invalid or missing conversion specifier"));
858
859 ++i;
860 res.push_back(curr);
861 curr.clear();
862 }
863
864 // If there's a remaining partly-composed conversion, fail.
865 if (!curr.is_empty())
866 {
867 if (curr.type == conv_literal)
868 res.push_back(curr);
869 else
870 throw parse_error(_("trailing incomplete print format conversion"));
871 }
872
873 return res;
874 }
875
876
877 void print_format::print (ostream& o) const
878 {
879 o << tok->content << "(";
880 if (print_with_format)
881 o << lex_cast_qstring (raw_components);
882 if (print_with_delim)
883 o << lex_cast_qstring (delimiter.literal_string);
884 if (hist)
885 hist->print(o);
886 for (vector<expression*>::const_iterator i = args.begin();
887 i != args.end(); ++i)
888 {
889 if (i != args.begin() || print_with_format || print_with_delim)
890 o << ", ";
891 (*i)->print(o);
892 }
893 o << ")";
894 }
895
896 void stat_op::print (ostream& o) const
897 {
898 o << '@';
899 switch (ctype)
900 {
901 case sc_average:
902 o << "avg(";
903 break;
904
905 case sc_count:
906 o << "count(";
907 break;
908
909 case sc_sum:
910 o << "sum(";
911 break;
912
913 case sc_min:
914 o << "min(";
915 break;
916
917 case sc_max:
918 o << "max(";
919 break;
920 }
921 stat->print(o);
922 o << ")";
923 }
924
925 void
926 hist_op::print (ostream& o) const
927 {
928 o << '@';
929 switch (htype)
930 {
931 case hist_linear:
932 assert(params.size() == 3);
933 o << "hist_linear(";
934 stat->print(o);
935 for (size_t i = 0; i < params.size(); ++i)
936 {
937 o << ", " << params[i];
938 }
939 o << ")";
940 break;
941
942 case hist_log:
943 assert(params.size() == 0);
944 o << "hist_log(";
945 stat->print(o);
946 o << ")";
947 break;
948 }
949 }
950
951 ostream& operator << (ostream& o, const statement& k)
952 {
953 k.print (o);
954 return o;
955 }
956
957
958 void embeddedcode::print (ostream &o) const
959 {
960 o << "%{";
961 o << code;
962 o << "%}";
963 }
964
965 void block::print (ostream& o) const
966 {
967 o << "{" << endl;
968 for (unsigned i=0; i<statements.size(); i++)
969 o << *statements [i] << endl;
970 o << "}";
971 }
972
973 block::block (statement* car, statement* cdr)
974 {
975 statements.push_back(car);
976 statements.push_back(cdr);
977 this->tok = car->tok;
978 }
979
980
981
982 void try_block::print (ostream& o) const
983 {
984 o << "try {" << endl;
985 if (try_block) o << *try_block << endl;
986 o << "} catch ";
987 if (catch_error_var) o << "(" << *catch_error_var << ") ";
988 o << "{" << endl;
989 if (catch_block) o << *catch_block << endl;
990 o << "}" << endl;
991 }
992
993
994 void for_loop::print (ostream& o) const
995 {
996 o << "for (";
997 if (init) init->print (o);
998 o << "; ";
999 cond->print (o);
1000 o << "; ";
1001 if (incr) incr->print (o);
1002 o << ") ";
1003 block->print (o);
1004 }
1005
1006
1007 void foreach_loop::print (ostream& o) const
1008 {
1009 o << "foreach (";
1010 if (value)
1011 {
1012 value->print (o);
1013 o << " = ";
1014 }
1015 o << "[";
1016 for (unsigned i=0; i<indexes.size(); i++)
1017 {
1018 if (i > 0) o << ", ";
1019 indexes[i]->print (o);
1020 if (sort_direction != 0 && sort_column == i+1)
1021 o << (sort_direction > 0 ? "+" : "-");
1022 }
1023 o << "] in ";
1024 base->print_indexable (o);
1025 if (sort_direction != 0 && sort_column == 0)
1026 o << (sort_direction > 0 ? "+" : "-");
1027 if (limit)
1028 {
1029 o << " limit ";
1030 limit->print (o);
1031 }
1032 o << ") ";
1033 block->print (o);
1034 }
1035
1036
1037 void null_statement::print (ostream& o) const
1038 {
1039 o << ";";
1040 }
1041
1042
1043 void expr_statement::print (ostream& o) const
1044 {
1045 o << *value;
1046 }
1047
1048
1049 void return_statement::print (ostream& o) const
1050 {
1051 o << "return " << *value;
1052 }
1053
1054
1055 void delete_statement::print (ostream& o) const
1056 {
1057 o << "delete " << *value;
1058 }
1059
1060 void next_statement::print (ostream& o) const
1061 {
1062 o << "next";
1063 }
1064
1065 void break_statement::print (ostream& o) const
1066 {
1067 o << "break";
1068 }
1069
1070 void continue_statement::print (ostream& o) const
1071 {
1072 o << "continue";
1073 }
1074
1075 void if_statement::print (ostream& o) const
1076 {
1077 o << "if (" << *condition << ") "
1078 << *thenblock << endl;
1079 if (elseblock)
1080 o << "else " << *elseblock << endl;
1081 }
1082
1083
1084 void stapfile::print (ostream& o) const
1085 {
1086 o << "# file " << name << endl;
1087
1088 for (unsigned i=0; i<embeds.size(); i++)
1089 embeds[i]->print (o);
1090
1091 for (unsigned i=0; i<globals.size(); i++)
1092 {
1093 o << "global ";
1094 globals[i]->print (o);
1095 o << endl;
1096 }
1097
1098 for (unsigned i=0; i<aliases.size(); i++)
1099 {
1100 aliases[i]->print (o);
1101 o << endl;
1102 }
1103
1104 for (unsigned i=0; i<probes.size(); i++)
1105 {
1106 probes[i]->print (o);
1107 o << endl;
1108 }
1109
1110 for (unsigned j = 0; j < functions.size(); j++)
1111 {
1112 functions[j]->print (o);
1113 o << endl;
1114 }
1115 }
1116
1117
1118 void probe::print (ostream& o) const
1119 {
1120 o << "probe ";
1121 printsig (o);
1122 o << *body;
1123 }
1124
1125
1126 void probe::printsig (ostream& o) const
1127 {
1128 const probe_alias *alias = get_alias ();
1129 if (alias)
1130 {
1131 alias->printsig (o);
1132 return;
1133 }
1134
1135 for (unsigned i=0; i<locations.size(); i++)
1136 {
1137 if (i > 0) o << ",";
1138 locations[i]->print (o);
1139 }
1140 }
1141
1142
1143 void
1144 probe::collect_derivation_chain (std::vector<probe*> &probes_list)
1145 {
1146 probes_list.push_back(this);
1147 }
1148
1149
1150 void probe_point::print (ostream& o, bool print_extras) const
1151 {
1152 for (unsigned i=0; i<components.size(); i++)
1153 {
1154 if (i>0) o << ".";
1155 probe_point::component* c = components[i];
1156 o << c->functor;
1157 if (c->arg)
1158 o << "(" << *c->arg << ")";
1159 }
1160 if (!print_extras)
1161 return;
1162 if (sufficient)
1163 o << "!";
1164 else if (optional) // sufficient implies optional
1165 o << "?";
1166 if (condition)
1167 o<< " if (" << *condition << ")";
1168 }
1169
1170 string probe_point::str (bool print_extras) const
1171 {
1172 ostringstream o;
1173 print(o, print_extras);
1174 return o.str();
1175 }
1176
1177
1178 probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
1179 probe (), alias_names (aliases), epilogue_style(false)
1180 {
1181 }
1182
1183 void probe_alias::printsig (ostream& o) const
1184 {
1185 for (unsigned i=0; i<alias_names.size(); i++)
1186 {
1187 o << (i>0 ? " = " : "");
1188 alias_names[i]->print (o);
1189 }
1190 o << " = ";
1191 for (unsigned i=0; i<locations.size(); i++)
1192 {
1193 if (i > 0) o << ", ";
1194 locations[i]->print (o);
1195 }
1196 }
1197
1198
1199 ostream& operator << (ostream& o, const probe_point& k)
1200 {
1201 k.print (o);
1202 return o;
1203 }
1204
1205
1206 ostream& operator << (ostream& o, const symboldecl& k)
1207 {
1208 k.print (o);
1209 return o;
1210 }
1211
1212
1213
1214 // ------------------------------------------------------------------------
1215 // visitors
1216
1217
1218 void
1219 block::visit (visitor* u)
1220 {
1221 u->visit_block (this);
1222 }
1223
1224
1225 void
1226 try_block::visit (visitor* u)
1227 {
1228 u->visit_try_block (this);
1229 }
1230
1231
1232 void
1233 embeddedcode::visit (visitor* u)
1234 {
1235 u->visit_embeddedcode (this);
1236 }
1237
1238
1239 void
1240 for_loop::visit (visitor* u)
1241 {
1242 u->visit_for_loop (this);
1243 }
1244
1245 void
1246 foreach_loop::visit (visitor* u)
1247 {
1248 u->visit_foreach_loop (this);
1249 }
1250
1251 void
1252 null_statement::visit (visitor* u)
1253 {
1254 u->visit_null_statement (this);
1255 }
1256
1257 void
1258 expr_statement::visit (visitor* u)
1259 {
1260 u->visit_expr_statement (this);
1261 }
1262
1263 void
1264 return_statement::visit (visitor* u)
1265 {
1266 u->visit_return_statement (this);
1267 }
1268
1269 void
1270 delete_statement::visit (visitor* u)
1271 {
1272 u->push_active_lvalue (this->value);
1273 u->visit_delete_statement (this);
1274 u->pop_active_lvalue ();
1275 }
1276
1277 void
1278 if_statement::visit (visitor* u)
1279 {
1280 u->visit_if_statement (this);
1281 }
1282
1283 void
1284 next_statement::visit (visitor* u)
1285 {
1286 u->visit_next_statement (this);
1287 }
1288
1289 void
1290 break_statement::visit (visitor* u)
1291 {
1292 u->visit_break_statement (this);
1293 }
1294
1295 void
1296 continue_statement::visit (visitor* u)
1297 {
1298 u->visit_continue_statement (this);
1299 }
1300
1301 void
1302 literal_string::visit(visitor* u)
1303 {
1304 u->visit_literal_string (this);
1305 }
1306
1307 void
1308 literal_number::visit(visitor* u)
1309 {
1310 u->visit_literal_number (this);
1311 }
1312
1313 void
1314 binary_expression::visit (visitor* u)
1315 {
1316 u->visit_binary_expression (this);
1317 }
1318
1319 void
1320 embedded_expr::visit (visitor* u)
1321 {
1322 u->visit_embedded_expr (this);
1323 }
1324
1325 void
1326 unary_expression::visit (visitor* u)
1327 {
1328 u->visit_unary_expression (this);
1329 }
1330
1331 void
1332 pre_crement::visit (visitor* u)
1333 {
1334 u->push_active_lvalue (this->operand);
1335 u->visit_pre_crement (this);
1336 u->pop_active_lvalue ();
1337 }
1338
1339 void
1340 post_crement::visit (visitor* u)
1341 {
1342 u->push_active_lvalue (this->operand);
1343 u->visit_post_crement (this);
1344 u->pop_active_lvalue ();
1345 }
1346
1347 void
1348 logical_or_expr::visit (visitor* u)
1349 {
1350 u->visit_logical_or_expr (this);
1351 }
1352
1353 void
1354 logical_and_expr::visit (visitor* u)
1355 {
1356 u->visit_logical_and_expr (this);
1357 }
1358
1359 void
1360 array_in::visit (visitor* u)
1361 {
1362 u->visit_array_in (this);
1363 }
1364
1365 void
1366 comparison::visit (visitor* u)
1367 {
1368 u->visit_comparison (this);
1369 }
1370
1371 void
1372 concatenation::visit (visitor* u)
1373 {
1374 u->visit_concatenation (this);
1375 }
1376
1377 void
1378 ternary_expression::visit (visitor* u)
1379 {
1380 u->visit_ternary_expression (this);
1381 }
1382
1383 void
1384 assignment::visit (visitor* u)
1385 {
1386 u->push_active_lvalue (this->left);
1387 u->visit_assignment (this);
1388 u->pop_active_lvalue ();
1389 }
1390
1391 void
1392 symbol::visit (visitor* u)
1393 {
1394 u->visit_symbol (this);
1395 }
1396
1397 void
1398 target_symbol::visit (visitor* u)
1399 {
1400 u->visit_target_symbol(this);
1401 }
1402
1403 void
1404 target_symbol::visit_components (visitor* u)
1405 {
1406 for (unsigned i = 0; i < components.size(); ++i)
1407 if (components[i].type == comp_expression_array_index)
1408 components[i].expr_index->visit (u);
1409 }
1410
1411 void
1412 target_symbol::visit_components (update_visitor* u)
1413 {
1414 for (unsigned i = 0; i < components.size(); ++i)
1415 if (components[i].type == comp_expression_array_index)
1416 u->replace (components[i].expr_index);
1417 }
1418
1419 void
1420 cast_op::visit (visitor* u)
1421 {
1422 u->visit_cast_op(this);
1423 }
1424
1425
1426 void
1427 defined_op::visit (visitor* u)
1428 {
1429 u->visit_defined_op(this);
1430 }
1431
1432
1433 void
1434 entry_op::visit (visitor* u)
1435 {
1436 u->visit_entry_op(this);
1437 }
1438
1439
1440 void
1441 arrayindex::visit (visitor* u)
1442 {
1443 u->visit_arrayindex (this);
1444 }
1445
1446 void
1447 functioncall::visit (visitor* u)
1448 {
1449 u->visit_functioncall (this);
1450 }
1451
1452 void
1453 print_format::visit (visitor *u)
1454 {
1455 u->visit_print_format (this);
1456 }
1457
1458 void
1459 stat_op::visit (visitor *u)
1460 {
1461 u->visit_stat_op (this);
1462 }
1463
1464 void
1465 hist_op::visit (visitor *u)
1466 {
1467 u->visit_hist_op (this);
1468 }
1469
1470 void
1471 indexable::print_indexable (std::ostream& o) const
1472 {
1473 const symbol *sym;
1474 const hist_op *hist;
1475 classify_const_indexable(this, sym, hist);
1476 if (sym)
1477 sym->print (o);
1478 else
1479 {
1480 assert (hist);
1481 hist->print (o);
1482 }
1483 }
1484
1485 void
1486 indexable::visit_indexable (visitor* u)
1487 {
1488 symbol *sym;
1489 hist_op *hist;
1490 classify_indexable(this, sym, hist);
1491 if (sym)
1492 sym->visit (u);
1493 else
1494 {
1495 assert (hist);
1496 hist->visit (u);
1497 }
1498 }
1499
1500
1501 bool
1502 indexable::is_symbol(symbol *& sym_out)
1503 {
1504 sym_out = NULL;
1505 return false;
1506 }
1507
1508 bool
1509 indexable::is_hist_op(hist_op *& hist_out)
1510 {
1511 hist_out = NULL;
1512 return false;
1513 }
1514
1515 bool
1516 indexable::is_const_symbol(const symbol *& sym_out) const
1517 {
1518 sym_out = NULL;
1519 return false;
1520 }
1521
1522 bool
1523 indexable::is_const_hist_op(const hist_op *& hist_out) const
1524 {
1525 hist_out = NULL;
1526 return false;
1527 }
1528
1529 bool
1530 symbol::is_symbol(symbol *& sym_out)
1531 {
1532 sym_out = this;
1533 return true;
1534 }
1535
1536 bool
1537 symbol::is_const_symbol(const symbol *& sym_out) const
1538 {
1539 sym_out = this;
1540 return true;
1541 }
1542
1543 const token *
1544 symbol::get_tok() const
1545 {
1546 return tok;
1547 }
1548
1549 bool
1550 hist_op::is_hist_op(hist_op *& hist_out)
1551 {
1552 hist_out = this;
1553 return true;
1554 }
1555
1556 bool
1557 hist_op::is_const_hist_op(const hist_op *& hist_out) const
1558 {
1559 hist_out = this;
1560 return true;
1561 }
1562
1563 const token *
1564 hist_op::get_tok() const
1565 {
1566 return tok;
1567 }
1568
1569 void
1570 classify_indexable(indexable* ix,
1571 symbol *& array_out,
1572 hist_op *& hist_out)
1573 {
1574 array_out = NULL;
1575 hist_out = NULL;
1576 assert(ix != 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 (!(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 (! pr_contains (session.privilege, pr_stapdev) &&
1932 s->code.find ("/* unprivileged */") == string::npos &&
1933 s->code.find ("/* myproc-unprivileged */") == string::npos)
1934 throw semantic_error (_F("function may not be used when --privilege=%s is specified",
1935 pr_name (session.privilege)),
1936 current_function->tok);
1937
1938 // Don't allow /* guru */ functions unless -g is active.
1939 if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
1940 throw semantic_error (_("function may not be used unless -g is specified"),
1941 current_function->tok);
1942
1943 // We want to elide embedded-C functions when possible. For
1944 // example, each $target variable access is expanded to an
1945 // embedded-C function call. Yet, for safety reasons, we should
1946 // presume that embedded-C functions have intentional side-effects.
1947 //
1948 // To tell these two types of functions apart, we apply a
1949 // Kludge(tm): we look for a magic string within the function body.
1950 // $target variables as rvalues will have this; lvalues won't.
1951 // Also, explicit side-effect-free tapset functions will have this.
1952
1953 if (s->code.find ("/* pure */") != string::npos)
1954 return;
1955
1956 embedded_seen = true;
1957 }
1958
1959
1960 // About the same case as above.
1961 void
1962 varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1963 {
1964 // Don't allow embedded C functions in unprivileged mode unless
1965 // they are tagged with /* unprivileged */
1966 if (! pr_contains (session.privilege, pr_stapdev) &&
1967 e->code.find ("/* unprivileged */") == string::npos &&
1968 e->code.find ("/* myproc-unprivileged */") == string::npos)
1969 throw semantic_error (_F("embedded expression may not be used when --privilege=%s is specified",
1970 pr_name (session.privilege)),
1971 e->tok);
1972
1973 // Don't allow /* guru */ functions unless -g is active.
1974 if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
1975 throw semantic_error (_("embedded expression may not be used unless -g is specified"),
1976 e->tok);
1977
1978 // We want to elide embedded-C functions when possible. For
1979 // example, each $target variable access is expanded to an
1980 // embedded-C function call. Yet, for safety reasons, we should
1981 // presume that embedded-C functions have intentional side-effects.
1982 //
1983 // To tell these two types of functions apart, we apply a
1984 // Kludge(tm): we look for a magic string within the function body.
1985 // $target variables as rvalues will have this; lvalues won't.
1986 // Also, explicit side-effect-free tapset functions will have this.
1987
1988 if (e->code.find ("/* pure */") != string::npos)
1989 return;
1990
1991 embedded_seen = true;
1992 }
1993
1994
1995 void
1996 varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1997 {
1998 // Still-unresolved target symbol assignments get treated as
1999 // generating side-effects like embedded-C, to prevent premature
2000 // elision and later error message suppression (PR5516). rvalue use
2001 // of unresolved target symbols is OTOH not considered a side-effect.
2002
2003 if (is_active_lvalue (e))
2004 embedded_seen = true;
2005
2006 functioncall_traversing_visitor::visit_target_symbol (e);
2007 }
2008
2009 void
2010 varuse_collecting_visitor::visit_cast_op (cast_op *e)
2011 {
2012 // As with target_symbols, unresolved cast assignments need to preserved
2013 // for later error handling.
2014 if (is_active_lvalue (e))
2015 embedded_seen = true;
2016
2017 functioncall_traversing_visitor::visit_cast_op (e);
2018 }
2019
2020 void
2021 varuse_collecting_visitor::visit_defined_op (defined_op *e)
2022 {
2023 // XXX
2024 functioncall_traversing_visitor::visit_defined_op (e);
2025 }
2026
2027 void
2028 varuse_collecting_visitor::visit_entry_op (entry_op *e)
2029 {
2030 // XXX
2031 functioncall_traversing_visitor::visit_entry_op (e);
2032 }
2033
2034
2035 void
2036 varuse_collecting_visitor::visit_print_format (print_format* e)
2037 {
2038 // NB: Instead of being top-level statements, "print" and "printf"
2039 // are implemented as statement-expressions containing a
2040 // print_format. They have side-effects, but not via the
2041 // embedded-code detection method above.
2042 //
2043 // But sprint and sprintf don't have side-effects.
2044
2045 bool last_lvalue_read = current_lvalue_read;
2046 current_lvalue_read = true;
2047 if (e->print_to_stream)
2048 embedded_seen = true; // a proxy for "has unknown side-effects"
2049
2050 functioncall_traversing_visitor::visit_print_format (e);
2051 current_lvalue_read = last_lvalue_read;
2052 }
2053
2054
2055 void
2056 varuse_collecting_visitor::visit_assignment (assignment *e)
2057 {
2058 if (e->op == "=" || e->op == "<<<") // pure writes
2059 {
2060 expression* last_lvalue = current_lvalue;
2061 bool last_lvalue_read = current_lvalue_read;
2062 current_lvalue = e->left; // leave a mark for ::visit_symbol
2063 current_lvalue_read = true;
2064 functioncall_traversing_visitor::visit_assignment (e);
2065 current_lvalue = last_lvalue;
2066 current_lvalue_read = last_lvalue_read;
2067 }
2068 else // read-modify-writes
2069 {
2070 expression* last_lrvalue = current_lrvalue;
2071 current_lrvalue = e->left; // leave a mark for ::visit_symbol
2072 functioncall_traversing_visitor::visit_assignment (e);
2073 current_lrvalue = last_lrvalue;
2074 }
2075 }
2076
2077 void
2078 varuse_collecting_visitor::visit_symbol (symbol *e)
2079 {
2080 if (e->referent == 0)
2081 throw semantic_error (_("symbol without referent"), e->tok);
2082
2083 // We could handle initialized globals by marking them as "written".
2084 // However, this current visitor may be called for a function or
2085 // probe body, from the point of view of which this global is
2086 // already initialized, so not written.
2087 /*
2088 if (e->referent->init)
2089 written.insert (e->referent);
2090 */
2091
2092 if (current_lvalue == e || current_lrvalue == e)
2093 {
2094 written.insert (e->referent);
2095 }
2096 if (current_lvalue != e || current_lrvalue == e)
2097 {
2098 read.insert (e->referent);
2099 }
2100
2101 if (current_lrvalue == e)
2102 {
2103 if (current_lvalue_read)
2104 used.insert (e->referent);
2105 }
2106 else if (current_lvalue != e)
2107 used.insert (e->referent);
2108 }
2109
2110 // NB: stat_op need not be overridden, since it will get to
2111 // visit_symbol and only as a possible rvalue.
2112
2113
2114 void
2115 varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2116 {
2117 // Hooking this callback is necessary because of the hacky
2118 // statistics representation. For the expression "i[4] = 5", the
2119 // incoming lvalue will point to this arrayindex. However, the
2120 // symbol corresponding to the "i[4]" is multiply inherited with
2121 // arrayindex. If the symbol base part of this object is not at
2122 // offset 0, then static_cast<symbol*>(e) may result in a different
2123 // address, and not match lvalue by number when we recurse that way.
2124 // So we explicitly override the incoming lvalue/lrvalue values to
2125 // point at the embedded objects' actual base addresses.
2126
2127 expression* last_lrvalue = current_lrvalue;
2128 expression* last_lvalue = current_lvalue;
2129
2130 symbol *array = NULL;
2131 hist_op *hist = NULL;
2132 classify_indexable(e->base, array, hist);
2133
2134 if (array)
2135 {
2136 if (current_lrvalue == e) current_lrvalue = array;
2137 if (current_lvalue == e) current_lvalue = array;
2138 functioncall_traversing_visitor::visit_arrayindex (e);
2139 }
2140 else // if (hist)
2141 {
2142 if (current_lrvalue == e) current_lrvalue = hist->stat;
2143 if (current_lvalue == e) current_lvalue = hist->stat;
2144 functioncall_traversing_visitor::visit_arrayindex (e);
2145 }
2146
2147 current_lrvalue = last_lrvalue;
2148 current_lvalue = last_lvalue;
2149 }
2150
2151
2152 void
2153 varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2154 {
2155 expression* last_lrvalue = current_lrvalue;
2156 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2157 functioncall_traversing_visitor::visit_pre_crement (e);
2158 current_lrvalue = last_lrvalue;
2159 }
2160
2161 void
2162 varuse_collecting_visitor::visit_post_crement (post_crement *e)
2163 {
2164 expression* last_lrvalue = current_lrvalue;
2165 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2166 functioncall_traversing_visitor::visit_post_crement (e);
2167 current_lrvalue = last_lrvalue;
2168 }
2169
2170 void
2171 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2172 {
2173 // NB: we duplicate so don't bother call
2174 // functioncall_traversing_visitor::visit_foreach_loop (s);
2175
2176 symbol *array = NULL;
2177 hist_op *hist = NULL;
2178 classify_indexable (s->base, array, hist);
2179 if (array)
2180 array->visit(this);
2181 else
2182 hist->visit(this);
2183
2184 // If the collection is sorted, imply a "write" access to the
2185 // array in addition to the "read" one already noted above.
2186 if (s->sort_direction)
2187 {
2188 symbol *array = NULL;
2189 hist_op *hist = NULL;
2190 classify_indexable (s->base, array, hist);
2191 if (array) this->written.insert (array->referent);
2192 // XXX: Can hist_op iterations be sorted?
2193 }
2194
2195 // NB: don't forget to visit the index expressions, which are lvalues.
2196 for (unsigned i=0; i<s->indexes.size(); i++)
2197 {
2198 expression* last_lvalue = current_lvalue;
2199 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2200 s->indexes[i]->visit (this);
2201 current_lvalue = last_lvalue;
2202 }
2203
2204 // The value is an lvalue too
2205 if (s->value)
2206 {
2207 expression* last_lvalue = current_lvalue;
2208 current_lvalue = s->value; // leave a mark for ::visit_symbol
2209 s->value->visit (this);
2210 current_lvalue = last_lvalue;
2211 }
2212
2213 if (s->limit)
2214 s->limit->visit (this);
2215
2216 s->block->visit (this);
2217 }
2218
2219
2220 void
2221 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2222 {
2223 // Ideally, this would be treated like an assignment: a plain write
2224 // to the underlying value ("lvalue"). XXX: However, the
2225 // optimization pass is not smart enough to remove an unneeded
2226 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2227 // should protect the underlying value from optimizional mischief.
2228 expression* last_lrvalue = current_lrvalue;
2229 bool last_lvalue_read = current_lvalue_read;
2230 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2231 current_lvalue_read = true;
2232 functioncall_traversing_visitor::visit_delete_statement (s);
2233 current_lrvalue = last_lrvalue;
2234 current_lvalue_read = last_lvalue_read;
2235 }
2236
2237 bool
2238 varuse_collecting_visitor::side_effect_free ()
2239 {
2240 return (written.empty() && !embedded_seen);
2241 }
2242
2243
2244 bool
2245 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2246 {
2247 // A looser notion of side-effect-freeness with respect to a given
2248 // list of variables.
2249
2250 // That's useful because the written list may consist of local
2251 // variables of called functions. But visible side-effects only
2252 // occur if the client's locals, or any globals are written-to.
2253
2254 set<vardecl*> intersection;
2255 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2256 set_intersection (written.begin(), written.end(),
2257 vars.begin(), vars.end(),
2258 int_it);
2259
2260 return (intersection.empty() && !embedded_seen);
2261 }
2262
2263
2264
2265
2266 // ------------------------------------------------------------------------
2267
2268
2269 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2270 throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2271
2272
2273 void
2274 throwing_visitor::throwone (const token* t)
2275 {
2276 throw semantic_error (msg, t);
2277 }
2278
2279 void
2280 throwing_visitor::visit_block (block* s)
2281 {
2282 throwone (s->tok);
2283 }
2284
2285 void
2286 throwing_visitor::visit_try_block (try_block* s)
2287 {
2288 throwone (s->tok);
2289 }
2290
2291
2292 void
2293 throwing_visitor::visit_embeddedcode (embeddedcode* s)
2294 {
2295 throwone (s->tok);
2296 }
2297
2298 void
2299 throwing_visitor::visit_null_statement (null_statement* s)
2300 {
2301 throwone (s->tok);
2302 }
2303
2304 void
2305 throwing_visitor::visit_expr_statement (expr_statement* s)
2306 {
2307 throwone (s->tok);
2308 }
2309
2310 void
2311 throwing_visitor::visit_if_statement (if_statement* s)
2312 {
2313 throwone (s->tok);
2314 }
2315
2316 void
2317 throwing_visitor::visit_for_loop (for_loop* s)
2318 {
2319 throwone (s->tok);
2320 }
2321
2322 void
2323 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2324 {
2325 throwone (s->tok);
2326 }
2327
2328 void
2329 throwing_visitor::visit_return_statement (return_statement* s)
2330 {
2331 throwone (s->tok);
2332 }
2333
2334 void
2335 throwing_visitor::visit_delete_statement (delete_statement* s)
2336 {
2337 throwone (s->tok);
2338 }
2339
2340 void
2341 throwing_visitor::visit_next_statement (next_statement* s)
2342 {
2343 throwone (s->tok);
2344 }
2345
2346 void
2347 throwing_visitor::visit_break_statement (break_statement* s)
2348 {
2349 throwone (s->tok);
2350 }
2351
2352 void
2353 throwing_visitor::visit_continue_statement (continue_statement* s)
2354 {
2355 throwone (s->tok);
2356 }
2357
2358 void
2359 throwing_visitor::visit_literal_string (literal_string* e)
2360 {
2361 throwone (e->tok);
2362 }
2363
2364 void
2365 throwing_visitor::visit_literal_number (literal_number* e)
2366 {
2367 throwone (e->tok);
2368 }
2369
2370 void
2371 throwing_visitor::visit_embedded_expr (embedded_expr* e)
2372 {
2373 throwone (e->tok);
2374 }
2375
2376 void
2377 throwing_visitor::visit_binary_expression (binary_expression* e)
2378 {
2379 throwone (e->tok);
2380 }
2381
2382 void
2383 throwing_visitor::visit_unary_expression (unary_expression* e)
2384 {
2385 throwone (e->tok);
2386 }
2387
2388 void
2389 throwing_visitor::visit_pre_crement (pre_crement* e)
2390 {
2391 throwone (e->tok);
2392 }
2393
2394 void
2395 throwing_visitor::visit_post_crement (post_crement* e)
2396 {
2397 throwone (e->tok);
2398 }
2399
2400
2401 void
2402 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2403 {
2404 throwone (e->tok);
2405 }
2406
2407 void
2408 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2409 {
2410 throwone (e->tok);
2411 }
2412
2413 void
2414 throwing_visitor::visit_array_in (array_in* e)
2415 {
2416 throwone (e->tok);
2417 }
2418
2419 void
2420 throwing_visitor::visit_comparison (comparison* e)
2421 {
2422 throwone (e->tok);
2423 }
2424
2425 void
2426 throwing_visitor::visit_concatenation (concatenation* e)
2427 {
2428 throwone (e->tok);
2429 }
2430
2431 void
2432 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2433 {
2434 throwone (e->tok);
2435 }
2436
2437 void
2438 throwing_visitor::visit_assignment (assignment* e)
2439 {
2440 throwone (e->tok);
2441 }
2442
2443 void
2444 throwing_visitor::visit_symbol (symbol* e)
2445 {
2446 throwone (e->tok);
2447 }
2448
2449 void
2450 throwing_visitor::visit_target_symbol (target_symbol* e)
2451 {
2452 throwone (e->tok);
2453 }
2454
2455 void
2456 throwing_visitor::visit_cast_op (cast_op* e)
2457 {
2458 throwone (e->tok);
2459 }
2460
2461 void
2462 throwing_visitor::visit_defined_op (defined_op* e)
2463 {
2464 throwone (e->tok);
2465 }
2466
2467 void
2468 throwing_visitor::visit_entry_op (entry_op* e)
2469 {
2470 throwone (e->tok);
2471 }
2472
2473
2474 void
2475 throwing_visitor::visit_arrayindex (arrayindex* e)
2476 {
2477 throwone (e->tok);
2478 }
2479
2480 void
2481 throwing_visitor::visit_functioncall (functioncall* e)
2482 {
2483 throwone (e->tok);
2484 }
2485
2486 void
2487 throwing_visitor::visit_print_format (print_format* e)
2488 {
2489 throwone (e->tok);
2490 }
2491
2492 void
2493 throwing_visitor::visit_stat_op (stat_op* e)
2494 {
2495 throwone (e->tok);
2496 }
2497
2498 void
2499 throwing_visitor::visit_hist_op (hist_op* e)
2500 {
2501 throwone (e->tok);
2502 }
2503
2504
2505 // ------------------------------------------------------------------------
2506
2507
2508 void
2509 update_visitor::visit_block (block* s)
2510 {
2511 for (unsigned i = 0; i < s->statements.size(); ++i)
2512 replace (s->statements[i]);
2513 provide (s);
2514 }
2515
2516 void
2517 update_visitor::visit_try_block (try_block* s)
2518 {
2519 replace (s->try_block);
2520 replace (s->catch_error_var);
2521 replace (s->catch_block);
2522 provide (s);
2523 }
2524
2525 void
2526 update_visitor::visit_embeddedcode (embeddedcode* s)
2527 {
2528 provide (s);
2529 }
2530
2531 void
2532 update_visitor::visit_null_statement (null_statement* s)
2533 {
2534 provide (s);
2535 }
2536
2537 void
2538 update_visitor::visit_expr_statement (expr_statement* s)
2539 {
2540 replace (s->value);
2541 provide (s);
2542 }
2543
2544 void
2545 update_visitor::visit_if_statement (if_statement* s)
2546 {
2547 replace (s->condition);
2548 replace (s->thenblock);
2549 replace (s->elseblock);
2550 provide (s);
2551 }
2552
2553 void
2554 update_visitor::visit_for_loop (for_loop* s)
2555 {
2556 replace (s->init);
2557 replace (s->cond);
2558 replace (s->incr);
2559 replace (s->block);
2560 provide (s);
2561 }
2562
2563 void
2564 update_visitor::visit_foreach_loop (foreach_loop* s)
2565 {
2566 for (unsigned i = 0; i < s->indexes.size(); ++i)
2567 replace (s->indexes[i]);
2568 replace (s->base);
2569 replace (s->value);
2570 replace (s->limit);
2571 replace (s->block);
2572 provide (s);
2573 }
2574
2575 void
2576 update_visitor::visit_return_statement (return_statement* s)
2577 {
2578 replace (s->value);
2579 provide (s);
2580 }
2581
2582 void
2583 update_visitor::visit_delete_statement (delete_statement* s)
2584 {
2585 replace (s->value);
2586 provide (s);
2587 }
2588
2589 void
2590 update_visitor::visit_next_statement (next_statement* s)
2591 {
2592 provide (s);
2593 }
2594
2595 void
2596 update_visitor::visit_break_statement (break_statement* s)
2597 {
2598 provide (s);
2599 }
2600
2601 void
2602 update_visitor::visit_continue_statement (continue_statement* s)
2603 {
2604 provide (s);
2605 }
2606
2607 void
2608 update_visitor::visit_literal_string (literal_string* e)
2609 {
2610 provide (e);
2611 }
2612
2613 void
2614 update_visitor::visit_literal_number (literal_number* e)
2615 {
2616 provide (e);
2617 }
2618
2619 void
2620 update_visitor::visit_embedded_expr (embedded_expr* e)
2621 {
2622 provide (e);
2623 }
2624
2625 void
2626 update_visitor::visit_binary_expression (binary_expression* e)
2627 {
2628 replace (e->left);
2629 replace (e->right);
2630 provide (e);
2631 }
2632
2633 void
2634 update_visitor::visit_unary_expression (unary_expression* e)
2635 {
2636 replace (e->operand);
2637 provide (e);
2638 }
2639
2640 void
2641 update_visitor::visit_pre_crement (pre_crement* e)
2642 {
2643 replace (e->operand);
2644 provide (e);
2645 }
2646
2647 void
2648 update_visitor::visit_post_crement (post_crement* e)
2649 {
2650 replace (e->operand);
2651 provide (e);
2652 }
2653
2654
2655 void
2656 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2657 {
2658 replace (e->left);
2659 replace (e->right);
2660 provide (e);
2661 }
2662
2663 void
2664 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2665 {
2666 replace (e->left);
2667 replace (e->right);
2668 provide (e);
2669 }
2670
2671 void
2672 update_visitor::visit_array_in (array_in* e)
2673 {
2674 replace (e->operand);
2675 provide (e);
2676 }
2677
2678 void
2679 update_visitor::visit_comparison (comparison* e)
2680 {
2681 replace (e->left);
2682 replace (e->right);
2683 provide (e);
2684 }
2685
2686 void
2687 update_visitor::visit_concatenation (concatenation* e)
2688 {
2689 replace (e->left);
2690 replace (e->right);
2691 provide (e);
2692 }
2693
2694 void
2695 update_visitor::visit_ternary_expression (ternary_expression* e)
2696 {
2697 replace (e->cond);
2698 replace (e->truevalue);
2699 replace (e->falsevalue);
2700 provide (e);
2701 }
2702
2703 void
2704 update_visitor::visit_assignment (assignment* e)
2705 {
2706 replace (e->left);
2707 replace (e->right);
2708 provide (e);
2709 }
2710
2711 void
2712 update_visitor::visit_symbol (symbol* e)
2713 {
2714 provide (e);
2715 }
2716
2717 void
2718 update_visitor::visit_target_symbol (target_symbol* e)
2719 {
2720 e->visit_components (this);
2721 provide (e);
2722 }
2723
2724 void
2725 update_visitor::visit_cast_op (cast_op* e)
2726 {
2727 replace (e->operand);
2728 e->visit_components (this);
2729 provide (e);
2730 }
2731
2732 void
2733 update_visitor::visit_defined_op (defined_op* e)
2734 {
2735 replace (e->operand);
2736 provide (e);
2737 }
2738
2739 void
2740 update_visitor::visit_entry_op (entry_op* e)
2741 {
2742 replace (e->operand);
2743 provide (e);
2744 }
2745
2746 void
2747 update_visitor::visit_arrayindex (arrayindex* e)
2748 {
2749 replace (e->base);
2750 for (unsigned i = 0; i < e->indexes.size(); ++i)
2751 replace (e->indexes[i]);
2752 provide (e);
2753 }
2754
2755 void
2756 update_visitor::visit_functioncall (functioncall* e)
2757 {
2758 for (unsigned i = 0; i < e->args.size(); ++i)
2759 replace (e->args[i]);
2760 provide (e);
2761 }
2762
2763 void
2764 update_visitor::visit_print_format (print_format* e)
2765 {
2766 for (unsigned i = 0; i < e->args.size(); ++i)
2767 replace (e->args[i]);
2768 replace (e->hist);
2769 provide (e);
2770 }
2771
2772 void
2773 update_visitor::visit_stat_op (stat_op* e)
2774 {
2775 replace (e->stat);
2776 provide (e);
2777 }
2778
2779 void
2780 update_visitor::visit_hist_op (hist_op* e)
2781 {
2782 replace (e->stat);
2783 provide (e);
2784 }
2785
2786 template <> indexable*
2787 update_visitor::require <indexable> (indexable* src, bool clearok)
2788 {
2789 indexable *dst = NULL;
2790 if (src != NULL)
2791 {
2792 symbol *array_src=NULL;
2793 hist_op *hist_src=NULL;
2794
2795 classify_indexable(src, array_src, hist_src);
2796
2797 if (array_src)
2798 dst = require (array_src);
2799 else
2800 dst = require (hist_src);
2801 assert(clearok || dst);
2802 }
2803 return dst;
2804 }
2805
2806
2807 // ------------------------------------------------------------------------
2808
2809
2810 void
2811 deep_copy_visitor::visit_block (block* s)
2812 {
2813 update_visitor::visit_block(new block(*s));
2814 }
2815
2816 void
2817 deep_copy_visitor::visit_try_block (try_block* s)
2818 {
2819 update_visitor::visit_try_block(new try_block(*s));
2820 }
2821
2822 void
2823 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2824 {
2825 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2826 }
2827
2828 void
2829 deep_copy_visitor::visit_null_statement (null_statement* s)
2830 {
2831 update_visitor::visit_null_statement(new null_statement(*s));
2832 }
2833
2834 void
2835 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2836 {
2837 update_visitor::visit_expr_statement(new expr_statement(*s));
2838 }
2839
2840 void
2841 deep_copy_visitor::visit_if_statement (if_statement* s)
2842 {
2843 update_visitor::visit_if_statement(new if_statement(*s));
2844 }
2845
2846 void
2847 deep_copy_visitor::visit_for_loop (for_loop* s)
2848 {
2849 update_visitor::visit_for_loop(new for_loop(*s));
2850 }
2851
2852 void
2853 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2854 {
2855 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2856 }
2857
2858 void
2859 deep_copy_visitor::visit_return_statement (return_statement* s)
2860 {
2861 update_visitor::visit_return_statement(new return_statement(*s));
2862 }
2863
2864 void
2865 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2866 {
2867 update_visitor::visit_delete_statement(new delete_statement(*s));
2868 }
2869
2870 void
2871 deep_copy_visitor::visit_next_statement (next_statement* s)
2872 {
2873 update_visitor::visit_next_statement(new next_statement(*s));
2874 }
2875
2876 void
2877 deep_copy_visitor::visit_break_statement (break_statement* s)
2878 {
2879 update_visitor::visit_break_statement(new break_statement(*s));
2880 }
2881
2882 void
2883 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2884 {
2885 update_visitor::visit_continue_statement(new continue_statement(*s));
2886 }
2887
2888 void
2889 deep_copy_visitor::visit_literal_string (literal_string* e)
2890 {
2891 update_visitor::visit_literal_string(new literal_string(*e));
2892 }
2893
2894 void
2895 deep_copy_visitor::visit_literal_number (literal_number* e)
2896 {
2897 update_visitor::visit_literal_number(new literal_number(*e));
2898 }
2899
2900 void
2901 deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2902 {
2903 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2904 }
2905
2906 void
2907 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2908 {
2909 update_visitor::visit_binary_expression(new binary_expression(*e));
2910 }
2911
2912 void
2913 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2914 {
2915 update_visitor::visit_unary_expression(new unary_expression(*e));
2916 }
2917
2918 void
2919 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2920 {
2921 update_visitor::visit_pre_crement(new pre_crement(*e));
2922 }
2923
2924 void
2925 deep_copy_visitor::visit_post_crement (post_crement* e)
2926 {
2927 update_visitor::visit_post_crement(new post_crement(*e));
2928 }
2929
2930
2931 void
2932 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2933 {
2934 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2935 }
2936
2937 void
2938 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2939 {
2940 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2941 }
2942
2943 void
2944 deep_copy_visitor::visit_array_in (array_in* e)
2945 {
2946 update_visitor::visit_array_in(new array_in(*e));
2947 }
2948
2949 void
2950 deep_copy_visitor::visit_comparison (comparison* e)
2951 {
2952 update_visitor::visit_comparison(new comparison(*e));
2953 }
2954
2955 void
2956 deep_copy_visitor::visit_concatenation (concatenation* e)
2957 {
2958 update_visitor::visit_concatenation(new concatenation(*e));
2959 }
2960
2961 void
2962 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2963 {
2964 update_visitor::visit_ternary_expression(new ternary_expression(*e));
2965 }
2966
2967 void
2968 deep_copy_visitor::visit_assignment (assignment* e)
2969 {
2970 update_visitor::visit_assignment(new assignment(*e));
2971 }
2972
2973 void
2974 deep_copy_visitor::visit_symbol (symbol* e)
2975 {
2976 symbol* n = new symbol(*e);
2977 n->referent = NULL; // don't copy!
2978 update_visitor::visit_symbol(n);
2979 }
2980
2981 void
2982 deep_copy_visitor::visit_target_symbol (target_symbol* e)
2983 {
2984 target_symbol* n = new target_symbol(*e);
2985 n->referent = NULL; // don't copy!
2986 update_visitor::visit_target_symbol(n);
2987 }
2988
2989 void
2990 deep_copy_visitor::visit_cast_op (cast_op* e)
2991 {
2992 update_visitor::visit_cast_op(new cast_op(*e));
2993 }
2994
2995 void
2996 deep_copy_visitor::visit_defined_op (defined_op* e)
2997 {
2998 update_visitor::visit_defined_op(new defined_op(*e));
2999 }
3000
3001 void
3002 deep_copy_visitor::visit_entry_op (entry_op* e)
3003 {
3004 update_visitor::visit_entry_op(new entry_op(*e));
3005 }
3006
3007 void
3008 deep_copy_visitor::visit_arrayindex (arrayindex* e)
3009 {
3010 update_visitor::visit_arrayindex(new arrayindex(*e));
3011 }
3012
3013 void
3014 deep_copy_visitor::visit_functioncall (functioncall* e)
3015 {
3016 functioncall* n = new functioncall(*e);
3017 n->referent = NULL; // don't copy!
3018 update_visitor::visit_functioncall(n);
3019 }
3020
3021 void
3022 deep_copy_visitor::visit_print_format (print_format* e)
3023 {
3024 update_visitor::visit_print_format(new print_format(*e));
3025 }
3026
3027 void
3028 deep_copy_visitor::visit_stat_op (stat_op* e)
3029 {
3030 update_visitor::visit_stat_op(new stat_op(*e));
3031 }
3032
3033 void
3034 deep_copy_visitor::visit_hist_op (hist_op* e)
3035 {
3036 update_visitor::visit_hist_op(new hist_op(*e));
3037 }
3038
3039 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.175453 seconds and 5 git commands to generate.