1 : // parse tree functions
2 : // Copyright (C) 2005-2008 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 :
14 : #include <iostream>
15 : #include <typeinfo>
16 : #include <sstream>
17 : #include <cassert>
18 : #include <cstring>
19 : #include <vector>
20 : #include <algorithm>
21 : #include <cstring>
22 :
23 : using namespace std;
24 :
25 :
26 :
27 27577864 : expression::expression ():
28 27577864 : type (pe_unknown), tok (0)
29 : {
30 27577864 : }
31 :
32 :
33 10 : expression::~expression ()
34 : {
35 10 : }
36 :
37 :
38 10275975 : statement::statement ():
39 10275975 : tok (0)
40 : {
41 10275975 : }
42 :
43 :
44 97 : statement::~statement ()
45 : {
46 97 : }
47 :
48 :
49 10968930 : symbol::symbol ():
50 10968930 : referent (0)
51 : {
52 10968930 : }
53 :
54 :
55 549344 : arrayindex::arrayindex ():
56 549344 : base (0)
57 : {
58 549344 : }
59 :
60 :
61 2128495 : functioncall::functioncall ():
62 2128495 : referent (0)
63 : {
64 2128495 : }
65 :
66 :
67 907676 : symboldecl::symboldecl ():
68 : tok (0),
69 907676 : type (pe_unknown)
70 : {
71 907676 : }
72 :
73 :
74 97 : symboldecl::~symboldecl ()
75 : {
76 97 : }
77 :
78 : probe_point::probe_point (std::vector<component*> const & comps,
79 0 : const token * t):
80 : components(comps), tok(t), optional (false), sufficient (false),
81 0 : condition (0)
82 : {
83 0 : }
84 :
85 : // NB: shallow-copy of compoonents & condition!
86 528246 : probe_point::probe_point (const probe_point& pp):
87 : components(pp.components), tok(pp.tok), optional (pp.optional), sufficient (pp.sufficient),
88 528246 : condition (pp.condition)
89 : {
90 528246 : }
91 :
92 :
93 2983463 : probe_point::probe_point ():
94 2983463 : tok (0), optional (false), sufficient (false), condition (0)
95 : {
96 2983463 : }
97 :
98 :
99 : unsigned probe::last_probeidx = 0;
100 1687493 : probe::probe ():
101 1687493 : body (0), tok (0)
102 : {
103 1687493 : this->name = string ("probe_") + lex_cast<string>(last_probeidx ++);
104 1687493 : }
105 :
106 :
107 7963364 : probe_point::component::component ():
108 7963364 : arg (0)
109 : {
110 7963364 : }
111 :
112 :
113 1243662 : probe_point::component::component (std::string const & f, literal * a):
114 1243662 : functor(f), arg(a)
115 : {
116 1243662 : }
117 :
118 :
119 493379 : vardecl::vardecl ():
120 493379 : arity (-1), maxsize(0), init(NULL)
121 : {
122 493379 : }
123 :
124 :
125 : void
126 410058 : vardecl::set_arity (int a)
127 : {
128 410058 : if (a < 0)
129 78 : return;
130 :
131 409980 : if ((arity != a && arity >= 0) || (a == 0 && maxsize > 0))
132 0 : throw semantic_error ("inconsistent arity", tok);
133 :
134 409980 : if (arity != a)
135 : {
136 89897 : arity = a;
137 89897 : index_types.resize (arity);
138 90408 : for (int i=0; i<arity; i++)
139 511 : index_types[i] = pe_unknown;
140 : }
141 : }
142 :
143 : bool
144 373602 : vardecl::compatible_arity (int a)
145 : {
146 373602 : if (a == 0 && maxsize > 0)
147 4 : return false;
148 373598 : if (arity == -1 || a == -1)
149 86933 : return true;
150 286665 : return arity == a;
151 : }
152 :
153 :
154 414297 : functiondecl::functiondecl ():
155 414297 : body (0)
156 : {
157 414297 : }
158 :
159 :
160 1858812 : literal_number::literal_number (int64_t v)
161 : {
162 1858812 : value = v;
163 1858812 : type = pe_long;
164 1858812 : }
165 :
166 :
167 4672774 : literal_string::literal_string (const string& v)
168 : {
169 4672774 : value = v;
170 4672774 : type = pe_string;
171 4672774 : }
172 :
173 :
174 : ostream&
175 181571 : operator << (ostream& o, const exp_type& e)
176 : {
177 181571 : switch (e)
178 : {
179 424 : case pe_unknown: o << "unknown"; break;
180 93362 : case pe_long: o << "long"; break;
181 87709 : case pe_string: o << "string"; break;
182 76 : case pe_stats: o << "stats"; break;
183 0 : default: o << "???"; break;
184 : }
185 181571 : return o;
186 : }
187 :
188 :
189 : // ------------------------------------------------------------------------
190 : // parse tree printing
191 :
192 3117981 : ostream& operator << (ostream& o, const expression& k)
193 : {
194 3117981 : k.print (o);
195 3117981 : return o;
196 : }
197 :
198 :
199 1850610 : void literal_string::print (ostream& o) const
200 : {
201 1850610 : o << '"';
202 27442426 : for (unsigned i=0; i<value.size(); i++)
203 25591816 : if (value[i] == '"') // or other escapeworthy characters?
204 6 : o << '\\' << '"';
205 : else
206 25591810 : o << value[i];
207 1850610 : o << '"';
208 1850610 : }
209 :
210 :
211 158369 : void literal_number::print (ostream& o) const
212 : {
213 158369 : o << value;
214 158369 : }
215 :
216 :
217 303629 : void binary_expression::print (ostream& o) const
218 : {
219 : o << "(" << *left << ") "
220 : << op
221 303629 : << " (" << *right << ")";
222 303629 : }
223 :
224 :
225 4042 : void unary_expression::print (ostream& o) const
226 : {
227 4042 : o << op << '(' << *operand << ")";
228 4042 : }
229 :
230 217 : void array_in::print (ostream& o) const
231 : {
232 217 : o << "[";
233 489 : for (unsigned i=0; i<operand->indexes.size(); i++)
234 : {
235 272 : if (i > 0) o << ", ";
236 272 : operand->indexes[i]->print (o);
237 : }
238 217 : o << "] in ";
239 217 : operand->base->print_indexable (o);
240 217 : }
241 :
242 51443 : void post_crement::print (ostream& o) const
243 : {
244 51443 : o << '(' << *operand << ")" << op;
245 51443 : }
246 :
247 :
248 119 : void ternary_expression::print (ostream& o) const
249 : {
250 : o << "(" << *cond << ")?("
251 : << *truevalue << "):("
252 119 : << *falsevalue << ")";
253 119 : }
254 :
255 :
256 597914 : void symbol::print (ostream& o) const
257 : {
258 597914 : o << name;
259 597914 : }
260 :
261 :
262 2772 : void target_symbol::print (std::ostream& o) const
263 : {
264 2772 : o << base_name;
265 3447 : for (unsigned i = 0; i < components.size(); ++i)
266 : {
267 675 : switch (components[i].first)
268 : {
269 : case comp_literal_array_index:
270 7 : o << '[' << components[i].second << ']';
271 7 : break;
272 : case comp_struct_member:
273 668 : o << "->" << components[i].second;
274 : break;
275 : }
276 : }
277 2772 : }
278 :
279 :
280 17390 : void vardecl::print (ostream& o) const
281 : {
282 17390 : o << name;
283 17390 : if (maxsize > 0)
284 17 : o << "[" << maxsize << "]";
285 17390 : if (arity > 0 || index_types.size() > 0)
286 0 : o << "[...]";
287 17390 : if (init)
288 : {
289 15 : o << " = ";
290 15 : init->print(o);
291 : }
292 17390 : }
293 :
294 :
295 82842 : void vardecl::printsig (ostream& o) const
296 : {
297 82842 : o << name;
298 82842 : if (maxsize > 0)
299 19 : o << "[" << maxsize << "]";
300 82842 : o << ":" << type;
301 82842 : if (index_types.size() > 0)
302 : {
303 343 : o << " [";
304 804 : for (unsigned i=0; i<index_types.size(); i++)
305 461 : o << (i>0 ? ", " : "") << index_types[i];
306 343 : o << "]";
307 : }
308 82842 : }
309 :
310 :
311 385 : void functiondecl::print (ostream& o) const
312 : {
313 385 : o << "function " << name << " (";
314 729 : for (unsigned i=0; i<formal_args.size(); i++)
315 344 : o << (i>0 ? ", " : "") << *formal_args[i];
316 385 : o << ")" << endl;
317 385 : body->print(o);
318 385 : }
319 :
320 :
321 81500 : void functiondecl::printsig (ostream& o) const
322 : {
323 81500 : o << name << ":" << type << " (";
324 98227 : for (unsigned i=0; i<formal_args.size(); i++)
325 : o << (i>0 ? ", " : "")
326 : << *formal_args[i]
327 : << ":"
328 16727 : << formal_args[i]->type;
329 81500 : o << ")";
330 81500 : }
331 :
332 :
333 59725 : void arrayindex::print (ostream& o) const
334 : {
335 59725 : base->print_indexable (o);
336 59725 : o << "[";
337 121396 : for (unsigned i=0; i<indexes.size(); i++)
338 61671 : o << (i>0 ? ", " : "") << *indexes[i];
339 59725 : o << "]";
340 59725 : }
341 :
342 :
343 273025 : void functioncall::print (ostream& o) const
344 : {
345 273025 : o << function << "(";
346 338922 : for (unsigned i=0; i<args.size(); i++)
347 65897 : o << (i>0 ? ", " : "") << *args[i];
348 273025 : o << ")";
349 273025 : }
350 :
351 :
352 : bool
353 : print_format::parse_print(const std::string &name,
354 10996535 : bool &stream, bool &format, bool &delim, bool &newline, bool &_char)
355 : {
356 10996535 : const char *n = name.c_str();
357 :
358 10996535 : stream = true;
359 10996535 : format = delim = newline = _char = false;
360 :
361 10996535 : if (strcmp(n, "print_char") == 0)
362 : {
363 14 : _char = true;
364 14 : return true;
365 : }
366 :
367 10996521 : if (*n == 's')
368 : {
369 1128441 : stream = false;
370 1128441 : ++n;
371 : }
372 :
373 10996521 : if (0 != strncmp(n, "print", 5))
374 10401227 : return false;
375 595294 : n += 5;
376 :
377 595294 : if (*n == 'f')
378 : {
379 569404 : format = true;
380 569404 : ++n;
381 : }
382 : else
383 : {
384 25890 : if (*n == 'd')
385 : {
386 39 : delim = true;
387 39 : ++n;
388 : }
389 :
390 25890 : if (*n == 'l' && *(n+1) == 'n')
391 : {
392 155 : newline = true;
393 155 : n += 2;
394 : }
395 : }
396 :
397 595294 : return (*n == '\0');
398 : }
399 :
400 :
401 : string
402 4577 : print_format::components_to_string(vector<format_component> const & components)
403 : {
404 4577 : ostringstream oss;
405 :
406 22581 : for (vector<format_component>::const_iterator i = components.begin();
407 : i != components.end(); ++i)
408 : {
409 :
410 18004 : assert (i->type != conv_unspecified);
411 :
412 18004 : if (i->type == conv_literal)
413 : {
414 8520 : assert(!i->literal_string.empty());
415 35453 : for (string::const_iterator j = i->literal_string.begin();
416 : j != i->literal_string.end(); ++j)
417 : {
418 : // See also: c_unparser::visit_literal_string and lex_cast_qstring
419 26933 : if (*j == '%')
420 8 : oss << '%';
421 26925 : else if(*j == '"')
422 36 : oss << '\\';
423 26933 : oss << *j;
424 : }
425 : }
426 : else
427 : {
428 9484 : oss << '%';
429 :
430 9484 : if (i->flags & static_cast<unsigned long>(fmt_flag_zeropad))
431 33 : oss << '0';
432 :
433 9484 : if (i->flags & static_cast<unsigned long>(fmt_flag_plus))
434 1 : oss << '+';
435 :
436 9484 : if (i->flags & static_cast<unsigned long>(fmt_flag_space))
437 2 : oss << ' ';
438 :
439 9484 : if (i->flags & static_cast<unsigned long>(fmt_flag_left))
440 61 : oss << '-';
441 :
442 9484 : if (i->flags & static_cast<unsigned long>(fmt_flag_special))
443 34 : oss << '#';
444 :
445 9484 : if (i->widthtype == width_dynamic)
446 13 : oss << '*';
447 9471 : else if (i->widthtype != width_unspecified && i->width > 0)
448 254 : oss << i->width;
449 :
450 9484 : if (i->prectype == prec_dynamic)
451 14 : oss << ".*";
452 9470 : else if (i->prectype != prec_unspecified && i->precision > 0)
453 19 : oss << '.' << i->precision;
454 :
455 9484 : switch (i->type)
456 : {
457 : case conv_binary:
458 78 : oss << "b";
459 78 : break;
460 :
461 : case conv_signed_decimal:
462 2158 : oss << "lld";
463 2158 : break;
464 :
465 : case conv_unsigned_decimal:
466 24 : oss << "llu";
467 24 : break;
468 :
469 : case conv_unsigned_octal:
470 54 : oss << "llo";
471 54 : break;
472 :
473 : case conv_unsigned_ptr:
474 807 : oss << "p";
475 807 : break;
476 :
477 : case conv_unsigned_uppercase_hex:
478 11 : oss << "llX";
479 11 : break;
480 :
481 : case conv_unsigned_lowercase_hex:
482 89 : oss << "llx";
483 89 : break;
484 :
485 : case conv_string:
486 6246 : oss << 's';
487 6246 : break;
488 :
489 : case conv_memory:
490 17 : oss << 'm';
491 17 : break;
492 :
493 : case conv_size:
494 0 : oss << 'n';
495 : break;
496 :
497 : default:
498 : break;
499 : }
500 : }
501 : }
502 4577 : return oss.str ();
503 : }
504 :
505 : vector<print_format::format_component>
506 569404 : print_format::string_to_components(string const & str)
507 : {
508 569404 : format_component curr;
509 569404 : vector<format_component> res;
510 :
511 569404 : curr.clear();
512 :
513 569404 : string::const_iterator i = str.begin();
514 :
515 4445189 : while (i != str.end())
516 : {
517 3306381 : if (*i != '%')
518 : {
519 1959366 : assert (curr.type == conv_unspecified || curr.type == conv_literal);
520 1959366 : curr.type = conv_literal;
521 1959366 : curr.literal_string += *i;
522 1959366 : ++i;
523 1959366 : continue;
524 : }
525 1347015 : else if (i+1 == str.end() || *(i+1) == '%')
526 : {
527 2164 : assert(*i == '%');
528 : // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
529 2164 : assert (curr.type == conv_unspecified || curr.type == conv_literal);
530 2164 : curr.type = conv_literal;
531 2164 : curr.literal_string += '%';
532 2164 : i += 2;
533 2164 : continue;
534 : }
535 : else
536 : {
537 1344851 : assert(*i == '%');
538 1344851 : if (curr.type != conv_unspecified)
539 : {
540 : // Flush any component we were previously accumulating
541 811879 : assert (curr.type == conv_literal);
542 811879 : res.push_back(curr);
543 811879 : curr.clear();
544 : }
545 : }
546 1344851 : ++i;
547 :
548 1344851 : if (i == str.end())
549 0 : break;
550 :
551 : // Now we are definitely parsing a conversion.
552 : // Begin by parsing flags (which are optional).
553 :
554 1344851 : switch (*i)
555 : {
556 : case '0':
557 2201 : curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
558 2201 : ++i;
559 2201 : break;
560 :
561 : case '+':
562 3 : curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
563 3 : ++i;
564 3 : break;
565 :
566 : case '-':
567 59 : curr.flags |= static_cast<unsigned long>(fmt_flag_left);
568 59 : ++i;
569 59 : break;
570 :
571 : case ' ':
572 6 : curr.flags |= static_cast<unsigned long>(fmt_flag_space);
573 6 : ++i;
574 6 : break;
575 :
576 : case '#':
577 9741 : curr.flags |= static_cast<unsigned long>(fmt_flag_special);
578 9741 : ++i;
579 : break;
580 :
581 : default:
582 : break;
583 : }
584 :
585 1344851 : if (i == str.end())
586 0 : break;
587 :
588 : // Parse optional width
589 1344851 : if (*i == '*')
590 : {
591 13 : curr.widthtype = width_dynamic;
592 13 : ++i;
593 : }
594 1344838 : else if (isdigit(*i))
595 : {
596 3509 : curr.widthtype = width_static;
597 3509 : curr.width = 0;
598 3610 : do
599 : {
600 3610 : curr.width *= 10;
601 3610 : curr.width += (*i - '0');
602 3610 : ++i;
603 : }
604 : while (i != str.end() && isdigit(*i));
605 : }
606 :
607 1344851 : if (i == str.end())
608 0 : break;
609 :
610 : // Parse optional precision
611 1344851 : if (*i == '.')
612 : {
613 37 : ++i;
614 37 : if (i == str.end())
615 0 : break;
616 37 : if (*i == '*')
617 : {
618 14 : curr.prectype = prec_dynamic;
619 14 : ++i;
620 : }
621 23 : else if (isdigit(*i))
622 : {
623 23 : curr.prectype = prec_static;
624 23 : curr.precision = 0;
625 23 : do
626 : {
627 23 : curr.precision *= 10;
628 23 : curr.precision += (*i - '0');
629 23 : ++i;
630 : }
631 : while (i != str.end() && isdigit(*i));
632 : }
633 : }
634 :
635 1344851 : if (i == str.end())
636 0 : break;
637 :
638 : // Parse the actual conversion specifier (sdiouxX)
639 1344851 : switch (*i)
640 : {
641 : // Valid conversion types
642 : case 'b':
643 78 : curr.type = conv_binary;
644 78 : break;
645 :
646 : case 's':
647 304890 : curr.type = conv_string;
648 304890 : break;
649 :
650 : case 'm':
651 17 : curr.type = conv_memory;
652 17 : break;
653 :
654 : case 'd':
655 : case 'i':
656 727002 : curr.type = conv_signed_decimal;
657 727002 : break;
658 :
659 : case 'o':
660 9761 : curr.type = conv_unsigned_octal;
661 9761 : break;
662 :
663 : case 'u':
664 26 : curr.type = conv_unsigned_decimal;
665 26 : break;
666 :
667 : case 'p':
668 280268 : curr.type = conv_unsigned_ptr;
669 280268 : break;
670 :
671 : case 'X':
672 13 : curr.type = conv_unsigned_uppercase_hex;
673 13 : break;
674 :
675 : case 'x':
676 22796 : curr.type = conv_unsigned_lowercase_hex;
677 22796 : break;
678 :
679 : case 'n':
680 0 : curr.type = conv_size;
681 : break;
682 :
683 : default:
684 : break;
685 : }
686 :
687 1344851 : if (curr.type == conv_unspecified)
688 0 : throw parse_error("invalid or missing conversion specifier");
689 :
690 1344851 : ++i;
691 1344851 : res.push_back(curr);
692 1344851 : curr.clear();
693 : }
694 :
695 : // If there's a remaining partly-composed conversion, fail.
696 569404 : if (!curr.is_empty())
697 : {
698 12032 : if (curr.type == conv_literal)
699 12032 : res.push_back(curr);
700 : else
701 0 : throw parse_error("trailing incomplete print format conversion");
702 : }
703 :
704 569404 : return res;
705 : }
706 :
707 :
708 132528 : void print_format::print (ostream& o) const
709 : {
710 132528 : o << tok->content << "(";
711 132528 : if (print_with_format)
712 128547 : o << lex_cast_qstring (raw_components);
713 132528 : if (print_with_delim)
714 89 : o << lex_cast_qstring (delimiter.literal_string);
715 132528 : if (hist)
716 275 : hist->print(o);
717 386745 : for (vector<expression*>::const_iterator i = args.begin();
718 : i != args.end(); ++i)
719 : {
720 254217 : if (i != args.begin() || print_with_format || print_with_delim)
721 250600 : o << ", ";
722 254217 : (*i)->print(o);
723 : }
724 132528 : o << ")";
725 132528 : }
726 :
727 767 : void stat_op::print (ostream& o) const
728 : {
729 767 : o << '@';
730 767 : switch (ctype)
731 : {
732 : case sc_average:
733 121 : o << "avg(";
734 121 : break;
735 :
736 : case sc_count:
737 322 : o << "count(";
738 322 : break;
739 :
740 : case sc_sum:
741 134 : o << "sum(";
742 134 : break;
743 :
744 : case sc_min:
745 95 : o << "min(";
746 95 : break;
747 :
748 : case sc_max:
749 95 : o << "max(";
750 : break;
751 : }
752 767 : stat->print(o);
753 767 : o << ")";
754 767 : }
755 :
756 : void
757 366 : hist_op::print (ostream& o) const
758 : {
759 366 : o << '@';
760 366 : switch (htype)
761 : {
762 : case hist_linear:
763 163 : assert(params.size() == 3);
764 163 : o << "hist_linear(";
765 163 : stat->print(o);
766 652 : for (size_t i = 0; i < params.size(); ++i)
767 : {
768 489 : o << ", " << params[i];
769 : }
770 163 : o << ")";
771 163 : break;
772 :
773 : case hist_log:
774 203 : assert(params.size() == 0);
775 203 : o << "hist_log(";
776 203 : stat->print(o);
777 203 : o << ")";
778 : break;
779 : }
780 366 : }
781 :
782 740369 : ostream& operator << (ostream& o, const statement& k)
783 : {
784 740369 : k.print (o);
785 740369 : return o;
786 : }
787 :
788 :
789 76841 : void embeddedcode::print (ostream &o) const
790 : {
791 76841 : o << "%{";
792 76841 : o << code;
793 76841 : o << "%}";
794 76841 : }
795 :
796 127198 : void block::print (ostream& o) const
797 : {
798 127198 : o << "{" << endl;
799 645442 : for (unsigned i=0; i<statements.size(); i++)
800 518244 : o << *statements [i] << endl;
801 127198 : o << "}";
802 127198 : }
803 :
804 :
805 565 : void for_loop::print (ostream& o) const
806 : {
807 565 : o << "for (";
808 565 : if (init) init->print (o);
809 565 : o << "; ";
810 565 : cond->print (o);
811 565 : o << "; ";
812 565 : if (incr) incr->print (o);
813 565 : o << ") ";
814 565 : block->print (o);
815 565 : }
816 :
817 :
818 407 : void foreach_loop::print (ostream& o) const
819 : {
820 407 : o << "foreach ([";
821 915 : for (unsigned i=0; i<indexes.size(); i++)
822 : {
823 508 : if (i > 0) o << ", ";
824 508 : indexes[i]->print (o);
825 508 : if (sort_direction != 0 && sort_column == i+1)
826 57 : o << (sort_direction > 0 ? "+" : "-");
827 : }
828 407 : o << "] in ";
829 407 : base->print_indexable (o);
830 407 : if (sort_direction != 0 && sort_column == 0)
831 88 : o << (sort_direction > 0 ? "+" : "-");
832 407 : if (limit)
833 : {
834 72 : o << " limit ";
835 72 : limit->print (o);
836 : }
837 407 : o << ") ";
838 407 : block->print (o);
839 407 : }
840 :
841 :
842 104150 : void null_statement::print (ostream& o) const
843 : {
844 104150 : o << ";";
845 104150 : }
846 :
847 :
848 329111 : void expr_statement::print (ostream& o) const
849 : {
850 329111 : o << *value;
851 329111 : }
852 :
853 :
854 62955 : void return_statement::print (ostream& o) const
855 : {
856 62955 : o << "return " << *value;
857 62955 : }
858 :
859 :
860 1737 : void delete_statement::print (ostream& o) const
861 : {
862 1737 : o << "delete " << *value;
863 1737 : }
864 :
865 2037 : void next_statement::print (ostream& o) const
866 : {
867 2037 : o << "next";
868 2037 : }
869 :
870 29 : void break_statement::print (ostream& o) const
871 : {
872 29 : o << "break";
873 29 : }
874 :
875 28 : void continue_statement::print (ostream& o) const
876 : {
877 28 : o << "continue";
878 28 : }
879 :
880 191558 : void if_statement::print (ostream& o) const
881 : {
882 : o << "if (" << *condition << ") "
883 191558 : << *thenblock << endl;
884 191558 : if (elseblock)
885 28530 : o << "else " << *elseblock << endl;
886 191558 : }
887 :
888 :
889 554 : void stapfile::print (ostream& o) const
890 : {
891 554 : o << "# file " << name << endl;
892 :
893 585 : for (unsigned i=0; i<embeds.size(); i++)
894 31 : embeds[i]->print (o);
895 :
896 873 : for (unsigned i=0; i<globals.size(); i++)
897 : {
898 319 : o << "global ";
899 319 : globals[i]->print (o);
900 319 : o << endl;
901 : }
902 :
903 1693 : for (unsigned i=0; i<aliases.size(); i++)
904 : {
905 1139 : aliases[i]->print (o);
906 1139 : o << endl;
907 : }
908 :
909 1452 : for (unsigned i=0; i<probes.size(); i++)
910 : {
911 898 : probes[i]->print (o);
912 898 : o << endl;
913 : }
914 :
915 939 : for (unsigned j = 0; j < functions.size(); j++)
916 : {
917 385 : functions[j]->print (o);
918 385 : o << endl;
919 : }
920 554 : }
921 :
922 :
923 2037 : void probe::print (ostream& o) const
924 : {
925 2037 : o << "probe ";
926 2037 : printsig (o);
927 2037 : o << *body;
928 2037 : }
929 :
930 :
931 539893 : void probe::printsig (ostream& o) const
932 : {
933 1139663 : for (unsigned i=0; i<locations.size(); i++)
934 : {
935 599770 : if (i > 0) o << ",";
936 599770 : locations[i]->print (o);
937 : }
938 539893 : }
939 :
940 :
941 : void
942 40973 : probe::collect_derivation_chain (std::vector<probe*> &probes_list)
943 : {
944 40973 : probes_list.push_back(this);
945 40973 : }
946 :
947 :
948 1108035 : void probe_point::print (ostream& o) const
949 : {
950 3891747 : for (unsigned i=0; i<components.size(); i++)
951 : {
952 2783712 : if (i>0) o << ".";
953 2783712 : probe_point::component* c = components[i];
954 2783712 : o << c->functor;
955 2783712 : if (c->arg)
956 1741887 : o << "(" << *c->arg << ")";
957 : }
958 1108035 : if (sufficient)
959 83 : o << "!";
960 1107952 : else if (optional) // sufficient implies optional
961 163432 : o << "?";
962 1108035 : if (condition)
963 65 : o<< " if (" << *condition << ")";
964 1108035 : }
965 :
966 0 : string probe_point::str ()
967 : {
968 0 : ostringstream o;
969 0 : for (unsigned i=0; i<components.size(); i++)
970 : {
971 0 : if (i>0) o << ".";
972 0 : probe_point::component* c = components[i];
973 0 : o << c->functor;
974 0 : if (c->arg)
975 0 : o << "(" << *c->arg << ")";
976 : }
977 0 : if (sufficient)
978 0 : o << "!";
979 0 : else if (optional) // sufficient implies optional
980 0 : o << "?";
981 0 : if (condition)
982 0 : o<< " if (" << *condition << ")";
983 0 : return o.str();
984 : }
985 :
986 :
987 1150295 : probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
988 1150295 : probe (), alias_names (aliases)
989 : {
990 1150295 : }
991 :
992 1140 : void probe_alias::printsig (ostream& o) const
993 : {
994 2280 : for (unsigned i=0; i<alias_names.size(); i++)
995 : {
996 1140 : o << (i>0 ? " = " : "");
997 1140 : alias_names[i]->print (o);
998 : }
999 1140 : o << " = ";
1000 2918 : for (unsigned i=0; i<locations.size(); i++)
1001 : {
1002 1778 : if (i > 0) o << ", ";
1003 1778 : locations[i]->print (o);
1004 : }
1005 1140 : }
1006 :
1007 :
1008 18183 : ostream& operator << (ostream& o, const probe_point& k)
1009 : {
1010 18183 : k.print (o);
1011 18183 : return o;
1012 : }
1013 :
1014 :
1015 17071 : ostream& operator << (ostream& o, const symboldecl& k)
1016 : {
1017 17071 : k.print (o);
1018 17071 : return o;
1019 : }
1020 :
1021 :
1022 :
1023 : // ------------------------------------------------------------------------
1024 : // visitors
1025 :
1026 :
1027 : void
1028 7417538 : block::visit (visitor* u)
1029 : {
1030 7417538 : u->visit_block (this);
1031 7417531 : }
1032 :
1033 :
1034 : void
1035 2055137 : embeddedcode::visit (visitor* u)
1036 : {
1037 2055137 : u->visit_embeddedcode (this);
1038 2055137 : }
1039 :
1040 :
1041 : void
1042 4083 : for_loop::visit (visitor* u)
1043 : {
1044 4083 : u->visit_for_loop (this);
1045 4083 : }
1046 :
1047 : void
1048 2538 : foreach_loop::visit (visitor* u)
1049 : {
1050 2538 : u->visit_foreach_loop (this);
1051 2538 : }
1052 :
1053 : void
1054 1415791 : null_statement::visit (visitor* u)
1055 : {
1056 1415791 : u->visit_null_statement (this);
1057 1415791 : }
1058 :
1059 : void
1060 7939589 : expr_statement::visit (visitor* u)
1061 : {
1062 7939589 : u->visit_expr_statement (this);
1063 7939529 : }
1064 :
1065 : void
1066 762967 : return_statement::visit (visitor* u)
1067 : {
1068 762967 : u->visit_return_statement (this);
1069 762967 : }
1070 :
1071 : void
1072 14253 : delete_statement::visit (visitor* u)
1073 : {
1074 14253 : u->push_active_lvalue (this->value);
1075 14253 : u->visit_delete_statement (this);
1076 14253 : u->pop_active_lvalue ();
1077 14253 : }
1078 :
1079 : void
1080 3855728 : if_statement::visit (visitor* u)
1081 : {
1082 3855728 : u->visit_if_statement (this);
1083 3855726 : }
1084 :
1085 : void
1086 13199 : next_statement::visit (visitor* u)
1087 : {
1088 13199 : u->visit_next_statement (this);
1089 13199 : }
1090 :
1091 : void
1092 131 : break_statement::visit (visitor* u)
1093 : {
1094 131 : u->visit_break_statement (this);
1095 130 : }
1096 :
1097 : void
1098 138 : continue_statement::visit (visitor* u)
1099 : {
1100 138 : u->visit_continue_statement (this);
1101 137 : }
1102 :
1103 : void
1104 1657282 : literal_string::visit(visitor* u)
1105 : {
1106 1657282 : u->visit_literal_string (this);
1107 1657282 : }
1108 :
1109 : void
1110 2499287 : literal_number::visit(visitor* u)
1111 : {
1112 2499287 : u->visit_literal_number (this);
1113 2499286 : }
1114 :
1115 : void
1116 135152 : binary_expression::visit (visitor* u)
1117 : {
1118 135152 : u->visit_binary_expression (this);
1119 135152 : }
1120 :
1121 : void
1122 24261 : unary_expression::visit (visitor* u)
1123 : {
1124 24261 : u->visit_unary_expression (this);
1125 24261 : }
1126 :
1127 : void
1128 13018 : pre_crement::visit (visitor* u)
1129 : {
1130 13018 : u->push_active_lvalue (this->operand);
1131 13018 : u->visit_pre_crement (this);
1132 13018 : u->pop_active_lvalue ();
1133 13018 : }
1134 :
1135 : void
1136 1234227 : post_crement::visit (visitor* u)
1137 : {
1138 1234227 : u->push_active_lvalue (this->operand);
1139 1234227 : u->visit_post_crement (this);
1140 1234227 : u->pop_active_lvalue ();
1141 1234227 : }
1142 :
1143 : void
1144 3004 : logical_or_expr::visit (visitor* u)
1145 : {
1146 3004 : u->visit_logical_or_expr (this);
1147 3004 : }
1148 :
1149 : void
1150 2447 : logical_and_expr::visit (visitor* u)
1151 : {
1152 2447 : u->visit_logical_and_expr (this);
1153 2447 : }
1154 :
1155 : void
1156 2340 : array_in::visit (visitor* u)
1157 : {
1158 2340 : u->visit_array_in (this);
1159 2340 : }
1160 :
1161 : void
1162 1785500 : comparison::visit (visitor* u)
1163 : {
1164 1785500 : u->visit_comparison (this);
1165 1785497 : }
1166 :
1167 : void
1168 88528 : concatenation::visit (visitor* u)
1169 : {
1170 88528 : u->visit_concatenation (this);
1171 88528 : }
1172 :
1173 : void
1174 1870 : ternary_expression::visit (visitor* u)
1175 : {
1176 1870 : u->visit_ternary_expression (this);
1177 1870 : }
1178 :
1179 : void
1180 4095831 : assignment::visit (visitor* u)
1181 : {
1182 4095831 : u->push_active_lvalue (this->left);
1183 4095831 : u->visit_assignment (this);
1184 4095787 : u->pop_active_lvalue ();
1185 4095787 : }
1186 :
1187 : void
1188 12904638 : symbol::visit (visitor* u)
1189 : {
1190 12904638 : u->visit_symbol (this);
1191 12904637 : }
1192 :
1193 : void
1194 328566 : target_symbol::visit (visitor* u)
1195 : {
1196 328566 : u->visit_target_symbol(this);
1197 328506 : }
1198 :
1199 : void
1200 1310557 : arrayindex::visit (visitor* u)
1201 : {
1202 1310557 : u->visit_arrayindex (this);
1203 1310557 : }
1204 :
1205 : void
1206 5560535 : functioncall::visit (visitor* u)
1207 : {
1208 5560535 : u->visit_functioncall (this);
1209 5560533 : }
1210 :
1211 : void
1212 3025646 : print_format::visit (visitor *u)
1213 : {
1214 3025646 : u->visit_print_format (this);
1215 3025632 : }
1216 :
1217 : void
1218 4312 : stat_op::visit (visitor *u)
1219 : {
1220 4312 : u->visit_stat_op (this);
1221 4311 : }
1222 :
1223 : void
1224 1884 : hist_op::visit (visitor *u)
1225 : {
1226 1884 : u->visit_hist_op (this);
1227 1884 : }
1228 :
1229 : void
1230 60349 : indexable::print_indexable (std::ostream& o) const
1231 : {
1232 : const symbol *sym;
1233 : const hist_op *hist;
1234 60349 : classify_const_indexable(this, sym, hist);
1235 60349 : if (sym)
1236 60258 : sym->print (o);
1237 : else
1238 : {
1239 91 : assert (hist);
1240 91 : hist->print (o);
1241 : }
1242 60349 : }
1243 :
1244 : void
1245 5285 : indexable::visit_indexable (visitor* u)
1246 : {
1247 : symbol *sym;
1248 : hist_op *hist;
1249 5285 : classify_indexable(this, sym, hist);
1250 5285 : if (sym)
1251 5285 : sym->visit (u);
1252 : else
1253 : {
1254 0 : assert (hist);
1255 0 : hist->visit (u);
1256 : }
1257 5285 : }
1258 :
1259 :
1260 : bool
1261 574 : indexable::is_symbol(symbol *& sym_out)
1262 : {
1263 574 : sym_out = NULL;
1264 574 : return false;
1265 : }
1266 :
1267 : bool
1268 0 : indexable::is_hist_op(hist_op *& hist_out)
1269 : {
1270 0 : hist_out = NULL;
1271 0 : return false;
1272 : }
1273 :
1274 : bool
1275 91 : indexable::is_const_symbol(const symbol *& sym_out) const
1276 : {
1277 91 : sym_out = NULL;
1278 91 : return false;
1279 : }
1280 :
1281 : bool
1282 0 : indexable::is_const_hist_op(const hist_op *& hist_out) const
1283 : {
1284 0 : hist_out = NULL;
1285 0 : return false;
1286 : }
1287 :
1288 : bool
1289 1771884 : symbol::is_symbol(symbol *& sym_out)
1290 : {
1291 1771884 : sym_out = this;
1292 1771884 : return true;
1293 : }
1294 :
1295 : bool
1296 60258 : symbol::is_const_symbol(const symbol *& sym_out) const
1297 : {
1298 60258 : sym_out = this;
1299 60258 : return true;
1300 : }
1301 :
1302 : const token *
1303 14151 : symbol::get_tok() const
1304 : {
1305 14151 : return tok;
1306 : }
1307 :
1308 : bool
1309 574 : hist_op::is_hist_op(hist_op *& hist_out)
1310 : {
1311 574 : hist_out = this;
1312 574 : return true;
1313 : }
1314 :
1315 : bool
1316 91 : hist_op::is_const_hist_op(const hist_op *& hist_out) const
1317 : {
1318 91 : hist_out = this;
1319 91 : return true;
1320 : }
1321 :
1322 : const token *
1323 3 : hist_op::get_tok() const
1324 : {
1325 3 : return tok;
1326 : }
1327 :
1328 : void
1329 : classify_indexable(indexable* ix,
1330 : symbol *& array_out,
1331 1772416 : hist_op *& hist_out)
1332 : {
1333 1772416 : array_out = NULL;
1334 1772416 : hist_out = NULL;
1335 1772416 : if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1336 0 : throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1337 1772416 : if (ix && !(hist_out || array_out))
1338 0 : throw semantic_error("Failed to classify indexable", ix->get_tok());
1339 1772416 : }
1340 :
1341 : void
1342 : classify_const_indexable(const indexable* ix,
1343 : const symbol *& array_out,
1344 60349 : const hist_op *& hist_out)
1345 : {
1346 60349 : array_out = NULL;
1347 60349 : hist_out = NULL;
1348 60349 : if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
1349 0 : throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1350 60349 : }
1351 :
1352 : // ------------------------------------------------------------------------
1353 :
1354 : bool
1355 164773 : visitor::is_active_lvalue(expression *e)
1356 : {
1357 280578 : for (unsigned i = 0; i < active_lvalues.size(); ++i)
1358 : {
1359 119631 : if (active_lvalues[i] == e)
1360 3826 : return true;
1361 : }
1362 160947 : return false;
1363 : }
1364 :
1365 : void
1366 5357329 : visitor::push_active_lvalue(expression *e)
1367 : {
1368 5357329 : active_lvalues.push_back(e);
1369 5357329 : }
1370 :
1371 : void
1372 5357285 : visitor::pop_active_lvalue()
1373 : {
1374 5357285 : assert(!active_lvalues.empty());
1375 5357285 : active_lvalues.pop_back();
1376 5357285 : }
1377 :
1378 :
1379 :
1380 : // ------------------------------------------------------------------------
1381 :
1382 : void
1383 4131178 : traversing_visitor::visit_block (block* s)
1384 : {
1385 10391987 : for (unsigned i=0; i<s->statements.size(); i++)
1386 6260810 : s->statements[i]->visit (this);
1387 4131177 : }
1388 :
1389 : void
1390 837965 : traversing_visitor::visit_embeddedcode (embeddedcode*)
1391 : {
1392 837965 : }
1393 :
1394 : void
1395 1100518 : traversing_visitor::visit_null_statement (null_statement*)
1396 : {
1397 1100518 : }
1398 :
1399 : void
1400 3914414 : traversing_visitor::visit_expr_statement (expr_statement* s)
1401 : {
1402 3914414 : s->value->visit (this);
1403 3914413 : }
1404 :
1405 : void
1406 2469445 : traversing_visitor::visit_if_statement (if_statement* s)
1407 : {
1408 2469445 : s->condition->visit (this);
1409 2469445 : s->thenblock->visit (this);
1410 2469445 : if (s->elseblock)
1411 400843 : s->elseblock->visit (this);
1412 2469445 : }
1413 :
1414 : void
1415 2587 : traversing_visitor::visit_for_loop (for_loop* s)
1416 : {
1417 2587 : if (s->init) s->init->visit (this);
1418 2587 : s->cond->visit (this);
1419 2587 : if (s->incr) s->incr->visit (this);
1420 2587 : s->block->visit (this);
1421 2587 : }
1422 :
1423 : void
1424 1395 : traversing_visitor::visit_foreach_loop (foreach_loop* s)
1425 : {
1426 1395 : symbol *array = NULL;
1427 1395 : hist_op *hist = NULL;
1428 1395 : classify_indexable (s->base, array, hist);
1429 1395 : if (array)
1430 1335 : array->visit(this);
1431 : else
1432 60 : hist->visit(this);
1433 :
1434 3111 : for (unsigned i=0; i<s->indexes.size(); i++)
1435 1716 : s->indexes[i]->visit (this);
1436 :
1437 1395 : if (s->limit)
1438 206 : s->limit->visit (this);
1439 :
1440 1395 : s->block->visit (this);
1441 1395 : }
1442 :
1443 : void
1444 676890 : traversing_visitor::visit_return_statement (return_statement* s)
1445 : {
1446 676890 : s->value->visit (this);
1447 676890 : }
1448 :
1449 : void
1450 10039 : traversing_visitor::visit_delete_statement (delete_statement* s)
1451 : {
1452 10039 : s->value->visit (this);
1453 10039 : }
1454 :
1455 : void
1456 9194 : traversing_visitor::visit_next_statement (next_statement*)
1457 : {
1458 9194 : }
1459 :
1460 : void
1461 100 : traversing_visitor::visit_break_statement (break_statement*)
1462 : {
1463 100 : }
1464 :
1465 : void
1466 109 : traversing_visitor::visit_continue_statement (continue_statement*)
1467 : {
1468 109 : }
1469 :
1470 : void
1471 1294788 : traversing_visitor::visit_literal_string (literal_string*)
1472 : {
1473 1294788 : }
1474 :
1475 : void
1476 1857395 : traversing_visitor::visit_literal_number (literal_number*)
1477 : {
1478 1857395 : }
1479 :
1480 : void
1481 111659 : traversing_visitor::visit_binary_expression (binary_expression* e)
1482 : {
1483 111659 : e->left->visit (this);
1484 111659 : e->right->visit (this);
1485 111659 : }
1486 :
1487 : void
1488 18769 : traversing_visitor::visit_unary_expression (unary_expression* e)
1489 : {
1490 18769 : e->operand->visit (this);
1491 18769 : }
1492 :
1493 : void
1494 9053 : traversing_visitor::visit_pre_crement (pre_crement* e)
1495 : {
1496 9053 : e->operand->visit (this);
1497 9053 : }
1498 :
1499 : void
1500 880680 : traversing_visitor::visit_post_crement (post_crement* e)
1501 : {
1502 880680 : e->operand->visit (this);
1503 880680 : }
1504 :
1505 :
1506 : void
1507 2750 : traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1508 : {
1509 2750 : e->left->visit (this);
1510 2750 : e->right->visit (this);
1511 2750 : }
1512 :
1513 : void
1514 1728 : traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1515 : {
1516 1728 : e->left->visit (this);
1517 1728 : e->right->visit (this);
1518 1728 : }
1519 :
1520 : void
1521 1902 : traversing_visitor::visit_array_in (array_in* e)
1522 : {
1523 1902 : e->operand->visit (this);
1524 1902 : }
1525 :
1526 : void
1527 1336354 : traversing_visitor::visit_comparison (comparison* e)
1528 : {
1529 1336354 : e->left->visit (this);
1530 1336353 : e->right->visit (this);
1531 1336353 : }
1532 :
1533 : void
1534 75166 : traversing_visitor::visit_concatenation (concatenation* e)
1535 : {
1536 75166 : e->left->visit (this);
1537 75166 : e->right->visit (this);
1538 75166 : }
1539 :
1540 : void
1541 1628 : traversing_visitor::visit_ternary_expression (ternary_expression* e)
1542 : {
1543 1628 : e->cond->visit (this);
1544 1628 : e->truevalue->visit (this);
1545 1628 : e->falsevalue->visit (this);
1546 1628 : }
1547 :
1548 : void
1549 2455323 : traversing_visitor::visit_assignment (assignment* e)
1550 : {
1551 2455323 : e->left->visit (this);
1552 2455323 : e->right->visit (this);
1553 2455323 : }
1554 :
1555 : void
1556 3907822 : traversing_visitor::visit_symbol (symbol*)
1557 : {
1558 3907822 : }
1559 :
1560 : void
1561 214 : traversing_visitor::visit_target_symbol (target_symbol*)
1562 : {
1563 214 : }
1564 :
1565 : void
1566 883674 : traversing_visitor::visit_arrayindex (arrayindex* e)
1567 : {
1568 1778514 : for (unsigned i=0; i<e->indexes.size(); i++)
1569 894840 : e->indexes[i]->visit (this);
1570 :
1571 883674 : symbol *array = NULL;
1572 883674 : hist_op *hist = NULL;
1573 883674 : classify_indexable(e->base, array, hist);
1574 883674 : if (array)
1575 883464 : return array->visit(this);
1576 : else
1577 210 : return hist->visit(this);
1578 : }
1579 :
1580 : void
1581 3762263 : traversing_visitor::visit_functioncall (functioncall* e)
1582 : {
1583 4566718 : for (unsigned i=0; i<e->args.size(); i++)
1584 804455 : e->args[i]->visit (this);
1585 3762263 : }
1586 :
1587 : void
1588 2150738 : traversing_visitor::visit_print_format (print_format* e)
1589 : {
1590 6256715 : for (unsigned i=0; i<e->args.size(); i++)
1591 4105978 : e->args[i]->visit (this);
1592 2150737 : if (e->hist)
1593 1134 : e->hist->visit(this);
1594 2150737 : }
1595 :
1596 : void
1597 2636 : traversing_visitor::visit_stat_op (stat_op* e)
1598 : {
1599 2636 : e->stat->visit (this);
1600 2636 : }
1601 :
1602 : void
1603 1317 : traversing_visitor::visit_hist_op (hist_op* e)
1604 : {
1605 1317 : e->stat->visit (this);
1606 1317 : }
1607 :
1608 :
1609 : void
1610 2938824 : functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1611 : {
1612 2938824 : traversing_visitor::visit_functioncall (e);
1613 :
1614 : // prevent infinite recursion
1615 2938824 : if (traversed.find (e->referent) == traversed.end ())
1616 : {
1617 1318450 : traversed.insert (e->referent);
1618 : // recurse
1619 1318450 : functiondecl* last_current_function = current_function;
1620 1318450 : current_function = e->referent;
1621 1318450 : e->referent->body->visit (this);
1622 1318450 : current_function = last_current_function;
1623 : }
1624 2938824 : }
1625 :
1626 :
1627 : void
1628 956687 : varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1629 : {
1630 : // We want to elide embedded-C functions when possible. For
1631 : // example, each $target variable access is expanded to an
1632 : // embedded-C function call. Yet, for safety reasons, we should
1633 : // presume that embedded-C functions have intentional side-effects.
1634 : //
1635 : // To tell these two types of functions apart, we apply a
1636 : // Kludge(tm): we look for a magic string within the function body.
1637 : // $target variables as rvalues will have this; lvalues won't.
1638 : // Also, explicit side-effect-free tapset functions will have this.
1639 :
1640 956687 : assert (current_function); // only they get embedded code
1641 956687 : if (s->code.find ("/* pure */") != string::npos)
1642 948847 : return;
1643 :
1644 7840 : embedded_seen = true;
1645 : }
1646 :
1647 : void
1648 299 : varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1649 : {
1650 : // Still-unresolved target symbol assignments get treated as
1651 : // generating side-effects like embedded-C, to prevent premature
1652 : // elision and later error message suppression (PR5516). rvalue use
1653 : // of unresolved target symbols is OTOH not considered a side-effect.
1654 :
1655 299 : if (is_active_lvalue (e))
1656 3 : embedded_seen = true;
1657 299 : }
1658 :
1659 : void
1660 1055915 : varuse_collecting_visitor::visit_print_format (print_format* e)
1661 : {
1662 : // NB: Instead of being top-level statements, "print" and "printf"
1663 : // are implemented as statement-expressions containing a
1664 : // print_format. They have side-effects, but not via the
1665 : // embedded-code detection method above.
1666 : //
1667 : // But sprint and sprintf don't have side-effects.
1668 :
1669 1055915 : if (e->print_to_stream)
1670 836027 : embedded_seen = true; // a proxy for "has unknown side-effects"
1671 :
1672 1055915 : functioncall_traversing_visitor::visit_print_format (e);
1673 1055915 : }
1674 :
1675 :
1676 : void
1677 1376206 : varuse_collecting_visitor::visit_assignment (assignment *e)
1678 : {
1679 1376206 : if (e->op == "=" || e->op == "<<<") // pure writes
1680 : {
1681 1374196 : expression* last_lvalue = current_lvalue;
1682 1374196 : current_lvalue = e->left; // leave a mark for ::visit_symbol
1683 1374196 : functioncall_traversing_visitor::visit_assignment (e);
1684 1374196 : current_lvalue = last_lvalue;
1685 : }
1686 : else // read-modify-writes
1687 : {
1688 2010 : expression* last_lrvalue = current_lrvalue;
1689 2010 : current_lrvalue = e->left; // leave a mark for ::visit_symbol
1690 2010 : functioncall_traversing_visitor::visit_assignment (e);
1691 2010 : current_lrvalue = last_lrvalue;
1692 : }
1693 1376206 : }
1694 :
1695 : void
1696 4535009 : varuse_collecting_visitor::visit_symbol (symbol *e)
1697 : {
1698 4535009 : if (e->referent == 0)
1699 0 : throw semantic_error ("symbol without referent", e->tok);
1700 :
1701 4535009 : if (current_lvalue == e || current_lrvalue == e)
1702 : {
1703 1804313 : written.insert (e->referent);
1704 : // clog << "write ";
1705 : }
1706 4535009 : if (current_lvalue != e || current_lrvalue == e)
1707 : {
1708 3160820 : read.insert (e->referent);
1709 : // clog << "read ";
1710 : }
1711 : // clog << *e->tok << endl;
1712 4535009 : }
1713 :
1714 : // NB: stat_op need not be overridden, since it will get to
1715 : // visit_symbol and only as a possible rvalue.
1716 :
1717 :
1718 : void
1719 451974 : varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
1720 : {
1721 : // Hooking this callback is necessary because of the hacky
1722 : // statistics representation. For the expression "i[4] = 5", the
1723 : // incoming lvalue will point to this arrayindex. However, the
1724 : // symbol corresponding to the "i[4]" is multiply inherited with
1725 : // arrayindex. If the symbol base part of this object is not at
1726 : // offset 0, then static_cast<symbol*>(e) may result in a different
1727 : // address, and not match lvalue by number when we recurse that way.
1728 : // So we explicitly override the incoming lvalue/lrvalue values to
1729 : // point at the embedded objects' actual base addresses.
1730 :
1731 451974 : expression* last_lrvalue = current_lrvalue;
1732 451974 : expression* last_lvalue = current_lvalue;
1733 :
1734 451974 : symbol *array = NULL;
1735 451974 : hist_op *hist = NULL;
1736 451974 : classify_indexable(e->base, array, hist);
1737 :
1738 451974 : if (array)
1739 : {
1740 451874 : if (current_lrvalue == e) current_lrvalue = array;
1741 451874 : if (current_lvalue == e) current_lvalue = array;
1742 451874 : functioncall_traversing_visitor::visit_arrayindex (e);
1743 : }
1744 : else // if (hist)
1745 : {
1746 100 : if (current_lrvalue == e) current_lrvalue = hist->stat;
1747 100 : if (current_lvalue == e) current_lvalue = hist->stat;
1748 100 : functioncall_traversing_visitor::visit_arrayindex (e);
1749 : }
1750 :
1751 451974 : current_lrvalue = last_lrvalue;
1752 451974 : current_lvalue = last_lvalue;
1753 451974 : }
1754 :
1755 :
1756 : void
1757 3933 : varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
1758 : {
1759 3933 : expression* last_lrvalue = current_lrvalue;
1760 3933 : current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1761 3933 : functioncall_traversing_visitor::visit_pre_crement (e);
1762 3933 : current_lrvalue = last_lrvalue;
1763 3933 : }
1764 :
1765 : void
1766 419495 : varuse_collecting_visitor::visit_post_crement (post_crement *e)
1767 : {
1768 419495 : expression* last_lrvalue = current_lrvalue;
1769 419495 : current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1770 419495 : functioncall_traversing_visitor::visit_post_crement (e);
1771 419495 : current_lrvalue = last_lrvalue;
1772 419495 : }
1773 :
1774 : void
1775 590 : varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
1776 : {
1777 590 : functioncall_traversing_visitor::visit_foreach_loop (s);
1778 : // If the collection is sorted, imply a "write" access to the
1779 : // array in addition to the "read" one already noted in the
1780 : // base class call above.
1781 590 : if (s->sort_direction)
1782 : {
1783 200 : symbol *array = NULL;
1784 200 : hist_op *hist = NULL;
1785 200 : classify_indexable (s->base, array, hist);
1786 200 : if (array) this->written.insert (array->referent);
1787 : // XXX: Can hist_op iterations be sorted?
1788 : }
1789 590 : }
1790 :
1791 :
1792 : void
1793 4686 : varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
1794 : {
1795 : // Ideally, this would be treated like an assignment: a plain write
1796 : // to the underlying value ("lvalue"). XXX: However, the
1797 : // optimization pass is not smart enough to remove an unneeded
1798 : // "delete" yet, so we pose more like a *crement ("lrvalue"). This
1799 : // should protect the underlying value from optimizional mischief.
1800 4686 : expression* last_lrvalue = current_lrvalue;
1801 4686 : current_lrvalue = s->value; // leave a mark for ::visit_symbol
1802 4686 : functioncall_traversing_visitor::visit_delete_statement (s);
1803 4686 : current_lrvalue = last_lrvalue;
1804 4686 : }
1805 :
1806 : bool
1807 78285 : varuse_collecting_visitor::side_effect_free ()
1808 : {
1809 78285 : return (written.empty() && !embedded_seen);
1810 : }
1811 :
1812 :
1813 : bool
1814 891457 : varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
1815 : {
1816 : // A looser notion of side-effect-freeness with respect to a given
1817 : // list of variables.
1818 :
1819 : // That's useful because the written list may consist of local
1820 : // variables of called functions. But visible side-effects only
1821 : // occur if the client's locals, or any globals are written-to.
1822 :
1823 891457 : set<vardecl*> intersection;
1824 891457 : insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
1825 : set_intersection (written.begin(), written.end(),
1826 : vars.begin(), vars.end(),
1827 891457 : int_it);
1828 :
1829 891457 : return (intersection.empty() && !embedded_seen);
1830 : }
1831 :
1832 :
1833 :
1834 :
1835 : // ------------------------------------------------------------------------
1836 :
1837 :
1838 9056 : throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
1839 474942 : throwing_visitor::throwing_visitor (): msg ("invalid element") {}
1840 :
1841 :
1842 : void
1843 0 : throwing_visitor::throwone (const token* t)
1844 : {
1845 0 : throw semantic_error (msg, t);
1846 : }
1847 :
1848 : void
1849 0 : throwing_visitor::visit_block (block* s)
1850 : {
1851 0 : throwone (s->tok);
1852 0 : }
1853 :
1854 : void
1855 0 : throwing_visitor::visit_embeddedcode (embeddedcode* s)
1856 : {
1857 0 : throwone (s->tok);
1858 0 : }
1859 :
1860 : void
1861 0 : throwing_visitor::visit_null_statement (null_statement* s)
1862 : {
1863 0 : throwone (s->tok);
1864 0 : }
1865 :
1866 : void
1867 0 : throwing_visitor::visit_expr_statement (expr_statement* s)
1868 : {
1869 0 : throwone (s->tok);
1870 0 : }
1871 :
1872 : void
1873 0 : throwing_visitor::visit_if_statement (if_statement* s)
1874 : {
1875 0 : throwone (s->tok);
1876 0 : }
1877 :
1878 : void
1879 0 : throwing_visitor::visit_for_loop (for_loop* s)
1880 : {
1881 0 : throwone (s->tok);
1882 0 : }
1883 :
1884 : void
1885 0 : throwing_visitor::visit_foreach_loop (foreach_loop* s)
1886 : {
1887 0 : throwone (s->tok);
1888 0 : }
1889 :
1890 : void
1891 0 : throwing_visitor::visit_return_statement (return_statement* s)
1892 : {
1893 0 : throwone (s->tok);
1894 0 : }
1895 :
1896 : void
1897 0 : throwing_visitor::visit_delete_statement (delete_statement* s)
1898 : {
1899 0 : throwone (s->tok);
1900 0 : }
1901 :
1902 : void
1903 0 : throwing_visitor::visit_next_statement (next_statement* s)
1904 : {
1905 0 : throwone (s->tok);
1906 0 : }
1907 :
1908 : void
1909 0 : throwing_visitor::visit_break_statement (break_statement* s)
1910 : {
1911 0 : throwone (s->tok);
1912 0 : }
1913 :
1914 : void
1915 0 : throwing_visitor::visit_continue_statement (continue_statement* s)
1916 : {
1917 0 : throwone (s->tok);
1918 0 : }
1919 :
1920 : void
1921 0 : throwing_visitor::visit_literal_string (literal_string* e)
1922 : {
1923 0 : throwone (e->tok);
1924 0 : }
1925 :
1926 : void
1927 1 : throwing_visitor::visit_literal_number (literal_number* e)
1928 : {
1929 1 : throwone (e->tok);
1930 0 : }
1931 :
1932 : void
1933 0 : throwing_visitor::visit_binary_expression (binary_expression* e)
1934 : {
1935 0 : throwone (e->tok);
1936 0 : }
1937 :
1938 : void
1939 0 : throwing_visitor::visit_unary_expression (unary_expression* e)
1940 : {
1941 0 : throwone (e->tok);
1942 0 : }
1943 :
1944 : void
1945 0 : throwing_visitor::visit_pre_crement (pre_crement* e)
1946 : {
1947 0 : throwone (e->tok);
1948 0 : }
1949 :
1950 : void
1951 0 : throwing_visitor::visit_post_crement (post_crement* e)
1952 : {
1953 0 : throwone (e->tok);
1954 0 : }
1955 :
1956 :
1957 : void
1958 0 : throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
1959 : {
1960 0 : throwone (e->tok);
1961 0 : }
1962 :
1963 : void
1964 0 : throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
1965 : {
1966 0 : throwone (e->tok);
1967 0 : }
1968 :
1969 : void
1970 0 : throwing_visitor::visit_array_in (array_in* e)
1971 : {
1972 0 : throwone (e->tok);
1973 0 : }
1974 :
1975 : void
1976 0 : throwing_visitor::visit_comparison (comparison* e)
1977 : {
1978 0 : throwone (e->tok);
1979 0 : }
1980 :
1981 : void
1982 0 : throwing_visitor::visit_concatenation (concatenation* e)
1983 : {
1984 0 : throwone (e->tok);
1985 0 : }
1986 :
1987 : void
1988 0 : throwing_visitor::visit_ternary_expression (ternary_expression* e)
1989 : {
1990 0 : throwone (e->tok);
1991 0 : }
1992 :
1993 : void
1994 0 : throwing_visitor::visit_assignment (assignment* e)
1995 : {
1996 0 : throwone (e->tok);
1997 0 : }
1998 :
1999 : void
2000 0 : throwing_visitor::visit_symbol (symbol* e)
2001 : {
2002 0 : throwone (e->tok);
2003 0 : }
2004 :
2005 : void
2006 0 : throwing_visitor::visit_target_symbol (target_symbol* e)
2007 : {
2008 0 : throwone (e->tok);
2009 0 : }
2010 :
2011 : void
2012 0 : throwing_visitor::visit_arrayindex (arrayindex* e)
2013 : {
2014 0 : throwone (e->tok);
2015 0 : }
2016 :
2017 : void
2018 0 : throwing_visitor::visit_functioncall (functioncall* e)
2019 : {
2020 0 : throwone (e->tok);
2021 0 : }
2022 :
2023 : void
2024 0 : throwing_visitor::visit_print_format (print_format* e)
2025 : {
2026 0 : throwone (e->tok);
2027 0 : }
2028 :
2029 : void
2030 0 : throwing_visitor::visit_stat_op (stat_op* e)
2031 : {
2032 0 : throwone (e->tok);
2033 0 : }
2034 :
2035 : void
2036 0 : throwing_visitor::visit_hist_op (hist_op* e)
2037 : {
2038 0 : throwone (e->tok);
2039 0 : }
2040 :
2041 :
2042 : // ------------------------------------------------------------------------
2043 :
2044 :
2045 : void
2046 1181993 : deep_copy_visitor::visit_block (block* s)
2047 : {
2048 1181993 : block* n = new block;
2049 1181993 : n->tok = s->tok;
2050 2227425 : for (unsigned i = 0; i < s->statements.size(); ++i)
2051 : {
2052 : statement* ns;
2053 1045437 : require <statement*> (this, &ns, s->statements[i]);
2054 1045432 : n->statements.push_back(ns);
2055 : }
2056 1181988 : provide <block*> (this, n);
2057 1181988 : }
2058 :
2059 : void
2060 0 : deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2061 : {
2062 0 : embeddedcode* n = new embeddedcode;
2063 0 : n->tok = s->tok;
2064 0 : n->code = s->code;
2065 0 : provide <embeddedcode*> (this, n);
2066 0 : }
2067 :
2068 : void
2069 1245 : deep_copy_visitor::visit_null_statement (null_statement* s)
2070 : {
2071 1245 : null_statement* n = new null_statement;
2072 1245 : n->tok = s->tok;
2073 1245 : provide <null_statement*> (this, n);
2074 1245 : }
2075 :
2076 : void
2077 1139893 : deep_copy_visitor::visit_expr_statement (expr_statement* s)
2078 : {
2079 1139893 : expr_statement* n = new expr_statement;
2080 1139893 : n->tok = s->tok;
2081 1139893 : require <expression*> (this, &(n->value), s->value);
2082 1139888 : provide <expr_statement*> (this, n);
2083 1139888 : }
2084 :
2085 : void
2086 421819 : deep_copy_visitor::visit_if_statement (if_statement* s)
2087 : {
2088 421819 : if_statement* n = new if_statement;
2089 421819 : n->tok = s->tok;
2090 421819 : require <expression*> (this, &(n->condition), s->condition);
2091 421819 : require <statement*> (this, &(n->thenblock), s->thenblock);
2092 421819 : require <statement*> (this, &(n->elseblock), s->elseblock);
2093 421819 : provide <if_statement*> (this, n);
2094 421819 : }
2095 :
2096 : void
2097 207 : deep_copy_visitor::visit_for_loop (for_loop* s)
2098 : {
2099 207 : for_loop* n = new for_loop;
2100 207 : n->tok = s->tok;
2101 207 : require <expr_statement*> (this, &(n->init), s->init);
2102 207 : require <expression*> (this, &(n->cond), s->cond);
2103 207 : require <expr_statement*> (this, &(n->incr), s->incr);
2104 207 : require <statement*> (this, &(n->block), s->block);
2105 207 : provide <for_loop*> (this, n);
2106 207 : }
2107 :
2108 : void
2109 116 : deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2110 : {
2111 116 : foreach_loop* n = new foreach_loop;
2112 116 : n->tok = s->tok;
2113 251 : for (unsigned i = 0; i < s->indexes.size(); ++i)
2114 : {
2115 : symbol* sym;
2116 135 : require <symbol*> (this, &sym, s->indexes[i]);
2117 135 : n->indexes.push_back(sym);
2118 : }
2119 :
2120 116 : require <indexable*> (this, &(n->base), s->base);
2121 :
2122 116 : n->sort_direction = s->sort_direction;
2123 116 : n->sort_column = s->sort_column;
2124 116 : require <expression*> (this, &(n->limit), s->limit);
2125 :
2126 116 : require <statement*> (this, &(n->block), s->block);
2127 116 : provide <foreach_loop*> (this, n);
2128 116 : }
2129 :
2130 : void
2131 0 : deep_copy_visitor::visit_return_statement (return_statement* s)
2132 : {
2133 0 : return_statement* n = new return_statement;
2134 0 : n->tok = s->tok;
2135 0 : require <expression*> (this, &(n->value), s->value);
2136 0 : provide <return_statement*> (this, n);
2137 0 : }
2138 :
2139 : void
2140 784 : deep_copy_visitor::visit_delete_statement (delete_statement* s)
2141 : {
2142 784 : delete_statement* n = new delete_statement;
2143 784 : n->tok = s->tok;
2144 784 : require <expression*> (this, &(n->value), s->value);
2145 784 : provide <delete_statement*> (this, n);
2146 784 : }
2147 :
2148 : void
2149 1312 : deep_copy_visitor::visit_next_statement (next_statement* s)
2150 : {
2151 1312 : next_statement* n = new next_statement;
2152 1312 : n->tok = s->tok;
2153 1312 : provide <next_statement*> (this, n);
2154 1312 : }
2155 :
2156 : void
2157 6 : deep_copy_visitor::visit_break_statement (break_statement* s)
2158 : {
2159 6 : break_statement* n = new break_statement;
2160 6 : n->tok = s->tok;
2161 6 : provide <break_statement*> (this, n);
2162 6 : }
2163 :
2164 : void
2165 5 : deep_copy_visitor::visit_continue_statement (continue_statement* s)
2166 : {
2167 5 : continue_statement* n = new continue_statement;
2168 5 : n->tok = s->tok;
2169 5 : provide <continue_statement*> (this, n);
2170 5 : }
2171 :
2172 : void
2173 152969 : deep_copy_visitor::visit_literal_string (literal_string* e)
2174 : {
2175 152969 : literal_string* n = new literal_string(e->value);
2176 152969 : n->tok = e->tok;
2177 152969 : provide <literal_string*> (this, n);
2178 152969 : }
2179 :
2180 : void
2181 248006 : deep_copy_visitor::visit_literal_number (literal_number* e)
2182 : {
2183 248006 : literal_number* n = new literal_number(e->value);
2184 248006 : n->tok = e->tok;
2185 248006 : provide <literal_number*> (this, n);
2186 248006 : }
2187 :
2188 : void
2189 2675 : deep_copy_visitor::visit_binary_expression (binary_expression* e)
2190 : {
2191 2675 : binary_expression* n = new binary_expression;
2192 2675 : n->op = e->op;
2193 2675 : n->tok = e->tok;
2194 2675 : require <expression*> (this, &(n->left), e->left);
2195 2675 : require <expression*> (this, &(n->right), e->right);
2196 2675 : provide <binary_expression*> (this, n);
2197 2675 : }
2198 :
2199 : void
2200 1380 : deep_copy_visitor::visit_unary_expression (unary_expression* e)
2201 : {
2202 1380 : unary_expression* n = new unary_expression;
2203 1380 : n->op = e->op;
2204 1380 : n->tok = e->tok;
2205 1380 : require <expression*> (this, &(n->operand), e->operand);
2206 1380 : provide <unary_expression*> (this, n);
2207 1380 : }
2208 :
2209 : void
2210 1435 : deep_copy_visitor::visit_pre_crement (pre_crement* e)
2211 : {
2212 1435 : pre_crement* n = new pre_crement;
2213 1435 : n->op = e->op;
2214 1435 : n->tok = e->tok;
2215 1435 : require <expression*> (this, &(n->operand), e->operand);
2216 1435 : provide <pre_crement*> (this, n);
2217 1435 : }
2218 :
2219 : void
2220 168862 : deep_copy_visitor::visit_post_crement (post_crement* e)
2221 : {
2222 168862 : post_crement* n = new post_crement;
2223 168862 : n->op = e->op;
2224 168862 : n->tok = e->tok;
2225 168862 : require <expression*> (this, &(n->operand), e->operand);
2226 168862 : provide <post_crement*> (this, n);
2227 168862 : }
2228 :
2229 :
2230 : void
2231 3 : deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2232 : {
2233 3 : logical_or_expr* n = new logical_or_expr;
2234 3 : n->op = e->op;
2235 3 : n->tok = e->tok;
2236 3 : require <expression*> (this, &(n->left), e->left);
2237 3 : require <expression*> (this, &(n->right), e->right);
2238 3 : provide <logical_or_expr*> (this, n);
2239 3 : }
2240 :
2241 : void
2242 263 : deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2243 : {
2244 263 : logical_and_expr* n = new logical_and_expr;
2245 263 : n->op = e->op;
2246 263 : n->tok = e->tok;
2247 263 : require <expression*> (this, &(n->left), e->left);
2248 263 : require <expression*> (this, &(n->right), e->right);
2249 263 : provide <logical_and_expr*> (this, n);
2250 263 : }
2251 :
2252 : void
2253 108 : deep_copy_visitor::visit_array_in (array_in* e)
2254 : {
2255 108 : array_in* n = new array_in;
2256 108 : n->tok = e->tok;
2257 108 : require <arrayindex*> (this, &(n->operand), e->operand);
2258 108 : provide <array_in*> (this, n);
2259 108 : }
2260 :
2261 : void
2262 174927 : deep_copy_visitor::visit_comparison (comparison* e)
2263 : {
2264 174927 : comparison* n = new comparison;
2265 174927 : n->op = e->op;
2266 174927 : n->tok = e->tok;
2267 174927 : require <expression*> (this, &(n->left), e->left);
2268 174927 : require <expression*> (this, &(n->right), e->right);
2269 174927 : provide <comparison*> (this, n);
2270 174927 : }
2271 :
2272 : void
2273 207 : deep_copy_visitor::visit_concatenation (concatenation* e)
2274 : {
2275 207 : concatenation* n = new concatenation;
2276 207 : n->op = e->op;
2277 207 : n->tok = e->tok;
2278 207 : require <expression*> (this, &(n->left), e->left);
2279 207 : require <expression*> (this, &(n->right), e->right);
2280 207 : provide <concatenation*> (this, n);
2281 207 : }
2282 :
2283 : void
2284 71 : deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2285 : {
2286 71 : ternary_expression* n = new ternary_expression;
2287 71 : n->tok = e->tok;
2288 71 : require <expression*> (this, &(n->cond), e->cond);
2289 71 : require <expression*> (this, &(n->truevalue), e->truevalue);
2290 71 : require <expression*> (this, &(n->falsevalue), e->falsevalue);
2291 71 : provide <ternary_expression*> (this, n);
2292 71 : }
2293 :
2294 : void
2295 419471 : deep_copy_visitor::visit_assignment (assignment* e)
2296 : {
2297 419471 : assignment* n = new assignment;
2298 419471 : n->op = e->op;
2299 419471 : n->tok = e->tok;
2300 419471 : require <expression*> (this, &(n->left), e->left);
2301 419471 : require <expression*> (this, &(n->right), e->right);
2302 419471 : provide <assignment*> (this, n);
2303 419471 : }
2304 :
2305 : void
2306 1757920 : deep_copy_visitor::visit_symbol (symbol* e)
2307 : {
2308 1757920 : symbol* n = new symbol;
2309 1757920 : n->tok = e->tok;
2310 1757920 : n->name = e->name;
2311 1757920 : n->referent = NULL;
2312 1757920 : provide <symbol*> (this, n);
2313 1757920 : }
2314 :
2315 : void
2316 212503 : deep_copy_visitor::visit_target_symbol (target_symbol* e)
2317 : {
2318 212503 : target_symbol* n = new target_symbol;
2319 212503 : n->tok = e->tok;
2320 212503 : n->base_name = e->base_name;
2321 212503 : n->components = e->components;
2322 212503 : provide <target_symbol*> (this, n);
2323 212503 : }
2324 :
2325 : void
2326 173276 : deep_copy_visitor::visit_arrayindex (arrayindex* e)
2327 : {
2328 173276 : arrayindex* n = new arrayindex;
2329 173276 : n->tok = e->tok;
2330 :
2331 173276 : require <indexable*> (this, &(n->base), e->base);
2332 :
2333 347583 : for (unsigned i = 0; i < e->indexes.size(); ++i)
2334 : {
2335 : expression* ne;
2336 174307 : require <expression*> (this, &ne, e->indexes[i]);
2337 174307 : n->indexes.push_back(ne);
2338 : }
2339 173276 : provide <arrayindex*> (this, n);
2340 173276 : }
2341 :
2342 : void
2343 584677 : deep_copy_visitor::visit_functioncall (functioncall* e)
2344 : {
2345 584677 : functioncall* n = new functioncall;
2346 584677 : n->tok = e->tok;
2347 584677 : n->function = e->function;
2348 584677 : n->referent = NULL;
2349 742083 : for (unsigned i = 0; i < e->args.size(); ++i)
2350 : {
2351 : expression* na;
2352 157406 : require <expression*> (this, &na, e->args[i]);
2353 157406 : n->args.push_back(na);
2354 : }
2355 584677 : provide <functioncall*> (this, n);
2356 584677 : }
2357 :
2358 : void
2359 404868 : deep_copy_visitor::visit_print_format (print_format* e)
2360 : {
2361 404868 : print_format* n = new print_format;
2362 404868 : n->tok = e->tok;
2363 404868 : n->print_to_stream = e->print_to_stream;
2364 404868 : n->print_with_format = e->print_with_format;
2365 404868 : n->print_with_delim = e->print_with_delim;
2366 404868 : n->print_with_newline = e->print_with_newline;
2367 404868 : n->print_char = e->print_char;
2368 404868 : n->raw_components = e->raw_components;
2369 404868 : n->components = e->components;
2370 404868 : n->delimiter = e->delimiter;
2371 1182522 : for (unsigned i = 0; i < e->args.size(); ++i)
2372 : {
2373 : expression* na;
2374 777656 : require <expression*> (this, &na, e->args[i]);
2375 777654 : n->args.push_back(na);
2376 : }
2377 404866 : if (e->hist)
2378 87 : require <hist_op*> (this, &n->hist, e->hist);
2379 404866 : provide <print_format*> (this, n);
2380 404866 : }
2381 :
2382 : void
2383 250 : deep_copy_visitor::visit_stat_op (stat_op* e)
2384 : {
2385 250 : stat_op* n = new stat_op;
2386 250 : n->tok = e->tok;
2387 250 : n->ctype = e->ctype;
2388 250 : require <expression*> (this, &(n->stat), e->stat);
2389 250 : provide <stat_op*> (this, n);
2390 250 : }
2391 :
2392 : void
2393 112 : deep_copy_visitor::visit_hist_op (hist_op* e)
2394 : {
2395 112 : hist_op* n = new hist_op;
2396 112 : n->tok = e->tok;
2397 112 : n->htype = e->htype;
2398 112 : n->params = e->params;
2399 112 : require <expression*> (this, &(n->stat), e->stat);
2400 112 : provide <hist_op*> (this, n);
2401 112 : }
2402 :
2403 : block*
2404 529755 : deep_copy_visitor::deep_copy (block* b)
2405 : {
2406 : block* n;
2407 529755 : deep_copy_visitor v;
2408 529755 : require <block*> (&v, &n, b);
2409 529755 : return n;
2410 : }
2411 :
2412 : statement*
2413 174188 : deep_copy_visitor::deep_copy (statement* s)
2414 : {
2415 : statement* n;
2416 174188 : deep_copy_visitor v;
2417 174188 : require <statement*> (&v, &n, s);
2418 174188 : return n;
2419 : }
2420 :
2421 : expression*
2422 10 : deep_copy_visitor::deep_copy (expression* s)
2423 : {
2424 : expression* n;
2425 10 : deep_copy_visitor v;
2426 10 : require <expression*> (&v, &n, s);
2427 10 : return n;
2428 : }
2429 :
2430 : template <> void
2431 173392 : require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
2432 : {
2433 173392 : if (src != NULL)
2434 : {
2435 173392 : symbol *array_src=NULL, *array_dst=NULL;
2436 173392 : hist_op *hist_src=NULL, *hist_dst=NULL;
2437 :
2438 173392 : classify_indexable(src, array_src, hist_src);
2439 :
2440 173392 : *dst = NULL;
2441 :
2442 173392 : if (array_src)
2443 : {
2444 173367 : require <symbol*> (v, &array_dst, array_src);
2445 173367 : *dst = array_dst;
2446 : }
2447 : else
2448 : {
2449 25 : require <hist_op*> (v, &hist_dst, hist_src);
2450 25 : *dst = hist_dst;
2451 : }
2452 173392 : assert (*dst);
2453 : }
2454 175580 : }
2455 1094 :
|