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