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