]> sourceware.org Git - systemtap.git/blob - staptree.cxx
PR13513: undo PR11759 PREEMPT_RT hack
[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 ! pr_contains (session.privilege, pr_stapsys) &&
1933 s->code.find ("/* unprivileged */") == string::npos &&
1934 s->code.find ("/* myproc-unprivileged */") == string::npos)
1935 throw semantic_error (_F("function may not be used when --privilege=%s is specified",
1936 pr_name (session.privilege)),
1937 current_function->tok);
1938
1939 // Don't allow /* guru */ functions unless -g is active.
1940 if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
1941 throw semantic_error (_("function may not be used unless -g is specified"),
1942 current_function->tok);
1943
1944 // We want to elide embedded-C functions when possible. For
1945 // example, each $target variable access is expanded to an
1946 // embedded-C function call. Yet, for safety reasons, we should
1947 // presume that embedded-C functions have intentional side-effects.
1948 //
1949 // To tell these two types of functions apart, we apply a
1950 // Kludge(tm): we look for a magic string within the function body.
1951 // $target variables as rvalues will have this; lvalues won't.
1952 // Also, explicit side-effect-free tapset functions will have this.
1953
1954 if (s->code.find ("/* pure */") != string::npos)
1955 return;
1956
1957 embedded_seen = true;
1958 }
1959
1960
1961 // About the same case as above.
1962 void
1963 varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1964 {
1965 // Don't allow embedded C expressions in unprivileged mode unless
1966 // they are tagged with /* unprivileged */
1967 if (! pr_contains (session.privilege, pr_stapdev) &&
1968 ! pr_contains (session.privilege, pr_stapsys) &&
1969 e->code.find ("/* unprivileged */") == string::npos &&
1970 e->code.find ("/* myproc-unprivileged */") == string::npos)
1971 throw semantic_error (_F("embedded expression may not be used when --privilege=%s is specified",
1972 pr_name (session.privilege)),
1973 e->tok);
1974
1975 // Don't allow /* guru */ functions unless -g is active.
1976 if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
1977 throw semantic_error (_("embedded expression may not be used unless -g is specified"),
1978 e->tok);
1979
1980 // We want to elide embedded-C functions when possible. For
1981 // example, each $target variable access is expanded to an
1982 // embedded-C function call. Yet, for safety reasons, we should
1983 // presume that embedded-C functions have intentional side-effects.
1984 //
1985 // To tell these two types of functions apart, we apply a
1986 // Kludge(tm): we look for a magic string within the function body.
1987 // $target variables as rvalues will have this; lvalues won't.
1988 // Also, explicit side-effect-free tapset functions will have this.
1989
1990 if (e->code.find ("/* pure */") != string::npos)
1991 return;
1992
1993 embedded_seen = true;
1994 }
1995
1996
1997 void
1998 varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1999 {
2000 // Still-unresolved target symbol assignments get treated as
2001 // generating side-effects like embedded-C, to prevent premature
2002 // elision and later error message suppression (PR5516). rvalue use
2003 // of unresolved target symbols is OTOH not considered a side-effect.
2004
2005 if (is_active_lvalue (e))
2006 embedded_seen = true;
2007
2008 functioncall_traversing_visitor::visit_target_symbol (e);
2009 }
2010
2011 void
2012 varuse_collecting_visitor::visit_cast_op (cast_op *e)
2013 {
2014 // As with target_symbols, unresolved cast assignments need to preserved
2015 // for later error handling.
2016 if (is_active_lvalue (e))
2017 embedded_seen = true;
2018
2019 functioncall_traversing_visitor::visit_cast_op (e);
2020 }
2021
2022 void
2023 varuse_collecting_visitor::visit_defined_op (defined_op *e)
2024 {
2025 // XXX
2026 functioncall_traversing_visitor::visit_defined_op (e);
2027 }
2028
2029 void
2030 varuse_collecting_visitor::visit_entry_op (entry_op *e)
2031 {
2032 // XXX
2033 functioncall_traversing_visitor::visit_entry_op (e);
2034 }
2035
2036
2037 void
2038 varuse_collecting_visitor::visit_print_format (print_format* e)
2039 {
2040 // NB: Instead of being top-level statements, "print" and "printf"
2041 // are implemented as statement-expressions containing a
2042 // print_format. They have side-effects, but not via the
2043 // embedded-code detection method above.
2044 //
2045 // But sprint and sprintf don't have side-effects.
2046
2047 bool last_lvalue_read = current_lvalue_read;
2048 current_lvalue_read = true;
2049 if (e->print_to_stream)
2050 embedded_seen = true; // a proxy for "has unknown side-effects"
2051
2052 functioncall_traversing_visitor::visit_print_format (e);
2053 current_lvalue_read = last_lvalue_read;
2054 }
2055
2056
2057 void
2058 varuse_collecting_visitor::visit_assignment (assignment *e)
2059 {
2060 if (e->op == "=" || e->op == "<<<") // pure writes
2061 {
2062 expression* last_lvalue = current_lvalue;
2063 bool last_lvalue_read = current_lvalue_read;
2064 current_lvalue = e->left; // leave a mark for ::visit_symbol
2065 current_lvalue_read = true;
2066 functioncall_traversing_visitor::visit_assignment (e);
2067 current_lvalue = last_lvalue;
2068 current_lvalue_read = last_lvalue_read;
2069 }
2070 else // read-modify-writes
2071 {
2072 expression* last_lrvalue = current_lrvalue;
2073 current_lrvalue = e->left; // leave a mark for ::visit_symbol
2074 functioncall_traversing_visitor::visit_assignment (e);
2075 current_lrvalue = last_lrvalue;
2076 }
2077 }
2078
2079 void
2080 varuse_collecting_visitor::visit_symbol (symbol *e)
2081 {
2082 if (e->referent == 0)
2083 throw semantic_error (_("symbol without referent"), e->tok);
2084
2085 // We could handle initialized globals by marking them as "written".
2086 // However, this current visitor may be called for a function or
2087 // probe body, from the point of view of which this global is
2088 // already initialized, so not written.
2089 /*
2090 if (e->referent->init)
2091 written.insert (e->referent);
2092 */
2093
2094 if (current_lvalue == e || current_lrvalue == e)
2095 {
2096 written.insert (e->referent);
2097 }
2098 if (current_lvalue != e || current_lrvalue == e)
2099 {
2100 read.insert (e->referent);
2101 }
2102
2103 if (current_lrvalue == e)
2104 {
2105 if (current_lvalue_read)
2106 used.insert (e->referent);
2107 }
2108 else if (current_lvalue != e)
2109 used.insert (e->referent);
2110 }
2111
2112 // NB: stat_op need not be overridden, since it will get to
2113 // visit_symbol and only as a possible rvalue.
2114
2115
2116 void
2117 varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2118 {
2119 // Hooking this callback is necessary because of the hacky
2120 // statistics representation. For the expression "i[4] = 5", the
2121 // incoming lvalue will point to this arrayindex. However, the
2122 // symbol corresponding to the "i[4]" is multiply inherited with
2123 // arrayindex. If the symbol base part of this object is not at
2124 // offset 0, then static_cast<symbol*>(e) may result in a different
2125 // address, and not match lvalue by number when we recurse that way.
2126 // So we explicitly override the incoming lvalue/lrvalue values to
2127 // point at the embedded objects' actual base addresses.
2128
2129 expression* last_lrvalue = current_lrvalue;
2130 expression* last_lvalue = current_lvalue;
2131
2132 symbol *array = NULL;
2133 hist_op *hist = NULL;
2134 classify_indexable(e->base, array, hist);
2135
2136 if (array)
2137 {
2138 if (current_lrvalue == e) current_lrvalue = array;
2139 if (current_lvalue == e) current_lvalue = array;
2140 functioncall_traversing_visitor::visit_arrayindex (e);
2141 }
2142 else // if (hist)
2143 {
2144 if (current_lrvalue == e) current_lrvalue = hist->stat;
2145 if (current_lvalue == e) current_lvalue = hist->stat;
2146 functioncall_traversing_visitor::visit_arrayindex (e);
2147 }
2148
2149 current_lrvalue = last_lrvalue;
2150 current_lvalue = last_lvalue;
2151 }
2152
2153
2154 void
2155 varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2156 {
2157 expression* last_lrvalue = current_lrvalue;
2158 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2159 functioncall_traversing_visitor::visit_pre_crement (e);
2160 current_lrvalue = last_lrvalue;
2161 }
2162
2163 void
2164 varuse_collecting_visitor::visit_post_crement (post_crement *e)
2165 {
2166 expression* last_lrvalue = current_lrvalue;
2167 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
2168 functioncall_traversing_visitor::visit_post_crement (e);
2169 current_lrvalue = last_lrvalue;
2170 }
2171
2172 void
2173 varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2174 {
2175 // NB: we duplicate so don't bother call
2176 // functioncall_traversing_visitor::visit_foreach_loop (s);
2177
2178 symbol *array = NULL;
2179 hist_op *hist = NULL;
2180 classify_indexable (s->base, array, hist);
2181 if (array)
2182 array->visit(this);
2183 else
2184 hist->visit(this);
2185
2186 // If the collection is sorted, imply a "write" access to the
2187 // array in addition to the "read" one already noted above.
2188 if (s->sort_direction)
2189 {
2190 symbol *array = NULL;
2191 hist_op *hist = NULL;
2192 classify_indexable (s->base, array, hist);
2193 if (array) this->written.insert (array->referent);
2194 // XXX: Can hist_op iterations be sorted?
2195 }
2196
2197 // NB: don't forget to visit the index expressions, which are lvalues.
2198 for (unsigned i=0; i<s->indexes.size(); i++)
2199 {
2200 expression* last_lvalue = current_lvalue;
2201 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2202 s->indexes[i]->visit (this);
2203 current_lvalue = last_lvalue;
2204 }
2205
2206 // The value is an lvalue too
2207 if (s->value)
2208 {
2209 expression* last_lvalue = current_lvalue;
2210 current_lvalue = s->value; // leave a mark for ::visit_symbol
2211 s->value->visit (this);
2212 current_lvalue = last_lvalue;
2213 }
2214
2215 if (s->limit)
2216 s->limit->visit (this);
2217
2218 s->block->visit (this);
2219 }
2220
2221
2222 void
2223 varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2224 {
2225 // Ideally, this would be treated like an assignment: a plain write
2226 // to the underlying value ("lvalue"). XXX: However, the
2227 // optimization pass is not smart enough to remove an unneeded
2228 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2229 // should protect the underlying value from optimizional mischief.
2230 expression* last_lrvalue = current_lrvalue;
2231 bool last_lvalue_read = current_lvalue_read;
2232 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2233 current_lvalue_read = true;
2234 functioncall_traversing_visitor::visit_delete_statement (s);
2235 current_lrvalue = last_lrvalue;
2236 current_lvalue_read = last_lvalue_read;
2237 }
2238
2239 bool
2240 varuse_collecting_visitor::side_effect_free ()
2241 {
2242 return (written.empty() && !embedded_seen);
2243 }
2244
2245
2246 bool
2247 varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2248 {
2249 // A looser notion of side-effect-freeness with respect to a given
2250 // list of variables.
2251
2252 // That's useful because the written list may consist of local
2253 // variables of called functions. But visible side-effects only
2254 // occur if the client's locals, or any globals are written-to.
2255
2256 set<vardecl*> intersection;
2257 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2258 set_intersection (written.begin(), written.end(),
2259 vars.begin(), vars.end(),
2260 int_it);
2261
2262 return (intersection.empty() && !embedded_seen);
2263 }
2264
2265
2266
2267
2268 // ------------------------------------------------------------------------
2269
2270
2271 throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2272 throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2273
2274
2275 void
2276 throwing_visitor::throwone (const token* t)
2277 {
2278 throw semantic_error (msg, t);
2279 }
2280
2281 void
2282 throwing_visitor::visit_block (block* s)
2283 {
2284 throwone (s->tok);
2285 }
2286
2287 void
2288 throwing_visitor::visit_try_block (try_block* s)
2289 {
2290 throwone (s->tok);
2291 }
2292
2293
2294 void
2295 throwing_visitor::visit_embeddedcode (embeddedcode* s)
2296 {
2297 throwone (s->tok);
2298 }
2299
2300 void
2301 throwing_visitor::visit_null_statement (null_statement* s)
2302 {
2303 throwone (s->tok);
2304 }
2305
2306 void
2307 throwing_visitor::visit_expr_statement (expr_statement* s)
2308 {
2309 throwone (s->tok);
2310 }
2311
2312 void
2313 throwing_visitor::visit_if_statement (if_statement* s)
2314 {
2315 throwone (s->tok);
2316 }
2317
2318 void
2319 throwing_visitor::visit_for_loop (for_loop* s)
2320 {
2321 throwone (s->tok);
2322 }
2323
2324 void
2325 throwing_visitor::visit_foreach_loop (foreach_loop* s)
2326 {
2327 throwone (s->tok);
2328 }
2329
2330 void
2331 throwing_visitor::visit_return_statement (return_statement* s)
2332 {
2333 throwone (s->tok);
2334 }
2335
2336 void
2337 throwing_visitor::visit_delete_statement (delete_statement* s)
2338 {
2339 throwone (s->tok);
2340 }
2341
2342 void
2343 throwing_visitor::visit_next_statement (next_statement* s)
2344 {
2345 throwone (s->tok);
2346 }
2347
2348 void
2349 throwing_visitor::visit_break_statement (break_statement* s)
2350 {
2351 throwone (s->tok);
2352 }
2353
2354 void
2355 throwing_visitor::visit_continue_statement (continue_statement* s)
2356 {
2357 throwone (s->tok);
2358 }
2359
2360 void
2361 throwing_visitor::visit_literal_string (literal_string* e)
2362 {
2363 throwone (e->tok);
2364 }
2365
2366 void
2367 throwing_visitor::visit_literal_number (literal_number* e)
2368 {
2369 throwone (e->tok);
2370 }
2371
2372 void
2373 throwing_visitor::visit_embedded_expr (embedded_expr* e)
2374 {
2375 throwone (e->tok);
2376 }
2377
2378 void
2379 throwing_visitor::visit_binary_expression (binary_expression* e)
2380 {
2381 throwone (e->tok);
2382 }
2383
2384 void
2385 throwing_visitor::visit_unary_expression (unary_expression* e)
2386 {
2387 throwone (e->tok);
2388 }
2389
2390 void
2391 throwing_visitor::visit_pre_crement (pre_crement* e)
2392 {
2393 throwone (e->tok);
2394 }
2395
2396 void
2397 throwing_visitor::visit_post_crement (post_crement* e)
2398 {
2399 throwone (e->tok);
2400 }
2401
2402
2403 void
2404 throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2405 {
2406 throwone (e->tok);
2407 }
2408
2409 void
2410 throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2411 {
2412 throwone (e->tok);
2413 }
2414
2415 void
2416 throwing_visitor::visit_array_in (array_in* e)
2417 {
2418 throwone (e->tok);
2419 }
2420
2421 void
2422 throwing_visitor::visit_comparison (comparison* e)
2423 {
2424 throwone (e->tok);
2425 }
2426
2427 void
2428 throwing_visitor::visit_concatenation (concatenation* e)
2429 {
2430 throwone (e->tok);
2431 }
2432
2433 void
2434 throwing_visitor::visit_ternary_expression (ternary_expression* e)
2435 {
2436 throwone (e->tok);
2437 }
2438
2439 void
2440 throwing_visitor::visit_assignment (assignment* e)
2441 {
2442 throwone (e->tok);
2443 }
2444
2445 void
2446 throwing_visitor::visit_symbol (symbol* e)
2447 {
2448 throwone (e->tok);
2449 }
2450
2451 void
2452 throwing_visitor::visit_target_symbol (target_symbol* e)
2453 {
2454 throwone (e->tok);
2455 }
2456
2457 void
2458 throwing_visitor::visit_cast_op (cast_op* e)
2459 {
2460 throwone (e->tok);
2461 }
2462
2463 void
2464 throwing_visitor::visit_defined_op (defined_op* e)
2465 {
2466 throwone (e->tok);
2467 }
2468
2469 void
2470 throwing_visitor::visit_entry_op (entry_op* e)
2471 {
2472 throwone (e->tok);
2473 }
2474
2475
2476 void
2477 throwing_visitor::visit_arrayindex (arrayindex* e)
2478 {
2479 throwone (e->tok);
2480 }
2481
2482 void
2483 throwing_visitor::visit_functioncall (functioncall* e)
2484 {
2485 throwone (e->tok);
2486 }
2487
2488 void
2489 throwing_visitor::visit_print_format (print_format* e)
2490 {
2491 throwone (e->tok);
2492 }
2493
2494 void
2495 throwing_visitor::visit_stat_op (stat_op* e)
2496 {
2497 throwone (e->tok);
2498 }
2499
2500 void
2501 throwing_visitor::visit_hist_op (hist_op* e)
2502 {
2503 throwone (e->tok);
2504 }
2505
2506
2507 // ------------------------------------------------------------------------
2508
2509
2510 void
2511 update_visitor::visit_block (block* s)
2512 {
2513 for (unsigned i = 0; i < s->statements.size(); ++i)
2514 replace (s->statements[i]);
2515 provide (s);
2516 }
2517
2518 void
2519 update_visitor::visit_try_block (try_block* s)
2520 {
2521 replace (s->try_block);
2522 replace (s->catch_error_var);
2523 replace (s->catch_block);
2524 provide (s);
2525 }
2526
2527 void
2528 update_visitor::visit_embeddedcode (embeddedcode* s)
2529 {
2530 provide (s);
2531 }
2532
2533 void
2534 update_visitor::visit_null_statement (null_statement* s)
2535 {
2536 provide (s);
2537 }
2538
2539 void
2540 update_visitor::visit_expr_statement (expr_statement* s)
2541 {
2542 replace (s->value);
2543 provide (s);
2544 }
2545
2546 void
2547 update_visitor::visit_if_statement (if_statement* s)
2548 {
2549 replace (s->condition);
2550 replace (s->thenblock);
2551 replace (s->elseblock);
2552 provide (s);
2553 }
2554
2555 void
2556 update_visitor::visit_for_loop (for_loop* s)
2557 {
2558 replace (s->init);
2559 replace (s->cond);
2560 replace (s->incr);
2561 replace (s->block);
2562 provide (s);
2563 }
2564
2565 void
2566 update_visitor::visit_foreach_loop (foreach_loop* s)
2567 {
2568 for (unsigned i = 0; i < s->indexes.size(); ++i)
2569 replace (s->indexes[i]);
2570 replace (s->base);
2571 replace (s->value);
2572 replace (s->limit);
2573 replace (s->block);
2574 provide (s);
2575 }
2576
2577 void
2578 update_visitor::visit_return_statement (return_statement* s)
2579 {
2580 replace (s->value);
2581 provide (s);
2582 }
2583
2584 void
2585 update_visitor::visit_delete_statement (delete_statement* s)
2586 {
2587 replace (s->value);
2588 provide (s);
2589 }
2590
2591 void
2592 update_visitor::visit_next_statement (next_statement* s)
2593 {
2594 provide (s);
2595 }
2596
2597 void
2598 update_visitor::visit_break_statement (break_statement* s)
2599 {
2600 provide (s);
2601 }
2602
2603 void
2604 update_visitor::visit_continue_statement (continue_statement* s)
2605 {
2606 provide (s);
2607 }
2608
2609 void
2610 update_visitor::visit_literal_string (literal_string* e)
2611 {
2612 provide (e);
2613 }
2614
2615 void
2616 update_visitor::visit_literal_number (literal_number* e)
2617 {
2618 provide (e);
2619 }
2620
2621 void
2622 update_visitor::visit_embedded_expr (embedded_expr* e)
2623 {
2624 provide (e);
2625 }
2626
2627 void
2628 update_visitor::visit_binary_expression (binary_expression* e)
2629 {
2630 replace (e->left);
2631 replace (e->right);
2632 provide (e);
2633 }
2634
2635 void
2636 update_visitor::visit_unary_expression (unary_expression* e)
2637 {
2638 replace (e->operand);
2639 provide (e);
2640 }
2641
2642 void
2643 update_visitor::visit_pre_crement (pre_crement* e)
2644 {
2645 replace (e->operand);
2646 provide (e);
2647 }
2648
2649 void
2650 update_visitor::visit_post_crement (post_crement* e)
2651 {
2652 replace (e->operand);
2653 provide (e);
2654 }
2655
2656
2657 void
2658 update_visitor::visit_logical_or_expr (logical_or_expr* e)
2659 {
2660 replace (e->left);
2661 replace (e->right);
2662 provide (e);
2663 }
2664
2665 void
2666 update_visitor::visit_logical_and_expr (logical_and_expr* e)
2667 {
2668 replace (e->left);
2669 replace (e->right);
2670 provide (e);
2671 }
2672
2673 void
2674 update_visitor::visit_array_in (array_in* e)
2675 {
2676 replace (e->operand);
2677 provide (e);
2678 }
2679
2680 void
2681 update_visitor::visit_comparison (comparison* e)
2682 {
2683 replace (e->left);
2684 replace (e->right);
2685 provide (e);
2686 }
2687
2688 void
2689 update_visitor::visit_concatenation (concatenation* e)
2690 {
2691 replace (e->left);
2692 replace (e->right);
2693 provide (e);
2694 }
2695
2696 void
2697 update_visitor::visit_ternary_expression (ternary_expression* e)
2698 {
2699 replace (e->cond);
2700 replace (e->truevalue);
2701 replace (e->falsevalue);
2702 provide (e);
2703 }
2704
2705 void
2706 update_visitor::visit_assignment (assignment* e)
2707 {
2708 replace (e->left);
2709 replace (e->right);
2710 provide (e);
2711 }
2712
2713 void
2714 update_visitor::visit_symbol (symbol* e)
2715 {
2716 provide (e);
2717 }
2718
2719 void
2720 update_visitor::visit_target_symbol (target_symbol* e)
2721 {
2722 e->visit_components (this);
2723 provide (e);
2724 }
2725
2726 void
2727 update_visitor::visit_cast_op (cast_op* e)
2728 {
2729 replace (e->operand);
2730 e->visit_components (this);
2731 provide (e);
2732 }
2733
2734 void
2735 update_visitor::visit_defined_op (defined_op* e)
2736 {
2737 replace (e->operand);
2738 provide (e);
2739 }
2740
2741 void
2742 update_visitor::visit_entry_op (entry_op* e)
2743 {
2744 replace (e->operand);
2745 provide (e);
2746 }
2747
2748 void
2749 update_visitor::visit_arrayindex (arrayindex* e)
2750 {
2751 replace (e->base);
2752 for (unsigned i = 0; i < e->indexes.size(); ++i)
2753 replace (e->indexes[i]);
2754 provide (e);
2755 }
2756
2757 void
2758 update_visitor::visit_functioncall (functioncall* e)
2759 {
2760 for (unsigned i = 0; i < e->args.size(); ++i)
2761 replace (e->args[i]);
2762 provide (e);
2763 }
2764
2765 void
2766 update_visitor::visit_print_format (print_format* e)
2767 {
2768 for (unsigned i = 0; i < e->args.size(); ++i)
2769 replace (e->args[i]);
2770 replace (e->hist);
2771 provide (e);
2772 }
2773
2774 void
2775 update_visitor::visit_stat_op (stat_op* e)
2776 {
2777 replace (e->stat);
2778 provide (e);
2779 }
2780
2781 void
2782 update_visitor::visit_hist_op (hist_op* e)
2783 {
2784 replace (e->stat);
2785 provide (e);
2786 }
2787
2788 template <> indexable*
2789 update_visitor::require <indexable> (indexable* src, bool clearok)
2790 {
2791 indexable *dst = NULL;
2792 if (src != NULL)
2793 {
2794 symbol *array_src=NULL;
2795 hist_op *hist_src=NULL;
2796
2797 classify_indexable(src, array_src, hist_src);
2798
2799 if (array_src)
2800 dst = require (array_src);
2801 else
2802 dst = require (hist_src);
2803 assert(clearok || dst);
2804 }
2805 return dst;
2806 }
2807
2808
2809 // ------------------------------------------------------------------------
2810
2811
2812 void
2813 deep_copy_visitor::visit_block (block* s)
2814 {
2815 update_visitor::visit_block(new block(*s));
2816 }
2817
2818 void
2819 deep_copy_visitor::visit_try_block (try_block* s)
2820 {
2821 update_visitor::visit_try_block(new try_block(*s));
2822 }
2823
2824 void
2825 deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2826 {
2827 update_visitor::visit_embeddedcode(new embeddedcode(*s));
2828 }
2829
2830 void
2831 deep_copy_visitor::visit_null_statement (null_statement* s)
2832 {
2833 update_visitor::visit_null_statement(new null_statement(*s));
2834 }
2835
2836 void
2837 deep_copy_visitor::visit_expr_statement (expr_statement* s)
2838 {
2839 update_visitor::visit_expr_statement(new expr_statement(*s));
2840 }
2841
2842 void
2843 deep_copy_visitor::visit_if_statement (if_statement* s)
2844 {
2845 update_visitor::visit_if_statement(new if_statement(*s));
2846 }
2847
2848 void
2849 deep_copy_visitor::visit_for_loop (for_loop* s)
2850 {
2851 update_visitor::visit_for_loop(new for_loop(*s));
2852 }
2853
2854 void
2855 deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2856 {
2857 update_visitor::visit_foreach_loop(new foreach_loop(*s));
2858 }
2859
2860 void
2861 deep_copy_visitor::visit_return_statement (return_statement* s)
2862 {
2863 update_visitor::visit_return_statement(new return_statement(*s));
2864 }
2865
2866 void
2867 deep_copy_visitor::visit_delete_statement (delete_statement* s)
2868 {
2869 update_visitor::visit_delete_statement(new delete_statement(*s));
2870 }
2871
2872 void
2873 deep_copy_visitor::visit_next_statement (next_statement* s)
2874 {
2875 update_visitor::visit_next_statement(new next_statement(*s));
2876 }
2877
2878 void
2879 deep_copy_visitor::visit_break_statement (break_statement* s)
2880 {
2881 update_visitor::visit_break_statement(new break_statement(*s));
2882 }
2883
2884 void
2885 deep_copy_visitor::visit_continue_statement (continue_statement* s)
2886 {
2887 update_visitor::visit_continue_statement(new continue_statement(*s));
2888 }
2889
2890 void
2891 deep_copy_visitor::visit_literal_string (literal_string* e)
2892 {
2893 update_visitor::visit_literal_string(new literal_string(*e));
2894 }
2895
2896 void
2897 deep_copy_visitor::visit_literal_number (literal_number* e)
2898 {
2899 update_visitor::visit_literal_number(new literal_number(*e));
2900 }
2901
2902 void
2903 deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2904 {
2905 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2906 }
2907
2908 void
2909 deep_copy_visitor::visit_binary_expression (binary_expression* e)
2910 {
2911 update_visitor::visit_binary_expression(new binary_expression(*e));
2912 }
2913
2914 void
2915 deep_copy_visitor::visit_unary_expression (unary_expression* e)
2916 {
2917 update_visitor::visit_unary_expression(new unary_expression(*e));
2918 }
2919
2920 void
2921 deep_copy_visitor::visit_pre_crement (pre_crement* e)
2922 {
2923 update_visitor::visit_pre_crement(new pre_crement(*e));
2924 }
2925
2926 void
2927 deep_copy_visitor::visit_post_crement (post_crement* e)
2928 {
2929 update_visitor::visit_post_crement(new post_crement(*e));
2930 }
2931
2932
2933 void
2934 deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2935 {
2936 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
2937 }
2938
2939 void
2940 deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2941 {
2942 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
2943 }
2944
2945 void
2946 deep_copy_visitor::visit_array_in (array_in* e)
2947 {
2948 update_visitor::visit_array_in(new array_in(*e));
2949 }
2950
2951 void
2952 deep_copy_visitor::visit_comparison (comparison* e)
2953 {
2954 update_visitor::visit_comparison(new comparison(*e));
2955 }
2956
2957 void
2958 deep_copy_visitor::visit_concatenation (concatenation* e)
2959 {
2960 update_visitor::visit_concatenation(new concatenation(*e));
2961 }
2962
2963 void
2964 deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2965 {
2966 update_visitor::visit_ternary_expression(new ternary_expression(*e));
2967 }
2968
2969 void
2970 deep_copy_visitor::visit_assignment (assignment* e)
2971 {
2972 update_visitor::visit_assignment(new assignment(*e));
2973 }
2974
2975 void
2976 deep_copy_visitor::visit_symbol (symbol* e)
2977 {
2978 symbol* n = new symbol(*e);
2979 n->referent = NULL; // don't copy!
2980 update_visitor::visit_symbol(n);
2981 }
2982
2983 void
2984 deep_copy_visitor::visit_target_symbol (target_symbol* e)
2985 {
2986 target_symbol* n = new target_symbol(*e);
2987 n->referent = NULL; // don't copy!
2988 update_visitor::visit_target_symbol(n);
2989 }
2990
2991 void
2992 deep_copy_visitor::visit_cast_op (cast_op* e)
2993 {
2994 update_visitor::visit_cast_op(new cast_op(*e));
2995 }
2996
2997 void
2998 deep_copy_visitor::visit_defined_op (defined_op* e)
2999 {
3000 update_visitor::visit_defined_op(new defined_op(*e));
3001 }
3002
3003 void
3004 deep_copy_visitor::visit_entry_op (entry_op* e)
3005 {
3006 update_visitor::visit_entry_op(new entry_op(*e));
3007 }
3008
3009 void
3010 deep_copy_visitor::visit_arrayindex (arrayindex* e)
3011 {
3012 update_visitor::visit_arrayindex(new arrayindex(*e));
3013 }
3014
3015 void
3016 deep_copy_visitor::visit_functioncall (functioncall* e)
3017 {
3018 functioncall* n = new functioncall(*e);
3019 n->referent = NULL; // don't copy!
3020 update_visitor::visit_functioncall(n);
3021 }
3022
3023 void
3024 deep_copy_visitor::visit_print_format (print_format* e)
3025 {
3026 update_visitor::visit_print_format(new print_format(*e));
3027 }
3028
3029 void
3030 deep_copy_visitor::visit_stat_op (stat_op* e)
3031 {
3032 update_visitor::visit_stat_op(new stat_op(*e));
3033 }
3034
3035 void
3036 deep_copy_visitor::visit_hist_op (hist_op* e)
3037 {
3038 update_visitor::visit_hist_op(new hist_op(*e));
3039 }
3040
3041 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.170107 seconds and 5 git commands to generate.