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