]> sourceware.org Git - systemtap.git/blame - staptree.cxx
The Death of target_symbol::base_name
[systemtap.git] / staptree.cxx
CommitLineData
56099f08 1// parse tree functions
f4fe2e93 2// Copyright (C) 2005-2010 Red Hat Inc.
69c68955
FCE
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"
72dbc915 12#include "util.h"
313db8e6 13#include "session.h"
72dbc915 14
2f1a1aea 15#include <iostream>
56099f08 16#include <typeinfo>
d02548c0 17#include <sstream>
56099f08 18#include <cassert>
b2199bb3 19#include <cstring>
c3a3c0c9 20#include <vector>
66e00001 21#include <algorithm>
edc22ba9 22#include <cstring>
2f1a1aea 23
2b066ec1
FCE
24using namespace std;
25
2f1a1aea 26
c1d5f3f6 27
56099f08
FCE
28expression::expression ():
29 type (pe_unknown), tok (0)
30{
dff50e09 31}
56099f08
FCE
32
33
34expression::~expression ()
35{
36}
37
38
39statement::statement ():
40 tok (0)
41{
dff50e09 42}
56099f08
FCE
43
44
f946b10f
JS
45statement::statement (const token* tok):
46 tok (tok)
47{
48}
49
50
51null_statement::null_statement (const token* tok):
52 statement(tok)
53{
54}
55
56
56099f08
FCE
57statement::~statement ()
58{
59}
60
61
62symbol::symbol ():
63 referent (0)
64{
65}
66
67
68arrayindex::arrayindex ():
d02548c0 69 base (0)
56099f08
FCE
70{
71}
72
73
74functioncall::functioncall ():
75 referent (0)
76{
77}
78
79
80symboldecl::symboldecl ():
81 tok (0),
82 type (pe_unknown)
83{
dff50e09 84}
56099f08
FCE
85
86
87symboldecl::~symboldecl ()
88{
89}
90
f1a0157a
CW
91probe_point::probe_point (std::vector<component*> const & comps):
92 components(comps), optional (false), sufficient (false),
80342244 93 condition (0)
a229fcd7
GH
94{
95}
56099f08 96
1939ea32
FCE
97// NB: shallow-copy of compoonents & condition!
98probe_point::probe_point (const probe_point& pp):
f1a0157a 99 components(pp.components), optional (pp.optional), sufficient (pp.sufficient),
1939ea32
FCE
100 condition (pp.condition)
101{
102}
103
104
9c0c0e46 105probe_point::probe_point ():
f1a0157a 106 optional (false), sufficient (false), condition (0)
82919855
FCE
107{
108}
109
110
111probe::probe ():
5d23847d 112 body (0), tok (0)
9c0c0e46 113{
54649971 114 static unsigned last_probeidx = 0;
aca66a36 115 this->name = string ("probe_") + lex_cast(last_probeidx ++);
9c0c0e46
FCE
116}
117
118
119probe_point::component::component ():
120 arg (0)
121{
122}
123
124
dff50e09
FCE
125probe_point::component::component (std::string const & f, literal * a):
126 functor(f), arg(a)
a229fcd7
GH
127{
128}
129
130
2b066ec1 131vardecl::vardecl ():
58701b78 132 arity_tok(0), arity (-1), maxsize(0), init(NULL), skip_init(false)
56099f08
FCE
133{
134}
135
136
2b066ec1 137void
58701b78 138vardecl::set_arity (int a, const token* t)
56099f08 139{
d98d459c
GH
140 if (a < 0)
141 return;
8846477c 142
58701b78 143 if (a == 0 && maxsize > 0)
8846477c
FCE
144 throw semantic_error ("inconsistent arity", tok);
145
58701b78
JS
146 if (arity != a && arity >= 0)
147 {
148 semantic_error err ("inconsistent arity (" + lex_cast(arity) +
149 " vs. " + lex_cast(a) + ")", t?:tok);
150 if (arity_tok)
151 err.chain = new semantic_error ("arity " + lex_cast(arity) +
152 " first inferred here", arity_tok);
153 throw err;
154 }
155
8846477c
FCE
156 if (arity != a)
157 {
58701b78 158 arity_tok = t;
8846477c
FCE
159 arity = a;
160 index_types.resize (arity);
161 for (int i=0; i<arity; i++)
162 index_types[i] = pe_unknown;
163 }
56099f08
FCE
164}
165
dff50e09 166bool
313b2f74
GH
167vardecl::compatible_arity (int a)
168{
ef474d24
JS
169 if (a == 0 && maxsize > 0)
170 return false;
d98d459c 171 if (arity == -1 || a == -1)
313b2f74
GH
172 return true;
173 return arity == a;
174}
175
56099f08
FCE
176
177functiondecl::functiondecl ():
59de45f1 178 body (0), synthetic (false)
56099f08
FCE
179{
180}
181
f8809d54
JS
182void
183functiondecl::join (systemtap_session& s)
184{
185 if (!synthetic)
186 throw semantic_error ("internal error, joining a non-synthetic function", tok);
187 if (!s.functions.insert (make_pair (name, this)).second)
188 throw semantic_error ("synthetic function '" + name +
189 "' conflicts with an existing function", tok);
190 tok->location.file->functions.push_back (this);
191}
192
56099f08 193
9ea68eb9 194literal_number::literal_number (int64_t v, bool hex)
56099f08
FCE
195{
196 value = v;
9ea68eb9 197 print_hex = hex;
56099f08
FCE
198 type = pe_long;
199}
200
2f1a1aea 201
56099f08
FCE
202literal_string::literal_string (const string& v)
203{
204 value = v;
205 type = pe_string;
206}
207
208
209ostream&
210operator << (ostream& o, const exp_type& e)
211{
212 switch (e)
213 {
214 case pe_unknown: o << "unknown"; break;
215 case pe_long: o << "long"; break;
216 case pe_string: o << "string"; break;
217 case pe_stats: o << "stats"; break;
218 default: o << "???"; break;
219 }
220 return o;
221}
222
223
dc5a09fc 224void
5f36109e 225target_symbol::assert_no_components(const std::string& tapset, bool pretty_ok)
dc5a09fc
JS
226{
227 if (components.empty())
228 return;
229
230 switch (components[0].type)
231 {
5f36109e
JS
232 case comp_literal_array_index:
233 case comp_expression_array_index:
277c21bc 234 throw semantic_error(tapset + " variable '" + name +
dc5a09fc
JS
235 "' may not be used as array",
236 components[0].tok);
5f36109e 237 case comp_struct_member:
277c21bc 238 throw semantic_error(tapset + " variable '" + name +
dc5a09fc
JS
239 "' may not be used as a structure",
240 components[0].tok);
5f36109e
JS
241 case comp_pretty_print:
242 if (!pretty_ok)
277c21bc 243 throw semantic_error(tapset + " variable '" + name +
5f36109e
JS
244 "' may not be pretty-printed",
245 components[0].tok);
246 return;
dc5a09fc
JS
247 default:
248 throw semantic_error ("invalid use of " + tapset +
277c21bc 249 " variable '" + name + "'",
dc5a09fc
JS
250 components[0].tok);
251 }
252}
253
254
1af1e62d 255void target_symbol::chain (const semantic_error &er)
c69a87e0 256{
1af1e62d
JS
257 semantic_error* e = new semantic_error(er);
258 if (!e->tok1)
259 e->tok1 = this->tok;
c69a87e0
FCE
260 assert (e->chain == 0);
261 e->chain = this->saved_conversion_error;
262 this->saved_conversion_error = e;
263}
264
265
56099f08
FCE
266// ------------------------------------------------------------------------
267// parse tree printing
268
cc9ee605 269ostream& operator << (ostream& o, const expression& k)
56099f08
FCE
270{
271 k.print (o);
272 return o;
273}
274
275
cc9ee605 276void literal_string::print (ostream& o) const
56099f08 277{
cc9ee605
FCE
278 o << '"';
279 for (unsigned i=0; i<value.size(); i++)
280 if (value[i] == '"') // or other escapeworthy characters?
281 o << '\\' << '"';
282 else
283 o << value[i];
284 o << '"';
56099f08
FCE
285}
286
f3c26ea5 287
cc9ee605 288void literal_number::print (ostream& o) const
56099f08 289{
9ea68eb9
JS
290 if (print_hex)
291 o << hex << showbase;
56099f08 292 o << value;
9ea68eb9
JS
293 if (print_hex)
294 o << dec << noshowbase;
56099f08
FCE
295}
296
297
7d902887
FCE
298void embedded_expr::print (ostream& o) const
299{
300 o << "%{ " << code << " %}";
301}
302
303
cc9ee605 304void binary_expression::print (ostream& o) const
56099f08 305{
dff50e09
FCE
306 o << "(" << *left << ") "
307 << op
a9c62ac9 308 << " (" << *right << ")";
56099f08 309}
2f1a1aea
FCE
310
311
cc9ee605 312void unary_expression::print (ostream& o) const
2f1a1aea 313{
dff50e09 314 o << op << '(' << *operand << ")";
56099f08
FCE
315}
316
cc9ee605 317void array_in::print (ostream& o) const
69c68955
FCE
318{
319 o << "[";
320 for (unsigned i=0; i<operand->indexes.size(); i++)
321 {
322 if (i > 0) o << ", ";
323 operand->indexes[i]->print (o);
324 }
a9c62ac9
FCE
325 o << "] in ";
326 operand->base->print_indexable (o);
69c68955 327}
56099f08 328
cc9ee605 329void post_crement::print (ostream& o) const
56099f08 330{
dff50e09 331 o << '(' << *operand << ")" << op;
56099f08
FCE
332}
333
334
cc9ee605 335void ternary_expression::print (ostream& o) const
56099f08 336{
ae56fddd
FCE
337 o << "(" << *cond << ")?("
338 << *truevalue << "):("
dff50e09 339 << *falsevalue << ")";
56099f08
FCE
340}
341
342
cc9ee605 343void symbol::print (ostream& o) const
56099f08
FCE
344{
345 o << name;
346}
347
348
c67847a0
JS
349void target_symbol::component::print (ostream& o) const
350{
351 switch (type)
352 {
5f36109e 353 case comp_pretty_print:
c67847a0
JS
354 case comp_struct_member:
355 o << "->" << member;
356 break;
357 case comp_literal_array_index:
358 o << '[' << num_index << ']';
359 break;
6fda2dff
JS
360 case comp_expression_array_index:
361 o << '[' << *expr_index << ']';
362 break;
c67847a0
JS
363 }
364}
365
366
367std::ostream& operator << (std::ostream& o, const target_symbol::component& c)
368{
369 c.print (o);
370 return o;
371}
372
373
8eb285ac 374void target_symbol::print (ostream& o) const
d7f3e0c5 375{
03c75a4a
JS
376 if (addressof)
377 o << "&";
277c21bc 378 o << name;
d7f3e0c5 379 for (unsigned i = 0; i < components.size(); ++i)
c67847a0 380 o << components[i];
d7f3e0c5
GH
381}
382
383
8eb285ac 384void cast_op::print (ostream& o) const
9b5af295 385{
03c75a4a
JS
386 if (addressof)
387 o << "&";
277c21bc 388 o << name << '(' << *operand;
9b5af295
JS
389 o << ", " << lex_cast_qstring (type);
390 if (module.length() > 0)
391 o << ", " << lex_cast_qstring (module);
392 o << ')';
393 for (unsigned i = 0; i < components.size(); ++i)
c67847a0 394 o << components[i];
9b5af295
JS
395}
396
397
30263a73
FCE
398void defined_op::print (ostream& o) const
399{
400 o << "@defined(" << *operand << ")";
401}
402
403
cc9ee605 404void vardecl::print (ostream& o) const
56099f08
FCE
405{
406 o << name;
ef474d24
JS
407 if (maxsize > 0)
408 o << "[" << maxsize << "]";
bed7c0af 409 if (arity > 0 || index_types.size() > 0)
56099f08 410 o << "[...]";
9ba8c134
JS
411 if (init)
412 {
413 o << " = ";
414 init->print(o);
415 }
56099f08
FCE
416}
417
2f1a1aea 418
cc9ee605 419void vardecl::printsig (ostream& o) const
56099f08 420{
ef474d24
JS
421 o << name;
422 if (maxsize > 0)
423 o << "[" << maxsize << "]";
424 o << ":" << type;
56099f08 425 if (index_types.size() > 0)
2f1a1aea 426 {
56099f08
FCE
427 o << " [";
428 for (unsigned i=0; i<index_types.size(); i++)
429 o << (i>0 ? ", " : "") << index_types[i];
430 o << "]";
431 }
432}
433
434
cc9ee605 435void functiondecl::print (ostream& o) const
56099f08
FCE
436{
437 o << "function " << name << " (";
438 for (unsigned i=0; i<formal_args.size(); i++)
439 o << (i>0 ? ", " : "") << *formal_args[i];
440 o << ")" << endl;
441 body->print(o);
442}
443
444
cc9ee605 445void functiondecl::printsig (ostream& o) const
56099f08
FCE
446{
447 o << name << ":" << type << " (";
448 for (unsigned i=0; i<formal_args.size(); i++)
449 o << (i>0 ? ", " : "")
450 << *formal_args[i]
451 << ":"
452 << formal_args[i]->type;
453 o << ")";
454}
455
456
cc9ee605 457void arrayindex::print (ostream& o) const
56099f08 458{
a9c62ac9
FCE
459 base->print_indexable (o);
460 o << "[";
56099f08
FCE
461 for (unsigned i=0; i<indexes.size(); i++)
462 o << (i>0 ? ", " : "") << *indexes[i];
463 o << "]";
464}
465
466
cc9ee605 467void functioncall::print (ostream& o) const
56099f08
FCE
468{
469 o << function << "(";
470 for (unsigned i=0; i<args.size(); i++)
471 o << (i>0 ? ", " : "") << *args[i];
472 o << ")";
dff50e09 473}
56099f08
FCE
474
475
d5e178c1
JS
476print_format*
477print_format::create(const token *t)
3cb17058 478{
d5e178c1
JS
479 bool stream, format, delim, newline, _char;
480 const char *n = t->content.c_str();
3cb17058
JS
481
482 stream = true;
32784362
MH
483 format = delim = newline = _char = false;
484
485 if (strcmp(n, "print_char") == 0)
d5e178c1 486 _char = true;
3cb17058
JS
487 else
488 {
d5e178c1
JS
489 if (*n == 's')
490 {
491 stream = false;
3cb17058
JS
492 ++n;
493 }
494
d5e178c1
JS
495 if (0 != strncmp(n, "print", 5))
496 return NULL;
497 n += 5;
498
499 if (*n == 'f')
500 {
501 format = true;
502 ++n;
503 }
504 else
505 {
506 if (*n == 'd')
507 {
508 delim = true;
509 ++n;
510 }
511
512 if (*n == 'l' && *(n+1) == 'n')
513 {
514 newline = true;
515 n += 2;
516 }
3cb17058 517 }
d5e178c1
JS
518
519 if (*n != '\0')
520 return NULL;
3cb17058
JS
521 }
522
d5e178c1
JS
523 print_format *pf = new print_format(stream, format, delim, newline, _char);
524 pf->tok = t;
525 return pf;
3cb17058
JS
526}
527
528
dff50e09 529string
d02548c0
GH
530print_format::components_to_string(vector<format_component> const & components)
531{
532 ostringstream oss;
533
534 for (vector<format_component>::const_iterator i = components.begin();
535 i != components.end(); ++i)
536 {
537
538 assert (i->type != conv_unspecified);
539
540 if (i->type == conv_literal)
541 {
542 assert(!i->literal_string.empty());
543 for (string::const_iterator j = i->literal_string.begin();
544 j != i->literal_string.end(); ++j)
545 {
c4bb5be2 546 // See also: c_unparser::visit_literal_string and lex_cast_qstring
d02548c0
GH
547 if (*j == '%')
548 oss << '%';
c4bb5be2
FCE
549 else if(*j == '"')
550 oss << '\\';
d02548c0
GH
551 oss << *j;
552 }
553 }
554 else
555 {
556 oss << '%';
557
558 if (i->flags & static_cast<unsigned long>(fmt_flag_zeropad))
559 oss << '0';
560
561 if (i->flags & static_cast<unsigned long>(fmt_flag_plus))
562 oss << '+';
563
564 if (i->flags & static_cast<unsigned long>(fmt_flag_space))
565 oss << ' ';
566
567 if (i->flags & static_cast<unsigned long>(fmt_flag_left))
568 oss << '-';
569
570 if (i->flags & static_cast<unsigned long>(fmt_flag_special))
571 oss << '#';
572
34201621
DB
573 if (i->widthtype == width_dynamic)
574 oss << '*';
575 else if (i->widthtype != width_unspecified && i->width > 0)
d02548c0
GH
576 oss << i->width;
577
34201621
DB
578 if (i->prectype == prec_dynamic)
579 oss << ".*";
580 else if (i->prectype != prec_unspecified && i->precision > 0)
d02548c0
GH
581 oss << '.' << i->precision;
582
dff50e09 583 switch (i->type)
dc0b623a
MH
584 {
585 case conv_binary:
586 oss << "b";
587 break;
588
fecccf83
EB
589 case conv_char:
590 oss << "llc";
591 break;
592
d02548c0
GH
593 case conv_signed_decimal:
594 oss << "lld";
595 break;
596
597 case conv_unsigned_decimal:
598 oss << "llu";
599 break;
600
601 case conv_unsigned_octal:
602 oss << "llo";
603 break;
604
58cf0567
MH
605 case conv_unsigned_ptr:
606 oss << "p";
607 break;
608
d02548c0
GH
609 case conv_unsigned_uppercase_hex:
610 oss << "llX";
611 break;
612
613 case conv_unsigned_lowercase_hex:
614 oss << "llx";
615 break;
616
617 case conv_string:
618 oss << 's';
619 break;
dff50e09 620
34201621
DB
621 case conv_memory:
622 oss << 'm';
623 break;
dff50e09 624
30c94a80
EB
625 case conv_memory_hex:
626 oss << 'M';
627 break;
628
d02548c0
GH
629 default:
630 break;
631 }
632 }
633 }
634 return oss.str ();
635}
dff50e09
FCE
636
637vector<print_format::format_component>
d02548c0
GH
638print_format::string_to_components(string const & str)
639{
640 format_component curr;
641 vector<format_component> res;
642
d02548c0
GH
643 curr.clear();
644
645 string::const_iterator i = str.begin();
dff50e09 646
d02548c0
GH
647 while (i != str.end())
648 {
07c17d67 649 if (*i != '%')
d02548c0 650 {
07c17d67
GH
651 assert (curr.type == conv_unspecified || curr.type == conv_literal);
652 curr.type = conv_literal;
dc0b623a 653 curr.literal_string += *i;
d02548c0 654 ++i;
07c17d67
GH
655 continue;
656 }
657 else if (i+1 == str.end() || *(i+1) == '%')
658 {
659 assert(*i == '%');
660 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
661 assert (curr.type == conv_unspecified || curr.type == conv_literal);
662 curr.type = conv_literal;
663 curr.literal_string += '%';
2a99f48f 664 i += 2;
07c17d67
GH
665 continue;
666 }
dff50e09 667 else
07c17d67
GH
668 {
669 assert(*i == '%');
670 if (curr.type != conv_unspecified)
d02548c0 671 {
07c17d67
GH
672 // Flush any component we were previously accumulating
673 assert (curr.type == conv_literal);
674 res.push_back(curr);
675 curr.clear();
676 }
677 }
678 ++i;
dff50e09 679
07c17d67
GH
680 if (i == str.end())
681 break;
d02548c0 682
dff50e09 683 // Now we are definitely parsing a conversion.
d898100a 684 // Begin by parsing flags (which are optional).
d02548c0 685
07c17d67
GH
686 switch (*i)
687 {
688 case '0':
689 curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
690 ++i;
d02548c0 691 break;
dff50e09 692
07c17d67
GH
693 case '+':
694 curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
695 ++i;
d02548c0 696 break;
dff50e09 697
07c17d67
GH
698 case '-':
699 curr.flags |= static_cast<unsigned long>(fmt_flag_left);
700 ++i;
d02548c0 701 break;
dff50e09 702
07c17d67
GH
703 case ' ':
704 curr.flags |= static_cast<unsigned long>(fmt_flag_space);
705 ++i;
706 break;
dff50e09 707
07c17d67
GH
708 case '#':
709 curr.flags |= static_cast<unsigned long>(fmt_flag_special);
710 ++i;
711 break;
dc0b623a 712
07c17d67
GH
713 default:
714 break;
715 }
d02548c0 716
34201621
DB
717 if (i == str.end())
718 break;
719
07c17d67 720 // Parse optional width
34201621 721 if (*i == '*')
07c17d67 722 {
34201621 723 curr.widthtype = width_dynamic;
07c17d67
GH
724 ++i;
725 }
34201621
DB
726 else if (isdigit(*i))
727 {
728 curr.widthtype = width_static;
729 curr.width = 0;
730 do
731 {
732 curr.width *= 10;
733 curr.width += (*i - '0');
734 ++i;
735 }
736 while (i != str.end() && isdigit(*i));
737 }
d02548c0 738
07c17d67
GH
739 if (i == str.end())
740 break;
d02548c0 741
07c17d67
GH
742 // Parse optional precision
743 if (*i == '.')
744 {
745 ++i;
746 if (i == str.end())
747 break;
34201621 748 if (*i == '*')
07c17d67 749 {
34201621 750 curr.prectype = prec_dynamic;
d02548c0 751 ++i;
07c17d67 752 }
34201621
DB
753 else if (isdigit(*i))
754 {
755 curr.prectype = prec_static;
756 curr.precision = 0;
757 do
758 {
759 curr.precision *= 10;
760 curr.precision += (*i - '0');
761 ++i;
762 }
763 while (i != str.end() && isdigit(*i));
764 }
07c17d67 765 }
d02548c0 766
07c17d67
GH
767 if (i == str.end())
768 break;
d02548c0 769
fecccf83 770 // Parse the actual conversion specifier (bcsmdioupxXn)
07c17d67
GH
771 switch (*i)
772 {
773 // Valid conversion types
dc0b623a
MH
774 case 'b':
775 curr.type = conv_binary;
776 break;
dff50e09 777
fecccf83
EB
778 case 'c':
779 curr.type = conv_char;
780 break;
781
07c17d67
GH
782 case 's':
783 curr.type = conv_string;
784 break;
dff50e09 785
34201621
DB
786 case 'm':
787 curr.type = conv_memory;
788 break;
dff50e09 789
30c94a80
EB
790 case 'M':
791 curr.type = conv_memory_hex;
792 break;
793
07c17d67
GH
794 case 'd':
795 case 'i':
796 curr.type = conv_signed_decimal;
797 break;
dff50e09 798
07c17d67
GH
799 case 'o':
800 curr.type = conv_unsigned_octal;
801 break;
dff50e09 802
07c17d67
GH
803 case 'u':
804 curr.type = conv_unsigned_decimal;
805 break;
dff50e09 806
58cf0567
MH
807 case 'p':
808 curr.type = conv_unsigned_ptr;
809 break;
810
07c17d67
GH
811 case 'X':
812 curr.type = conv_unsigned_uppercase_hex;
813 break;
dff50e09 814
07c17d67
GH
815 case 'x':
816 curr.type = conv_unsigned_lowercase_hex;
817 break;
dc0b623a 818
07c17d67 819 default:
d02548c0
GH
820 break;
821 }
dff50e09 822
07c17d67 823 if (curr.type == conv_unspecified)
a9c62ac9 824 throw parse_error("invalid or missing conversion specifier");
dff50e09 825
07c17d67 826 ++i;
dc0b623a 827 res.push_back(curr);
dff50e09 828 curr.clear();
d02548c0
GH
829 }
830
07c17d67
GH
831 // If there's a remaining partly-composed conversion, fail.
832 if (!curr.is_empty())
833 {
834 if (curr.type == conv_literal)
dff50e09 835 res.push_back(curr);
07c17d67 836 else
a9c62ac9 837 throw parse_error("trailing incomplete print format conversion");
07c17d67 838 }
d02548c0
GH
839
840 return res;
841}
842
843
844void print_format::print (ostream& o) const
845{
3cb17058 846 o << tok->content << "(";
d02548c0 847 if (print_with_format)
3cb17058
JS
848 o << lex_cast_qstring (raw_components);
849 if (print_with_delim)
850 o << lex_cast_qstring (delimiter.literal_string);
a9c62ac9
FCE
851 if (hist)
852 hist->print(o);
d02548c0
GH
853 for (vector<expression*>::const_iterator i = args.begin();
854 i != args.end(); ++i)
855 {
3cb17058 856 if (i != args.begin() || print_with_format || print_with_delim)
d02548c0
GH
857 o << ", ";
858 (*i)->print(o);
859 }
860 o << ")";
861}
862
863void stat_op::print (ostream& o) const
864{
865 o << '@';
866 switch (ctype)
867 {
868 case sc_average:
869 o << "avg(";
870 break;
871
872 case sc_count:
873 o << "count(";
874 break;
875
876 case sc_sum:
877 o << "sum(";
878 break;
879
880 case sc_min:
881 o << "min(";
882 break;
dff50e09 883
d02548c0
GH
884 case sc_max:
885 o << "max(";
886 break;
887 }
888 stat->print(o);
889 o << ")";
890}
891
dff50e09 892void
d02548c0
GH
893hist_op::print (ostream& o) const
894{
895 o << '@';
896 switch (htype)
897 {
898 case hist_linear:
899 assert(params.size() == 3);
900 o << "hist_linear(";
901 stat->print(o);
902 for (size_t i = 0; i < params.size(); ++i)
903 {
904 o << ", " << params[i];
905 }
906 o << ")";
907 break;
908
909 case hist_log:
e38723d2 910 assert(params.size() == 0);
d02548c0
GH
911 o << "hist_log(";
912 stat->print(o);
d02548c0
GH
913 o << ")";
914 break;
915 }
916}
917
cc9ee605 918ostream& operator << (ostream& o, const statement& k)
56099f08
FCE
919{
920 k.print (o);
921 return o;
922}
923
924
cc9ee605 925void embeddedcode::print (ostream &o) const
54dfabe9
FCE
926{
927 o << "%{";
928 o << code;
929 o << "%}";
930}
931
cc9ee605 932void block::print (ostream& o) const
56099f08
FCE
933{
934 o << "{" << endl;
935 for (unsigned i=0; i<statements.size(); i++)
69c68955 936 o << *statements [i] << endl;
bb2e3076 937 o << "}";
56099f08
FCE
938}
939
ba6f838d
FCE
940block::block (statement* car, statement* cdr)
941{
942 statements.push_back(car);
943 statements.push_back(cdr);
944 this->tok = car->tok;
945}
946
947
56099f08 948
f4fe2e93
FCE
949void try_block::print (ostream& o) const
950{
951 o << "try {" << endl;
952 if (try_block) o << *try_block << endl;
953 o << "} catch ";
954 if (catch_error_var) o << "(" << *catch_error_var << ") ";
955 o << "{" << endl;
956 if (catch_block) o << *catch_block << endl;
957 o << "}" << endl;
958}
959
960
cc9ee605 961void for_loop::print (ostream& o) const
56099f08 962{
f3c26ea5 963 o << "for (";
cbfbbf69 964 if (init) init->print (o);
f3c26ea5
FCE
965 o << "; ";
966 cond->print (o);
967 o << "; ";
cbfbbf69 968 if (incr) incr->print (o);
bb2e3076 969 o << ") ";
f3c26ea5 970 block->print (o);
56099f08
FCE
971}
972
973
cc9ee605 974void foreach_loop::print (ostream& o) const
69c68955 975{
c261711d
JS
976 o << "foreach (";
977 if (value)
978 {
979 value->print (o);
980 o << " = ";
981 }
982 o << "[";
69c68955
FCE
983 for (unsigned i=0; i<indexes.size(); i++)
984 {
985 if (i > 0) o << ", ";
986 indexes[i]->print (o);
93484556
FCE
987 if (sort_direction != 0 && sort_column == i+1)
988 o << (sort_direction > 0 ? "+" : "-");
69c68955 989 }
a9c62ac9
FCE
990 o << "] in ";
991 base->print_indexable (o);
93484556
FCE
992 if (sort_direction != 0 && sort_column == 0)
993 o << (sort_direction > 0 ? "+" : "-");
27f21e8c
DS
994 if (limit)
995 {
996 o << " limit ";
997 limit->print (o);
998 }
93484556 999 o << ") ";
69c68955
FCE
1000 block->print (o);
1001}
1002
1003
cc9ee605 1004void null_statement::print (ostream& o) const
56099f08 1005{
dff50e09 1006 o << ";";
56099f08
FCE
1007}
1008
1009
cc9ee605 1010void expr_statement::print (ostream& o) const
56099f08
FCE
1011{
1012 o << *value;
1013}
1014
1015
cc9ee605 1016void return_statement::print (ostream& o) const
56099f08
FCE
1017{
1018 o << "return " << *value;
1019}
1020
1021
cc9ee605 1022void delete_statement::print (ostream& o) const
56099f08
FCE
1023{
1024 o << "delete " << *value;
1025}
1026
cc9ee605 1027void next_statement::print (ostream& o) const
f3c26ea5
FCE
1028{
1029 o << "next";
1030}
1031
cc9ee605 1032void break_statement::print (ostream& o) const
f3c26ea5
FCE
1033{
1034 o << "break";
1035}
1036
cc9ee605 1037void continue_statement::print (ostream& o) const
f3c26ea5
FCE
1038{
1039 o << "continue";
1040}
56099f08 1041
cc9ee605 1042void if_statement::print (ostream& o) const
56099f08 1043{
bb2e3076 1044 o << "if (" << *condition << ") "
56099f08
FCE
1045 << *thenblock << endl;
1046 if (elseblock)
1047 o << "else " << *elseblock << endl;
1048}
1049
1050
cc9ee605 1051void stapfile::print (ostream& o) const
56099f08
FCE
1052{
1053 o << "# file " << name << endl;
1054
54dfabe9
FCE
1055 for (unsigned i=0; i<embeds.size(); i++)
1056 embeds[i]->print (o);
1057
bed7c0af
FCE
1058 for (unsigned i=0; i<globals.size(); i++)
1059 {
1060 o << "global ";
1061 globals[i]->print (o);
1062 o << endl;
1063 }
1064
20c6c071
GH
1065 for (unsigned i=0; i<aliases.size(); i++)
1066 {
1067 aliases[i]->print (o);
1068 o << endl;
1069 }
1070
bed7c0af 1071 for (unsigned i=0; i<probes.size(); i++)
56099f08
FCE
1072 {
1073 probes[i]->print (o);
1074 o << endl;
1075 }
1076
1077 for (unsigned j = 0; j < functions.size(); j++)
1078 {
1079 functions[j]->print (o);
1080 o << endl;
1081 }
1082}
1083
1084
cc9ee605 1085void probe::print (ostream& o) const
56099f08
FCE
1086{
1087 o << "probe ";
40a1cb62
FCE
1088 printsig (o);
1089 o << *body;
1090}
1091
1092
cc9ee605 1093void probe::printsig (ostream& o) const
40a1cb62 1094{
77b2151e
DB
1095 const probe_alias *alias = get_alias ();
1096 if (alias)
1097 {
1098 alias->printsig (o);
1099 return;
1100 }
dff50e09 1101
9c0c0e46 1102 for (unsigned i=0; i<locations.size(); i++)
56099f08 1103 {
65aeaea0 1104 if (i > 0) o << ",";
9c0c0e46 1105 locations[i]->print (o);
56099f08 1106 }
56099f08
FCE
1107}
1108
1109
c3a3c0c9 1110void
2c5a19c6 1111probe::collect_derivation_chain (std::vector<probe*> &probes_list)
c3a3c0c9 1112{
2c5a19c6 1113 probes_list.push_back(this);
c3a3c0c9
WC
1114}
1115
1116
cc9ee605 1117void probe_point::print (ostream& o) const
56099f08 1118{
9c0c0e46
FCE
1119 for (unsigned i=0; i<components.size(); i++)
1120 {
1121 if (i>0) o << ".";
1122 probe_point::component* c = components[i];
1123 o << c->functor;
1124 if (c->arg)
1125 o << "(" << *c->arg << ")";
1126 }
d898100a
FCE
1127 if (sufficient)
1128 o << "!";
1129 else if (optional) // sufficient implies optional
6e3347a9 1130 o << "?";
cbbe8080
MH
1131 if (condition)
1132 o<< " if (" << *condition << ")";
c3a3c0c9
WC
1133}
1134
1135string probe_point::str ()
1136{
1137 ostringstream o;
fc80eab8 1138 print(o);
c3a3c0c9 1139 return o.str();
56099f08
FCE
1140}
1141
cc9ee605 1142
20c6c071
GH
1143probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
1144 probe (), alias_names (aliases)
1145{
1146}
1147
cc9ee605 1148void probe_alias::printsig (ostream& o) const
20c6c071
GH
1149{
1150 for (unsigned i=0; i<alias_names.size(); i++)
1151 {
1152 o << (i>0 ? " = " : "");
1153 alias_names[i]->print (o);
1154 }
5227f1ea 1155 o << " = ";
20c6c071
GH
1156 for (unsigned i=0; i<locations.size(); i++)
1157 {
d898100a 1158 if (i > 0) o << ", ";
20c6c071
GH
1159 locations[i]->print (o);
1160 }
1161}
1162
56099f08 1163
cc9ee605 1164ostream& operator << (ostream& o, const probe_point& k)
82919855
FCE
1165{
1166 k.print (o);
1167 return o;
1168}
1169
1170
cc9ee605 1171ostream& operator << (ostream& o, const symboldecl& k)
56099f08
FCE
1172{
1173 k.print (o);
1174 return o;
1175}
1176
1177
82919855
FCE
1178
1179// ------------------------------------------------------------------------
1180// visitors
1181
1182
1183void
1184block::visit (visitor* u)
1185{
1186 u->visit_block (this);
1187}
1188
54dfabe9 1189
f4fe2e93
FCE
1190void
1191try_block::visit (visitor* u)
1192{
1193 u->visit_try_block (this);
1194}
1195
1196
54dfabe9
FCE
1197void
1198embeddedcode::visit (visitor* u)
1199{
1200 u->visit_embeddedcode (this);
1201}
1202
1203
82919855
FCE
1204void
1205for_loop::visit (visitor* u)
1206{
1207 u->visit_for_loop (this);
1208}
1209
69c68955
FCE
1210void
1211foreach_loop::visit (visitor* u)
1212{
1213 u->visit_foreach_loop (this);
1214}
1215
82919855
FCE
1216void
1217null_statement::visit (visitor* u)
1218{
1219 u->visit_null_statement (this);
1220}
1221
1222void
1223expr_statement::visit (visitor* u)
1224{
1225 u->visit_expr_statement (this);
1226}
1227
1228void
1229return_statement::visit (visitor* u)
1230{
1231 u->visit_return_statement (this);
1232}
1233
1234void
1235delete_statement::visit (visitor* u)
1236{
d7f3e0c5 1237 u->push_active_lvalue (this->value);
82919855 1238 u->visit_delete_statement (this);
d7f3e0c5 1239 u->pop_active_lvalue ();
82919855
FCE
1240}
1241
1242void
1243if_statement::visit (visitor* u)
1244{
1245 u->visit_if_statement (this);
1246}
1247
f3c26ea5
FCE
1248void
1249next_statement::visit (visitor* u)
1250{
1251 u->visit_next_statement (this);
1252}
1253
1254void
1255break_statement::visit (visitor* u)
1256{
1257 u->visit_break_statement (this);
1258}
1259
1260void
1261continue_statement::visit (visitor* u)
1262{
1263 u->visit_continue_statement (this);
1264}
1265
82919855
FCE
1266void
1267literal_string::visit(visitor* u)
1268{
1269 u->visit_literal_string (this);
1270}
1271
1272void
1273literal_number::visit(visitor* u)
1274{
1275 u->visit_literal_number (this);
1276}
1277
1278void
1279binary_expression::visit (visitor* u)
1280{
1281 u->visit_binary_expression (this);
1282}
1283
7d902887
FCE
1284void
1285embedded_expr::visit (visitor* u)
1286{
1287 u->visit_embedded_expr (this);
1288}
1289
82919855
FCE
1290void
1291unary_expression::visit (visitor* u)
1292{
1293 u->visit_unary_expression (this);
1294}
1295
1296void
1297pre_crement::visit (visitor* u)
1298{
d7f3e0c5 1299 u->push_active_lvalue (this->operand);
82919855 1300 u->visit_pre_crement (this);
d7f3e0c5 1301 u->pop_active_lvalue ();
82919855
FCE
1302}
1303
1304void
1305post_crement::visit (visitor* u)
1306{
d7f3e0c5 1307 u->push_active_lvalue (this->operand);
82919855 1308 u->visit_post_crement (this);
d7f3e0c5 1309 u->pop_active_lvalue ();
82919855
FCE
1310}
1311
1312void
1313logical_or_expr::visit (visitor* u)
1314{
1315 u->visit_logical_or_expr (this);
1316}
1317
1318void
1319logical_and_expr::visit (visitor* u)
1320{
1321 u->visit_logical_and_expr (this);
1322}
1323
1324void
1325array_in::visit (visitor* u)
1326{
1327 u->visit_array_in (this);
1328}
1329
1330void
1331comparison::visit (visitor* u)
1332{
1333 u->visit_comparison (this);
1334}
1335
1336void
1337concatenation::visit (visitor* u)
1338{
1339 u->visit_concatenation (this);
1340}
1341
82919855
FCE
1342void
1343ternary_expression::visit (visitor* u)
1344{
1345 u->visit_ternary_expression (this);
1346}
1347
1348void
1349assignment::visit (visitor* u)
1350{
d7f3e0c5 1351 u->push_active_lvalue (this->left);
82919855 1352 u->visit_assignment (this);
d7f3e0c5 1353 u->pop_active_lvalue ();
82919855
FCE
1354}
1355
1356void
1357symbol::visit (visitor* u)
1358{
1359 u->visit_symbol (this);
1360}
1361
dff50e09 1362void
d7f3e0c5
GH
1363target_symbol::visit (visitor* u)
1364{
1365 u->visit_target_symbol(this);
1366}
1367
6fda2dff
JS
1368void
1369target_symbol::visit_components (visitor* u)
1370{
1371 for (unsigned i = 0; i < components.size(); ++i)
1372 if (components[i].type == comp_expression_array_index)
1373 components[i].expr_index->visit (u);
1374}
1375
1376void
1377target_symbol::visit_components (update_visitor* u)
1378{
1379 for (unsigned i = 0; i < components.size(); ++i)
1380 if (components[i].type == comp_expression_array_index)
8b095b45 1381 u->replace (components[i].expr_index);
6fda2dff
JS
1382}
1383
9b5af295
JS
1384void
1385cast_op::visit (visitor* u)
1386{
1387 u->visit_cast_op(this);
1388}
1389
30263a73
FCE
1390
1391void
1392defined_op::visit (visitor* u)
1393{
1394 u->visit_defined_op(this);
1395}
1396
1397
82919855
FCE
1398void
1399arrayindex::visit (visitor* u)
1400{
1401 u->visit_arrayindex (this);
1402}
1403
1404void
1405functioncall::visit (visitor* u)
1406{
1407 u->visit_functioncall (this);
1408}
1409
d02548c0
GH
1410void
1411print_format::visit (visitor *u)
1412{
1413 u->visit_print_format (this);
1414}
1415
1416void
1417stat_op::visit (visitor *u)
1418{
1419 u->visit_stat_op (this);
1420}
1421
1422void
1423hist_op::visit (visitor *u)
1424{
1425 u->visit_hist_op (this);
1426}
1427
dff50e09 1428void
d02548c0
GH
1429indexable::print_indexable (std::ostream& o) const
1430{
1431 const symbol *sym;
1432 const hist_op *hist;
1433 classify_const_indexable(this, sym, hist);
1434 if (sym)
1435 sym->print (o);
1436 else
1437 {
1438 assert (hist);
1439 hist->print (o);
dff50e09 1440 }
d02548c0
GH
1441}
1442
dff50e09 1443void
d02548c0
GH
1444indexable::visit_indexable (visitor* u)
1445{
1446 symbol *sym;
1447 hist_op *hist;
1448 classify_indexable(this, sym, hist);
1449 if (sym)
1450 sym->visit (u);
1451 else
1452 {
1453 assert (hist);
1454 hist->visit (u);
1455 }
1456}
1457
1458
dff50e09 1459bool
d02548c0
GH
1460indexable::is_symbol(symbol *& sym_out)
1461{
1462 sym_out = NULL;
1463 return false;
1464}
1465
dff50e09 1466bool
d02548c0
GH
1467indexable::is_hist_op(hist_op *& hist_out)
1468{
1469 hist_out = NULL;
1470 return false;
1471}
1472
dff50e09 1473bool
d02548c0
GH
1474indexable::is_const_symbol(const symbol *& sym_out) const
1475{
1476 sym_out = NULL;
1477 return false;
1478}
1479
dff50e09 1480bool
d02548c0
GH
1481indexable::is_const_hist_op(const hist_op *& hist_out) const
1482{
1483 hist_out = NULL;
1484 return false;
1485}
1486
dff50e09 1487bool
d02548c0
GH
1488symbol::is_symbol(symbol *& sym_out)
1489{
1490 sym_out = this;
1491 return true;
1492}
1493
dff50e09 1494bool
d02548c0
GH
1495symbol::is_const_symbol(const symbol *& sym_out) const
1496{
1497 sym_out = this;
1498 return true;
1499}
1500
1501const token *
1502symbol::get_tok() const
1503{
1504 return tok;
1505}
1506
dff50e09 1507bool
d02548c0
GH
1508hist_op::is_hist_op(hist_op *& hist_out)
1509{
1510 hist_out = this;
1511 return true;
1512}
1513
dff50e09 1514bool
d02548c0
GH
1515hist_op::is_const_hist_op(const hist_op *& hist_out) const
1516{
1517 hist_out = this;
1518 return true;
1519}
1520
1521const token *
1522hist_op::get_tok() const
1523{
1524 return tok;
1525}
1526
1527void
1528classify_indexable(indexable* ix,
1529 symbol *& array_out,
dff50e09 1530 hist_op *& hist_out)
d02548c0
GH
1531{
1532 array_out = NULL;
1533 hist_out = NULL;
1534 if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
1535 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1536 if (ix && !(hist_out || array_out))
1537 throw semantic_error("Failed to classify indexable", ix->get_tok());
1538}
1539
1540void
1541classify_const_indexable(const indexable* ix,
1542 const symbol *& array_out,
dff50e09 1543 const hist_op *& hist_out)
d02548c0
GH
1544{
1545 array_out = NULL;
1546 hist_out = NULL;
1547 if (!(ix->is_const_symbol(array_out) || ix->is_const_hist_op(hist_out)))
1548 throw semantic_error("Expecting symbol or histogram operator", ix->get_tok());
1549}
1550
d7f3e0c5
GH
1551// ------------------------------------------------------------------------
1552
dff50e09 1553bool
d7f3e0c5
GH
1554visitor::is_active_lvalue(expression *e)
1555{
1556 for (unsigned i = 0; i < active_lvalues.size(); ++i)
1557 {
1558 if (active_lvalues[i] == e)
1559 return true;
1560 }
1561 return false;
1562}
1563
dff50e09 1564void
d7f3e0c5
GH
1565visitor::push_active_lvalue(expression *e)
1566{
1567 active_lvalues.push_back(e);
1568}
1569
dff50e09 1570void
d7f3e0c5
GH
1571visitor::pop_active_lvalue()
1572{
1573 assert(!active_lvalues.empty());
1574 active_lvalues.pop_back();
1575}
1576
1577
82919855
FCE
1578
1579// ------------------------------------------------------------------------
1580
1581void
54dfabe9 1582traversing_visitor::visit_block (block* s)
82919855
FCE
1583{
1584 for (unsigned i=0; i<s->statements.size(); i++)
1585 s->statements[i]->visit (this);
1586}
1587
f4fe2e93
FCE
1588void
1589traversing_visitor::visit_try_block (try_block* s)
1590{
1591 if (s->try_block)
1592 s->try_block->visit (this);
1593 if (s->catch_error_var)
1594 s->catch_error_var->visit (this);
1595 if (s->catch_block)
1596 s->catch_block->visit (this);
1597}
1598
82919855 1599void
78f6bba6 1600traversing_visitor::visit_embeddedcode (embeddedcode*)
54dfabe9
FCE
1601{
1602}
1603
1604void
78f6bba6 1605traversing_visitor::visit_null_statement (null_statement*)
82919855
FCE
1606{
1607}
1608
1609void
54dfabe9 1610traversing_visitor::visit_expr_statement (expr_statement* s)
82919855
FCE
1611{
1612 s->value->visit (this);
1613}
1614
1615void
1616traversing_visitor::visit_if_statement (if_statement* s)
1617{
1618 s->condition->visit (this);
1619 s->thenblock->visit (this);
2b066ec1
FCE
1620 if (s->elseblock)
1621 s->elseblock->visit (this);
82919855
FCE
1622}
1623
1624void
1625traversing_visitor::visit_for_loop (for_loop* s)
1626{
cbfbbf69 1627 if (s->init) s->init->visit (this);
82919855 1628 s->cond->visit (this);
cbfbbf69 1629 if (s->incr) s->incr->visit (this);
82919855
FCE
1630 s->block->visit (this);
1631}
1632
69c68955
FCE
1633void
1634traversing_visitor::visit_foreach_loop (foreach_loop* s)
1635{
dff50e09 1636 symbol *array = NULL;
71572ba8
GH
1637 hist_op *hist = NULL;
1638 classify_indexable (s->base, array, hist);
1639 if (array)
1640 array->visit(this);
1641 else
1642 hist->visit(this);
1643
69c68955
FCE
1644 for (unsigned i=0; i<s->indexes.size(); i++)
1645 s->indexes[i]->visit (this);
27f21e8c 1646
c261711d
JS
1647 if (s->value)
1648 s->value->visit (this);
1649
27f21e8c
DS
1650 if (s->limit)
1651 s->limit->visit (this);
1652
69c68955
FCE
1653 s->block->visit (this);
1654}
1655
82919855
FCE
1656void
1657traversing_visitor::visit_return_statement (return_statement* s)
1658{
1659 s->value->visit (this);
1660}
1661
1662void
1663traversing_visitor::visit_delete_statement (delete_statement* s)
1664{
1665 s->value->visit (this);
1666}
1667
f3c26ea5 1668void
78f6bba6 1669traversing_visitor::visit_next_statement (next_statement*)
f3c26ea5
FCE
1670{
1671}
1672
1673void
78f6bba6 1674traversing_visitor::visit_break_statement (break_statement*)
f3c26ea5
FCE
1675{
1676}
1677
1678void
78f6bba6 1679traversing_visitor::visit_continue_statement (continue_statement*)
f3c26ea5
FCE
1680{
1681}
1682
82919855 1683void
78f6bba6 1684traversing_visitor::visit_literal_string (literal_string*)
82919855
FCE
1685{
1686}
1687
1688void
78f6bba6 1689traversing_visitor::visit_literal_number (literal_number*)
82919855
FCE
1690{
1691}
1692
7d902887
FCE
1693void
1694traversing_visitor::visit_embedded_expr (embedded_expr*)
1695{
1696}
1697
82919855
FCE
1698void
1699traversing_visitor::visit_binary_expression (binary_expression* e)
1700{
1701 e->left->visit (this);
1702 e->right->visit (this);
1703}
1704
1705void
1706traversing_visitor::visit_unary_expression (unary_expression* e)
1707{
1708 e->operand->visit (this);
1709}
1710
1711void
1712traversing_visitor::visit_pre_crement (pre_crement* e)
1713{
1714 e->operand->visit (this);
1715}
1716
1717void
1718traversing_visitor::visit_post_crement (post_crement* e)
1719{
1720 e->operand->visit (this);
1721}
1722
1723
1724void
1725traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
1726{
1727 e->left->visit (this);
1728 e->right->visit (this);
1729}
1730
1731void
1732traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
1733{
1734 e->left->visit (this);
1735 e->right->visit (this);
1736}
1737
1738void
1739traversing_visitor::visit_array_in (array_in* e)
1740{
ce10591c 1741 e->operand->visit (this);
82919855
FCE
1742}
1743
1744void
1745traversing_visitor::visit_comparison (comparison* e)
1746{
1747 e->left->visit (this);
1748 e->right->visit (this);
1749}
1750
1751void
1752traversing_visitor::visit_concatenation (concatenation* e)
1753{
1754 e->left->visit (this);
1755 e->right->visit (this);
1756}
1757
82919855
FCE
1758void
1759traversing_visitor::visit_ternary_expression (ternary_expression* e)
1760{
1761 e->cond->visit (this);
1762 e->truevalue->visit (this);
1763 e->falsevalue->visit (this);
1764}
1765
1766void
1767traversing_visitor::visit_assignment (assignment* e)
1768{
1769 e->left->visit (this);
1770 e->right->visit (this);
1771}
1772
1773void
78f6bba6 1774traversing_visitor::visit_symbol (symbol*)
82919855
FCE
1775{
1776}
1777
d7f3e0c5 1778void
6fda2dff 1779traversing_visitor::visit_target_symbol (target_symbol* e)
d7f3e0c5 1780{
6fda2dff 1781 e->visit_components (this);
d7f3e0c5
GH
1782}
1783
9b5af295
JS
1784void
1785traversing_visitor::visit_cast_op (cast_op* e)
1786{
1787 e->operand->visit (this);
6fda2dff 1788 e->visit_components (this);
9b5af295
JS
1789}
1790
30263a73
FCE
1791void
1792traversing_visitor::visit_defined_op (defined_op* e)
1793{
1794 e->operand->visit (this);
1795}
1796
1797
82919855
FCE
1798void
1799traversing_visitor::visit_arrayindex (arrayindex* e)
1800{
cbfbbf69
FCE
1801 for (unsigned i=0; i<e->indexes.size(); i++)
1802 e->indexes[i]->visit (this);
1803
1bbeef03
GH
1804 symbol *array = NULL;
1805 hist_op *hist = NULL;
1806 classify_indexable(e->base, array, hist);
1807 if (array)
1808 return array->visit(this);
1809 else
1810 return hist->visit(this);
82919855
FCE
1811}
1812
1813void
1814traversing_visitor::visit_functioncall (functioncall* e)
1815{
1816 for (unsigned i=0; i<e->args.size(); i++)
1817 e->args[i]->visit (this);
1818}
1819
d02548c0
GH
1820void
1821traversing_visitor::visit_print_format (print_format* e)
1822{
1823 for (unsigned i=0; i<e->args.size(); i++)
1824 e->args[i]->visit (this);
a4636912
GH
1825 if (e->hist)
1826 e->hist->visit(this);
d02548c0
GH
1827}
1828
1829void
1830traversing_visitor::visit_stat_op (stat_op* e)
1831{
1832 e->stat->visit (this);
1833}
1834
1835void
1836traversing_visitor::visit_hist_op (hist_op* e)
1837{
1838 e->stat->visit (this);
1839}
1840
82919855 1841
cbfbbf69 1842void
dff50e09 1843functioncall_traversing_visitor::visit_functioncall (functioncall* e)
cbfbbf69
FCE
1844{
1845 traversing_visitor::visit_functioncall (e);
1846
1847 // prevent infinite recursion
1848 if (traversed.find (e->referent) == traversed.end ())
1849 {
1850 traversed.insert (e->referent);
1851 // recurse
3066c15c
FCE
1852 functiondecl* last_current_function = current_function;
1853 current_function = e->referent;
cbfbbf69 1854 e->referent->body->visit (this);
3066c15c 1855 current_function = last_current_function;
cbfbbf69
FCE
1856 }
1857}
1858
1859
f4fe2e93
FCE
1860void
1861varuse_collecting_visitor::visit_try_block (try_block *s)
1862{
1863 if (s->try_block)
1864 s->try_block->visit (this);
1865 if (s->catch_error_var)
1866 written.insert (s->catch_error_var->referent);
1867 if (s->catch_block)
1868 s->catch_block->visit (this);
1869
1870 // NB: don't functioncall_traversing_visitor::visit_try_block (s);
1871 // since that would count s->catch_error_var as a read also.
1872}
1873
1874
cbfbbf69
FCE
1875void
1876varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
1877{
313db8e6
DB
1878 assert (current_function); // only they get embedded code
1879
1880 // Don't allow embedded C functions in unprivileged mode unless
1881 // they are tagged with /* unprivileged */
1882 if (session.unprivileged && s->code.find ("/* unprivileged */") == string::npos)
1883 throw semantic_error ("function may not be used when --unprivileged is specified",
1884 current_function->tok);
1885
cba1d02d
JS
1886 // Don't allow /* guru */ functions unless -g is active.
1887 if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
1888 throw semantic_error ("function may not be used unless -g is specified",
1889 current_function->tok);
1890
1b07c728
FCE
1891 // We want to elide embedded-C functions when possible. For
1892 // example, each $target variable access is expanded to an
1893 // embedded-C function call. Yet, for safety reasons, we should
1894 // presume that embedded-C functions have intentional side-effects.
1895 //
1896 // To tell these two types of functions apart, we apply a
1897 // Kludge(tm): we look for a magic string within the function body.
1898 // $target variables as rvalues will have this; lvalues won't.
1899 // Also, explicit side-effect-free tapset functions will have this.
dff50e09 1900
1b07c728 1901 if (s->code.find ("/* pure */") != string::npos)
3066c15c
FCE
1902 return;
1903
cbfbbf69
FCE
1904 embedded_seen = true;
1905}
1906
7d902887
FCE
1907
1908// About the same case as above.
1909void
1910varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
1911{
1912 // Don't allow embedded C functions in unprivileged mode unless
1913 // they are tagged with /* unprivileged */
1914 if (session.unprivileged && e->code.find ("/* unprivileged */") == string::npos)
1915 throw semantic_error ("embedded expression may not be used when --unprivileged is specified",
1916 e->tok);
1917
1918 // Don't allow /* guru */ functions unless -g is active.
1919 if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
1920 throw semantic_error ("embedded expression may not be used unless -g is specified",
1921 e->tok);
1922
1923 // We want to elide embedded-C functions when possible. For
1924 // example, each $target variable access is expanded to an
1925 // embedded-C function call. Yet, for safety reasons, we should
1926 // presume that embedded-C functions have intentional side-effects.
1927 //
1928 // To tell these two types of functions apart, we apply a
1929 // Kludge(tm): we look for a magic string within the function body.
1930 // $target variables as rvalues will have this; lvalues won't.
1931 // Also, explicit side-effect-free tapset functions will have this.
1932
1933 if (e->code.find ("/* pure */") != string::npos)
1934 return;
1935
1936 embedded_seen = true;
1937}
1938
1939
b0be9bdb
FCE
1940void
1941varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
1942{
1943 // Still-unresolved target symbol assignments get treated as
1944 // generating side-effects like embedded-C, to prevent premature
1945 // elision and later error message suppression (PR5516). rvalue use
1946 // of unresolved target symbols is OTOH not considered a side-effect.
1947
1948 if (is_active_lvalue (e))
1949 embedded_seen = true;
6fda2dff
JS
1950
1951 functioncall_traversing_visitor::visit_target_symbol (e);
b0be9bdb 1952}
cbfbbf69 1953
9b5af295
JS
1954void
1955varuse_collecting_visitor::visit_cast_op (cast_op *e)
1956{
1957 // As with target_symbols, unresolved cast assignments need to preserved
1958 // for later error handling.
1959 if (is_active_lvalue (e))
1960 embedded_seen = true;
1961
1962 functioncall_traversing_visitor::visit_cast_op (e);
1963}
1964
30263a73
FCE
1965void
1966varuse_collecting_visitor::visit_defined_op (defined_op *e)
1967{
1968 // XXX
1969 functioncall_traversing_visitor::visit_defined_op (e);
1970}
1971
1972
cbfbbf69
FCE
1973void
1974varuse_collecting_visitor::visit_print_format (print_format* e)
1975{
1976 // NB: Instead of being top-level statements, "print" and "printf"
1977 // are implemented as statement-expressions containing a
1978 // print_format. They have side-effects, but not via the
dff50e09 1979 // embedded-code detection method above.
1b07c728
FCE
1980 //
1981 // But sprint and sprintf don't have side-effects.
1982
1983 if (e->print_to_stream)
1984 embedded_seen = true; // a proxy for "has unknown side-effects"
1985
cbfbbf69
FCE
1986 functioncall_traversing_visitor::visit_print_format (e);
1987}
1988
1989
1990void
1991varuse_collecting_visitor::visit_assignment (assignment *e)
1992{
1993 if (e->op == "=" || e->op == "<<<") // pure writes
1994 {
3066c15c 1995 expression* last_lvalue = current_lvalue;
cbfbbf69
FCE
1996 current_lvalue = e->left; // leave a mark for ::visit_symbol
1997 functioncall_traversing_visitor::visit_assignment (e);
1998 current_lvalue = last_lvalue;
1999 }
2000 else // read-modify-writes
2001 {
2002 expression* last_lrvalue = current_lrvalue;
2003 current_lrvalue = e->left; // leave a mark for ::visit_symbol
2004 functioncall_traversing_visitor::visit_assignment (e);
2005 current_lrvalue = last_lrvalue;
2006 }
2007}
2008
2009void
2010varuse_collecting_visitor::visit_symbol (symbol *e)
2011{
2012 if (e->referent == 0)
2013 throw semantic_error ("symbol without referent", e->tok);
2014
d0c4107b
FCE
2015 // We could handle initialized globals by marking them as "written".
2016 // However, this current visitor may be called for a function or
2017 // probe body, from the point of view of which this global is
2018 // already initialized, so not written.
2019 /*
27d24ae2
FCE
2020 if (e->referent->init)
2021 written.insert (e->referent);
d0c4107b 2022 */
27d24ae2 2023
cbfbbf69
FCE
2024 if (current_lvalue == e || current_lrvalue == e)
2025 {
2026 written.insert (e->referent);
2027 // clog << "write ";
2028 }
2029 if (current_lvalue != e || current_lrvalue == e)
2030 {
2031 read.insert (e->referent);
2032 // clog << "read ";
2033 }
2034 // clog << *e->tok << endl;
2035}
2036
2037// NB: stat_op need not be overridden, since it will get to
2038// visit_symbol and only as a possible rvalue.
2039
d20fd9e9 2040
cbfbbf69
FCE
2041void
2042varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
2043{
2044 // Hooking this callback is necessary because of the hacky
2045 // statistics representation. For the expression "i[4] = 5", the
2046 // incoming lvalue will point to this arrayindex. However, the
2047 // symbol corresponding to the "i[4]" is multiply inherited with
2048 // arrayindex. If the symbol base part of this object is not at
2049 // offset 0, then static_cast<symbol*>(e) may result in a different
2050 // address, and not match lvalue by number when we recurse that way.
2051 // So we explicitly override the incoming lvalue/lrvalue values to
2052 // point at the embedded objects' actual base addresses.
2053
2054 expression* last_lrvalue = current_lrvalue;
2055 expression* last_lvalue = current_lvalue;
2056
2057 symbol *array = NULL;
2058 hist_op *hist = NULL;
2059 classify_indexable(e->base, array, hist);
2060
2061 if (array)
2062 {
2063 if (current_lrvalue == e) current_lrvalue = array;
2064 if (current_lvalue == e) current_lvalue = array;
2065 functioncall_traversing_visitor::visit_arrayindex (e);
2066 }
2067 else // if (hist)
2068 {
2069 if (current_lrvalue == e) current_lrvalue = hist->stat;
2070 if (current_lvalue == e) current_lvalue = hist->stat;
2071 functioncall_traversing_visitor::visit_arrayindex (e);
2072 }
2073
2074 current_lrvalue = last_lrvalue;
2075 current_lvalue = last_lvalue;
2076}
2077
2078
2079void
2080varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
2081{
980759f3
MW
2082 expression* last_lrvalue = current_lrvalue;
2083 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
cbfbbf69 2084 functioncall_traversing_visitor::visit_pre_crement (e);
980759f3 2085 current_lrvalue = last_lrvalue;
cbfbbf69
FCE
2086}
2087
2088void
2089varuse_collecting_visitor::visit_post_crement (post_crement *e)
2090{
980759f3
MW
2091 expression* last_lrvalue = current_lrvalue;
2092 current_lrvalue = e->operand; // leave a mark for ::visit_symbol
cbfbbf69 2093 functioncall_traversing_visitor::visit_post_crement (e);
980759f3 2094 current_lrvalue = last_lrvalue;
cbfbbf69
FCE
2095}
2096
3066c15c
FCE
2097void
2098varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
2099{
27d24ae2
FCE
2100 // NB: we duplicate so don't bother call
2101 // functioncall_traversing_visitor::visit_foreach_loop (s);
2102
dff50e09 2103 symbol *array = NULL;
27d24ae2
FCE
2104 hist_op *hist = NULL;
2105 classify_indexable (s->base, array, hist);
2106 if (array)
2107 array->visit(this);
2108 else
2109 hist->visit(this);
2110
3066c15c 2111 // If the collection is sorted, imply a "write" access to the
27d24ae2 2112 // array in addition to the "read" one already noted above.
3066c15c
FCE
2113 if (s->sort_direction)
2114 {
dff50e09 2115 symbol *array = NULL;
3066c15c
FCE
2116 hist_op *hist = NULL;
2117 classify_indexable (s->base, array, hist);
2118 if (array) this->written.insert (array->referent);
2119 // XXX: Can hist_op iterations be sorted?
2120 }
27d24ae2
FCE
2121
2122 // NB: don't forget to visit the index expressions, which are lvalues.
2123 for (unsigned i=0; i<s->indexes.size(); i++)
2124 {
2125 expression* last_lvalue = current_lvalue;
2126 current_lvalue = s->indexes[i]; // leave a mark for ::visit_symbol
2127 s->indexes[i]->visit (this);
2128 current_lvalue = last_lvalue;
2129 }
2130
c261711d
JS
2131 // The value is an lvalue too
2132 if (s->value)
2133 {
2134 expression* last_lvalue = current_lvalue;
2135 current_lvalue = s->value; // leave a mark for ::visit_symbol
2136 s->value->visit (this);
2137 current_lvalue = last_lvalue;
2138 }
2139
27d24ae2
FCE
2140 if (s->limit)
2141 s->limit->visit (this);
2142
2143 s->block->visit (this);
3066c15c 2144}
cbfbbf69
FCE
2145
2146
3066c15c
FCE
2147void
2148varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
2149{
2150 // Ideally, this would be treated like an assignment: a plain write
2151 // to the underlying value ("lvalue"). XXX: However, the
2152 // optimization pass is not smart enough to remove an unneeded
2153 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2154 // should protect the underlying value from optimizional mischief.
2155 expression* last_lrvalue = current_lrvalue;
2156 current_lrvalue = s->value; // leave a mark for ::visit_symbol
2157 functioncall_traversing_visitor::visit_delete_statement (s);
2158 current_lrvalue = last_lrvalue;
2159}
cbfbbf69 2160
cf9ff341
FCE
2161bool
2162varuse_collecting_visitor::side_effect_free ()
2163{
2164 return (written.empty() && !embedded_seen);
2165}
2166
2167
2168bool
2169varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
2170{
2171 // A looser notion of side-effect-freeness with respect to a given
2172 // list of variables.
2173
2174 // That's useful because the written list may consist of local
2175 // variables of called functions. But visible side-effects only
2176 // occur if the client's locals, or any globals are written-to.
2177
2178 set<vardecl*> intersection;
2179 insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
2180 set_intersection (written.begin(), written.end(),
2181 vars.begin(), vars.end(),
2182 int_it);
2183
2184 return (intersection.empty() && !embedded_seen);
2185}
2186
2187
2188
cbfbbf69 2189
82919855
FCE
2190// ------------------------------------------------------------------------
2191
2192
2193throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
2194throwing_visitor::throwing_visitor (): msg ("invalid element") {}
2195
2196
2197void
2198throwing_visitor::throwone (const token* t)
2199{
2200 throw semantic_error (msg, t);
2201}
2202
2203void
54dfabe9
FCE
2204throwing_visitor::visit_block (block* s)
2205{
2206 throwone (s->tok);
2207}
2208
f4fe2e93
FCE
2209void
2210throwing_visitor::visit_try_block (try_block* s)
2211{
2212 throwone (s->tok);
2213}
2214
2215
54dfabe9
FCE
2216void
2217throwing_visitor::visit_embeddedcode (embeddedcode* s)
82919855
FCE
2218{
2219 throwone (s->tok);
2220}
2221
2222void
54dfabe9 2223throwing_visitor::visit_null_statement (null_statement* s)
82919855
FCE
2224{
2225 throwone (s->tok);
2226}
2227
2228void
54dfabe9 2229throwing_visitor::visit_expr_statement (expr_statement* s)
82919855
FCE
2230{
2231 throwone (s->tok);
2232}
2233
2234void
2235throwing_visitor::visit_if_statement (if_statement* s)
2236{
2237 throwone (s->tok);
2238}
2239
2240void
2241throwing_visitor::visit_for_loop (for_loop* s)
2242{
2243 throwone (s->tok);
2244}
2245
69c68955
FCE
2246void
2247throwing_visitor::visit_foreach_loop (foreach_loop* s)
2248{
2249 throwone (s->tok);
2250}
2251
82919855
FCE
2252void
2253throwing_visitor::visit_return_statement (return_statement* s)
2254{
2255 throwone (s->tok);
2256}
2257
2258void
2259throwing_visitor::visit_delete_statement (delete_statement* s)
2260{
2261 throwone (s->tok);
2262}
2263
f3c26ea5
FCE
2264void
2265throwing_visitor::visit_next_statement (next_statement* s)
2266{
2267 throwone (s->tok);
2268}
2269
2270void
2271throwing_visitor::visit_break_statement (break_statement* s)
2272{
2273 throwone (s->tok);
2274}
2275
2276void
2277throwing_visitor::visit_continue_statement (continue_statement* s)
2278{
2279 throwone (s->tok);
2280}
2281
82919855
FCE
2282void
2283throwing_visitor::visit_literal_string (literal_string* e)
2284{
2285 throwone (e->tok);
2286}
2287
2288void
2289throwing_visitor::visit_literal_number (literal_number* e)
2290{
2291 throwone (e->tok);
2292}
2293
7d902887
FCE
2294void
2295throwing_visitor::visit_embedded_expr (embedded_expr* e)
2296{
2297 throwone (e->tok);
2298}
2299
82919855
FCE
2300void
2301throwing_visitor::visit_binary_expression (binary_expression* e)
2302{
2303 throwone (e->tok);
2304}
2305
2306void
2307throwing_visitor::visit_unary_expression (unary_expression* e)
2308{
2309 throwone (e->tok);
2310}
2311
2312void
2313throwing_visitor::visit_pre_crement (pre_crement* e)
2314{
2315 throwone (e->tok);
2316}
2317
2318void
2319throwing_visitor::visit_post_crement (post_crement* e)
2320{
2321 throwone (e->tok);
0054a7ea
FCE
2322}
2323
2324
82919855
FCE
2325void
2326throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
2327{
2328 throwone (e->tok);
2329}
2330
2331void
2332throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
2333{
2334 throwone (e->tok);
2335}
2336
2337void
2338throwing_visitor::visit_array_in (array_in* e)
2339{
2340 throwone (e->tok);
2341}
2342
2343void
2344throwing_visitor::visit_comparison (comparison* e)
2345{
2346 throwone (e->tok);
2347}
2348
2349void
2350throwing_visitor::visit_concatenation (concatenation* e)
2351{
2352 throwone (e->tok);
2353}
2354
82919855
FCE
2355void
2356throwing_visitor::visit_ternary_expression (ternary_expression* e)
2357{
2358 throwone (e->tok);
2359}
2360
2361void
2362throwing_visitor::visit_assignment (assignment* e)
2363{
2364 throwone (e->tok);
2365}
2366
2367void
2368throwing_visitor::visit_symbol (symbol* e)
2369{
2370 throwone (e->tok);
2371}
2372
d7f3e0c5
GH
2373void
2374throwing_visitor::visit_target_symbol (target_symbol* e)
2375{
2376 throwone (e->tok);
2377}
2378
9b5af295
JS
2379void
2380throwing_visitor::visit_cast_op (cast_op* e)
2381{
2382 throwone (e->tok);
2383}
2384
30263a73
FCE
2385void
2386throwing_visitor::visit_defined_op (defined_op* e)
2387{
2388 throwone (e->tok);
2389}
2390
2391
82919855
FCE
2392void
2393throwing_visitor::visit_arrayindex (arrayindex* e)
2394{
2395 throwone (e->tok);
2396}
2397
2398void
2399throwing_visitor::visit_functioncall (functioncall* e)
2400{
2401 throwone (e->tok);
2402}
85365d1b 2403
d02548c0
GH
2404void
2405throwing_visitor::visit_print_format (print_format* e)
2406{
2407 throwone (e->tok);
2408}
2409
2410void
2411throwing_visitor::visit_stat_op (stat_op* e)
2412{
2413 throwone (e->tok);
2414}
2415
2416void
2417throwing_visitor::visit_hist_op (hist_op* e)
2418{
2419 throwone (e->tok);
2420}
2421
85365d1b
GH
2422
2423// ------------------------------------------------------------------------
2424
85365d1b
GH
2425
2426void
4b6455e8 2427update_visitor::visit_block (block* s)
85365d1b 2428{
85365d1b 2429 for (unsigned i = 0; i < s->statements.size(); ++i)
8b095b45 2430 replace (s->statements[i]);
4b6455e8
JS
2431 provide (s);
2432}
2433
f4fe2e93
FCE
2434void
2435update_visitor::visit_try_block (try_block* s)
2436{
2437 replace (s->try_block);
2438 replace (s->catch_error_var);
2439 replace (s->catch_block);
2440 provide (s);
2441}
2442
4b6455e8
JS
2443void
2444update_visitor::visit_embeddedcode (embeddedcode* s)
2445{
2446 provide (s);
2447}
2448
2449void
2450update_visitor::visit_null_statement (null_statement* s)
2451{
2452 provide (s);
2453}
2454
2455void
2456update_visitor::visit_expr_statement (expr_statement* s)
2457{
8b095b45 2458 replace (s->value);
4b6455e8
JS
2459 provide (s);
2460}
2461
2462void
2463update_visitor::visit_if_statement (if_statement* s)
2464{
8b095b45
JS
2465 replace (s->condition);
2466 replace (s->thenblock);
2467 replace (s->elseblock);
4b6455e8
JS
2468 provide (s);
2469}
2470
2471void
2472update_visitor::visit_for_loop (for_loop* s)
2473{
8b095b45
JS
2474 replace (s->init);
2475 replace (s->cond);
2476 replace (s->incr);
2477 replace (s->block);
4b6455e8
JS
2478 provide (s);
2479}
2480
2481void
2482update_visitor::visit_foreach_loop (foreach_loop* s)
2483{
2484 for (unsigned i = 0; i < s->indexes.size(); ++i)
8b095b45
JS
2485 replace (s->indexes[i]);
2486 replace (s->base);
c261711d 2487 replace (s->value);
8b095b45
JS
2488 replace (s->limit);
2489 replace (s->block);
4b6455e8
JS
2490 provide (s);
2491}
2492
2493void
2494update_visitor::visit_return_statement (return_statement* s)
2495{
8b095b45 2496 replace (s->value);
4b6455e8
JS
2497 provide (s);
2498}
2499
2500void
2501update_visitor::visit_delete_statement (delete_statement* s)
2502{
8b095b45 2503 replace (s->value);
4b6455e8
JS
2504 provide (s);
2505}
2506
2507void
2508update_visitor::visit_next_statement (next_statement* s)
2509{
2510 provide (s);
2511}
2512
2513void
2514update_visitor::visit_break_statement (break_statement* s)
2515{
2516 provide (s);
2517}
2518
2519void
2520update_visitor::visit_continue_statement (continue_statement* s)
2521{
2522 provide (s);
2523}
2524
2525void
2526update_visitor::visit_literal_string (literal_string* e)
2527{
2528 provide (e);
2529}
2530
2531void
2532update_visitor::visit_literal_number (literal_number* e)
2533{
2534 provide (e);
2535}
2536
7d902887
FCE
2537void
2538update_visitor::visit_embedded_expr (embedded_expr* e)
2539{
2540 provide (e);
2541}
2542
4b6455e8
JS
2543void
2544update_visitor::visit_binary_expression (binary_expression* e)
2545{
8b095b45
JS
2546 replace (e->left);
2547 replace (e->right);
4b6455e8
JS
2548 provide (e);
2549}
2550
2551void
2552update_visitor::visit_unary_expression (unary_expression* e)
2553{
8b095b45 2554 replace (e->operand);
4b6455e8
JS
2555 provide (e);
2556}
2557
2558void
2559update_visitor::visit_pre_crement (pre_crement* e)
2560{
8b095b45 2561 replace (e->operand);
4b6455e8
JS
2562 provide (e);
2563}
2564
2565void
2566update_visitor::visit_post_crement (post_crement* e)
2567{
8b095b45 2568 replace (e->operand);
4b6455e8
JS
2569 provide (e);
2570}
2571
2572
2573void
2574update_visitor::visit_logical_or_expr (logical_or_expr* e)
2575{
8b095b45
JS
2576 replace (e->left);
2577 replace (e->right);
4b6455e8
JS
2578 provide (e);
2579}
2580
2581void
2582update_visitor::visit_logical_and_expr (logical_and_expr* e)
2583{
8b095b45
JS
2584 replace (e->left);
2585 replace (e->right);
4b6455e8
JS
2586 provide (e);
2587}
2588
2589void
2590update_visitor::visit_array_in (array_in* e)
2591{
8b095b45 2592 replace (e->operand);
4b6455e8
JS
2593 provide (e);
2594}
2595
2596void
2597update_visitor::visit_comparison (comparison* e)
2598{
8b095b45
JS
2599 replace (e->left);
2600 replace (e->right);
4b6455e8
JS
2601 provide (e);
2602}
2603
2604void
2605update_visitor::visit_concatenation (concatenation* e)
2606{
8b095b45
JS
2607 replace (e->left);
2608 replace (e->right);
4b6455e8
JS
2609 provide (e);
2610}
2611
2612void
2613update_visitor::visit_ternary_expression (ternary_expression* e)
2614{
8b095b45
JS
2615 replace (e->cond);
2616 replace (e->truevalue);
2617 replace (e->falsevalue);
4b6455e8
JS
2618 provide (e);
2619}
2620
2621void
2622update_visitor::visit_assignment (assignment* e)
2623{
8b095b45
JS
2624 replace (e->left);
2625 replace (e->right);
4b6455e8
JS
2626 provide (e);
2627}
2628
2629void
2630update_visitor::visit_symbol (symbol* e)
2631{
2632 provide (e);
2633}
2634
2635void
2636update_visitor::visit_target_symbol (target_symbol* e)
2637{
6fda2dff 2638 e->visit_components (this);
4b6455e8
JS
2639 provide (e);
2640}
2641
9b5af295
JS
2642void
2643update_visitor::visit_cast_op (cast_op* e)
2644{
8b095b45 2645 replace (e->operand);
6fda2dff 2646 e->visit_components (this);
9b5af295
JS
2647 provide (e);
2648}
2649
30263a73
FCE
2650void
2651update_visitor::visit_defined_op (defined_op* e)
2652{
2653 replace (e->operand);
2654 provide (e);
2655}
2656
4b6455e8
JS
2657void
2658update_visitor::visit_arrayindex (arrayindex* e)
2659{
8b095b45 2660 replace (e->base);
4b6455e8 2661 for (unsigned i = 0; i < e->indexes.size(); ++i)
8b095b45 2662 replace (e->indexes[i]);
4b6455e8
JS
2663 provide (e);
2664}
2665
2666void
2667update_visitor::visit_functioncall (functioncall* e)
2668{
2669 for (unsigned i = 0; i < e->args.size(); ++i)
8b095b45 2670 replace (e->args[i]);
4b6455e8
JS
2671 provide (e);
2672}
2673
2674void
2675update_visitor::visit_print_format (print_format* e)
2676{
2677 for (unsigned i = 0; i < e->args.size(); ++i)
8b095b45
JS
2678 replace (e->args[i]);
2679 replace (e->hist);
4b6455e8
JS
2680 provide (e);
2681}
2682
2683void
2684update_visitor::visit_stat_op (stat_op* e)
2685{
8b095b45 2686 replace (e->stat);
4b6455e8
JS
2687 provide (e);
2688}
2689
2690void
2691update_visitor::visit_hist_op (hist_op* e)
2692{
8b095b45 2693 replace (e->stat);
4b6455e8
JS
2694 provide (e);
2695}
2696
2697template <> indexable*
3a4235b9 2698update_visitor::require <indexable> (indexable* src, bool clearok)
4b6455e8
JS
2699{
2700 indexable *dst = NULL;
2701 if (src != NULL)
2702 {
2703 symbol *array_src=NULL;
2704 hist_op *hist_src=NULL;
2705
2706 classify_indexable(src, array_src, hist_src);
2707
2708 if (array_src)
2709 dst = require (array_src);
2710 else
2711 dst = require (hist_src);
1cd151d5 2712 assert(clearok || dst);
4b6455e8
JS
2713 }
2714 return dst;
2715}
2716
2717
2718// ------------------------------------------------------------------------
2719
2720
2721void
2722deep_copy_visitor::visit_block (block* s)
2723{
2724 update_visitor::visit_block(new block(*s));
85365d1b
GH
2725}
2726
f4fe2e93
FCE
2727void
2728deep_copy_visitor::visit_try_block (try_block* s)
2729{
2730 update_visitor::visit_try_block(new try_block(*s));
2731}
2732
85365d1b 2733void
54dfabe9
FCE
2734deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
2735{
4b6455e8 2736 update_visitor::visit_embeddedcode(new embeddedcode(*s));
54dfabe9
FCE
2737}
2738
2739void
2740deep_copy_visitor::visit_null_statement (null_statement* s)
85365d1b 2741{
4b6455e8 2742 update_visitor::visit_null_statement(new null_statement(*s));
85365d1b
GH
2743}
2744
2745void
54dfabe9 2746deep_copy_visitor::visit_expr_statement (expr_statement* s)
85365d1b 2747{
4b6455e8 2748 update_visitor::visit_expr_statement(new expr_statement(*s));
85365d1b
GH
2749}
2750
2751void
2752deep_copy_visitor::visit_if_statement (if_statement* s)
2753{
4b6455e8 2754 update_visitor::visit_if_statement(new if_statement(*s));
85365d1b
GH
2755}
2756
2757void
2758deep_copy_visitor::visit_for_loop (for_loop* s)
2759{
4b6455e8 2760 update_visitor::visit_for_loop(new for_loop(*s));
85365d1b
GH
2761}
2762
2763void
2764deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
2765{
4b6455e8 2766 update_visitor::visit_foreach_loop(new foreach_loop(*s));
85365d1b
GH
2767}
2768
2769void
2770deep_copy_visitor::visit_return_statement (return_statement* s)
2771{
4b6455e8 2772 update_visitor::visit_return_statement(new return_statement(*s));
85365d1b
GH
2773}
2774
2775void
2776deep_copy_visitor::visit_delete_statement (delete_statement* s)
2777{
4b6455e8 2778 update_visitor::visit_delete_statement(new delete_statement(*s));
85365d1b
GH
2779}
2780
2781void
2782deep_copy_visitor::visit_next_statement (next_statement* s)
2783{
4b6455e8 2784 update_visitor::visit_next_statement(new next_statement(*s));
85365d1b
GH
2785}
2786
2787void
2788deep_copy_visitor::visit_break_statement (break_statement* s)
2789{
4b6455e8 2790 update_visitor::visit_break_statement(new break_statement(*s));
85365d1b
GH
2791}
2792
2793void
2794deep_copy_visitor::visit_continue_statement (continue_statement* s)
2795{
4b6455e8 2796 update_visitor::visit_continue_statement(new continue_statement(*s));
85365d1b
GH
2797}
2798
2799void
2800deep_copy_visitor::visit_literal_string (literal_string* e)
2801{
4b6455e8 2802 update_visitor::visit_literal_string(new literal_string(*e));
85365d1b
GH
2803}
2804
2805void
2806deep_copy_visitor::visit_literal_number (literal_number* e)
2807{
4b6455e8 2808 update_visitor::visit_literal_number(new literal_number(*e));
85365d1b
GH
2809}
2810
7d902887
FCE
2811void
2812deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
2813{
2814 update_visitor::visit_embedded_expr(new embedded_expr(*e));
2815}
2816
85365d1b
GH
2817void
2818deep_copy_visitor::visit_binary_expression (binary_expression* e)
2819{
4b6455e8 2820 update_visitor::visit_binary_expression(new binary_expression(*e));
85365d1b
GH
2821}
2822
2823void
2824deep_copy_visitor::visit_unary_expression (unary_expression* e)
2825{
4b6455e8 2826 update_visitor::visit_unary_expression(new unary_expression(*e));
85365d1b
GH
2827}
2828
2829void
2830deep_copy_visitor::visit_pre_crement (pre_crement* e)
2831{
4b6455e8 2832 update_visitor::visit_pre_crement(new pre_crement(*e));
85365d1b
GH
2833}
2834
2835void
2836deep_copy_visitor::visit_post_crement (post_crement* e)
2837{
4b6455e8 2838 update_visitor::visit_post_crement(new post_crement(*e));
85365d1b
GH
2839}
2840
2841
2842void
2843deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
2844{
4b6455e8 2845 update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
85365d1b
GH
2846}
2847
2848void
2849deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
2850{
4b6455e8 2851 update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
85365d1b
GH
2852}
2853
2854void
2855deep_copy_visitor::visit_array_in (array_in* e)
2856{
4b6455e8 2857 update_visitor::visit_array_in(new array_in(*e));
85365d1b
GH
2858}
2859
2860void
2861deep_copy_visitor::visit_comparison (comparison* e)
2862{
4b6455e8 2863 update_visitor::visit_comparison(new comparison(*e));
85365d1b
GH
2864}
2865
2866void
2867deep_copy_visitor::visit_concatenation (concatenation* e)
2868{
4b6455e8 2869 update_visitor::visit_concatenation(new concatenation(*e));
85365d1b
GH
2870}
2871
2872void
2873deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
2874{
4b6455e8 2875 update_visitor::visit_ternary_expression(new ternary_expression(*e));
85365d1b
GH
2876}
2877
2878void
2879deep_copy_visitor::visit_assignment (assignment* e)
2880{
4b6455e8 2881 update_visitor::visit_assignment(new assignment(*e));
85365d1b
GH
2882}
2883
2884void
2885deep_copy_visitor::visit_symbol (symbol* e)
2886{
4b6455e8
JS
2887 symbol* n = new symbol(*e);
2888 n->referent = NULL; // don't copy!
2889 update_visitor::visit_symbol(n);
d7f3e0c5
GH
2890}
2891
2892void
2893deep_copy_visitor::visit_target_symbol (target_symbol* e)
2894{
4b6455e8
JS
2895 target_symbol* n = new target_symbol(*e);
2896 n->referent = NULL; // don't copy!
2897 update_visitor::visit_target_symbol(n);
85365d1b
GH
2898}
2899
9b5af295
JS
2900void
2901deep_copy_visitor::visit_cast_op (cast_op* e)
2902{
2903 update_visitor::visit_cast_op(new cast_op(*e));
2904}
2905
30263a73
FCE
2906void
2907deep_copy_visitor::visit_defined_op (defined_op* e)
2908{
2909 update_visitor::visit_defined_op(new defined_op(*e));
2910}
2911
85365d1b
GH
2912void
2913deep_copy_visitor::visit_arrayindex (arrayindex* e)
2914{
4b6455e8 2915 update_visitor::visit_arrayindex(new arrayindex(*e));
85365d1b
GH
2916}
2917
2918void
2919deep_copy_visitor::visit_functioncall (functioncall* e)
2920{
4b6455e8
JS
2921 functioncall* n = new functioncall(*e);
2922 n->referent = NULL; // don't copy!
2923 update_visitor::visit_functioncall(n);
85365d1b
GH
2924}
2925
d02548c0
GH
2926void
2927deep_copy_visitor::visit_print_format (print_format* e)
2928{
4b6455e8 2929 update_visitor::visit_print_format(new print_format(*e));
d02548c0
GH
2930}
2931
2932void
2933deep_copy_visitor::visit_stat_op (stat_op* e)
2934{
4b6455e8 2935 update_visitor::visit_stat_op(new stat_op(*e));
d02548c0
GH
2936}
2937
2938void
2939deep_copy_visitor::visit_hist_op (hist_op* e)
2940{
4b6455e8 2941 update_visitor::visit_hist_op(new hist_op(*e));
edc22ba9
DB
2942}
2943
73267b89 2944/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.4444 seconds and 5 git commands to generate.