]> sourceware.org Git - systemtap.git/blame - staptree.cxx
test for pr2205
[systemtap.git] / staptree.cxx
CommitLineData
56099f08 1// parse tree functions
69c68955
FCE
2// Copyright (C) 2005 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.
2f1a1aea 8
2b066ec1 9#include "config.h"
2f1a1aea
FCE
10#include "staptree.h"
11#include "parse.h"
12#include <iostream>
56099f08 13#include <typeinfo>
d02548c0 14#include <sstream>
56099f08 15#include <cassert>
2f1a1aea 16
2b066ec1
FCE
17using namespace std;
18
2f1a1aea 19
a9c62ac9
FCE
20// return as quoted string, with at least '"' backslash-escaped
21template <typename IN> inline string
22lex_cast_qstring(IN const & in)
23{
24 stringstream ss;
25 string out, out2;
26 if (!(ss << in))
27 throw runtime_error("bad lexical cast");
28 out = ss.str();
29 out2 += '"';
30 for (unsigned i=0; i<out.length(); i++)
31 {
32 if (out[i] == '"') // XXX others?
33 out2 += '\\';
34 out2 += out[i];
35 }
36 out2 += '"';
37 return out2;
38}
39
40
56099f08
FCE
41expression::expression ():
42 type (pe_unknown), tok (0)
43{
44}
45
46
47expression::~expression ()
48{
49}
50
51
52statement::statement ():
53 tok (0)
54{
55}
56
57
58statement::~statement ()
59{
60}
61
62
63symbol::symbol ():
64 referent (0)
65{
66}
67
68
69arrayindex::arrayindex ():
d02548c0 70 base (0)
56099f08
FCE
71{
72}
73
74
75functioncall::functioncall ():
76 referent (0)
77{
78}
79
80
81symboldecl::symboldecl ():
82 tok (0),
83 type (pe_unknown)
84{
85}
86
87
88symboldecl::~symboldecl ()
89{
90}
91
a229fcd7
GH
92probe_point::probe_point (std::vector<component*> const & comps,
93 const token * t):
94 components(comps), tok(t)
95{
96}
56099f08 97
9c0c0e46 98probe_point::probe_point ():
82919855
FCE
99 tok (0)
100{
101}
102
103
104probe::probe ():
105 body (0), tok (0)
9c0c0e46
FCE
106{
107}
108
109
110probe_point::component::component ():
111 arg (0)
112{
113}
114
115
a229fcd7
GH
116probe_point::component::component (std::string const & f, literal * a):
117 functor(f), arg(a)
118{
119}
120
121
2b066ec1
FCE
122vardecl::vardecl ():
123 arity (-1)
56099f08
FCE
124{
125}
126
127
2b066ec1
FCE
128void
129vardecl::set_arity (int a)
56099f08 130{
d98d459c
GH
131 if (a < 0)
132 return;
8846477c
FCE
133
134 if (arity != a && arity >= 0)
135 throw semantic_error ("inconsistent arity", tok);
136
137 if (arity != a)
138 {
139 arity = a;
140 index_types.resize (arity);
141 for (int i=0; i<arity; i++)
142 index_types[i] = pe_unknown;
143 }
56099f08
FCE
144}
145
313b2f74
GH
146bool
147vardecl::compatible_arity (int a)
148{
d98d459c 149 if (arity == -1 || a == -1)
313b2f74
GH
150 return true;
151 return arity == a;
152}
153
56099f08
FCE
154
155functiondecl::functiondecl ():
156 body (0)
157{
158}
159
160
3a20432b 161literal_number::literal_number (int64_t v)
56099f08
FCE
162{
163 value = v;
164 type = pe_long;
165}
166
2f1a1aea 167
56099f08
FCE
168literal_string::literal_string (const string& v)
169{
170 value = v;
171 type = pe_string;
172}
173
174
175ostream&
176operator << (ostream& o, const exp_type& e)
177{
178 switch (e)
179 {
180 case pe_unknown: o << "unknown"; break;
181 case pe_long: o << "long"; break;
182 case pe_string: o << "string"; break;
183 case pe_stats: o << "stats"; break;
184 default: o << "???"; break;
185 }
186 return o;
187}
188
189
190// ------------------------------------------------------------------------
191// parse tree printing
192
cc9ee605 193ostream& operator << (ostream& o, const expression& k)
56099f08
FCE
194{
195 k.print (o);
196 return o;
197}
198
199
cc9ee605 200void literal_string::print (ostream& o) const
56099f08 201{
cc9ee605
FCE
202 o << '"';
203 for (unsigned i=0; i<value.size(); i++)
204 if (value[i] == '"') // or other escapeworthy characters?
205 o << '\\' << '"';
206 else
207 o << value[i];
208 o << '"';
56099f08
FCE
209}
210
f3c26ea5 211
cc9ee605 212void literal_number::print (ostream& o) const
56099f08
FCE
213{
214 o << value;
215}
216
217
cc9ee605 218void binary_expression::print (ostream& o) const
56099f08 219{
a9c62ac9 220 o << "(" << *left << ") "
56099f08 221 << op
a9c62ac9 222 << " (" << *right << ")";
56099f08 223}
2f1a1aea
FCE
224
225
cc9ee605 226void unary_expression::print (ostream& o) const
2f1a1aea 227{
56099f08
FCE
228 o << op << '(' << *operand << ")";
229}
230
cc9ee605 231void array_in::print (ostream& o) const
69c68955
FCE
232{
233 o << "[";
234 for (unsigned i=0; i<operand->indexes.size(); i++)
235 {
236 if (i > 0) o << ", ";
237 operand->indexes[i]->print (o);
238 }
a9c62ac9
FCE
239 o << "] in ";
240 operand->base->print_indexable (o);
69c68955 241}
56099f08 242
cc9ee605 243void post_crement::print (ostream& o) const
56099f08
FCE
244{
245 o << '(' << *operand << ")" << op;
246}
247
248
cc9ee605 249void ternary_expression::print (ostream& o) const
56099f08 250{
ae56fddd
FCE
251 o << "(" << *cond << ")?("
252 << *truevalue << "):("
56099f08
FCE
253 << *falsevalue << ")";
254}
255
256
cc9ee605 257void symbol::print (ostream& o) const
56099f08
FCE
258{
259 o << name;
260}
261
262
cc9ee605 263void target_symbol::print (std::ostream& o) const
d7f3e0c5
GH
264{
265 o << base_name;
266 for (unsigned i = 0; i < components.size(); ++i)
267 {
268 switch (components[i].first)
269 {
270 case comp_literal_array_index:
271 o << '[' << components[i].second << ']';
272 break;
246b383e 273 case comp_struct_member:
d7f3e0c5
GH
274 o << "->" << components[i].second;
275 break;
d7f3e0c5
GH
276 }
277 }
278}
279
280
cc9ee605 281void vardecl::print (ostream& o) const
56099f08
FCE
282{
283 o << name;
bed7c0af 284 if (arity > 0 || index_types.size() > 0)
56099f08
FCE
285 o << "[...]";
286}
287
2f1a1aea 288
cc9ee605 289void vardecl::printsig (ostream& o) const
56099f08
FCE
290{
291 o << name << ":" << type;
292 if (index_types.size() > 0)
2f1a1aea 293 {
56099f08
FCE
294 o << " [";
295 for (unsigned i=0; i<index_types.size(); i++)
296 o << (i>0 ? ", " : "") << index_types[i];
297 o << "]";
298 }
299}
300
301
cc9ee605 302void functiondecl::print (ostream& o) const
56099f08
FCE
303{
304 o << "function " << name << " (";
305 for (unsigned i=0; i<formal_args.size(); i++)
306 o << (i>0 ? ", " : "") << *formal_args[i];
307 o << ")" << endl;
308 body->print(o);
309}
310
311
cc9ee605 312void functiondecl::printsig (ostream& o) const
56099f08
FCE
313{
314 o << name << ":" << type << " (";
315 for (unsigned i=0; i<formal_args.size(); i++)
316 o << (i>0 ? ", " : "")
317 << *formal_args[i]
318 << ":"
319 << formal_args[i]->type;
320 o << ")";
321}
322
323
cc9ee605 324void arrayindex::print (ostream& o) const
56099f08 325{
a9c62ac9
FCE
326 base->print_indexable (o);
327 o << "[";
56099f08
FCE
328 for (unsigned i=0; i<indexes.size(); i++)
329 o << (i>0 ? ", " : "") << *indexes[i];
330 o << "]";
331}
332
333
cc9ee605 334void functioncall::print (ostream& o) const
56099f08
FCE
335{
336 o << function << "(";
337 for (unsigned i=0; i<args.size(); i++)
338 o << (i>0 ? ", " : "") << *args[i];
339 o << ")";
340}
341
342
d02548c0
GH
343string
344print_format::components_to_string(vector<format_component> const & components)
345{
346 ostringstream oss;
347
348 for (vector<format_component>::const_iterator i = components.begin();
349 i != components.end(); ++i)
350 {
351
352 assert (i->type != conv_unspecified);
353
354 if (i->type == conv_literal)
355 {
356 assert(!i->literal_string.empty());
357 for (string::const_iterator j = i->literal_string.begin();
358 j != i->literal_string.end(); ++j)
359 {
360 if (*j == '%')
361 oss << '%';
362 oss << *j;
363 }
364 }
365 else
366 {
367 oss << '%';
368
369 if (i->flags & static_cast<unsigned long>(fmt_flag_zeropad))
370 oss << '0';
371
372 if (i->flags & static_cast<unsigned long>(fmt_flag_plus))
373 oss << '+';
374
375 if (i->flags & static_cast<unsigned long>(fmt_flag_space))
376 oss << ' ';
377
378 if (i->flags & static_cast<unsigned long>(fmt_flag_left))
379 oss << '-';
380
381 if (i->flags & static_cast<unsigned long>(fmt_flag_special))
382 oss << '#';
383
384 if (i->width > 0)
385 oss << i->width;
386
387 if (i->precision > 0)
388 oss << '.' << i->precision;
389
390 switch (i->type)
391 {
392 case conv_signed_decimal:
393 oss << "lld";
394 break;
395
396 case conv_unsigned_decimal:
397 oss << "llu";
398 break;
399
400 case conv_unsigned_octal:
401 oss << "llo";
402 break;
403
404 case conv_unsigned_uppercase_hex:
405 oss << "llX";
406 break;
407
408 case conv_unsigned_lowercase_hex:
409 oss << "llx";
410 break;
411
412 case conv_string:
413 oss << 's';
414 break;
415
416 default:
417 break;
418 }
419 }
420 }
421 return oss.str ();
422}
423
424vector<print_format::format_component>
425print_format::string_to_components(string const & str)
426{
427 format_component curr;
428 vector<format_component> res;
429
d02548c0
GH
430 curr.clear();
431
432 string::const_iterator i = str.begin();
07c17d67 433
d02548c0
GH
434 while (i != str.end())
435 {
07c17d67 436 if (*i != '%')
d02548c0 437 {
07c17d67
GH
438 assert (curr.type == conv_unspecified || curr.type == conv_literal);
439 curr.type = conv_literal;
440 curr.literal_string += *i;
d02548c0 441 ++i;
07c17d67
GH
442 continue;
443 }
444 else if (i+1 == str.end() || *(i+1) == '%')
445 {
446 assert(*i == '%');
447 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
448 assert (curr.type == conv_unspecified || curr.type == conv_literal);
449 curr.type = conv_literal;
450 curr.literal_string += '%';
451 ++i;
452 continue;
453 }
454 else
455 {
456 assert(*i == '%');
457 if (curr.type != conv_unspecified)
d02548c0 458 {
07c17d67
GH
459 // Flush any component we were previously accumulating
460 assert (curr.type == conv_literal);
461 res.push_back(curr);
462 curr.clear();
463 }
464 }
465 ++i;
466
467 if (i == str.end())
468 break;
d02548c0 469
07c17d67
GH
470 // Now we are definitely parsing a conversion.
471 // Begin by parsing flags (whicih are optional).
d02548c0 472
07c17d67
GH
473 switch (*i)
474 {
475 case '0':
476 curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
477 ++i;
d02548c0 478 break;
07c17d67
GH
479
480 case '+':
481 curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
482 ++i;
d02548c0
GH
483 break;
484
07c17d67
GH
485 case '-':
486 curr.flags |= static_cast<unsigned long>(fmt_flag_left);
487 ++i;
d02548c0 488 break;
07c17d67
GH
489
490 case ' ':
491 curr.flags |= static_cast<unsigned long>(fmt_flag_space);
492 ++i;
493 break;
494
495 case '#':
496 curr.flags |= static_cast<unsigned long>(fmt_flag_special);
497 ++i;
498 break;
499
500 default:
501 break;
502 }
d02548c0 503
07c17d67
GH
504 // Parse optional width
505
506 while (i != str.end() && isdigit(*i))
507 {
508 curr.width *= 10;
509 curr.width += (*i - '0');
510 ++i;
511 }
d02548c0 512
07c17d67
GH
513 if (i == str.end())
514 break;
d02548c0 515
07c17d67
GH
516 // Parse optional precision
517 if (*i == '.')
518 {
519 ++i;
520 if (i == str.end())
521 break;
522 while (i != str.end() && isdigit(*i))
523 {
524 curr.precision *= 10;
525 curr.precision += (*i - '0');
d02548c0 526 ++i;
07c17d67
GH
527 }
528 }
d02548c0 529
07c17d67
GH
530 if (i == str.end())
531 break;
d02548c0 532
07c17d67
GH
533 // Parse the actual conversion specifier (sdiouxX)
534 switch (*i)
535 {
536 // Valid conversion types
537 case 's':
538 curr.type = conv_string;
539 break;
540
541 case 'd':
542 case 'i':
543 curr.type = conv_signed_decimal;
544 break;
545
546 case 'o':
547 curr.type = conv_unsigned_octal;
548 break;
549
550 case 'u':
551 curr.type = conv_unsigned_decimal;
552 break;
553
554 case 'X':
555 curr.type = conv_unsigned_uppercase_hex;
556 break;
557
558 case 'x':
559 curr.type = conv_unsigned_lowercase_hex;
560 break;
561
562 default:
d02548c0
GH
563 break;
564 }
07c17d67
GH
565
566 if (curr.type == conv_unspecified)
a9c62ac9 567 throw parse_error("invalid or missing conversion specifier");
07c17d67
GH
568
569 ++i;
570 res.push_back(curr);
571 curr.clear();
d02548c0
GH
572 }
573
07c17d67
GH
574 // If there's a remaining partly-composed conversion, fail.
575 if (!curr.is_empty())
576 {
577 if (curr.type == conv_literal)
578 res.push_back(curr);
579 else
a9c62ac9 580 throw parse_error("trailing incomplete print format conversion");
07c17d67 581 }
d02548c0
GH
582
583 return res;
584}
585
586
587void print_format::print (ostream& o) const
588{
589 string name = (string(print_to_stream ? "" : "s")
590 + string("print")
591 + string(print_with_format ? "f" : ""));
592 o << name << "(";
593 if (print_with_format)
594 {
a9c62ac9 595 o << lex_cast_qstring (raw_components);
d02548c0 596 }
a9c62ac9
FCE
597 if (hist)
598 hist->print(o);
d02548c0
GH
599 for (vector<expression*>::const_iterator i = args.begin();
600 i != args.end(); ++i)
601 {
a9c62ac9 602 if (i != args.begin() || print_with_format)
d02548c0
GH
603 o << ", ";
604 (*i)->print(o);
605 }
606 o << ")";
607}
608
609void stat_op::print (ostream& o) const
610{
611 o << '@';
612 switch (ctype)
613 {
614 case sc_average:
615 o << "avg(";
616 break;
617
618 case sc_count:
619 o << "count(";
620 break;
621
622 case sc_sum:
623 o << "sum(";
624 break;
625
626 case sc_min:
627 o << "min(";
628 break;
629
630 case sc_max:
631 o << "max(";
632 break;
633 }
634 stat->print(o);
635 o << ")";
636}
637
638void
639hist_op::print (ostream& o) const
640{
641 o << '@';
642 switch (htype)
643 {
644 case hist_linear:
645 assert(params.size() == 3);
646 o << "hist_linear(";
647 stat->print(o);
648 for (size_t i = 0; i < params.size(); ++i)
649 {
650 o << ", " << params[i];
651 }
652 o << ")";
653 break;
654
655 case hist_log:
656 assert(params.size() == 1);
657 o << "hist_log(";
658 stat->print(o);
659 for (size_t i = 0; i < params.size(); ++i)
660 {
661 o << ", " << params[i];
662 }
663 o << ")";
664 break;
665 }
666}
667
cc9ee605 668ostream& operator << (ostream& o, const statement& k)
56099f08
FCE
669{
670 k.print (o);
671 return o;
672}
673
674
cc9ee605 675void embeddedcode::print (ostream &o) const
54dfabe9
FCE
676{
677 o << "%{";
678 o << code;
679 o << "%}";
680}
681
cc9ee605 682void block::print (ostream& o) const
56099f08
FCE
683{
684 o << "{" << endl;
685 for (unsigned i=0; i<statements.size(); i++)
69c68955 686 o << *statements [i] << endl;
bb2e3076 687 o << "}";
56099f08
FCE
688}
689
690
cc9ee605 691void for_loop::print (ostream& o) const
56099f08 692{
f3c26ea5 693 o << "for (";
cbfbbf69 694 if (init) init->print (o);
f3c26ea5
FCE
695 o << "; ";
696 cond->print (o);
697 o << "; ";
cbfbbf69 698 if (incr) incr->print (o);
bb2e3076 699 o << ") ";
f3c26ea5 700 block->print (o);
56099f08
FCE
701}
702
703
cc9ee605 704void foreach_loop::print (ostream& o) const
69c68955
FCE
705{
706 o << "foreach ([";
707 for (unsigned i=0; i<indexes.size(); i++)
708 {
709 if (i > 0) o << ", ";
710 indexes[i]->print (o);
93484556
FCE
711 if (sort_direction != 0 && sort_column == i+1)
712 o << (sort_direction > 0 ? "+" : "-");
69c68955 713 }
a9c62ac9
FCE
714 o << "] in ";
715 base->print_indexable (o);
93484556
FCE
716 if (sort_direction != 0 && sort_column == 0)
717 o << (sort_direction > 0 ? "+" : "-");
718 o << ") ";
69c68955
FCE
719 block->print (o);
720}
721
722
cc9ee605 723void null_statement::print (ostream& o) const
56099f08
FCE
724{
725 o << ";";
726}
727
728
cc9ee605 729void expr_statement::print (ostream& o) const
56099f08
FCE
730{
731 o << *value;
732}
733
734
cc9ee605 735void return_statement::print (ostream& o) const
56099f08
FCE
736{
737 o << "return " << *value;
738}
739
740
cc9ee605 741void delete_statement::print (ostream& o) const
56099f08
FCE
742{
743 o << "delete " << *value;
744}
745
cc9ee605 746void next_statement::print (ostream& o) const
f3c26ea5
FCE
747{
748 o << "next";
749}
750
cc9ee605 751void break_statement::print (ostream& o) const
f3c26ea5
FCE
752{
753 o << "break";
754}
755
cc9ee605 756void continue_statement::print (ostream& o) const
f3c26ea5
FCE
757{
758 o << "continue";
759}
56099f08 760
cc9ee605 761void if_statement::print (ostream& o) const
56099f08 762{
bb2e3076 763 o << "if (" << *condition << ") "
56099f08
FCE
764 << *thenblock << endl;
765 if (elseblock)
766 o << "else " << *elseblock << endl;
767}
768
769
cc9ee605 770void stapfile::print (ostream& o) const
56099f08
FCE
771{
772 o << "# file " << name << endl;
773
54dfabe9
FCE
774 for (unsigned i=0; i<embeds.size(); i++)
775 embeds[i]->print (o);
776
bed7c0af
FCE
777 for (unsigned i=0; i<globals.size(); i++)
778 {
779 o << "global ";
780 globals[i]->print (o);
781 o << endl;
782 }
783
20c6c071
GH
784 for (unsigned i=0; i<aliases.size(); i++)
785 {
786 aliases[i]->print (o);
787 o << endl;
788 }
789
bed7c0af 790 for (unsigned i=0; i<probes.size(); i++)
56099f08
FCE
791 {
792 probes[i]->print (o);
793 o << endl;
794 }
795
796 for (unsigned j = 0; j < functions.size(); j++)
797 {
798 functions[j]->print (o);
799 o << endl;
800 }
801}
802
803
cc9ee605 804void probe::print (ostream& o) const
56099f08
FCE
805{
806 o << "probe ";
40a1cb62
FCE
807 printsig (o);
808 o << *body;
809}
810
811
cc9ee605 812void probe::printsig (ostream& o) const
40a1cb62 813{
9c0c0e46 814 for (unsigned i=0; i<locations.size(); i++)
56099f08 815 {
2930abc7 816 if (i > 0) o << "," << endl;
9c0c0e46 817 locations[i]->print (o);
56099f08 818 }
56099f08
FCE
819}
820
821
cc9ee605 822void probe_point::print (ostream& o) const
56099f08 823{
9c0c0e46
FCE
824 for (unsigned i=0; i<components.size(); i++)
825 {
826 if (i>0) o << ".";
827 probe_point::component* c = components[i];
828 o << c->functor;
829 if (c->arg)
830 o << "(" << *c->arg << ")";
831 }
56099f08
FCE
832}
833
cc9ee605 834
20c6c071
GH
835probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
836 probe (), alias_names (aliases)
837{
838}
839
cc9ee605 840void probe_alias::printsig (ostream& o) const
20c6c071
GH
841{
842 for (unsigned i=0; i<alias_names.size(); i++)
843 {
844 o << (i>0 ? " = " : "");
845 alias_names[i]->print (o);
846 }
5227f1ea 847 o << " = ";
20c6c071
GH
848 for (unsigned i=0; i<locations.size(); i++)
849 {
850 o << (i>0 ? ", " : "");
851 locations[i]->print (o);
852 }
853}
854
56099f08 855
cc9ee605 856ostream& operator << (ostream& o, const probe_point& k)
82919855
FCE
857{
858 k.print (o);
859 return o;
860}
861
862
cc9ee605 863ostream& operator << (ostream& o, const symboldecl& k)
56099f08
FCE
864{
865 k.print (o);
866 return o;
867}
868
869
82919855
FCE
870
871// ------------------------------------------------------------------------
872// visitors
873
874
875void
876block::visit (visitor* u)
877{
878 u->visit_block (this);
879}
880
54dfabe9
FCE
881
882void
883embeddedcode::visit (visitor* u)
884{
885 u->visit_embeddedcode (this);
886}
887
888
82919855
FCE
889void
890for_loop::visit (visitor* u)
891{
892 u->visit_for_loop (this);
893}
894
69c68955
FCE
895void
896foreach_loop::visit (visitor* u)
897{
898 u->visit_foreach_loop (this);
899}
900
82919855
FCE
901void
902null_statement::visit (visitor* u)
903{
904 u->visit_null_statement (this);
905}
906
907void
908expr_statement::visit (visitor* u)
909{
910 u->visit_expr_statement (this);
911}
912
913void
914return_statement::visit (visitor* u)
915{
916 u->visit_return_statement (this);
917}
918
919void
920delete_statement::visit (visitor* u)
921{
d7f3e0c5 922 u->push_active_lvalue (this->value);
82919855 923 u->visit_delete_statement (this);
d7f3e0c5 924 u->pop_active_lvalue ();
82919855
FCE
925}
926
927void
928if_statement::visit (visitor* u)
929{
930 u->visit_if_statement (this);
931}
932
f3c26ea5
FCE
933void
934next_statement::visit (visitor* u)
935{
936 u->visit_next_statement (this);
937}
938
939void
940break_statement::visit (visitor* u)
941{
942 u->visit_break_statement (this);
943}
944
945void
946continue_statement::visit (visitor* u)
947{
948 u->visit_continue_statement (this);
949}
950
82919855
FCE
951void
952literal_string::visit(visitor* u)
953{
954 u->visit_literal_string (this);
955}
956
957void
958literal_number::visit(visitor* u)
959{
960 u->visit_literal_number (this);
961}
962
963void
964binary_expression::visit (visitor* u)
965{
966 u->visit_binary_expression (this);
967}
968
969void
970unary_expression::visit (visitor* u)
971{
972 u->visit_unary_expression (this);
973}
974
975void
976pre_crement::visit (visitor* u)
977{
d7f3e0c5 978 u->push_active_lvalue (this->operand);
82919855 979 u->visit_pre_crement (this);
d7f3e0c5 980 u->pop_active_lvalue ();
82919855
FCE
981}
982
983void
984post_crement::visit (visitor* u)
985{
d7f3e0c5 986 u->push_active_lvalue (this->operand);
82919855 987 u->visit_post_crement (this);
d7f3e0c5 988 u->pop_active_lvalue ();
82919855
FCE
989}
990
991void
992logical_or_expr::visit (visitor* u)
993{
994 u->visit_logical_or_expr (this);
995}
996
997void
998logical_and_expr::visit (visitor* u)
999{
1000 u->visit_logical_and_expr (this);
1001}
1002
1003void
1004array_in::visit (visitor* u)
1005{
1006 u->visit_array_in (this);
1007}
1008
1009void
1010comparison::visit (visitor* u)
1011{
1012 u->visit_comparison (this);
1013}
1014
1015void
1016concatenation::visit (visitor* u)
1017{
1018 u->visit_concatenation (this);
1019}
1020
82919855
FCE
1021void
1022ternary_expression::visit (visitor* u)
1023{
1024 u->visit_ternary_expression (this);
1025}
1026
1027void
1028assignment::visit (visitor* u)
1029{
d7f3e0c5 1030 u->push_active_lvalue (this->left);
82919855 1031 u->visit_assignment (this);
d7f3e0c5 1032 u->pop_active_lvalue ();
82919855
FCE
1033}
1034
1035void
1036symbol::visit (visitor* u)
1037{
1038 u->visit_symbol (this);
1039}
1040
d7f3e0c5
GH
1041void
1042target_symbol::visit (visitor* u)
1043{
1044 u->visit_target_symbol(this);
1045}
1046
82919855
FCE
1047void
1048arrayindex::visit (visitor* u)
1049{
1050 u->visit_arrayindex (this);
1051}
1052
1053void
1054functioncall::visit (visitor* u)
1055{
1056 u->visit_functioncall (this);
1057}
1058
d02548c0
GH
1059void
1060print_format::visit (visitor *u)
1061{
1062 u->visit_print_format (this);
1063}
1064
1065void
1066stat_op::visit (visitor *u)
1067{
1068 u->visit_stat_op (this);
1069}
1070
1071void
1072hist_op::visit (visitor *u)
1073{
1074 u->visit_hist_op (this);
1075}
1076
1077void
1078indexable::print_indexable (std::ostream& o) const
1079{
1080 const symbol *sym;
1081 const hist_op *hist;
1082 classify_const_indexable(this, sym, hist);
1083 if (sym)
1084 sym->print (o);
1085 else
1086 {
1087 assert (hist);
1088 hist->print (o);
1089 }
1090}
1091
1092void
1093indexable::visit_indexable (visitor* u)
1094{
1095 symbol *sym;
1096 hist_op *hist;
1097 classify_indexable(this, sym, hist);
1098 if (sym)
1099 sym->visit (u);
1100 else
1101 {
1102 assert (hist);
1103 hist->visit (u);
1104 }
1105}
1106
1107
1108bool
1109indexable::is_symbol(symbol *& sym_out)
1110{
1111 sym_out = NULL;
1112 return false;
1113}
1114
1115bool
1116indexable::is_hist_op(hist_op *& hist_out)
1117{
1118 hist_out = NULL;
1119 return false;
1120}
1121
1122bool
1123indexable::is_const_symbol(const symbol *& sym_out) const
1124{
1125 sym_out = NULL;
1126 return false;
1127}
1128
1129bool
1130indexable::is_const_hist_op(const hist_op *& hist_out) const
1131{
1132 hist_out = NULL;
1133 return false;
1134}
1135
1136bool
1137symbol::is_symbol(symbol *& sym_out)
1138{
1139 sym_out = this;
1140 return true;
1141}
1142
1143bool
1144symbol::is_const_symbol(const symbol *& sym_out) const
1145{
1146 sym_out = this;
1147 return true;
1148}
1149
1150const token *
1151symbol::get_tok() const
1152{
1153 return tok;
1154}
1155
1156bool
1157hist_op::is_hist_op(hist_op *& hist_out)
1158{
1159 hist_out = this;
1160 return true;
1161}
1162
1163bool
1164hist_op::is_const_hist_op(const hist_op *& hist_out) const
1165{
1166 hist_out = this;
1167 return true;
1168}
1169
1170const token *
1171hist_op::get_tok() const
1172{
1173 return tok;
1174}
1175
1176void
1177classify_indexable(indexable* ix,
1178 symbol *& array_out,
1179 hist_op *& hist_out)
1180{
1181 array_out = NULL;
1182 hist_out = NULL;
1183 if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1184 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1185 if (ix && !(hist_out || array_out))
1186 throw semantic_error("Failed to classify indexable", ix->get_tok());
1187}
1188
1189void
1190classify_const_indexable(const indexable* ix,
1191 const symbol *& array_out,
1192 const hist_op *& hist_out)
1193{
1194 array_out = NULL;
1195 hist_out = NULL;
1196 if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
1197 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1198}
1199
d7f3e0c5
GH
1200// ------------------------------------------------------------------------
1201
1202bool
1203visitor::is_active_lvalue(expression *e)
1204{
1205 for (unsigned i = 0; i < active_lvalues.size(); ++i)
1206 {
1207 if (active_lvalues[i] == e)
1208 return true;
1209 }
1210 return false;
1211}
1212
1213void
1214visitor::push_active_lvalue(expression *e)
1215{
1216 active_lvalues.push_back(e);
1217}
1218
1219void
1220visitor::pop_active_lvalue()
1221{
1222 assert(!active_lvalues.empty());
1223 active_lvalues.pop_back();
1224}
1225
1226
82919855
FCE
1227
1228// ------------------------------------------------------------------------
1229
1230void
54dfabe9 1231traversing_visitor::visit_block (block* s)
82919855
FCE
1232{
1233 for (unsigned i=0; i<s->statements.size(); i++)
1234 s->statements[i]->visit (this);
1235}
1236
1237void
54dfabe9
FCE
1238traversing_visitor::visit_embeddedcode (embeddedcode* s)
1239{
1240}
1241
1242void
1243traversing_visitor::visit_null_statement (null_statement* s)
82919855
FCE
1244{
1245}
1246
1247void
54dfabe9 1248traversing_visitor::visit_expr_statement (expr_statement* s)
82919855
FCE
1249{
1250 s->value->visit (this);
1251}
1252
1253void
1254traversing_visitor::visit_if_statement (if_statement* s)
1255{
1256 s->condition->visit (this);
1257 s->thenblock->visit (this);
2b066ec1
FCE
1258 if (s->elseblock)
1259 s->elseblock->visit (this);
82919855
FCE
1260}
1261
1262void
1263traversing_visitor::visit_for_loop (for_loop* s)
1264{
cbfbbf69 1265 if (s->init) s->init->visit (this);
82919855 1266 s->cond->visit (this);
cbfbbf69 1267 if (s->incr) s->incr->visit (this);
82919855
FCE
1268 s->block->visit (this);
1269}
1270
69c68955
FCE
1271void
1272traversing_visitor::visit_foreach_loop (foreach_loop* s)
1273{
71572ba8
GH
1274 symbol *array = NULL;
1275 hist_op *hist = NULL;
1276 classify_indexable (s->base, array, hist);
1277 if (array)
1278 array->visit(this);
1279 else
1280 hist->visit(this);
1281
69c68955
FCE
1282 for (unsigned i=0; i<s->indexes.size(); i++)
1283 s->indexes[i]->visit (this);
1284 s->block->visit (this);
1285}
1286
82919855
FCE
1287void
1288traversing_visitor::visit_return_statement (return_statement* s)
1289{
1290 s->value->visit (this);
1291}
1292
1293void
1294traversing_visitor::visit_delete_statement (delete_statement* s)
1295{
1296 s->value->visit (this);
1297}
1298
f3c26ea5
FCE
1299void
1300traversing_visitor::visit_next_statement (next_statement* s)
1301{
1302}
1303
1304void
1305traversing_visitor::visit_break_statement (break_statement* s)
1306{
1307}
1308
1309void
1310traversing_visitor::visit_continue_statement (continue_statement* s)
1311{
1312}
1313
82919855
FCE
1314void
1315traversing_visitor::visit_literal_string (literal_string* e)
1316{
1317}
1318
1319void
1320traversing_visitor::visit_literal_number (literal_number* e)
1321{
1322}
1323
1324void
1325traversing_visitor::visit_binary_expression (binary_expression* e)
1326{
1327 e->left->visit (this);
1328 e->right->visit (this);
1329}
1330
1331void
1332traversing_visitor::visit_unary_expression (unary_expression* e)
1333{
1334 e->operand->visit (this);
1335}
1336
1337void
1338traversing_visitor::visit_pre_crement (pre_crement* e)
1339{
1340 e->operand->visit (this);
1341}
1342
1343void
1344traversing_visitor::visit_post_crement (post_crement* e)
1345{
1346 e->operand->visit (this);
1347}
1348
1349
1350void
1351traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1352{
1353 e->left->visit (this);
1354 e->right->visit (this);
1355}
1356
1357void
1358traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1359{
1360 e->left->visit (this);
1361 e->right->visit (this);
1362}
1363
1364void
1365traversing_visitor::visit_array_in (array_in* e)
1366{
ce10591c 1367 e->operand->visit (this);
82919855
FCE
1368}
1369
1370void
1371traversing_visitor::visit_comparison (comparison* e)
1372{
1373 e->left->visit (this);
1374 e->right->visit (this);
1375}
1376
1377void
1378traversing_visitor::visit_concatenation (concatenation* e)
1379{
1380 e->left->visit (this);
1381 e->right->visit (this);
1382}
1383
82919855
FCE
1384void
1385traversing_visitor::visit_ternary_expression (ternary_expression* e)
1386{
1387 e->cond->visit (this);
1388 e->truevalue->visit (this);
1389 e->falsevalue->visit (this);
1390}
1391
1392void
1393traversing_visitor::visit_assignment (assignment* e)
1394{
1395 e->left->visit (this);
1396 e->right->visit (this);
1397}
1398
1399void
1400traversing_visitor::visit_symbol (symbol* e)
1401{
1402}
1403
d7f3e0c5
GH
1404void
1405traversing_visitor::visit_target_symbol (target_symbol* e)
1406{
1407}
1408
82919855
FCE
1409void
1410traversing_visitor::visit_arrayindex (arrayindex* e)
1411{
cbfbbf69
FCE
1412 for (unsigned i=0; i<e->indexes.size(); i++)
1413 e->indexes[i]->visit (this);
1414
1bbeef03
GH
1415 symbol *array = NULL;
1416 hist_op *hist = NULL;
1417 classify_indexable(e->base, array, hist);
1418 if (array)
1419 return array->visit(this);
1420 else
1421 return hist->visit(this);
82919855
FCE
1422}
1423
1424void
1425traversing_visitor::visit_functioncall (functioncall* e)
1426{
1427 for (unsigned i=0; i<e->args.size(); i++)
1428 e->args[i]->visit (this);
1429}
1430
d02548c0
GH
1431void
1432traversing_visitor::visit_print_format (print_format* e)
1433{
1434 for (unsigned i=0; i<e->args.size(); i++)
1435 e->args[i]->visit (this);
a4636912
GH
1436 if (e->hist)
1437 e->hist->visit(this);
d02548c0
GH
1438}
1439
1440void
1441traversing_visitor::visit_stat_op (stat_op* e)
1442{
1443 e->stat->visit (this);
1444}
1445
1446void
1447traversing_visitor::visit_hist_op (hist_op* e)
1448{
1449 e->stat->visit (this);
1450}
1451
82919855 1452
cbfbbf69
FCE
1453void
1454functioncall_traversing_visitor::visit_functioncall (functioncall* e)
1455{
1456 traversing_visitor::visit_functioncall (e);
1457
1458 // prevent infinite recursion
1459 if (traversed.find (e->referent) == traversed.end ())
1460 {
1461 traversed.insert (e->referent);
1462 // recurse
1463 e->referent->body->visit (this);
1464 }
1465}
1466
1467
1468void
1469varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1470{
1471 embedded_seen = true;
1472}
1473
1474
1475void
1476varuse_collecting_visitor::visit_print_format (print_format* e)
1477{
1478 // NB: Instead of being top-level statements, "print" and "printf"
1479 // are implemented as statement-expressions containing a
1480 // print_format. They have side-effects, but not via the
1481 // embedded-code detection method above.
1482 embedded_seen = true;
1483 functioncall_traversing_visitor::visit_print_format (e);
1484}
1485
1486
1487void
1488varuse_collecting_visitor::visit_assignment (assignment *e)
1489{
1490 if (e->op == "=" || e->op == "<<<") // pure writes
1491 {
1492 expression* last_lvalue = current_lrvalue;
1493 current_lvalue = e->left; // leave a mark for ::visit_symbol
1494 functioncall_traversing_visitor::visit_assignment (e);
1495 current_lvalue = last_lvalue;
1496 }
1497 else // read-modify-writes
1498 {
1499 expression* last_lrvalue = current_lrvalue;
1500 current_lrvalue = e->left; // leave a mark for ::visit_symbol
1501 functioncall_traversing_visitor::visit_assignment (e);
1502 current_lrvalue = last_lrvalue;
1503 }
1504}
1505
1506void
1507varuse_collecting_visitor::visit_symbol (symbol *e)
1508{
1509 if (e->referent == 0)
1510 throw semantic_error ("symbol without referent", e->tok);
1511
1512 if (current_lvalue == e || current_lrvalue == e)
1513 {
1514 written.insert (e->referent);
1515 // clog << "write ";
1516 }
1517 if (current_lvalue != e || current_lrvalue == e)
1518 {
1519 read.insert (e->referent);
1520 // clog << "read ";
1521 }
1522 // clog << *e->tok << endl;
1523}
1524
1525// NB: stat_op need not be overridden, since it will get to
1526// visit_symbol and only as a possible rvalue.
1527
1528void
1529varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
1530{
1531 // Hooking this callback is necessary because of the hacky
1532 // statistics representation. For the expression "i[4] = 5", the
1533 // incoming lvalue will point to this arrayindex. However, the
1534 // symbol corresponding to the "i[4]" is multiply inherited with
1535 // arrayindex. If the symbol base part of this object is not at
1536 // offset 0, then static_cast<symbol*>(e) may result in a different
1537 // address, and not match lvalue by number when we recurse that way.
1538 // So we explicitly override the incoming lvalue/lrvalue values to
1539 // point at the embedded objects' actual base addresses.
1540
1541 expression* last_lrvalue = current_lrvalue;
1542 expression* last_lvalue = current_lvalue;
1543
1544 symbol *array = NULL;
1545 hist_op *hist = NULL;
1546 classify_indexable(e->base, array, hist);
1547
1548 if (array)
1549 {
1550 if (current_lrvalue == e) current_lrvalue = array;
1551 if (current_lvalue == e) current_lvalue = array;
1552 functioncall_traversing_visitor::visit_arrayindex (e);
1553 }
1554 else // if (hist)
1555 {
1556 if (current_lrvalue == e) current_lrvalue = hist->stat;
1557 if (current_lvalue == e) current_lvalue = hist->stat;
1558 functioncall_traversing_visitor::visit_arrayindex (e);
1559 }
1560
1561 current_lrvalue = last_lrvalue;
1562 current_lvalue = last_lvalue;
1563}
1564
1565
1566void
1567varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
1568{
1569 expression* last_lrvalue = current_lrvalue;
1570 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1571 functioncall_traversing_visitor::visit_pre_crement (e);
1572 current_lrvalue = last_lrvalue;
1573}
1574
1575void
1576varuse_collecting_visitor::visit_post_crement (post_crement *e)
1577{
1578 expression* last_lrvalue = current_lrvalue;
1579 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
1580 functioncall_traversing_visitor::visit_post_crement (e);
1581 current_lrvalue = last_lrvalue;
1582}
1583
1584
1585
1586
1587
1588
82919855
FCE
1589// ------------------------------------------------------------------------
1590
1591
1592throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
1593throwing_visitor::throwing_visitor (): msg ("invalid element") {}
1594
1595
1596void
1597throwing_visitor::throwone (const token* t)
1598{
1599 throw semantic_error (msg, t);
1600}
1601
1602void
54dfabe9
FCE
1603throwing_visitor::visit_block (block* s)
1604{
1605 throwone (s->tok);
1606}
1607
1608void
1609throwing_visitor::visit_embeddedcode (embeddedcode* s)
82919855
FCE
1610{
1611 throwone (s->tok);
1612}
1613
1614void
54dfabe9 1615throwing_visitor::visit_null_statement (null_statement* s)
82919855
FCE
1616{
1617 throwone (s->tok);
1618}
1619
1620void
54dfabe9 1621throwing_visitor::visit_expr_statement (expr_statement* s)
82919855
FCE
1622{
1623 throwone (s->tok);
1624}
1625
1626void
1627throwing_visitor::visit_if_statement (if_statement* s)
1628{
1629 throwone (s->tok);
1630}
1631
1632void
1633throwing_visitor::visit_for_loop (for_loop* s)
1634{
1635 throwone (s->tok);
1636}
1637
69c68955
FCE
1638void
1639throwing_visitor::visit_foreach_loop (foreach_loop* s)
1640{
1641 throwone (s->tok);
1642}
1643
82919855
FCE
1644void
1645throwing_visitor::visit_return_statement (return_statement* s)
1646{
1647 throwone (s->tok);
1648}
1649
1650void
1651throwing_visitor::visit_delete_statement (delete_statement* s)
1652{
1653 throwone (s->tok);
1654}
1655
f3c26ea5
FCE
1656void
1657throwing_visitor::visit_next_statement (next_statement* s)
1658{
1659 throwone (s->tok);
1660}
1661
1662void
1663throwing_visitor::visit_break_statement (break_statement* s)
1664{
1665 throwone (s->tok);
1666}
1667
1668void
1669throwing_visitor::visit_continue_statement (continue_statement* s)
1670{
1671 throwone (s->tok);
1672}
1673
82919855
FCE
1674void
1675throwing_visitor::visit_literal_string (literal_string* e)
1676{
1677 throwone (e->tok);
1678}
1679
1680void
1681throwing_visitor::visit_literal_number (literal_number* e)
1682{
1683 throwone (e->tok);
1684}
1685
1686void
1687throwing_visitor::visit_binary_expression (binary_expression* e)
1688{
1689 throwone (e->tok);
1690}
1691
1692void
1693throwing_visitor::visit_unary_expression (unary_expression* e)
1694{
1695 throwone (e->tok);
1696}
1697
1698void
1699throwing_visitor::visit_pre_crement (pre_crement* e)
1700{
1701 throwone (e->tok);
1702}
1703
1704void
1705throwing_visitor::visit_post_crement (post_crement* e)
1706{
1707 throwone (e->tok);
0054a7ea
FCE
1708}
1709
1710
82919855
FCE
1711void
1712throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
1713{
1714 throwone (e->tok);
1715}
1716
1717void
1718throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
1719{
1720 throwone (e->tok);
1721}
1722
1723void
1724throwing_visitor::visit_array_in (array_in* e)
1725{
1726 throwone (e->tok);
1727}
1728
1729void
1730throwing_visitor::visit_comparison (comparison* e)
1731{
1732 throwone (e->tok);
1733}
1734
1735void
1736throwing_visitor::visit_concatenation (concatenation* e)
1737{
1738 throwone (e->tok);
1739}
1740
82919855
FCE
1741void
1742throwing_visitor::visit_ternary_expression (ternary_expression* e)
1743{
1744 throwone (e->tok);
1745}
1746
1747void
1748throwing_visitor::visit_assignment (assignment* e)
1749{
1750 throwone (e->tok);
1751}
1752
1753void
1754throwing_visitor::visit_symbol (symbol* e)
1755{
1756 throwone (e->tok);
1757}
1758
d7f3e0c5
GH
1759void
1760throwing_visitor::visit_target_symbol (target_symbol* e)
1761{
1762 throwone (e->tok);
1763}
1764
82919855
FCE
1765void
1766throwing_visitor::visit_arrayindex (arrayindex* e)
1767{
1768 throwone (e->tok);
1769}
1770
1771void
1772throwing_visitor::visit_functioncall (functioncall* e)
1773{
1774 throwone (e->tok);
1775}
85365d1b 1776
d02548c0
GH
1777void
1778throwing_visitor::visit_print_format (print_format* e)
1779{
1780 throwone (e->tok);
1781}
1782
1783void
1784throwing_visitor::visit_stat_op (stat_op* e)
1785{
1786 throwone (e->tok);
1787}
1788
1789void
1790throwing_visitor::visit_hist_op (hist_op* e)
1791{
1792 throwone (e->tok);
1793}
1794
85365d1b
GH
1795
1796// ------------------------------------------------------------------------
1797
85365d1b
GH
1798
1799void
54dfabe9 1800deep_copy_visitor::visit_block (block* s)
85365d1b 1801{
54dfabe9 1802 block* n = new block;
67c0a579 1803 n->tok = s->tok;
85365d1b
GH
1804 for (unsigned i = 0; i < s->statements.size(); ++i)
1805 {
54dfabe9 1806 statement* ns;
85365d1b
GH
1807 require <statement*> (this, &ns, s->statements[i]);
1808 n->statements.push_back(ns);
1809 }
1810 provide <block*> (this, n);
1811}
1812
1813void
54dfabe9
FCE
1814deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
1815{
1816 embeddedcode* n = new embeddedcode;
1817 n->tok = s->tok;
1818 n->code = s->code;
1819 provide <embeddedcode*> (this, n);
1820}
1821
1822void
1823deep_copy_visitor::visit_null_statement (null_statement* s)
85365d1b 1824{
54dfabe9 1825 null_statement* n = new null_statement;
67c0a579
GH
1826 n->tok = s->tok;
1827 provide <null_statement*> (this, n);
85365d1b
GH
1828}
1829
1830void
54dfabe9 1831deep_copy_visitor::visit_expr_statement (expr_statement* s)
85365d1b 1832{
54dfabe9 1833 expr_statement* n = new expr_statement;
67c0a579 1834 n->tok = s->tok;
85365d1b
GH
1835 require <expression*> (this, &(n->value), s->value);
1836 provide <expr_statement*> (this, n);
1837}
1838
1839void
1840deep_copy_visitor::visit_if_statement (if_statement* s)
1841{
54dfabe9 1842 if_statement* n = new if_statement;
67c0a579 1843 n->tok = s->tok;
85365d1b
GH
1844 require <expression*> (this, &(n->condition), s->condition);
1845 require <statement*> (this, &(n->thenblock), s->thenblock);
c37f6b36 1846 require <statement*> (this, &(n->elseblock), s->elseblock);
85365d1b
GH
1847 provide <if_statement*> (this, n);
1848}
1849
1850void
1851deep_copy_visitor::visit_for_loop (for_loop* s)
1852{
54dfabe9 1853 for_loop* n = new for_loop;
67c0a579 1854 n->tok = s->tok;
85365d1b
GH
1855 require <expr_statement*> (this, &(n->init), s->init);
1856 require <expression*> (this, &(n->cond), s->cond);
1857 require <expr_statement*> (this, &(n->incr), s->incr);
1858 require <statement*> (this, &(n->block), s->block);
1859 provide <for_loop*> (this, n);
1860}
1861
1862void
1863deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
1864{
54dfabe9 1865 foreach_loop* n = new foreach_loop;
67c0a579 1866 n->tok = s->tok;
85365d1b
GH
1867 for (unsigned i = 0; i < s->indexes.size(); ++i)
1868 {
54dfabe9 1869 symbol* sym;
85365d1b
GH
1870 require <symbol*> (this, &sym, s->indexes[i]);
1871 n->indexes.push_back(sym);
1872 }
d02548c0
GH
1873
1874 require <indexable*> (this, &(n->base), s->base);
1875
93484556
FCE
1876 n->sort_direction = s->sort_direction;
1877 n->sort_column = s->sort_column;
d02548c0 1878
85365d1b
GH
1879 require <statement*> (this, &(n->block), s->block);
1880 provide <foreach_loop*> (this, n);
1881}
1882
1883void
1884deep_copy_visitor::visit_return_statement (return_statement* s)
1885{
54dfabe9 1886 return_statement* n = new return_statement;
67c0a579 1887 n->tok = s->tok;
85365d1b
GH
1888 require <expression*> (this, &(n->value), s->value);
1889 provide <return_statement*> (this, n);
1890}
1891
1892void
1893deep_copy_visitor::visit_delete_statement (delete_statement* s)
1894{
54dfabe9 1895 delete_statement* n = new delete_statement;
67c0a579 1896 n->tok = s->tok;
85365d1b
GH
1897 require <expression*> (this, &(n->value), s->value);
1898 provide <delete_statement*> (this, n);
1899}
1900
1901void
1902deep_copy_visitor::visit_next_statement (next_statement* s)
1903{
54dfabe9 1904 next_statement* n = new next_statement;
67c0a579
GH
1905 n->tok = s->tok;
1906 provide <next_statement*> (this, n);
85365d1b
GH
1907}
1908
1909void
1910deep_copy_visitor::visit_break_statement (break_statement* s)
1911{
54dfabe9 1912 break_statement* n = new break_statement;
67c0a579
GH
1913 n->tok = s->tok;
1914 provide <break_statement*> (this, n);
85365d1b
GH
1915}
1916
1917void
1918deep_copy_visitor::visit_continue_statement (continue_statement* s)
1919{
54dfabe9 1920 continue_statement* n = new continue_statement;
67c0a579
GH
1921 n->tok = s->tok;
1922 provide <continue_statement*> (this, n);
85365d1b
GH
1923}
1924
1925void
1926deep_copy_visitor::visit_literal_string (literal_string* e)
1927{
54dfabe9 1928 literal_string* n = new literal_string(e->value);
67c0a579
GH
1929 n->tok = e->tok;
1930 provide <literal_string*> (this, n);
85365d1b
GH
1931}
1932
1933void
1934deep_copy_visitor::visit_literal_number (literal_number* e)
1935{
54dfabe9 1936 literal_number* n = new literal_number(e->value);
67c0a579
GH
1937 n->tok = e->tok;
1938 provide <literal_number*> (this, n);
85365d1b
GH
1939}
1940
1941void
1942deep_copy_visitor::visit_binary_expression (binary_expression* e)
1943{
54dfabe9 1944 binary_expression* n = new binary_expression;
85365d1b 1945 n->op = e->op;
67c0a579 1946 n->tok = e->tok;
85365d1b
GH
1947 require <expression*> (this, &(n->left), e->left);
1948 require <expression*> (this, &(n->right), e->right);
1949 provide <binary_expression*> (this, n);
1950}
1951
1952void
1953deep_copy_visitor::visit_unary_expression (unary_expression* e)
1954{
54dfabe9 1955 unary_expression* n = new unary_expression;
85365d1b 1956 n->op = e->op;
67c0a579 1957 n->tok = e->tok;
85365d1b
GH
1958 require <expression*> (this, &(n->operand), e->operand);
1959 provide <unary_expression*> (this, n);
1960}
1961
1962void
1963deep_copy_visitor::visit_pre_crement (pre_crement* e)
1964{
54dfabe9 1965 pre_crement* n = new pre_crement;
85365d1b 1966 n->op = e->op;
67c0a579 1967 n->tok = e->tok;
85365d1b
GH
1968 require <expression*> (this, &(n->operand), e->operand);
1969 provide <pre_crement*> (this, n);
1970}
1971
1972void
1973deep_copy_visitor::visit_post_crement (post_crement* e)
1974{
54dfabe9 1975 post_crement* n = new post_crement;
85365d1b 1976 n->op = e->op;
67c0a579 1977 n->tok = e->tok;
85365d1b
GH
1978 require <expression*> (this, &(n->operand), e->operand);
1979 provide <post_crement*> (this, n);
1980}
1981
1982
1983void
1984deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
1985{
54dfabe9 1986 logical_or_expr* n = new logical_or_expr;
85365d1b 1987 n->op = e->op;
67c0a579 1988 n->tok = e->tok;
85365d1b
GH
1989 require <expression*> (this, &(n->left), e->left);
1990 require <expression*> (this, &(n->right), e->right);
1991 provide <logical_or_expr*> (this, n);
1992}
1993
1994void
1995deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
1996{
54dfabe9 1997 logical_and_expr* n = new logical_and_expr;
85365d1b 1998 n->op = e->op;
67c0a579 1999 n->tok = e->tok;
85365d1b
GH
2000 require <expression*> (this, &(n->left), e->left);
2001 require <expression*> (this, &(n->right), e->right);
2002 provide <logical_and_expr*> (this, n);
2003}
2004
2005void
2006deep_copy_visitor::visit_array_in (array_in* e)
2007{
54dfabe9 2008 array_in* n = new array_in;
67c0a579 2009 n->tok = e->tok;
85365d1b
GH
2010 require <arrayindex*> (this, &(n->operand), e->operand);
2011 provide <array_in*> (this, n);
2012}
2013
2014void
2015deep_copy_visitor::visit_comparison (comparison* e)
2016{
54dfabe9 2017 comparison* n = new comparison;
85365d1b 2018 n->op = e->op;
67c0a579 2019 n->tok = e->tok;
85365d1b
GH
2020 require <expression*> (this, &(n->left), e->left);
2021 require <expression*> (this, &(n->right), e->right);
2022 provide <comparison*> (this, n);
2023}
2024
2025void
2026deep_copy_visitor::visit_concatenation (concatenation* e)
2027{
54dfabe9 2028 concatenation* n = new concatenation;
85365d1b 2029 n->op = e->op;
67c0a579 2030 n->tok = e->tok;
85365d1b
GH
2031 require <expression*> (this, &(n->left), e->left);
2032 require <expression*> (this, &(n->right), e->right);
2033 provide <concatenation*> (this, n);
2034}
2035
2036void
2037deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2038{
54dfabe9 2039 ternary_expression* n = new ternary_expression;
67c0a579 2040 n->tok = e->tok;
85365d1b
GH
2041 require <expression*> (this, &(n->cond), e->cond);
2042 require <expression*> (this, &(n->truevalue), e->truevalue);
2043 require <expression*> (this, &(n->falsevalue), e->falsevalue);
2044 provide <ternary_expression*> (this, n);
2045}
2046
2047void
2048deep_copy_visitor::visit_assignment (assignment* e)
2049{
54dfabe9 2050 assignment* n = new assignment;
85365d1b 2051 n->op = e->op;
67c0a579 2052 n->tok = e->tok;
85365d1b
GH
2053 require <expression*> (this, &(n->left), e->left);
2054 require <expression*> (this, &(n->right), e->right);
2055 provide <assignment*> (this, n);
2056}
2057
2058void
2059deep_copy_visitor::visit_symbol (symbol* e)
2060{
54dfabe9 2061 symbol* n = new symbol;
67c0a579 2062 n->tok = e->tok;
85365d1b
GH
2063 n->name = e->name;
2064 n->referent = NULL;
2065 provide <symbol*> (this, n);
d7f3e0c5
GH
2066}
2067
2068void
2069deep_copy_visitor::visit_target_symbol (target_symbol* e)
2070{
2071 target_symbol* n = new target_symbol;
2072 n->tok = e->tok;
2073 n->base_name = e->base_name;
2074 n->components = e->components;
2075 provide <target_symbol*> (this, n);
85365d1b
GH
2076}
2077
2078void
2079deep_copy_visitor::visit_arrayindex (arrayindex* e)
2080{
54dfabe9 2081 arrayindex* n = new arrayindex;
67c0a579 2082 n->tok = e->tok;
d02548c0
GH
2083
2084 require <indexable*> (this, &(n->base), e->base);
2085
85365d1b
GH
2086 for (unsigned i = 0; i < e->indexes.size(); ++i)
2087 {
54dfabe9 2088 expression* ne;
85365d1b
GH
2089 require <expression*> (this, &ne, e->indexes[i]);
2090 n->indexes.push_back(ne);
2091 }
2092 provide <arrayindex*> (this, n);
2093}
2094
2095void
2096deep_copy_visitor::visit_functioncall (functioncall* e)
2097{
54dfabe9 2098 functioncall* n = new functioncall;
67c0a579 2099 n->tok = e->tok;
85365d1b
GH
2100 n->function = e->function;
2101 n->referent = NULL;
2102 for (unsigned i = 0; i < e->args.size(); ++i)
2103 {
54dfabe9 2104 expression* na;
85365d1b
GH
2105 require <expression*> (this, &na, e->args[i]);
2106 n->args.push_back(na);
2107 }
2108 provide <functioncall*> (this, n);
2109}
2110
d02548c0
GH
2111void
2112deep_copy_visitor::visit_print_format (print_format* e)
2113{
2114 print_format* n = new print_format;
2115 n->tok = e->tok;
2116 n->print_with_format = e->print_with_format;
2117 n->print_to_stream = e->print_to_stream;
2118 n->components = e->components;
2119 for (unsigned i = 0; i < e->args.size(); ++i)
2120 {
2121 expression* na;
2122 require <expression*> (this, &na, e->args[i]);
2123 n->args.push_back(na);
2124 }
a4636912
GH
2125 if (e->hist)
2126 require <hist_op*> (this, &n->hist, e->hist);
d02548c0
GH
2127 provide <print_format*> (this, n);
2128}
2129
2130void
2131deep_copy_visitor::visit_stat_op (stat_op* e)
2132{
2133 stat_op* n = new stat_op;
2134 n->tok = e->tok;
2135 n->ctype = e->ctype;
2136 require <expression*> (this, &(n->stat), e->stat);
2137 provide <stat_op*> (this, n);
2138}
2139
2140void
2141deep_copy_visitor::visit_hist_op (hist_op* e)
2142{
2143 hist_op* n = new hist_op;
2144 n->tok = e->tok;
2145 n->htype = e->htype;
2146 n->params = e->params;
2147 require <expression*> (this, &(n->stat), e->stat);
2148 provide <hist_op*> (this, n);
2149}
2150
54dfabe9
FCE
2151block*
2152deep_copy_visitor::deep_copy (block* b)
85365d1b 2153{
54dfabe9 2154 block* n;
85365d1b
GH
2155 deep_copy_visitor v;
2156 require <block*> (&v, &n, b);
2157 return n;
2158}
2159
54dfabe9
FCE
2160statement*
2161deep_copy_visitor::deep_copy (statement* s)
85365d1b 2162{
54dfabe9 2163 statement* n;
85365d1b
GH
2164 deep_copy_visitor v;
2165 require <statement*> (&v, &n, s);
2166 return n;
2167}
This page took 0.262366 seconds and 5 git commands to generate.