1 // parse tree functions
2 // Copyright (C) 2005-2011 Red Hat Inc.
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
28 expression::expression ():
29 type (pe_unknown
), tok (0)
34 expression::~expression ()
39 statement::statement ():
45 statement::statement (const token
* tok
):
51 null_statement::null_statement (const token
* tok
):
57 statement::~statement ()
68 arrayindex::arrayindex ():
74 functioncall::functioncall ():
80 symboldecl::symboldecl ():
81 tok (0), systemtap_v_conditional (0),
87 symboldecl::~symboldecl ()
91 probe_point::probe_point (std::vector
<component
*> const & comps
):
92 components(comps
), optional (false), sufficient (false),
97 // NB: shallow-copy of compoonents & condition!
98 probe_point::probe_point (const probe_point
& pp
):
99 components(pp
.components
), optional (pp
.optional
), sufficient (pp
.sufficient
),
100 condition (pp
.condition
)
105 probe_point::probe_point ():
106 optional (false), sufficient (false), condition (0)
111 unsigned probe::last_probeidx
= 0;
114 body (0), tok (0), systemtap_v_conditional (0), privileged (false)
116 this->name
= string ("probe_") + lex_cast(last_probeidx
++);
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.
123 probe::probe(const probe
& p
, probe_point
* l
)
125 this->name
= string ("probe_") + lex_cast(last_probeidx
++);
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
;
130 this->systemtap_v_conditional
= p
.systemtap_v_conditional
;
131 assert (p
.locals
.size() == 0);
132 assert (p
.unused_locals
.size() == 0);
136 probe_point::component::component ():
142 probe_point::component::component (std::string
const & f
, literal
* a
):
143 functor(f
), arg(a
), tok(0)
149 arity_tok(0), arity (-1), maxsize(0), init(NULL
), skip_init(false)
155 vardecl::set_arity (int a
, const token
* t
)
160 if (a
== 0 && maxsize
> 0)
161 throw semantic_error (_("inconsistent arity"), tok
);
163 if (arity
!= a
&& arity
>= 0)
165 semantic_error
err (_F("inconsistent arity (%s vs %d)",
166 lex_cast(arity
).c_str(), a
), t
?:tok
);
168 err
.chain
= new semantic_error (_F("arity %s first inferred here",
169 lex_cast(arity
).c_str()), arity_tok
);
177 index_types
.resize (arity
);
178 for (int i
=0; i
<arity
; i
++)
179 index_types
[i
] = pe_unknown
;
184 vardecl::compatible_arity (int a
)
186 if (a
== 0 && maxsize
> 0)
188 if (arity
== -1 || a
== -1)
194 functiondecl::functiondecl ():
195 body (0), synthetic (false)
200 functiondecl::join (systemtap_session
& s
)
203 throw semantic_error (_("internal error, joining a non-synthetic function"), tok
);
204 if (!s
.functions
.insert (make_pair (name
, this)).second
)
205 throw semantic_error (_F("synthetic function '%s' conflicts with an existing function",
207 tok
->location
.file
->functions
.push_back (this);
211 literal_number::literal_number (int64_t v
, bool hex
)
219 literal_string::literal_string (const string
& v
)
227 operator << (ostream
& o
, const exp_type
& e
)
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;
242 target_symbol::assert_no_components(const std::string
& tapset
, bool pretty_ok
)
244 if (components
.empty())
247 switch (components
[0].type
)
249 case comp_literal_array_index
:
250 case comp_expression_array_index
:
251 throw semantic_error(_F("%s variable '%s' may not be used as array",
252 tapset
.c_str(), name
.c_str()), components
[0].tok
);
253 case comp_struct_member
:
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
);
256 case comp_pretty_print
:
258 throw semantic_error(_F("%s variable '%s' may not be pretty-printed",
259 tapset
.c_str(), name
.c_str()), components
[0].tok
);
262 throw semantic_error (_F("invalid use of %s variable '%s'",
263 tapset
.c_str(), name
.c_str()), components
[0].tok
);
268 void target_symbol::chain (const semantic_error
&er
)
270 semantic_error
* e
= new semantic_error(er
);
273 assert (e
->chain
== 0);
274 e
->chain
= this->saved_conversion_error
;
275 this->saved_conversion_error
= e
;
279 // ------------------------------------------------------------------------
280 // parse tree printing
282 ostream
& operator << (ostream
& o
, const expression
& k
)
289 void literal_string::print (ostream
& o
) const
292 for (unsigned i
=0; i
<value
.size(); i
++)
293 if (value
[i
] == '"') // or other escapeworthy characters?
301 void literal_number::print (ostream
& o
) const
304 o
<< hex
<< showbase
;
307 o
<< dec
<< noshowbase
;
311 void embedded_expr::print (ostream
& o
) const
313 o
<< "%{ " << code
<< " %}";
317 void binary_expression::print (ostream
& o
) const
319 o
<< "(" << *left
<< ") "
321 << " (" << *right
<< ")";
325 void unary_expression::print (ostream
& o
) const
327 o
<< op
<< '(' << *operand
<< ")";
330 void array_in::print (ostream
& o
) const
333 for (unsigned i
=0; i
<operand
->indexes
.size(); i
++)
335 if (i
> 0) o
<< ", ";
336 operand
->indexes
[i
]->print (o
);
339 operand
->base
->print_indexable (o
);
342 void post_crement::print (ostream
& o
) const
344 o
<< '(' << *operand
<< ")" << op
;
348 void ternary_expression::print (ostream
& o
) const
350 o
<< "(" << *cond
<< ")?("
351 << *truevalue
<< "):("
352 << *falsevalue
<< ")";
356 void symbol::print (ostream
& o
) const
362 void target_symbol::component::print (ostream
& o
) const
366 case comp_pretty_print
:
367 case comp_struct_member
:
370 case comp_literal_array_index
:
371 o
<< '[' << num_index
<< ']';
373 case comp_expression_array_index
:
374 o
<< '[' << *expr_index
<< ']';
380 std::ostream
& operator << (std::ostream
& o
, const target_symbol::component
& c
)
387 void target_symbol::print (ostream
& o
) const
392 for (unsigned i
= 0; i
< components
.size(); ++i
)
397 void cast_op::print (ostream
& o
) const
401 o
<< name
<< '(' << *operand
;
402 o
<< ", " << lex_cast_qstring (type_name
);
403 if (module
.length() > 0)
404 o
<< ", " << lex_cast_qstring (module
);
406 for (unsigned i
= 0; i
< components
.size(); ++i
)
411 void defined_op::print (ostream
& o
) const
413 o
<< "@defined(" << *operand
<< ")";
417 void entry_op::print (ostream
& o
) const
419 o
<< "@entry(" << *operand
<< ")";
423 void vardecl::print (ostream
& o
) const
427 o
<< "[" << maxsize
<< "]";
428 if (arity
> 0 || index_types
.size() > 0)
438 void vardecl::printsig (ostream
& o
) const
442 o
<< "[" << maxsize
<< "]";
444 if (index_types
.size() > 0)
447 for (unsigned i
=0; i
<index_types
.size(); i
++)
448 o
<< (i
>0 ? ", " : "") << index_types
[i
];
454 void functiondecl::print (ostream
& o
) const
456 o
<< "function " << name
<< " (";
457 for (unsigned i
=0; i
<formal_args
.size(); i
++)
458 o
<< (i
>0 ? ", " : "") << *formal_args
[i
];
464 void functiondecl::printsig (ostream
& o
) const
466 o
<< name
<< ":" << type
<< " (";
467 for (unsigned i
=0; i
<formal_args
.size(); i
++)
468 o
<< (i
>0 ? ", " : "")
471 << formal_args
[i
]->type
;
476 void arrayindex::print (ostream
& o
) const
478 base
->print_indexable (o
);
480 for (unsigned i
=0; i
<indexes
.size(); i
++)
481 o
<< (i
>0 ? ", " : "") << *indexes
[i
];
486 void functioncall::print (ostream
& o
) const
488 o
<< function
<< "(";
489 for (unsigned i
=0; i
<args
.size(); i
++)
490 o
<< (i
>0 ? ", " : "") << *args
[i
];
496 print_format::create(const token
*t
)
498 bool stream
, format
, delim
, newline
, _char
;
499 const char *n
= t
->content
.c_str();
502 format
= delim
= newline
= _char
= false;
504 if (strcmp(n
, "print_char") == 0)
514 if (0 != strncmp(n
, "print", 5))
531 if (*n
== 'l' && *(n
+1) == 'n')
542 print_format
*pf
= new print_format(stream
, format
, delim
, newline
, _char
);
549 print_format::components_to_string(vector
<format_component
> const & components
)
553 for (vector
<format_component
>::const_iterator i
= components
.begin();
554 i
!= components
.end(); ++i
)
557 assert (i
->type
!= conv_unspecified
);
559 if (i
->type
== conv_literal
)
561 assert(!i
->literal_string
.empty());
562 for (string::const_iterator j
= i
->literal_string
.begin();
563 j
!= i
->literal_string
.end(); ++j
)
565 // See also: c_unparser::visit_literal_string and lex_cast_qstring
577 if (i
->flags
& static_cast<unsigned long>(fmt_flag_zeropad
))
580 if (i
->flags
& static_cast<unsigned long>(fmt_flag_plus
))
583 if (i
->flags
& static_cast<unsigned long>(fmt_flag_space
))
586 if (i
->flags
& static_cast<unsigned long>(fmt_flag_left
))
589 if (i
->flags
& static_cast<unsigned long>(fmt_flag_special
))
592 if (i
->widthtype
== width_dynamic
)
594 else if (i
->widthtype
!= width_unspecified
&& i
->width
> 0)
597 if (i
->prectype
== prec_dynamic
)
599 else if (i
->prectype
!= prec_unspecified
&& i
->precision
> 0)
600 oss
<< '.' << i
->precision
;
612 case conv_signed_decimal
:
616 case conv_unsigned_decimal
:
620 case conv_unsigned_octal
:
624 case conv_unsigned_ptr
:
628 case conv_unsigned_uppercase_hex
:
632 case conv_unsigned_lowercase_hex
:
644 case conv_memory_hex
:
656 vector
<print_format::format_component
>
657 print_format::string_to_components(string
const & str
)
659 format_component curr
;
660 vector
<format_component
> res
;
664 string::const_iterator i
= str
.begin();
666 while (i
!= str
.end())
670 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
671 curr
.type
= conv_literal
;
672 curr
.literal_string
+= *i
;
676 else if (i
+1 == str
.end() || *(i
+1) == '%')
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
+= '%';
689 if (curr
.type
!= conv_unspecified
)
691 // Flush any component we were previously accumulating
692 assert (curr
.type
== conv_literal
);
702 // Now we are definitely parsing a conversion.
703 // Begin by parsing flags (which are optional).
708 curr
.flags
|= static_cast<unsigned long>(fmt_flag_zeropad
);
713 curr
.flags
|= static_cast<unsigned long>(fmt_flag_plus
);
718 curr
.flags
|= static_cast<unsigned long>(fmt_flag_left
);
723 curr
.flags
|= static_cast<unsigned long>(fmt_flag_space
);
728 curr
.flags
|= static_cast<unsigned long>(fmt_flag_special
);
739 // Parse optional width
742 curr
.widthtype
= width_dynamic
;
745 else if (isdigit(*i
))
747 curr
.widthtype
= width_static
;
752 curr
.width
+= (*i
- '0');
755 while (i
!= str
.end() && isdigit(*i
));
761 // Parse optional precision
769 curr
.prectype
= prec_dynamic
;
772 else if (isdigit(*i
))
774 curr
.prectype
= prec_static
;
778 curr
.precision
*= 10;
779 curr
.precision
+= (*i
- '0');
782 while (i
!= str
.end() && isdigit(*i
));
789 // Parse the type modifier
800 // Parse the actual conversion specifier (bcsmdioupxXn)
803 // Valid conversion types
805 curr
.type
= conv_binary
;
809 curr
.type
= conv_char
;
813 curr
.type
= conv_string
;
817 curr
.type
= conv_memory
;
821 curr
.type
= conv_memory_hex
;
826 curr
.type
= conv_signed_decimal
;
830 curr
.type
= conv_unsigned_octal
;
834 curr
.type
= conv_unsigned_decimal
;
838 curr
.type
= conv_unsigned_ptr
;
842 curr
.type
= conv_unsigned_uppercase_hex
;
846 curr
.type
= conv_unsigned_lowercase_hex
;
853 if (curr
.type
== conv_unspecified
)
854 throw parse_error(_("invalid or missing conversion specifier"));
861 // If there's a remaining partly-composed conversion, fail.
862 if (!curr
.is_empty())
864 if (curr
.type
== conv_literal
)
867 throw parse_error(_("trailing incomplete print format conversion"));
874 void print_format::print (ostream
& o
) const
876 o
<< tok
->content
<< "(";
877 if (print_with_format
)
878 o
<< lex_cast_qstring (raw_components
);
879 if (print_with_delim
)
880 o
<< lex_cast_qstring (delimiter
.literal_string
);
883 for (vector
<expression
*>::const_iterator i
= args
.begin();
884 i
!= args
.end(); ++i
)
886 if (i
!= args
.begin() || print_with_format
|| print_with_delim
)
893 void stat_op::print (ostream
& o
) const
923 hist_op::print (ostream
& o
) const
929 assert(params
.size() == 3);
932 for (size_t i
= 0; i
< params
.size(); ++i
)
934 o
<< ", " << params
[i
];
940 assert(params
.size() == 0);
948 ostream
& operator << (ostream
& o
, const statement
& k
)
955 void embeddedcode::print (ostream
&o
) const
962 void block::print (ostream
& o
) const
965 for (unsigned i
=0; i
<statements
.size(); i
++)
966 o
<< *statements
[i
] << endl
;
970 block::block (statement
* car
, statement
* cdr
)
972 statements
.push_back(car
);
973 statements
.push_back(cdr
);
974 this->tok
= car
->tok
;
979 void try_block::print (ostream
& o
) const
981 o
<< "try {" << endl
;
982 if (try_block
) o
<< *try_block
<< endl
;
984 if (catch_error_var
) o
<< "(" << *catch_error_var
<< ") ";
986 if (catch_block
) o
<< *catch_block
<< endl
;
991 void for_loop::print (ostream
& o
) const
994 if (init
) init
->print (o
);
998 if (incr
) incr
->print (o
);
1004 void foreach_loop::print (ostream
& o
) const
1013 for (unsigned i
=0; i
<indexes
.size(); i
++)
1015 if (i
> 0) o
<< ", ";
1016 indexes
[i
]->print (o
);
1017 if (sort_direction
!= 0 && sort_column
== i
+1)
1018 o
<< (sort_direction
> 0 ? "+" : "-");
1021 base
->print_indexable (o
);
1022 if (sort_direction
!= 0 && sort_column
== 0)
1023 o
<< (sort_direction
> 0 ? "+" : "-");
1034 void null_statement::print (ostream
& o
) const
1040 void expr_statement::print (ostream
& o
) const
1046 void return_statement::print (ostream
& o
) const
1048 o
<< "return " << *value
;
1052 void delete_statement::print (ostream
& o
) const
1054 o
<< "delete " << *value
;
1057 void next_statement::print (ostream
& o
) const
1062 void break_statement::print (ostream
& o
) const
1067 void continue_statement::print (ostream
& o
) const
1072 void if_statement::print (ostream
& o
) const
1074 o
<< "if (" << *condition
<< ") "
1075 << *thenblock
<< endl
;
1077 o
<< "else " << *elseblock
<< endl
;
1081 void stapfile::print (ostream
& o
) const
1083 o
<< "# file " << name
<< endl
;
1085 for (unsigned i
=0; i
<embeds
.size(); i
++)
1086 embeds
[i
]->print (o
);
1088 for (unsigned i
=0; i
<globals
.size(); i
++)
1091 globals
[i
]->print (o
);
1095 for (unsigned i
=0; i
<aliases
.size(); i
++)
1097 aliases
[i
]->print (o
);
1101 for (unsigned i
=0; i
<probes
.size(); i
++)
1103 probes
[i
]->print (o
);
1107 for (unsigned j
= 0; j
< functions
.size(); j
++)
1109 functions
[j
]->print (o
);
1115 void probe::print (ostream
& o
) const
1123 void probe::printsig (ostream
& o
) const
1125 const probe_alias
*alias
= get_alias ();
1128 alias
->printsig (o
);
1132 for (unsigned i
=0; i
<locations
.size(); i
++)
1134 if (i
> 0) o
<< ",";
1135 locations
[i
]->print (o
);
1141 probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
)
1143 probes_list
.push_back(this);
1147 void probe_point::print (ostream
& o
, bool print_extras
) const
1149 for (unsigned i
=0; i
<components
.size(); i
++)
1152 probe_point::component
* c
= components
[i
];
1155 o
<< "(" << *c
->arg
<< ")";
1161 else if (optional
) // sufficient implies optional
1164 o
<< " if (" << *condition
<< ")";
1167 string
probe_point::str (bool print_extras
) const
1170 print(o
, print_extras
);
1175 probe_alias::probe_alias(std::vector
<probe_point
*> const & aliases
):
1176 probe (), alias_names (aliases
), epilogue_style(false)
1180 void probe_alias::printsig (ostream
& o
) const
1182 for (unsigned i
=0; i
<alias_names
.size(); i
++)
1184 o
<< (i
>0 ? " = " : "");
1185 alias_names
[i
]->print (o
);
1188 for (unsigned i
=0; i
<locations
.size(); i
++)
1190 if (i
> 0) o
<< ", ";
1191 locations
[i
]->print (o
);
1196 ostream
& operator << (ostream
& o
, const probe_point
& k
)
1203 ostream
& operator << (ostream
& o
, const symboldecl
& k
)
1211 // ------------------------------------------------------------------------
1216 block::visit (visitor
* u
)
1218 u
->visit_block (this);
1223 try_block::visit (visitor
* u
)
1225 u
->visit_try_block (this);
1230 embeddedcode::visit (visitor
* u
)
1232 u
->visit_embeddedcode (this);
1237 for_loop::visit (visitor
* u
)
1239 u
->visit_for_loop (this);
1243 foreach_loop::visit (visitor
* u
)
1245 u
->visit_foreach_loop (this);
1249 null_statement::visit (visitor
* u
)
1251 u
->visit_null_statement (this);
1255 expr_statement::visit (visitor
* u
)
1257 u
->visit_expr_statement (this);
1261 return_statement::visit (visitor
* u
)
1263 u
->visit_return_statement (this);
1267 delete_statement::visit (visitor
* u
)
1269 u
->push_active_lvalue (this->value
);
1270 u
->visit_delete_statement (this);
1271 u
->pop_active_lvalue ();
1275 if_statement::visit (visitor
* u
)
1277 u
->visit_if_statement (this);
1281 next_statement::visit (visitor
* u
)
1283 u
->visit_next_statement (this);
1287 break_statement::visit (visitor
* u
)
1289 u
->visit_break_statement (this);
1293 continue_statement::visit (visitor
* u
)
1295 u
->visit_continue_statement (this);
1299 literal_string::visit(visitor
* u
)
1301 u
->visit_literal_string (this);
1305 literal_number::visit(visitor
* u
)
1307 u
->visit_literal_number (this);
1311 binary_expression::visit (visitor
* u
)
1313 u
->visit_binary_expression (this);
1317 embedded_expr::visit (visitor
* u
)
1319 u
->visit_embedded_expr (this);
1323 unary_expression::visit (visitor
* u
)
1325 u
->visit_unary_expression (this);
1329 pre_crement::visit (visitor
* u
)
1331 u
->push_active_lvalue (this->operand
);
1332 u
->visit_pre_crement (this);
1333 u
->pop_active_lvalue ();
1337 post_crement::visit (visitor
* u
)
1339 u
->push_active_lvalue (this->operand
);
1340 u
->visit_post_crement (this);
1341 u
->pop_active_lvalue ();
1345 logical_or_expr::visit (visitor
* u
)
1347 u
->visit_logical_or_expr (this);
1351 logical_and_expr::visit (visitor
* u
)
1353 u
->visit_logical_and_expr (this);
1357 array_in::visit (visitor
* u
)
1359 u
->visit_array_in (this);
1363 comparison::visit (visitor
* u
)
1365 u
->visit_comparison (this);
1369 concatenation::visit (visitor
* u
)
1371 u
->visit_concatenation (this);
1375 ternary_expression::visit (visitor
* u
)
1377 u
->visit_ternary_expression (this);
1381 assignment::visit (visitor
* u
)
1383 u
->push_active_lvalue (this->left
);
1384 u
->visit_assignment (this);
1385 u
->pop_active_lvalue ();
1389 symbol::visit (visitor
* u
)
1391 u
->visit_symbol (this);
1395 target_symbol::visit (visitor
* u
)
1397 u
->visit_target_symbol(this);
1401 target_symbol::visit_components (visitor
* u
)
1403 for (unsigned i
= 0; i
< components
.size(); ++i
)
1404 if (components
[i
].type
== comp_expression_array_index
)
1405 components
[i
].expr_index
->visit (u
);
1409 target_symbol::visit_components (update_visitor
* u
)
1411 for (unsigned i
= 0; i
< components
.size(); ++i
)
1412 if (components
[i
].type
== comp_expression_array_index
)
1413 u
->replace (components
[i
].expr_index
);
1417 cast_op::visit (visitor
* u
)
1419 u
->visit_cast_op(this);
1424 defined_op::visit (visitor
* u
)
1426 u
->visit_defined_op(this);
1431 entry_op::visit (visitor
* u
)
1433 u
->visit_entry_op(this);
1438 arrayindex::visit (visitor
* u
)
1440 u
->visit_arrayindex (this);
1444 functioncall::visit (visitor
* u
)
1446 u
->visit_functioncall (this);
1450 print_format::visit (visitor
*u
)
1452 u
->visit_print_format (this);
1456 stat_op::visit (visitor
*u
)
1458 u
->visit_stat_op (this);
1462 hist_op::visit (visitor
*u
)
1464 u
->visit_hist_op (this);
1468 indexable::print_indexable (std::ostream
& o
) const
1471 const hist_op
*hist
;
1472 classify_const_indexable(this, sym
, hist
);
1483 indexable::visit_indexable (visitor
* u
)
1487 classify_indexable(this, sym
, hist
);
1499 indexable::is_symbol(symbol
*& sym_out
)
1506 indexable::is_hist_op(hist_op
*& hist_out
)
1513 indexable::is_const_symbol(const symbol
*& sym_out
) const
1520 indexable::is_const_hist_op(const hist_op
*& hist_out
) const
1527 symbol::is_symbol(symbol
*& sym_out
)
1534 symbol::is_const_symbol(const symbol
*& sym_out
) const
1541 symbol::get_tok() const
1547 hist_op::is_hist_op(hist_op
*& hist_out
)
1554 hist_op::is_const_hist_op(const hist_op
*& hist_out
) const
1561 hist_op::get_tok() const
1567 classify_indexable(indexable
* ix
,
1568 symbol
*& array_out
,
1569 hist_op
*& hist_out
)
1574 if (!(ix
->is_symbol (array_out
) || ix
->is_hist_op (hist_out
)))
1575 throw semantic_error(_("Expecting symbol or histogram operator"), ix
->get_tok());
1576 if (!(hist_out
|| array_out
))
1577 throw semantic_error(_("Failed to classify indexable"), ix
->get_tok());
1581 classify_const_indexable(const indexable
* ix
,
1582 const symbol
*& array_out
,
1583 const hist_op
*& hist_out
)
1587 if (!(ix
->is_const_symbol(array_out
) || ix
->is_const_hist_op(hist_out
)))
1588 throw semantic_error(_("Expecting symbol or histogram operator"), ix
->get_tok());
1591 // ------------------------------------------------------------------------
1594 visitor::is_active_lvalue(expression
*e
)
1596 for (unsigned i
= 0; i
< active_lvalues
.size(); ++i
)
1598 if (active_lvalues
[i
] == e
)
1605 visitor::push_active_lvalue(expression
*e
)
1607 active_lvalues
.push_back(e
);
1611 visitor::pop_active_lvalue()
1613 assert(!active_lvalues
.empty());
1614 active_lvalues
.pop_back();
1619 // ------------------------------------------------------------------------
1622 traversing_visitor::visit_block (block
* s
)
1624 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
1625 s
->statements
[i
]->visit (this);
1629 traversing_visitor::visit_try_block (try_block
* s
)
1632 s
->try_block
->visit (this);
1633 if (s
->catch_error_var
)
1634 s
->catch_error_var
->visit (this);
1636 s
->catch_block
->visit (this);
1640 traversing_visitor::visit_embeddedcode (embeddedcode
*)
1645 traversing_visitor::visit_null_statement (null_statement
*)
1650 traversing_visitor::visit_expr_statement (expr_statement
* s
)
1652 s
->value
->visit (this);
1656 traversing_visitor::visit_if_statement (if_statement
* s
)
1658 s
->condition
->visit (this);
1659 s
->thenblock
->visit (this);
1661 s
->elseblock
->visit (this);
1665 traversing_visitor::visit_for_loop (for_loop
* s
)
1667 if (s
->init
) s
->init
->visit (this);
1668 s
->cond
->visit (this);
1669 if (s
->incr
) s
->incr
->visit (this);
1670 s
->block
->visit (this);
1674 traversing_visitor::visit_foreach_loop (foreach_loop
* s
)
1676 symbol
*array
= NULL
;
1677 hist_op
*hist
= NULL
;
1678 classify_indexable (s
->base
, array
, hist
);
1684 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1685 s
->indexes
[i
]->visit (this);
1688 s
->value
->visit (this);
1691 s
->limit
->visit (this);
1693 s
->block
->visit (this);
1697 traversing_visitor::visit_return_statement (return_statement
* s
)
1699 s
->value
->visit (this);
1703 traversing_visitor::visit_delete_statement (delete_statement
* s
)
1705 s
->value
->visit (this);
1709 traversing_visitor::visit_next_statement (next_statement
*)
1714 traversing_visitor::visit_break_statement (break_statement
*)
1719 traversing_visitor::visit_continue_statement (continue_statement
*)
1724 traversing_visitor::visit_literal_string (literal_string
*)
1729 traversing_visitor::visit_literal_number (literal_number
*)
1734 traversing_visitor::visit_embedded_expr (embedded_expr
*)
1739 traversing_visitor::visit_binary_expression (binary_expression
* e
)
1741 e
->left
->visit (this);
1742 e
->right
->visit (this);
1746 traversing_visitor::visit_unary_expression (unary_expression
* e
)
1748 e
->operand
->visit (this);
1752 traversing_visitor::visit_pre_crement (pre_crement
* e
)
1754 e
->operand
->visit (this);
1758 traversing_visitor::visit_post_crement (post_crement
* e
)
1760 e
->operand
->visit (this);
1765 traversing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
1767 e
->left
->visit (this);
1768 e
->right
->visit (this);
1772 traversing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
1774 e
->left
->visit (this);
1775 e
->right
->visit (this);
1779 traversing_visitor::visit_array_in (array_in
* e
)
1781 e
->operand
->visit (this);
1785 traversing_visitor::visit_comparison (comparison
* e
)
1787 e
->left
->visit (this);
1788 e
->right
->visit (this);
1792 traversing_visitor::visit_concatenation (concatenation
* e
)
1794 e
->left
->visit (this);
1795 e
->right
->visit (this);
1799 traversing_visitor::visit_ternary_expression (ternary_expression
* e
)
1801 e
->cond
->visit (this);
1802 e
->truevalue
->visit (this);
1803 e
->falsevalue
->visit (this);
1807 traversing_visitor::visit_assignment (assignment
* e
)
1809 e
->left
->visit (this);
1810 e
->right
->visit (this);
1814 traversing_visitor::visit_symbol (symbol
*)
1819 traversing_visitor::visit_target_symbol (target_symbol
* e
)
1821 e
->visit_components (this);
1825 traversing_visitor::visit_cast_op (cast_op
* e
)
1827 e
->operand
->visit (this);
1828 e
->visit_components (this);
1832 traversing_visitor::visit_defined_op (defined_op
* e
)
1834 e
->operand
->visit (this);
1838 traversing_visitor::visit_entry_op (entry_op
* e
)
1840 e
->operand
->visit (this);
1845 traversing_visitor::visit_arrayindex (arrayindex
* e
)
1847 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
1848 e
->indexes
[i
]->visit (this);
1850 symbol
*array
= NULL
;
1851 hist_op
*hist
= NULL
;
1852 classify_indexable(e
->base
, array
, hist
);
1854 return array
->visit(this);
1856 return hist
->visit(this);
1860 traversing_visitor::visit_functioncall (functioncall
* e
)
1862 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1863 e
->args
[i
]->visit (this);
1867 traversing_visitor::visit_print_format (print_format
* e
)
1869 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1870 e
->args
[i
]->visit (this);
1872 e
->hist
->visit(this);
1876 traversing_visitor::visit_stat_op (stat_op
* e
)
1878 e
->stat
->visit (this);
1882 traversing_visitor::visit_hist_op (hist_op
* e
)
1884 e
->stat
->visit (this);
1889 functioncall_traversing_visitor::visit_functioncall (functioncall
* e
)
1891 traversing_visitor::visit_functioncall (e
);
1893 // prevent infinite recursion
1894 if (traversed
.find (e
->referent
) == traversed
.end ())
1896 traversed
.insert (e
->referent
);
1898 functiondecl
* last_current_function
= current_function
;
1899 current_function
= e
->referent
;
1900 e
->referent
->body
->visit (this);
1901 current_function
= last_current_function
;
1907 varuse_collecting_visitor::visit_try_block (try_block
*s
)
1910 s
->try_block
->visit (this);
1911 if (s
->catch_error_var
)
1912 written
.insert (s
->catch_error_var
->referent
);
1914 s
->catch_block
->visit (this);
1916 // NB: don't functioncall_traversing_visitor::visit_try_block (s);
1917 // since that would count s->catch_error_var as a read also.
1922 varuse_collecting_visitor::visit_embeddedcode (embeddedcode
*s
)
1924 assert (current_function
); // only they get embedded code
1926 // Don't allow embedded C functions in unprivileged mode unless
1927 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
1928 if (session
.unprivileged
&&
1929 s
->code
.find ("/* unprivileged */") == string::npos
&&
1930 s
->code
.find ("/* myproc-unprivileged */") == string::npos
)
1931 throw semantic_error (_("function may not be used when --unprivileged is specified"),
1932 current_function
->tok
);
1934 // Don't allow /* guru */ functions unless -g is active.
1935 if (!session
.guru_mode
&& s
->code
.find ("/* guru */") != string::npos
)
1936 throw semantic_error (_("function may not be used unless -g is specified"),
1937 current_function
->tok
);
1939 // We want to elide embedded-C functions when possible. For
1940 // example, each $target variable access is expanded to an
1941 // embedded-C function call. Yet, for safety reasons, we should
1942 // presume that embedded-C functions have intentional side-effects.
1944 // To tell these two types of functions apart, we apply a
1945 // Kludge(tm): we look for a magic string within the function body.
1946 // $target variables as rvalues will have this; lvalues won't.
1947 // Also, explicit side-effect-free tapset functions will have this.
1949 if (s
->code
.find ("/* pure */") != string::npos
)
1952 embedded_seen
= true;
1956 // About the same case as above.
1958 varuse_collecting_visitor::visit_embedded_expr (embedded_expr
*e
)
1960 // Don't allow embedded C functions in unprivileged mode unless
1961 // they are tagged with /* unprivileged */
1962 if (session
.unprivileged
&&
1963 e
->code
.find ("/* unprivileged */") == string::npos
&&
1964 e
->code
.find ("/* myproc-unprivileged */") == string::npos
)
1965 throw semantic_error (_("embedded expression may not be used when --unprivileged is specified"),
1968 // Don't allow /* guru */ functions unless -g is active.
1969 if (!session
.guru_mode
&& e
->code
.find ("/* guru */") != string::npos
)
1970 throw semantic_error (_("embedded expression may not be used unless -g is specified"),
1973 // We want to elide embedded-C functions when possible. For
1974 // example, each $target variable access is expanded to an
1975 // embedded-C function call. Yet, for safety reasons, we should
1976 // presume that embedded-C functions have intentional side-effects.
1978 // To tell these two types of functions apart, we apply a
1979 // Kludge(tm): we look for a magic string within the function body.
1980 // $target variables as rvalues will have this; lvalues won't.
1981 // Also, explicit side-effect-free tapset functions will have this.
1983 if (e
->code
.find ("/* pure */") != string::npos
)
1986 embedded_seen
= true;
1991 varuse_collecting_visitor::visit_target_symbol (target_symbol
*e
)
1993 // Still-unresolved target symbol assignments get treated as
1994 // generating side-effects like embedded-C, to prevent premature
1995 // elision and later error message suppression (PR5516). rvalue use
1996 // of unresolved target symbols is OTOH not considered a side-effect.
1998 if (is_active_lvalue (e
))
1999 embedded_seen
= true;
2001 functioncall_traversing_visitor::visit_target_symbol (e
);
2005 varuse_collecting_visitor::visit_cast_op (cast_op
*e
)
2007 // As with target_symbols, unresolved cast assignments need to preserved
2008 // for later error handling.
2009 if (is_active_lvalue (e
))
2010 embedded_seen
= true;
2012 functioncall_traversing_visitor::visit_cast_op (e
);
2016 varuse_collecting_visitor::visit_defined_op (defined_op
*e
)
2019 functioncall_traversing_visitor::visit_defined_op (e
);
2023 varuse_collecting_visitor::visit_entry_op (entry_op
*e
)
2026 functioncall_traversing_visitor::visit_entry_op (e
);
2031 varuse_collecting_visitor::visit_print_format (print_format
* e
)
2033 // NB: Instead of being top-level statements, "print" and "printf"
2034 // are implemented as statement-expressions containing a
2035 // print_format. They have side-effects, but not via the
2036 // embedded-code detection method above.
2038 // But sprint and sprintf don't have side-effects.
2040 bool last_lvalue_read
= current_lvalue_read
;
2041 current_lvalue_read
= true;
2042 if (e
->print_to_stream
)
2043 embedded_seen
= true; // a proxy for "has unknown side-effects"
2045 functioncall_traversing_visitor::visit_print_format (e
);
2046 current_lvalue_read
= last_lvalue_read
;
2051 varuse_collecting_visitor::visit_assignment (assignment
*e
)
2053 if (e
->op
== "=" || e
->op
== "<<<") // pure writes
2055 expression
* last_lvalue
= current_lvalue
;
2056 bool last_lvalue_read
= current_lvalue_read
;
2057 current_lvalue
= e
->left
; // leave a mark for ::visit_symbol
2058 current_lvalue_read
= true;
2059 functioncall_traversing_visitor::visit_assignment (e
);
2060 current_lvalue
= last_lvalue
;
2061 current_lvalue_read
= last_lvalue_read
;
2063 else // read-modify-writes
2065 expression
* last_lrvalue
= current_lrvalue
;
2066 current_lrvalue
= e
->left
; // leave a mark for ::visit_symbol
2067 functioncall_traversing_visitor::visit_assignment (e
);
2068 current_lrvalue
= last_lrvalue
;
2073 varuse_collecting_visitor::visit_symbol (symbol
*e
)
2075 if (e
->referent
== 0)
2076 throw semantic_error (_("symbol without referent"), e
->tok
);
2078 // We could handle initialized globals by marking them as "written".
2079 // However, this current visitor may be called for a function or
2080 // probe body, from the point of view of which this global is
2081 // already initialized, so not written.
2083 if (e->referent->init)
2084 written.insert (e->referent);
2087 if (current_lvalue
== e
|| current_lrvalue
== e
)
2089 written
.insert (e
->referent
);
2091 if (current_lvalue
!= e
|| current_lrvalue
== e
)
2093 read
.insert (e
->referent
);
2096 if (current_lrvalue
== e
)
2098 if (current_lvalue_read
)
2099 used
.insert (e
->referent
);
2101 else if (current_lvalue
!= e
)
2102 used
.insert (e
->referent
);
2105 // NB: stat_op need not be overridden, since it will get to
2106 // visit_symbol and only as a possible rvalue.
2110 varuse_collecting_visitor::visit_arrayindex (arrayindex
*e
)
2112 // Hooking this callback is necessary because of the hacky
2113 // statistics representation. For the expression "i[4] = 5", the
2114 // incoming lvalue will point to this arrayindex. However, the
2115 // symbol corresponding to the "i[4]" is multiply inherited with
2116 // arrayindex. If the symbol base part of this object is not at
2117 // offset 0, then static_cast<symbol*>(e) may result in a different
2118 // address, and not match lvalue by number when we recurse that way.
2119 // So we explicitly override the incoming lvalue/lrvalue values to
2120 // point at the embedded objects' actual base addresses.
2122 expression
* last_lrvalue
= current_lrvalue
;
2123 expression
* last_lvalue
= current_lvalue
;
2125 symbol
*array
= NULL
;
2126 hist_op
*hist
= NULL
;
2127 classify_indexable(e
->base
, array
, hist
);
2131 if (current_lrvalue
== e
) current_lrvalue
= array
;
2132 if (current_lvalue
== e
) current_lvalue
= array
;
2133 functioncall_traversing_visitor::visit_arrayindex (e
);
2137 if (current_lrvalue
== e
) current_lrvalue
= hist
->stat
;
2138 if (current_lvalue
== e
) current_lvalue
= hist
->stat
;
2139 functioncall_traversing_visitor::visit_arrayindex (e
);
2142 current_lrvalue
= last_lrvalue
;
2143 current_lvalue
= last_lvalue
;
2148 varuse_collecting_visitor::visit_pre_crement (pre_crement
*e
)
2150 expression
* last_lrvalue
= current_lrvalue
;
2151 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
2152 functioncall_traversing_visitor::visit_pre_crement (e
);
2153 current_lrvalue
= last_lrvalue
;
2157 varuse_collecting_visitor::visit_post_crement (post_crement
*e
)
2159 expression
* last_lrvalue
= current_lrvalue
;
2160 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
2161 functioncall_traversing_visitor::visit_post_crement (e
);
2162 current_lrvalue
= last_lrvalue
;
2166 varuse_collecting_visitor::visit_foreach_loop (foreach_loop
* s
)
2168 // NB: we duplicate so don't bother call
2169 // functioncall_traversing_visitor::visit_foreach_loop (s);
2171 symbol
*array
= NULL
;
2172 hist_op
*hist
= NULL
;
2173 classify_indexable (s
->base
, array
, hist
);
2179 // If the collection is sorted, imply a "write" access to the
2180 // array in addition to the "read" one already noted above.
2181 if (s
->sort_direction
)
2183 symbol
*array
= NULL
;
2184 hist_op
*hist
= NULL
;
2185 classify_indexable (s
->base
, array
, hist
);
2186 if (array
) this->written
.insert (array
->referent
);
2187 // XXX: Can hist_op iterations be sorted?
2190 // NB: don't forget to visit the index expressions, which are lvalues.
2191 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
2193 expression
* last_lvalue
= current_lvalue
;
2194 current_lvalue
= s
->indexes
[i
]; // leave a mark for ::visit_symbol
2195 s
->indexes
[i
]->visit (this);
2196 current_lvalue
= last_lvalue
;
2199 // The value is an lvalue too
2202 expression
* last_lvalue
= current_lvalue
;
2203 current_lvalue
= s
->value
; // leave a mark for ::visit_symbol
2204 s
->value
->visit (this);
2205 current_lvalue
= last_lvalue
;
2209 s
->limit
->visit (this);
2211 s
->block
->visit (this);
2216 varuse_collecting_visitor::visit_delete_statement (delete_statement
* s
)
2218 // Ideally, this would be treated like an assignment: a plain write
2219 // to the underlying value ("lvalue"). XXX: However, the
2220 // optimization pass is not smart enough to remove an unneeded
2221 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
2222 // should protect the underlying value from optimizional mischief.
2223 expression
* last_lrvalue
= current_lrvalue
;
2224 bool last_lvalue_read
= current_lvalue_read
;
2225 current_lrvalue
= s
->value
; // leave a mark for ::visit_symbol
2226 current_lvalue_read
= true;
2227 functioncall_traversing_visitor::visit_delete_statement (s
);
2228 current_lrvalue
= last_lrvalue
;
2229 current_lvalue_read
= last_lvalue_read
;
2233 varuse_collecting_visitor::side_effect_free ()
2235 return (written
.empty() && !embedded_seen
);
2240 varuse_collecting_visitor::side_effect_free_wrt (const set
<vardecl
*>& vars
)
2242 // A looser notion of side-effect-freeness with respect to a given
2243 // list of variables.
2245 // That's useful because the written list may consist of local
2246 // variables of called functions. But visible side-effects only
2247 // occur if the client's locals, or any globals are written-to.
2249 set
<vardecl
*> intersection
;
2250 insert_iterator
<set
<vardecl
*> > int_it (intersection
, intersection
.begin());
2251 set_intersection (written
.begin(), written
.end(),
2252 vars
.begin(), vars
.end(),
2255 return (intersection
.empty() && !embedded_seen
);
2261 // ------------------------------------------------------------------------
2264 throwing_visitor::throwing_visitor (const std::string
& m
): msg (m
) {}
2265 throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
2269 throwing_visitor::throwone (const token
* t
)
2271 throw semantic_error (msg
, t
);
2275 throwing_visitor::visit_block (block
* s
)
2281 throwing_visitor::visit_try_block (try_block
* s
)
2288 throwing_visitor::visit_embeddedcode (embeddedcode
* s
)
2294 throwing_visitor::visit_null_statement (null_statement
* s
)
2300 throwing_visitor::visit_expr_statement (expr_statement
* s
)
2306 throwing_visitor::visit_if_statement (if_statement
* s
)
2312 throwing_visitor::visit_for_loop (for_loop
* s
)
2318 throwing_visitor::visit_foreach_loop (foreach_loop
* s
)
2324 throwing_visitor::visit_return_statement (return_statement
* s
)
2330 throwing_visitor::visit_delete_statement (delete_statement
* s
)
2336 throwing_visitor::visit_next_statement (next_statement
* s
)
2342 throwing_visitor::visit_break_statement (break_statement
* s
)
2348 throwing_visitor::visit_continue_statement (continue_statement
* s
)
2354 throwing_visitor::visit_literal_string (literal_string
* e
)
2360 throwing_visitor::visit_literal_number (literal_number
* e
)
2366 throwing_visitor::visit_embedded_expr (embedded_expr
* e
)
2372 throwing_visitor::visit_binary_expression (binary_expression
* e
)
2378 throwing_visitor::visit_unary_expression (unary_expression
* e
)
2384 throwing_visitor::visit_pre_crement (pre_crement
* e
)
2390 throwing_visitor::visit_post_crement (post_crement
* e
)
2397 throwing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2403 throwing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2409 throwing_visitor::visit_array_in (array_in
* e
)
2415 throwing_visitor::visit_comparison (comparison
* e
)
2421 throwing_visitor::visit_concatenation (concatenation
* e
)
2427 throwing_visitor::visit_ternary_expression (ternary_expression
* e
)
2433 throwing_visitor::visit_assignment (assignment
* e
)
2439 throwing_visitor::visit_symbol (symbol
* e
)
2445 throwing_visitor::visit_target_symbol (target_symbol
* e
)
2451 throwing_visitor::visit_cast_op (cast_op
* e
)
2457 throwing_visitor::visit_defined_op (defined_op
* e
)
2463 throwing_visitor::visit_entry_op (entry_op
* e
)
2470 throwing_visitor::visit_arrayindex (arrayindex
* e
)
2476 throwing_visitor::visit_functioncall (functioncall
* e
)
2482 throwing_visitor::visit_print_format (print_format
* e
)
2488 throwing_visitor::visit_stat_op (stat_op
* e
)
2494 throwing_visitor::visit_hist_op (hist_op
* e
)
2500 // ------------------------------------------------------------------------
2504 update_visitor::visit_block (block
* s
)
2506 for (unsigned i
= 0; i
< s
->statements
.size(); ++i
)
2507 replace (s
->statements
[i
]);
2512 update_visitor::visit_try_block (try_block
* s
)
2514 replace (s
->try_block
);
2515 replace (s
->catch_error_var
);
2516 replace (s
->catch_block
);
2521 update_visitor::visit_embeddedcode (embeddedcode
* s
)
2527 update_visitor::visit_null_statement (null_statement
* s
)
2533 update_visitor::visit_expr_statement (expr_statement
* s
)
2540 update_visitor::visit_if_statement (if_statement
* s
)
2542 replace (s
->condition
);
2543 replace (s
->thenblock
);
2544 replace (s
->elseblock
);
2549 update_visitor::visit_for_loop (for_loop
* s
)
2559 update_visitor::visit_foreach_loop (foreach_loop
* s
)
2561 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
2562 replace (s
->indexes
[i
]);
2571 update_visitor::visit_return_statement (return_statement
* s
)
2578 update_visitor::visit_delete_statement (delete_statement
* s
)
2585 update_visitor::visit_next_statement (next_statement
* s
)
2591 update_visitor::visit_break_statement (break_statement
* s
)
2597 update_visitor::visit_continue_statement (continue_statement
* s
)
2603 update_visitor::visit_literal_string (literal_string
* e
)
2609 update_visitor::visit_literal_number (literal_number
* e
)
2615 update_visitor::visit_embedded_expr (embedded_expr
* e
)
2621 update_visitor::visit_binary_expression (binary_expression
* e
)
2629 update_visitor::visit_unary_expression (unary_expression
* e
)
2631 replace (e
->operand
);
2636 update_visitor::visit_pre_crement (pre_crement
* e
)
2638 replace (e
->operand
);
2643 update_visitor::visit_post_crement (post_crement
* e
)
2645 replace (e
->operand
);
2651 update_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2659 update_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2667 update_visitor::visit_array_in (array_in
* e
)
2669 replace (e
->operand
);
2674 update_visitor::visit_comparison (comparison
* e
)
2682 update_visitor::visit_concatenation (concatenation
* e
)
2690 update_visitor::visit_ternary_expression (ternary_expression
* e
)
2693 replace (e
->truevalue
);
2694 replace (e
->falsevalue
);
2699 update_visitor::visit_assignment (assignment
* e
)
2707 update_visitor::visit_symbol (symbol
* e
)
2713 update_visitor::visit_target_symbol (target_symbol
* e
)
2715 e
->visit_components (this);
2720 update_visitor::visit_cast_op (cast_op
* e
)
2722 replace (e
->operand
);
2723 e
->visit_components (this);
2728 update_visitor::visit_defined_op (defined_op
* e
)
2730 replace (e
->operand
);
2735 update_visitor::visit_entry_op (entry_op
* e
)
2737 replace (e
->operand
);
2742 update_visitor::visit_arrayindex (arrayindex
* e
)
2745 for (unsigned i
= 0; i
< e
->indexes
.size(); ++i
)
2746 replace (e
->indexes
[i
]);
2751 update_visitor::visit_functioncall (functioncall
* e
)
2753 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2754 replace (e
->args
[i
]);
2759 update_visitor::visit_print_format (print_format
* e
)
2761 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2762 replace (e
->args
[i
]);
2768 update_visitor::visit_stat_op (stat_op
* e
)
2775 update_visitor::visit_hist_op (hist_op
* e
)
2781 template <> indexable
*
2782 update_visitor::require
<indexable
> (indexable
* src
, bool clearok
)
2784 indexable
*dst
= NULL
;
2787 symbol
*array_src
=NULL
;
2788 hist_op
*hist_src
=NULL
;
2790 classify_indexable(src
, array_src
, hist_src
);
2793 dst
= require (array_src
);
2795 dst
= require (hist_src
);
2796 assert(clearok
|| dst
);
2802 // ------------------------------------------------------------------------
2806 deep_copy_visitor::visit_block (block
* s
)
2808 update_visitor::visit_block(new block(*s
));
2812 deep_copy_visitor::visit_try_block (try_block
* s
)
2814 update_visitor::visit_try_block(new try_block(*s
));
2818 deep_copy_visitor::visit_embeddedcode (embeddedcode
* s
)
2820 update_visitor::visit_embeddedcode(new embeddedcode(*s
));
2824 deep_copy_visitor::visit_null_statement (null_statement
* s
)
2826 update_visitor::visit_null_statement(new null_statement(*s
));
2830 deep_copy_visitor::visit_expr_statement (expr_statement
* s
)
2832 update_visitor::visit_expr_statement(new expr_statement(*s
));
2836 deep_copy_visitor::visit_if_statement (if_statement
* s
)
2838 update_visitor::visit_if_statement(new if_statement(*s
));
2842 deep_copy_visitor::visit_for_loop (for_loop
* s
)
2844 update_visitor::visit_for_loop(new for_loop(*s
));
2848 deep_copy_visitor::visit_foreach_loop (foreach_loop
* s
)
2850 update_visitor::visit_foreach_loop(new foreach_loop(*s
));
2854 deep_copy_visitor::visit_return_statement (return_statement
* s
)
2856 update_visitor::visit_return_statement(new return_statement(*s
));
2860 deep_copy_visitor::visit_delete_statement (delete_statement
* s
)
2862 update_visitor::visit_delete_statement(new delete_statement(*s
));
2866 deep_copy_visitor::visit_next_statement (next_statement
* s
)
2868 update_visitor::visit_next_statement(new next_statement(*s
));
2872 deep_copy_visitor::visit_break_statement (break_statement
* s
)
2874 update_visitor::visit_break_statement(new break_statement(*s
));
2878 deep_copy_visitor::visit_continue_statement (continue_statement
* s
)
2880 update_visitor::visit_continue_statement(new continue_statement(*s
));
2884 deep_copy_visitor::visit_literal_string (literal_string
* e
)
2886 update_visitor::visit_literal_string(new literal_string(*e
));
2890 deep_copy_visitor::visit_literal_number (literal_number
* e
)
2892 update_visitor::visit_literal_number(new literal_number(*e
));
2896 deep_copy_visitor::visit_embedded_expr (embedded_expr
* e
)
2898 update_visitor::visit_embedded_expr(new embedded_expr(*e
));
2902 deep_copy_visitor::visit_binary_expression (binary_expression
* e
)
2904 update_visitor::visit_binary_expression(new binary_expression(*e
));
2908 deep_copy_visitor::visit_unary_expression (unary_expression
* e
)
2910 update_visitor::visit_unary_expression(new unary_expression(*e
));
2914 deep_copy_visitor::visit_pre_crement (pre_crement
* e
)
2916 update_visitor::visit_pre_crement(new pre_crement(*e
));
2920 deep_copy_visitor::visit_post_crement (post_crement
* e
)
2922 update_visitor::visit_post_crement(new post_crement(*e
));
2927 deep_copy_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2929 update_visitor::visit_logical_or_expr(new logical_or_expr(*e
));
2933 deep_copy_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2935 update_visitor::visit_logical_and_expr(new logical_and_expr(*e
));
2939 deep_copy_visitor::visit_array_in (array_in
* e
)
2941 update_visitor::visit_array_in(new array_in(*e
));
2945 deep_copy_visitor::visit_comparison (comparison
* e
)
2947 update_visitor::visit_comparison(new comparison(*e
));
2951 deep_copy_visitor::visit_concatenation (concatenation
* e
)
2953 update_visitor::visit_concatenation(new concatenation(*e
));
2957 deep_copy_visitor::visit_ternary_expression (ternary_expression
* e
)
2959 update_visitor::visit_ternary_expression(new ternary_expression(*e
));
2963 deep_copy_visitor::visit_assignment (assignment
* e
)
2965 update_visitor::visit_assignment(new assignment(*e
));
2969 deep_copy_visitor::visit_symbol (symbol
* e
)
2971 symbol
* n
= new symbol(*e
);
2972 n
->referent
= NULL
; // don't copy!
2973 update_visitor::visit_symbol(n
);
2977 deep_copy_visitor::visit_target_symbol (target_symbol
* e
)
2979 target_symbol
* n
= new target_symbol(*e
);
2980 n
->referent
= NULL
; // don't copy!
2981 update_visitor::visit_target_symbol(n
);
2985 deep_copy_visitor::visit_cast_op (cast_op
* e
)
2987 update_visitor::visit_cast_op(new cast_op(*e
));
2991 deep_copy_visitor::visit_defined_op (defined_op
* e
)
2993 update_visitor::visit_defined_op(new defined_op(*e
));
2997 deep_copy_visitor::visit_entry_op (entry_op
* e
)
2999 update_visitor::visit_entry_op(new entry_op(*e
));
3003 deep_copy_visitor::visit_arrayindex (arrayindex
* e
)
3005 update_visitor::visit_arrayindex(new arrayindex(*e
));
3009 deep_copy_visitor::visit_functioncall (functioncall
* e
)
3011 functioncall
* n
= new functioncall(*e
);
3012 n
->referent
= NULL
; // don't copy!
3013 update_visitor::visit_functioncall(n
);
3017 deep_copy_visitor::visit_print_format (print_format
* e
)
3019 update_visitor::visit_print_format(new print_format(*e
));
3023 deep_copy_visitor::visit_stat_op (stat_op
* e
)
3025 update_visitor::visit_stat_op(new stat_op(*e
));
3029 deep_copy_visitor::visit_hist_op (hist_op
* e
)
3031 update_visitor::visit_hist_op(new hist_op(*e
));
3034 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */