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