1 // parse tree functions
2 // Copyright (C) 2005-2009 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
27 expression::expression ():
28 type (pe_unknown
), tok (0)
33 expression::~expression ()
38 statement::statement ():
44 statement::~statement ()
55 arrayindex::arrayindex ():
61 functioncall::functioncall ():
67 symboldecl::symboldecl ():
74 symboldecl::~symboldecl ()
78 probe_point::probe_point (std::vector
<component
*> const & comps
,
80 components(comps
), tok(t
), optional (false), sufficient (false),
85 // NB: shallow-copy of compoonents & condition!
86 probe_point::probe_point (const probe_point
& pp
):
87 components(pp
.components
), tok(pp
.tok
), optional (pp
.optional
), sufficient (pp
.sufficient
),
88 condition (pp
.condition
)
93 probe_point::probe_point ():
94 tok (0), optional (false), sufficient (false), condition (0)
99 unsigned probe::last_probeidx
= 0;
103 this->name
= string ("probe_") + lex_cast
<string
>(last_probeidx
++);
107 probe_point::component::component ():
113 probe_point::component::component (std::string
const & f
, literal
* a
):
120 arity (-1), maxsize(0), init(NULL
)
126 vardecl::set_arity (int a
)
131 if ((arity
!= a
&& arity
>= 0) || (a
== 0 && maxsize
> 0))
132 throw semantic_error ("inconsistent arity", tok
);
137 index_types
.resize (arity
);
138 for (int i
=0; i
<arity
; i
++)
139 index_types
[i
] = pe_unknown
;
144 vardecl::compatible_arity (int a
)
146 if (a
== 0 && maxsize
> 0)
148 if (arity
== -1 || a
== -1)
154 functiondecl::functiondecl ():
160 literal_number::literal_number (int64_t v
)
167 literal_string::literal_string (const string
& v
)
175 operator << (ostream
& o
, const exp_type
& e
)
179 case pe_unknown
: o
<< "unknown"; break;
180 case pe_long
: o
<< "long"; break;
181 case pe_string
: o
<< "string"; break;
182 case pe_stats
: o
<< "stats"; break;
183 default: o
<< "???"; break;
190 target_symbol::assert_no_components(const std::string
& tapset
)
192 if (components
.empty())
195 switch (components
[0].type
)
197 case target_symbol::comp_literal_array_index
:
198 throw semantic_error(tapset
+ " variable '" + base_name
+
199 "' may not be used as array",
201 case target_symbol::comp_struct_member
:
202 throw semantic_error(tapset
+ " variable '" + base_name
+
203 "' may not be used as a structure",
206 throw semantic_error ("invalid use of " + tapset
+
207 " variable '" + base_name
+ "'",
213 // ------------------------------------------------------------------------
214 // parse tree printing
216 ostream
& operator << (ostream
& o
, const expression
& k
)
223 void literal_string::print (ostream
& o
) const
226 for (unsigned i
=0; i
<value
.size(); i
++)
227 if (value
[i
] == '"') // or other escapeworthy characters?
235 void literal_number::print (ostream
& o
) const
241 void binary_expression::print (ostream
& o
) const
243 o
<< "(" << *left
<< ") "
245 << " (" << *right
<< ")";
249 void unary_expression::print (ostream
& o
) const
251 o
<< op
<< '(' << *operand
<< ")";
254 void array_in::print (ostream
& o
) const
257 for (unsigned i
=0; i
<operand
->indexes
.size(); i
++)
259 if (i
> 0) o
<< ", ";
260 operand
->indexes
[i
]->print (o
);
263 operand
->base
->print_indexable (o
);
266 void post_crement::print (ostream
& o
) const
268 o
<< '(' << *operand
<< ")" << op
;
272 void ternary_expression::print (ostream
& o
) const
274 o
<< "(" << *cond
<< ")?("
275 << *truevalue
<< "):("
276 << *falsevalue
<< ")";
280 void symbol::print (ostream
& o
) const
286 void target_symbol::component::print (ostream
& o
) const
290 case comp_struct_member
:
293 case comp_literal_array_index
:
294 o
<< '[' << num_index
<< ']';
300 std::ostream
& operator << (std::ostream
& o
, const target_symbol::component
& c
)
307 void target_symbol::print (ostream
& o
) const
312 for (unsigned i
= 0; i
< components
.size(); ++i
)
317 void cast_op::print (ostream
& o
) const
321 o
<< base_name
<< '(' << *operand
;
322 o
<< ", " << lex_cast_qstring (type
);
323 if (module
.length() > 0)
324 o
<< ", " << lex_cast_qstring (module
);
326 for (unsigned i
= 0; i
< components
.size(); ++i
)
331 void vardecl::print (ostream
& o
) const
335 o
<< "[" << maxsize
<< "]";
336 if (arity
> 0 || index_types
.size() > 0)
346 void vardecl::printsig (ostream
& o
) const
350 o
<< "[" << maxsize
<< "]";
352 if (index_types
.size() > 0)
355 for (unsigned i
=0; i
<index_types
.size(); i
++)
356 o
<< (i
>0 ? ", " : "") << index_types
[i
];
362 void functiondecl::print (ostream
& o
) const
364 o
<< "function " << name
<< " (";
365 for (unsigned i
=0; i
<formal_args
.size(); i
++)
366 o
<< (i
>0 ? ", " : "") << *formal_args
[i
];
372 void functiondecl::printsig (ostream
& o
) const
374 o
<< name
<< ":" << type
<< " (";
375 for (unsigned i
=0; i
<formal_args
.size(); i
++)
376 o
<< (i
>0 ? ", " : "")
379 << formal_args
[i
]->type
;
384 void arrayindex::print (ostream
& o
) const
386 base
->print_indexable (o
);
388 for (unsigned i
=0; i
<indexes
.size(); i
++)
389 o
<< (i
>0 ? ", " : "") << *indexes
[i
];
394 void functioncall::print (ostream
& o
) const
396 o
<< function
<< "(";
397 for (unsigned i
=0; i
<args
.size(); i
++)
398 o
<< (i
>0 ? ", " : "") << *args
[i
];
404 print_format::parse_print(const std::string
&name
,
405 bool &stream
, bool &format
, bool &delim
, bool &newline
, bool &_char
)
407 const char *n
= name
.c_str();
410 format
= delim
= newline
= _char
= false;
412 if (strcmp(n
, "print_char") == 0)
424 if (0 != strncmp(n
, "print", 5))
441 if (*n
== 'l' && *(n
+1) == 'n')
453 print_format::components_to_string(vector
<format_component
> const & components
)
457 for (vector
<format_component
>::const_iterator i
= components
.begin();
458 i
!= components
.end(); ++i
)
461 assert (i
->type
!= conv_unspecified
);
463 if (i
->type
== conv_literal
)
465 assert(!i
->literal_string
.empty());
466 for (string::const_iterator j
= i
->literal_string
.begin();
467 j
!= i
->literal_string
.end(); ++j
)
469 // See also: c_unparser::visit_literal_string and lex_cast_qstring
481 if (i
->flags
& static_cast<unsigned long>(fmt_flag_zeropad
))
484 if (i
->flags
& static_cast<unsigned long>(fmt_flag_plus
))
487 if (i
->flags
& static_cast<unsigned long>(fmt_flag_space
))
490 if (i
->flags
& static_cast<unsigned long>(fmt_flag_left
))
493 if (i
->flags
& static_cast<unsigned long>(fmt_flag_special
))
496 if (i
->widthtype
== width_dynamic
)
498 else if (i
->widthtype
!= width_unspecified
&& i
->width
> 0)
501 if (i
->prectype
== prec_dynamic
)
503 else if (i
->prectype
!= prec_unspecified
&& i
->precision
> 0)
504 oss
<< '.' << i
->precision
;
516 case conv_signed_decimal
:
520 case conv_unsigned_decimal
:
524 case conv_unsigned_octal
:
528 case conv_unsigned_ptr
:
532 case conv_unsigned_uppercase_hex
:
536 case conv_unsigned_lowercase_hex
:
548 case conv_memory_hex
:
560 vector
<print_format::format_component
>
561 print_format::string_to_components(string
const & str
)
563 format_component curr
;
564 vector
<format_component
> res
;
568 string::const_iterator i
= str
.begin();
570 while (i
!= str
.end())
574 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
575 curr
.type
= conv_literal
;
576 curr
.literal_string
+= *i
;
580 else if (i
+1 == str
.end() || *(i
+1) == '%')
583 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
584 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
585 curr
.type
= conv_literal
;
586 curr
.literal_string
+= '%';
593 if (curr
.type
!= conv_unspecified
)
595 // Flush any component we were previously accumulating
596 assert (curr
.type
== conv_literal
);
606 // Now we are definitely parsing a conversion.
607 // Begin by parsing flags (which are optional).
612 curr
.flags
|= static_cast<unsigned long>(fmt_flag_zeropad
);
617 curr
.flags
|= static_cast<unsigned long>(fmt_flag_plus
);
622 curr
.flags
|= static_cast<unsigned long>(fmt_flag_left
);
627 curr
.flags
|= static_cast<unsigned long>(fmt_flag_space
);
632 curr
.flags
|= static_cast<unsigned long>(fmt_flag_special
);
643 // Parse optional width
646 curr
.widthtype
= width_dynamic
;
649 else if (isdigit(*i
))
651 curr
.widthtype
= width_static
;
656 curr
.width
+= (*i
- '0');
659 while (i
!= str
.end() && isdigit(*i
));
665 // Parse optional precision
673 curr
.prectype
= prec_dynamic
;
676 else if (isdigit(*i
))
678 curr
.prectype
= prec_static
;
682 curr
.precision
*= 10;
683 curr
.precision
+= (*i
- '0');
686 while (i
!= str
.end() && isdigit(*i
));
693 // Parse the actual conversion specifier (bcsmdioupxXn)
696 // Valid conversion types
698 curr
.type
= conv_binary
;
702 curr
.type
= conv_char
;
706 curr
.type
= conv_string
;
710 curr
.type
= conv_memory
;
714 curr
.type
= conv_memory_hex
;
719 curr
.type
= conv_signed_decimal
;
723 curr
.type
= conv_unsigned_octal
;
727 curr
.type
= conv_unsigned_decimal
;
731 curr
.type
= conv_unsigned_ptr
;
735 curr
.type
= conv_unsigned_uppercase_hex
;
739 curr
.type
= conv_unsigned_lowercase_hex
;
746 if (curr
.type
== conv_unspecified
)
747 throw parse_error("invalid or missing conversion specifier");
754 // If there's a remaining partly-composed conversion, fail.
755 if (!curr
.is_empty())
757 if (curr
.type
== conv_literal
)
760 throw parse_error("trailing incomplete print format conversion");
767 void print_format::print (ostream
& o
) const
769 o
<< tok
->content
<< "(";
770 if (print_with_format
)
771 o
<< lex_cast_qstring (raw_components
);
772 if (print_with_delim
)
773 o
<< lex_cast_qstring (delimiter
.literal_string
);
776 for (vector
<expression
*>::const_iterator i
= args
.begin();
777 i
!= args
.end(); ++i
)
779 if (i
!= args
.begin() || print_with_format
|| print_with_delim
)
786 void stat_op::print (ostream
& o
) const
816 hist_op::print (ostream
& o
) const
822 assert(params
.size() == 3);
825 for (size_t i
= 0; i
< params
.size(); ++i
)
827 o
<< ", " << params
[i
];
833 assert(params
.size() == 0);
841 ostream
& operator << (ostream
& o
, const statement
& k
)
848 void embeddedcode::print (ostream
&o
) const
855 void block::print (ostream
& o
) const
858 for (unsigned i
=0; i
<statements
.size(); i
++)
859 o
<< *statements
[i
] << endl
;
863 block::block (statement
* car
, statement
* cdr
)
865 statements
.push_back(car
);
866 statements
.push_back(cdr
);
867 this->tok
= car
->tok
;
872 void for_loop::print (ostream
& o
) const
875 if (init
) init
->print (o
);
879 if (incr
) incr
->print (o
);
885 void foreach_loop::print (ostream
& o
) const
888 for (unsigned i
=0; i
<indexes
.size(); i
++)
890 if (i
> 0) o
<< ", ";
891 indexes
[i
]->print (o
);
892 if (sort_direction
!= 0 && sort_column
== i
+1)
893 o
<< (sort_direction
> 0 ? "+" : "-");
896 base
->print_indexable (o
);
897 if (sort_direction
!= 0 && sort_column
== 0)
898 o
<< (sort_direction
> 0 ? "+" : "-");
909 void null_statement::print (ostream
& o
) const
915 void expr_statement::print (ostream
& o
) const
921 void return_statement::print (ostream
& o
) const
923 o
<< "return " << *value
;
927 void delete_statement::print (ostream
& o
) const
929 o
<< "delete " << *value
;
932 void next_statement::print (ostream
& o
) const
937 void break_statement::print (ostream
& o
) const
942 void continue_statement::print (ostream
& o
) const
947 void if_statement::print (ostream
& o
) const
949 o
<< "if (" << *condition
<< ") "
950 << *thenblock
<< endl
;
952 o
<< "else " << *elseblock
<< endl
;
956 void stapfile::print (ostream
& o
) const
958 o
<< "# file " << name
<< endl
;
960 for (unsigned i
=0; i
<embeds
.size(); i
++)
961 embeds
[i
]->print (o
);
963 for (unsigned i
=0; i
<globals
.size(); i
++)
966 globals
[i
]->print (o
);
970 for (unsigned i
=0; i
<aliases
.size(); i
++)
972 aliases
[i
]->print (o
);
976 for (unsigned i
=0; i
<probes
.size(); i
++)
978 probes
[i
]->print (o
);
982 for (unsigned j
= 0; j
< functions
.size(); j
++)
984 functions
[j
]->print (o
);
990 void probe::print (ostream
& o
) const
998 void probe::printsig (ostream
& o
) const
1000 const probe_alias
*alias
= get_alias ();
1003 alias
->printsig (o
);
1007 for (unsigned i
=0; i
<locations
.size(); i
++)
1009 if (i
> 0) o
<< ",";
1010 locations
[i
]->print (o
);
1016 probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
)
1018 probes_list
.push_back(this);
1022 void probe_point::print (ostream
& o
) const
1024 for (unsigned i
=0; i
<components
.size(); i
++)
1027 probe_point::component
* c
= components
[i
];
1030 o
<< "(" << *c
->arg
<< ")";
1034 else if (optional
) // sufficient implies optional
1037 o
<< " if (" << *condition
<< ")";
1040 string
probe_point::str ()
1043 for (unsigned i
=0; i
<components
.size(); i
++)
1046 probe_point::component
* c
= components
[i
];
1049 o
<< "(" << *c
->arg
<< ")";
1053 else if (optional
) // sufficient implies optional
1056 o
<< " if (" << *condition
<< ")";
1061 probe_alias::probe_alias(std::vector
<probe_point
*> const & aliases
):
1062 probe (), alias_names (aliases
)
1066 void probe_alias::printsig (ostream
& o
) const
1068 for (unsigned i
=0; i
<alias_names
.size(); i
++)
1070 o
<< (i
>0 ? " = " : "");
1071 alias_names
[i
]->print (o
);
1074 for (unsigned i
=0; i
<locations
.size(); i
++)
1076 if (i
> 0) o
<< ", ";
1077 locations
[i
]->print (o
);
1082 ostream
& operator << (ostream
& o
, const probe_point
& k
)
1089 ostream
& operator << (ostream
& o
, const symboldecl
& k
)
1097 // ------------------------------------------------------------------------
1102 block::visit (visitor
* u
)
1104 u
->visit_block (this);
1109 embeddedcode::visit (visitor
* u
)
1111 u
->visit_embeddedcode (this);
1116 for_loop::visit (visitor
* u
)
1118 u
->visit_for_loop (this);
1122 foreach_loop::visit (visitor
* u
)
1124 u
->visit_foreach_loop (this);
1128 null_statement::visit (visitor
* u
)
1130 u
->visit_null_statement (this);
1134 expr_statement::visit (visitor
* u
)
1136 u
->visit_expr_statement (this);
1140 return_statement::visit (visitor
* u
)
1142 u
->visit_return_statement (this);
1146 delete_statement::visit (visitor
* u
)
1148 u
->push_active_lvalue (this->value
);
1149 u
->visit_delete_statement (this);
1150 u
->pop_active_lvalue ();
1154 if_statement::visit (visitor
* u
)
1156 u
->visit_if_statement (this);
1160 next_statement::visit (visitor
* u
)
1162 u
->visit_next_statement (this);
1166 break_statement::visit (visitor
* u
)
1168 u
->visit_break_statement (this);
1172 continue_statement::visit (visitor
* u
)
1174 u
->visit_continue_statement (this);
1178 literal_string::visit(visitor
* u
)
1180 u
->visit_literal_string (this);
1184 literal_number::visit(visitor
* u
)
1186 u
->visit_literal_number (this);
1190 binary_expression::visit (visitor
* u
)
1192 u
->visit_binary_expression (this);
1196 unary_expression::visit (visitor
* u
)
1198 u
->visit_unary_expression (this);
1202 pre_crement::visit (visitor
* u
)
1204 u
->push_active_lvalue (this->operand
);
1205 u
->visit_pre_crement (this);
1206 u
->pop_active_lvalue ();
1210 post_crement::visit (visitor
* u
)
1212 u
->push_active_lvalue (this->operand
);
1213 u
->visit_post_crement (this);
1214 u
->pop_active_lvalue ();
1218 logical_or_expr::visit (visitor
* u
)
1220 u
->visit_logical_or_expr (this);
1224 logical_and_expr::visit (visitor
* u
)
1226 u
->visit_logical_and_expr (this);
1230 array_in::visit (visitor
* u
)
1232 u
->visit_array_in (this);
1236 comparison::visit (visitor
* u
)
1238 u
->visit_comparison (this);
1242 concatenation::visit (visitor
* u
)
1244 u
->visit_concatenation (this);
1248 ternary_expression::visit (visitor
* u
)
1250 u
->visit_ternary_expression (this);
1254 assignment::visit (visitor
* u
)
1256 u
->push_active_lvalue (this->left
);
1257 u
->visit_assignment (this);
1258 u
->pop_active_lvalue ();
1262 symbol::visit (visitor
* u
)
1264 u
->visit_symbol (this);
1268 target_symbol::visit (visitor
* u
)
1270 u
->visit_target_symbol(this);
1274 cast_op::visit (visitor
* u
)
1276 u
->visit_cast_op(this);
1280 arrayindex::visit (visitor
* u
)
1282 u
->visit_arrayindex (this);
1286 functioncall::visit (visitor
* u
)
1288 u
->visit_functioncall (this);
1292 print_format::visit (visitor
*u
)
1294 u
->visit_print_format (this);
1298 stat_op::visit (visitor
*u
)
1300 u
->visit_stat_op (this);
1304 hist_op::visit (visitor
*u
)
1306 u
->visit_hist_op (this);
1310 indexable::print_indexable (std::ostream
& o
) const
1313 const hist_op
*hist
;
1314 classify_const_indexable(this, sym
, hist
);
1325 indexable::visit_indexable (visitor
* u
)
1329 classify_indexable(this, sym
, hist
);
1341 indexable::is_symbol(symbol
*& sym_out
)
1348 indexable::is_hist_op(hist_op
*& hist_out
)
1355 indexable::is_const_symbol(const symbol
*& sym_out
) const
1362 indexable::is_const_hist_op(const hist_op
*& hist_out
) const
1369 symbol::is_symbol(symbol
*& sym_out
)
1376 symbol::is_const_symbol(const symbol
*& sym_out
) const
1383 symbol::get_tok() const
1389 hist_op::is_hist_op(hist_op
*& hist_out
)
1396 hist_op::is_const_hist_op(const hist_op
*& hist_out
) const
1403 hist_op::get_tok() const
1409 classify_indexable(indexable
* ix
,
1410 symbol
*& array_out
,
1411 hist_op
*& hist_out
)
1415 if (!(ix
->is_symbol (array_out
) || ix
->is_hist_op (hist_out
)))
1416 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1417 if (ix
&& !(hist_out
|| array_out
))
1418 throw semantic_error("Failed to classify indexable", ix
->get_tok());
1422 classify_const_indexable(const indexable
* ix
,
1423 const symbol
*& array_out
,
1424 const hist_op
*& hist_out
)
1428 if (!(ix
->is_const_symbol(array_out
) || ix
->is_const_hist_op(hist_out
)))
1429 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1432 // ------------------------------------------------------------------------
1435 visitor::is_active_lvalue(expression
*e
)
1437 for (unsigned i
= 0; i
< active_lvalues
.size(); ++i
)
1439 if (active_lvalues
[i
] == e
)
1446 visitor::push_active_lvalue(expression
*e
)
1448 active_lvalues
.push_back(e
);
1452 visitor::pop_active_lvalue()
1454 assert(!active_lvalues
.empty());
1455 active_lvalues
.pop_back();
1460 // ------------------------------------------------------------------------
1463 traversing_visitor::visit_block (block
* s
)
1465 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
1466 s
->statements
[i
]->visit (this);
1470 traversing_visitor::visit_embeddedcode (embeddedcode
*)
1475 traversing_visitor::visit_null_statement (null_statement
*)
1480 traversing_visitor::visit_expr_statement (expr_statement
* s
)
1482 s
->value
->visit (this);
1486 traversing_visitor::visit_if_statement (if_statement
* s
)
1488 s
->condition
->visit (this);
1489 s
->thenblock
->visit (this);
1491 s
->elseblock
->visit (this);
1495 traversing_visitor::visit_for_loop (for_loop
* s
)
1497 if (s
->init
) s
->init
->visit (this);
1498 s
->cond
->visit (this);
1499 if (s
->incr
) s
->incr
->visit (this);
1500 s
->block
->visit (this);
1504 traversing_visitor::visit_foreach_loop (foreach_loop
* s
)
1506 symbol
*array
= NULL
;
1507 hist_op
*hist
= NULL
;
1508 classify_indexable (s
->base
, array
, hist
);
1514 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1515 s
->indexes
[i
]->visit (this);
1518 s
->limit
->visit (this);
1520 s
->block
->visit (this);
1524 traversing_visitor::visit_return_statement (return_statement
* s
)
1526 s
->value
->visit (this);
1530 traversing_visitor::visit_delete_statement (delete_statement
* s
)
1532 s
->value
->visit (this);
1536 traversing_visitor::visit_next_statement (next_statement
*)
1541 traversing_visitor::visit_break_statement (break_statement
*)
1546 traversing_visitor::visit_continue_statement (continue_statement
*)
1551 traversing_visitor::visit_literal_string (literal_string
*)
1556 traversing_visitor::visit_literal_number (literal_number
*)
1561 traversing_visitor::visit_binary_expression (binary_expression
* e
)
1563 e
->left
->visit (this);
1564 e
->right
->visit (this);
1568 traversing_visitor::visit_unary_expression (unary_expression
* e
)
1570 e
->operand
->visit (this);
1574 traversing_visitor::visit_pre_crement (pre_crement
* e
)
1576 e
->operand
->visit (this);
1580 traversing_visitor::visit_post_crement (post_crement
* e
)
1582 e
->operand
->visit (this);
1587 traversing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
1589 e
->left
->visit (this);
1590 e
->right
->visit (this);
1594 traversing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
1596 e
->left
->visit (this);
1597 e
->right
->visit (this);
1601 traversing_visitor::visit_array_in (array_in
* e
)
1603 e
->operand
->visit (this);
1607 traversing_visitor::visit_comparison (comparison
* e
)
1609 e
->left
->visit (this);
1610 e
->right
->visit (this);
1614 traversing_visitor::visit_concatenation (concatenation
* e
)
1616 e
->left
->visit (this);
1617 e
->right
->visit (this);
1621 traversing_visitor::visit_ternary_expression (ternary_expression
* e
)
1623 e
->cond
->visit (this);
1624 e
->truevalue
->visit (this);
1625 e
->falsevalue
->visit (this);
1629 traversing_visitor::visit_assignment (assignment
* e
)
1631 e
->left
->visit (this);
1632 e
->right
->visit (this);
1636 traversing_visitor::visit_symbol (symbol
*)
1641 traversing_visitor::visit_target_symbol (target_symbol
*)
1646 traversing_visitor::visit_cast_op (cast_op
* e
)
1648 e
->operand
->visit (this);
1652 traversing_visitor::visit_arrayindex (arrayindex
* e
)
1654 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
1655 e
->indexes
[i
]->visit (this);
1657 symbol
*array
= NULL
;
1658 hist_op
*hist
= NULL
;
1659 classify_indexable(e
->base
, array
, hist
);
1661 return array
->visit(this);
1663 return hist
->visit(this);
1667 traversing_visitor::visit_functioncall (functioncall
* e
)
1669 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1670 e
->args
[i
]->visit (this);
1674 traversing_visitor::visit_print_format (print_format
* e
)
1676 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1677 e
->args
[i
]->visit (this);
1679 e
->hist
->visit(this);
1683 traversing_visitor::visit_stat_op (stat_op
* e
)
1685 e
->stat
->visit (this);
1689 traversing_visitor::visit_hist_op (hist_op
* e
)
1691 e
->stat
->visit (this);
1696 functioncall_traversing_visitor::visit_functioncall (functioncall
* e
)
1698 traversing_visitor::visit_functioncall (e
);
1700 // prevent infinite recursion
1701 if (traversed
.find (e
->referent
) == traversed
.end ())
1703 traversed
.insert (e
->referent
);
1705 functiondecl
* last_current_function
= current_function
;
1706 current_function
= e
->referent
;
1707 e
->referent
->body
->visit (this);
1708 current_function
= last_current_function
;
1714 varuse_collecting_visitor::visit_embeddedcode (embeddedcode
*s
)
1716 // We want to elide embedded-C functions when possible. For
1717 // example, each $target variable access is expanded to an
1718 // embedded-C function call. Yet, for safety reasons, we should
1719 // presume that embedded-C functions have intentional side-effects.
1721 // To tell these two types of functions apart, we apply a
1722 // Kludge(tm): we look for a magic string within the function body.
1723 // $target variables as rvalues will have this; lvalues won't.
1724 // Also, explicit side-effect-free tapset functions will have this.
1726 assert (current_function
); // only they get embedded code
1727 if (s
->code
.find ("/* pure */") != string::npos
)
1730 embedded_seen
= true;
1734 varuse_collecting_visitor::visit_target_symbol (target_symbol
*e
)
1736 // Still-unresolved target symbol assignments get treated as
1737 // generating side-effects like embedded-C, to prevent premature
1738 // elision and later error message suppression (PR5516). rvalue use
1739 // of unresolved target symbols is OTOH not considered a side-effect.
1741 if (is_active_lvalue (e
))
1742 embedded_seen
= true;
1746 varuse_collecting_visitor::visit_cast_op (cast_op
*e
)
1748 // As with target_symbols, unresolved cast assignments need to preserved
1749 // for later error handling.
1750 if (is_active_lvalue (e
))
1751 embedded_seen
= true;
1753 functioncall_traversing_visitor::visit_cast_op (e
);
1757 varuse_collecting_visitor::visit_print_format (print_format
* e
)
1759 // NB: Instead of being top-level statements, "print" and "printf"
1760 // are implemented as statement-expressions containing a
1761 // print_format. They have side-effects, but not via the
1762 // embedded-code detection method above.
1764 // But sprint and sprintf don't have side-effects.
1766 if (e
->print_to_stream
)
1767 embedded_seen
= true; // a proxy for "has unknown side-effects"
1769 functioncall_traversing_visitor::visit_print_format (e
);
1774 varuse_collecting_visitor::visit_assignment (assignment
*e
)
1776 if (e
->op
== "=" || e
->op
== "<<<") // pure writes
1778 expression
* last_lvalue
= current_lvalue
;
1779 current_lvalue
= e
->left
; // leave a mark for ::visit_symbol
1780 functioncall_traversing_visitor::visit_assignment (e
);
1781 current_lvalue
= last_lvalue
;
1783 else // read-modify-writes
1785 expression
* last_lrvalue
= current_lrvalue
;
1786 current_lrvalue
= e
->left
; // leave a mark for ::visit_symbol
1787 functioncall_traversing_visitor::visit_assignment (e
);
1788 current_lrvalue
= last_lrvalue
;
1793 varuse_collecting_visitor::visit_symbol (symbol
*e
)
1795 if (e
->referent
== 0)
1796 throw semantic_error ("symbol without referent", e
->tok
);
1798 // We could handle initialized globals by marking them as "written".
1799 // However, this current visitor may be called for a function or
1800 // probe body, from the point of view of which this global is
1801 // already initialized, so not written.
1803 if (e->referent->init)
1804 written.insert (e->referent);
1807 if (current_lvalue
== e
|| current_lrvalue
== e
)
1809 written
.insert (e
->referent
);
1810 // clog << "write ";
1812 if (current_lvalue
!= e
|| current_lrvalue
== e
)
1814 read
.insert (e
->referent
);
1817 // clog << *e->tok << endl;
1820 // NB: stat_op need not be overridden, since it will get to
1821 // visit_symbol and only as a possible rvalue.
1825 varuse_collecting_visitor::visit_arrayindex (arrayindex
*e
)
1827 // Hooking this callback is necessary because of the hacky
1828 // statistics representation. For the expression "i[4] = 5", the
1829 // incoming lvalue will point to this arrayindex. However, the
1830 // symbol corresponding to the "i[4]" is multiply inherited with
1831 // arrayindex. If the symbol base part of this object is not at
1832 // offset 0, then static_cast<symbol*>(e) may result in a different
1833 // address, and not match lvalue by number when we recurse that way.
1834 // So we explicitly override the incoming lvalue/lrvalue values to
1835 // point at the embedded objects' actual base addresses.
1837 expression
* last_lrvalue
= current_lrvalue
;
1838 expression
* last_lvalue
= current_lvalue
;
1840 symbol
*array
= NULL
;
1841 hist_op
*hist
= NULL
;
1842 classify_indexable(e
->base
, array
, hist
);
1846 if (current_lrvalue
== e
) current_lrvalue
= array
;
1847 if (current_lvalue
== e
) current_lvalue
= array
;
1848 functioncall_traversing_visitor::visit_arrayindex (e
);
1852 if (current_lrvalue
== e
) current_lrvalue
= hist
->stat
;
1853 if (current_lvalue
== e
) current_lvalue
= hist
->stat
;
1854 functioncall_traversing_visitor::visit_arrayindex (e
);
1857 current_lrvalue
= last_lrvalue
;
1858 current_lvalue
= last_lvalue
;
1863 varuse_collecting_visitor::visit_pre_crement (pre_crement
*e
)
1865 expression
* last_lrvalue
= current_lrvalue
;
1866 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1867 functioncall_traversing_visitor::visit_pre_crement (e
);
1868 current_lrvalue
= last_lrvalue
;
1872 varuse_collecting_visitor::visit_post_crement (post_crement
*e
)
1874 expression
* last_lrvalue
= current_lrvalue
;
1875 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1876 functioncall_traversing_visitor::visit_post_crement (e
);
1877 current_lrvalue
= last_lrvalue
;
1881 varuse_collecting_visitor::visit_foreach_loop (foreach_loop
* s
)
1883 // NB: we duplicate so don't bother call
1884 // functioncall_traversing_visitor::visit_foreach_loop (s);
1886 symbol
*array
= NULL
;
1887 hist_op
*hist
= NULL
;
1888 classify_indexable (s
->base
, array
, hist
);
1894 // If the collection is sorted, imply a "write" access to the
1895 // array in addition to the "read" one already noted above.
1896 if (s
->sort_direction
)
1898 symbol
*array
= NULL
;
1899 hist_op
*hist
= NULL
;
1900 classify_indexable (s
->base
, array
, hist
);
1901 if (array
) this->written
.insert (array
->referent
);
1902 // XXX: Can hist_op iterations be sorted?
1905 // NB: don't forget to visit the index expressions, which are lvalues.
1906 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1908 expression
* last_lvalue
= current_lvalue
;
1909 current_lvalue
= s
->indexes
[i
]; // leave a mark for ::visit_symbol
1910 s
->indexes
[i
]->visit (this);
1911 current_lvalue
= last_lvalue
;
1915 s
->limit
->visit (this);
1917 s
->block
->visit (this);
1922 varuse_collecting_visitor::visit_delete_statement (delete_statement
* s
)
1924 // Ideally, this would be treated like an assignment: a plain write
1925 // to the underlying value ("lvalue"). XXX: However, the
1926 // optimization pass is not smart enough to remove an unneeded
1927 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
1928 // should protect the underlying value from optimizional mischief.
1929 expression
* last_lrvalue
= current_lrvalue
;
1930 current_lrvalue
= s
->value
; // leave a mark for ::visit_symbol
1931 functioncall_traversing_visitor::visit_delete_statement (s
);
1932 current_lrvalue
= last_lrvalue
;
1936 varuse_collecting_visitor::side_effect_free ()
1938 return (written
.empty() && !embedded_seen
);
1943 varuse_collecting_visitor::side_effect_free_wrt (const set
<vardecl
*>& vars
)
1945 // A looser notion of side-effect-freeness with respect to a given
1946 // list of variables.
1948 // That's useful because the written list may consist of local
1949 // variables of called functions. But visible side-effects only
1950 // occur if the client's locals, or any globals are written-to.
1952 set
<vardecl
*> intersection
;
1953 insert_iterator
<set
<vardecl
*> > int_it (intersection
, intersection
.begin());
1954 set_intersection (written
.begin(), written
.end(),
1955 vars
.begin(), vars
.end(),
1958 return (intersection
.empty() && !embedded_seen
);
1964 // ------------------------------------------------------------------------
1967 throwing_visitor::throwing_visitor (const std::string
& m
): msg (m
) {}
1968 throwing_visitor::throwing_visitor (): msg ("invalid element") {}
1972 throwing_visitor::throwone (const token
* t
)
1974 throw semantic_error (msg
, t
);
1978 throwing_visitor::visit_block (block
* s
)
1984 throwing_visitor::visit_embeddedcode (embeddedcode
* s
)
1990 throwing_visitor::visit_null_statement (null_statement
* s
)
1996 throwing_visitor::visit_expr_statement (expr_statement
* s
)
2002 throwing_visitor::visit_if_statement (if_statement
* s
)
2008 throwing_visitor::visit_for_loop (for_loop
* s
)
2014 throwing_visitor::visit_foreach_loop (foreach_loop
* s
)
2020 throwing_visitor::visit_return_statement (return_statement
* s
)
2026 throwing_visitor::visit_delete_statement (delete_statement
* s
)
2032 throwing_visitor::visit_next_statement (next_statement
* s
)
2038 throwing_visitor::visit_break_statement (break_statement
* s
)
2044 throwing_visitor::visit_continue_statement (continue_statement
* s
)
2050 throwing_visitor::visit_literal_string (literal_string
* e
)
2056 throwing_visitor::visit_literal_number (literal_number
* e
)
2062 throwing_visitor::visit_binary_expression (binary_expression
* e
)
2068 throwing_visitor::visit_unary_expression (unary_expression
* e
)
2074 throwing_visitor::visit_pre_crement (pre_crement
* e
)
2080 throwing_visitor::visit_post_crement (post_crement
* e
)
2087 throwing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2093 throwing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2099 throwing_visitor::visit_array_in (array_in
* e
)
2105 throwing_visitor::visit_comparison (comparison
* e
)
2111 throwing_visitor::visit_concatenation (concatenation
* e
)
2117 throwing_visitor::visit_ternary_expression (ternary_expression
* e
)
2123 throwing_visitor::visit_assignment (assignment
* e
)
2129 throwing_visitor::visit_symbol (symbol
* e
)
2135 throwing_visitor::visit_target_symbol (target_symbol
* e
)
2141 throwing_visitor::visit_cast_op (cast_op
* e
)
2147 throwing_visitor::visit_arrayindex (arrayindex
* e
)
2153 throwing_visitor::visit_functioncall (functioncall
* e
)
2159 throwing_visitor::visit_print_format (print_format
* e
)
2165 throwing_visitor::visit_stat_op (stat_op
* e
)
2171 throwing_visitor::visit_hist_op (hist_op
* e
)
2177 // ------------------------------------------------------------------------
2181 update_visitor::visit_block (block
* s
)
2183 for (unsigned i
= 0; i
< s
->statements
.size(); ++i
)
2184 s
->statements
[i
] = require (s
->statements
[i
]);
2189 update_visitor::visit_embeddedcode (embeddedcode
* s
)
2195 update_visitor::visit_null_statement (null_statement
* s
)
2201 update_visitor::visit_expr_statement (expr_statement
* s
)
2203 s
->value
= require (s
->value
);
2208 update_visitor::visit_if_statement (if_statement
* s
)
2210 s
->condition
= require (s
->condition
);
2211 s
->thenblock
= require (s
->thenblock
);
2212 s
->elseblock
= require (s
->elseblock
);
2217 update_visitor::visit_for_loop (for_loop
* s
)
2219 s
->init
= require (s
->init
);
2220 s
->cond
= require (s
->cond
);
2221 s
->incr
= require (s
->incr
);
2222 s
->block
= require (s
->block
);
2227 update_visitor::visit_foreach_loop (foreach_loop
* s
)
2229 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
2230 s
->indexes
[i
] = require (s
->indexes
[i
]);
2231 s
->base
= require (s
->base
);
2232 s
->limit
= require (s
->limit
);
2233 s
->block
= require (s
->block
);
2238 update_visitor::visit_return_statement (return_statement
* s
)
2240 s
->value
= require (s
->value
);
2245 update_visitor::visit_delete_statement (delete_statement
* s
)
2247 s
->value
= require (s
->value
);
2252 update_visitor::visit_next_statement (next_statement
* s
)
2258 update_visitor::visit_break_statement (break_statement
* s
)
2264 update_visitor::visit_continue_statement (continue_statement
* s
)
2270 update_visitor::visit_literal_string (literal_string
* e
)
2276 update_visitor::visit_literal_number (literal_number
* e
)
2282 update_visitor::visit_binary_expression (binary_expression
* e
)
2284 e
->left
= require (e
->left
);
2285 e
->right
= require (e
->right
);
2290 update_visitor::visit_unary_expression (unary_expression
* e
)
2292 e
->operand
= require (e
->operand
);
2297 update_visitor::visit_pre_crement (pre_crement
* e
)
2299 e
->operand
= require (e
->operand
);
2304 update_visitor::visit_post_crement (post_crement
* e
)
2306 e
->operand
= require (e
->operand
);
2312 update_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2314 e
->left
= require (e
->left
);
2315 e
->right
= require (e
->right
);
2320 update_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2322 e
->left
= require (e
->left
);
2323 e
->right
= require (e
->right
);
2328 update_visitor::visit_array_in (array_in
* e
)
2330 e
->operand
= require (e
->operand
);
2335 update_visitor::visit_comparison (comparison
* e
)
2337 e
->left
= require (e
->left
);
2338 e
->right
= require (e
->right
);
2343 update_visitor::visit_concatenation (concatenation
* e
)
2345 e
->left
= require (e
->left
);
2346 e
->right
= require (e
->right
);
2351 update_visitor::visit_ternary_expression (ternary_expression
* e
)
2353 e
->cond
= require (e
->cond
);
2354 e
->truevalue
= require (e
->truevalue
);
2355 e
->falsevalue
= require (e
->falsevalue
);
2360 update_visitor::visit_assignment (assignment
* e
)
2362 e
->left
= require (e
->left
);
2363 e
->right
= require (e
->right
);
2368 update_visitor::visit_symbol (symbol
* e
)
2374 update_visitor::visit_target_symbol (target_symbol
* e
)
2380 update_visitor::visit_cast_op (cast_op
* e
)
2382 e
->operand
= require (e
->operand
);
2387 update_visitor::visit_arrayindex (arrayindex
* e
)
2389 e
->base
= require (e
->base
);
2390 for (unsigned i
= 0; i
< e
->indexes
.size(); ++i
)
2391 e
->indexes
[i
] = require (e
->indexes
[i
]);
2396 update_visitor::visit_functioncall (functioncall
* e
)
2398 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2399 e
->args
[i
] = require (e
->args
[i
]);
2404 update_visitor::visit_print_format (print_format
* e
)
2406 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2407 e
->args
[i
] = require (e
->args
[i
]);
2408 e
->hist
= require (e
->hist
);
2413 update_visitor::visit_stat_op (stat_op
* e
)
2415 e
->stat
= require (e
->stat
);
2420 update_visitor::visit_hist_op (hist_op
* e
)
2422 e
->stat
= require (e
->stat
);
2426 template <> indexable
*
2427 update_visitor::require
<indexable
*> (indexable
* src
, bool clearok
)
2429 indexable
*dst
= NULL
;
2432 symbol
*array_src
=NULL
;
2433 hist_op
*hist_src
=NULL
;
2435 classify_indexable(src
, array_src
, hist_src
);
2438 dst
= require (array_src
);
2440 dst
= require (hist_src
);
2441 assert(clearok
|| dst
);
2447 // ------------------------------------------------------------------------
2451 deep_copy_visitor::visit_block (block
* s
)
2453 update_visitor::visit_block(new block(*s
));
2457 deep_copy_visitor::visit_embeddedcode (embeddedcode
* s
)
2459 update_visitor::visit_embeddedcode(new embeddedcode(*s
));
2463 deep_copy_visitor::visit_null_statement (null_statement
* s
)
2465 update_visitor::visit_null_statement(new null_statement(*s
));
2469 deep_copy_visitor::visit_expr_statement (expr_statement
* s
)
2471 update_visitor::visit_expr_statement(new expr_statement(*s
));
2475 deep_copy_visitor::visit_if_statement (if_statement
* s
)
2477 update_visitor::visit_if_statement(new if_statement(*s
));
2481 deep_copy_visitor::visit_for_loop (for_loop
* s
)
2483 update_visitor::visit_for_loop(new for_loop(*s
));
2487 deep_copy_visitor::visit_foreach_loop (foreach_loop
* s
)
2489 update_visitor::visit_foreach_loop(new foreach_loop(*s
));
2493 deep_copy_visitor::visit_return_statement (return_statement
* s
)
2495 update_visitor::visit_return_statement(new return_statement(*s
));
2499 deep_copy_visitor::visit_delete_statement (delete_statement
* s
)
2501 update_visitor::visit_delete_statement(new delete_statement(*s
));
2505 deep_copy_visitor::visit_next_statement (next_statement
* s
)
2507 update_visitor::visit_next_statement(new next_statement(*s
));
2511 deep_copy_visitor::visit_break_statement (break_statement
* s
)
2513 update_visitor::visit_break_statement(new break_statement(*s
));
2517 deep_copy_visitor::visit_continue_statement (continue_statement
* s
)
2519 update_visitor::visit_continue_statement(new continue_statement(*s
));
2523 deep_copy_visitor::visit_literal_string (literal_string
* e
)
2525 update_visitor::visit_literal_string(new literal_string(*e
));
2529 deep_copy_visitor::visit_literal_number (literal_number
* e
)
2531 update_visitor::visit_literal_number(new literal_number(*e
));
2535 deep_copy_visitor::visit_binary_expression (binary_expression
* e
)
2537 update_visitor::visit_binary_expression(new binary_expression(*e
));
2541 deep_copy_visitor::visit_unary_expression (unary_expression
* e
)
2543 update_visitor::visit_unary_expression(new unary_expression(*e
));
2547 deep_copy_visitor::visit_pre_crement (pre_crement
* e
)
2549 update_visitor::visit_pre_crement(new pre_crement(*e
));
2553 deep_copy_visitor::visit_post_crement (post_crement
* e
)
2555 update_visitor::visit_post_crement(new post_crement(*e
));
2560 deep_copy_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2562 update_visitor::visit_logical_or_expr(new logical_or_expr(*e
));
2566 deep_copy_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2568 update_visitor::visit_logical_and_expr(new logical_and_expr(*e
));
2572 deep_copy_visitor::visit_array_in (array_in
* e
)
2574 update_visitor::visit_array_in(new array_in(*e
));
2578 deep_copy_visitor::visit_comparison (comparison
* e
)
2580 update_visitor::visit_comparison(new comparison(*e
));
2584 deep_copy_visitor::visit_concatenation (concatenation
* e
)
2586 update_visitor::visit_concatenation(new concatenation(*e
));
2590 deep_copy_visitor::visit_ternary_expression (ternary_expression
* e
)
2592 update_visitor::visit_ternary_expression(new ternary_expression(*e
));
2596 deep_copy_visitor::visit_assignment (assignment
* e
)
2598 update_visitor::visit_assignment(new assignment(*e
));
2602 deep_copy_visitor::visit_symbol (symbol
* e
)
2604 symbol
* n
= new symbol(*e
);
2605 n
->referent
= NULL
; // don't copy!
2606 update_visitor::visit_symbol(n
);
2610 deep_copy_visitor::visit_target_symbol (target_symbol
* e
)
2612 target_symbol
* n
= new target_symbol(*e
);
2613 n
->referent
= NULL
; // don't copy!
2614 update_visitor::visit_target_symbol(n
);
2618 deep_copy_visitor::visit_cast_op (cast_op
* e
)
2620 update_visitor::visit_cast_op(new cast_op(*e
));
2624 deep_copy_visitor::visit_arrayindex (arrayindex
* e
)
2626 update_visitor::visit_arrayindex(new arrayindex(*e
));
2630 deep_copy_visitor::visit_functioncall (functioncall
* e
)
2632 functioncall
* n
= new functioncall(*e
);
2633 n
->referent
= NULL
; // don't copy!
2634 update_visitor::visit_functioncall(n
);
2638 deep_copy_visitor::visit_print_format (print_format
* e
)
2640 update_visitor::visit_print_format(new print_format(*e
));
2644 deep_copy_visitor::visit_stat_op (stat_op
* e
)
2646 update_visitor::visit_stat_op(new stat_op(*e
));
2650 deep_copy_visitor::visit_hist_op (hist_op
* e
)
2652 update_visitor::visit_hist_op(new hist_op(*e
));
2655 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */