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
28 expression::expression ():
29 type (pe_unknown
), tok (0)
34 expression::~expression ()
39 statement::statement ():
45 statement::~statement ()
56 arrayindex::arrayindex ():
62 functioncall::functioncall ():
68 symboldecl::symboldecl ():
75 symboldecl::~symboldecl ()
79 probe_point::probe_point (std::vector
<component
*> const & comps
,
81 components(comps
), tok(t
), optional (false), sufficient (false),
86 // NB: shallow-copy of compoonents & condition!
87 probe_point::probe_point (const probe_point
& pp
):
88 components(pp
.components
), tok(pp
.tok
), optional (pp
.optional
), sufficient (pp
.sufficient
),
89 condition (pp
.condition
)
94 probe_point::probe_point ():
95 tok (0), optional (false), sufficient (false), condition (0)
100 unsigned probe::last_probeidx
= 0;
104 this->name
= string ("probe_") + lex_cast
<string
>(last_probeidx
++);
108 probe_point::component::component ():
114 probe_point::component::component (std::string
const & f
, literal
* a
):
121 arity (-1), maxsize(0), init(NULL
)
127 vardecl::set_arity (int a
)
132 if ((arity
!= a
&& arity
>= 0) || (a
== 0 && maxsize
> 0))
133 throw semantic_error ("inconsistent arity", tok
);
138 index_types
.resize (arity
);
139 for (int i
=0; i
<arity
; i
++)
140 index_types
[i
] = pe_unknown
;
145 vardecl::compatible_arity (int a
)
147 if (a
== 0 && maxsize
> 0)
149 if (arity
== -1 || a
== -1)
155 functiondecl::functiondecl ():
161 literal_number::literal_number (int64_t v
)
168 literal_string::literal_string (const string
& v
)
176 operator << (ostream
& o
, const exp_type
& e
)
180 case pe_unknown
: o
<< "unknown"; break;
181 case pe_long
: o
<< "long"; break;
182 case pe_string
: o
<< "string"; break;
183 case pe_stats
: o
<< "stats"; break;
184 default: o
<< "???"; break;
190 // ------------------------------------------------------------------------
191 // parse tree printing
193 ostream
& operator << (ostream
& o
, const expression
& k
)
200 void literal_string::print (ostream
& o
) const
203 for (unsigned i
=0; i
<value
.size(); i
++)
204 if (value
[i
] == '"') // or other escapeworthy characters?
212 void literal_number::print (ostream
& o
) const
218 void binary_expression::print (ostream
& o
) const
220 o
<< "(" << *left
<< ") "
222 << " (" << *right
<< ")";
226 void unary_expression::print (ostream
& o
) const
228 o
<< op
<< '(' << *operand
<< ")";
231 void array_in::print (ostream
& o
) const
234 for (unsigned i
=0; i
<operand
->indexes
.size(); i
++)
236 if (i
> 0) o
<< ", ";
237 operand
->indexes
[i
]->print (o
);
240 operand
->base
->print_indexable (o
);
243 void post_crement::print (ostream
& o
) const
245 o
<< '(' << *operand
<< ")" << op
;
249 void ternary_expression::print (ostream
& o
) const
251 o
<< "(" << *cond
<< ")?("
252 << *truevalue
<< "):("
253 << *falsevalue
<< ")";
257 void symbol::print (ostream
& o
) const
263 void target_symbol::print (std::ostream
& o
) const
266 for (unsigned i
= 0; i
< components
.size(); ++i
)
268 switch (components
[i
].first
)
270 case comp_literal_array_index
:
271 o
<< '[' << components
[i
].second
<< ']';
273 case comp_struct_member
:
274 o
<< "->" << components
[i
].second
;
281 void cast_op::print (std::ostream
& o
) const
283 o
<< base_name
<< '(' << *operand
;
284 o
<< ", " << lex_cast_qstring (type
);
285 if (module
.length() > 0)
286 o
<< ", " << lex_cast_qstring (module
);
288 for (unsigned i
= 0; i
< components
.size(); ++i
)
290 switch (components
[i
].first
)
292 case comp_literal_array_index
:
293 o
<< '[' << components
[i
].second
<< ']';
295 case comp_struct_member
:
296 o
<< "->" << components
[i
].second
;
303 void vardecl::print (ostream
& o
) const
307 o
<< "[" << maxsize
<< "]";
308 if (arity
> 0 || index_types
.size() > 0)
318 void vardecl::printsig (ostream
& o
) const
322 o
<< "[" << maxsize
<< "]";
324 if (index_types
.size() > 0)
327 for (unsigned i
=0; i
<index_types
.size(); i
++)
328 o
<< (i
>0 ? ", " : "") << index_types
[i
];
334 void functiondecl::print (ostream
& o
) const
336 o
<< "function " << name
<< " (";
337 for (unsigned i
=0; i
<formal_args
.size(); i
++)
338 o
<< (i
>0 ? ", " : "") << *formal_args
[i
];
344 void functiondecl::printsig (ostream
& o
) const
346 o
<< name
<< ":" << type
<< " (";
347 for (unsigned i
=0; i
<formal_args
.size(); i
++)
348 o
<< (i
>0 ? ", " : "")
351 << formal_args
[i
]->type
;
356 void arrayindex::print (ostream
& o
) const
358 base
->print_indexable (o
);
360 for (unsigned i
=0; i
<indexes
.size(); i
++)
361 o
<< (i
>0 ? ", " : "") << *indexes
[i
];
366 void functioncall::print (ostream
& o
) const
368 o
<< function
<< "(";
369 for (unsigned i
=0; i
<args
.size(); i
++)
370 o
<< (i
>0 ? ", " : "") << *args
[i
];
376 print_format::parse_print(const std::string
&name
,
377 bool &stream
, bool &format
, bool &delim
, bool &newline
, bool &_char
)
379 const char *n
= name
.c_str();
382 format
= delim
= newline
= _char
= false;
384 if (strcmp(n
, "print_char") == 0)
396 if (0 != strncmp(n
, "print", 5))
413 if (*n
== 'l' && *(n
+1) == 'n')
425 print_format::components_to_string(vector
<format_component
> const & components
)
429 for (vector
<format_component
>::const_iterator i
= components
.begin();
430 i
!= components
.end(); ++i
)
433 assert (i
->type
!= conv_unspecified
);
435 if (i
->type
== conv_literal
)
437 assert(!i
->literal_string
.empty());
438 for (string::const_iterator j
= i
->literal_string
.begin();
439 j
!= i
->literal_string
.end(); ++j
)
441 // See also: c_unparser::visit_literal_string and lex_cast_qstring
453 if (i
->flags
& static_cast<unsigned long>(fmt_flag_zeropad
))
456 if (i
->flags
& static_cast<unsigned long>(fmt_flag_plus
))
459 if (i
->flags
& static_cast<unsigned long>(fmt_flag_space
))
462 if (i
->flags
& static_cast<unsigned long>(fmt_flag_left
))
465 if (i
->flags
& static_cast<unsigned long>(fmt_flag_special
))
468 if (i
->widthtype
== width_dynamic
)
470 else if (i
->widthtype
!= width_unspecified
&& i
->width
> 0)
473 if (i
->prectype
== prec_dynamic
)
475 else if (i
->prectype
!= prec_unspecified
&& i
->precision
> 0)
476 oss
<< '.' << i
->precision
;
488 case conv_signed_decimal
:
492 case conv_unsigned_decimal
:
496 case conv_unsigned_octal
:
500 case conv_unsigned_ptr
:
504 case conv_unsigned_uppercase_hex
:
508 case conv_unsigned_lowercase_hex
:
520 case conv_memory_hex
:
532 vector
<print_format::format_component
>
533 print_format::string_to_components(string
const & str
)
535 format_component curr
;
536 vector
<format_component
> res
;
540 string::const_iterator i
= str
.begin();
542 while (i
!= str
.end())
546 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
547 curr
.type
= conv_literal
;
548 curr
.literal_string
+= *i
;
552 else if (i
+1 == str
.end() || *(i
+1) == '%')
555 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
556 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
557 curr
.type
= conv_literal
;
558 curr
.literal_string
+= '%';
565 if (curr
.type
!= conv_unspecified
)
567 // Flush any component we were previously accumulating
568 assert (curr
.type
== conv_literal
);
578 // Now we are definitely parsing a conversion.
579 // Begin by parsing flags (which are optional).
584 curr
.flags
|= static_cast<unsigned long>(fmt_flag_zeropad
);
589 curr
.flags
|= static_cast<unsigned long>(fmt_flag_plus
);
594 curr
.flags
|= static_cast<unsigned long>(fmt_flag_left
);
599 curr
.flags
|= static_cast<unsigned long>(fmt_flag_space
);
604 curr
.flags
|= static_cast<unsigned long>(fmt_flag_special
);
615 // Parse optional width
618 curr
.widthtype
= width_dynamic
;
621 else if (isdigit(*i
))
623 curr
.widthtype
= width_static
;
628 curr
.width
+= (*i
- '0');
631 while (i
!= str
.end() && isdigit(*i
));
637 // Parse optional precision
645 curr
.prectype
= prec_dynamic
;
648 else if (isdigit(*i
))
650 curr
.prectype
= prec_static
;
654 curr
.precision
*= 10;
655 curr
.precision
+= (*i
- '0');
658 while (i
!= str
.end() && isdigit(*i
));
665 // Parse the actual conversion specifier (bcsmdioupxXn)
668 // Valid conversion types
670 curr
.type
= conv_binary
;
674 curr
.type
= conv_char
;
678 curr
.type
= conv_string
;
682 curr
.type
= conv_memory
;
686 curr
.type
= conv_memory_hex
;
691 curr
.type
= conv_signed_decimal
;
695 curr
.type
= conv_unsigned_octal
;
699 curr
.type
= conv_unsigned_decimal
;
703 curr
.type
= conv_unsigned_ptr
;
707 curr
.type
= conv_unsigned_uppercase_hex
;
711 curr
.type
= conv_unsigned_lowercase_hex
;
718 if (curr
.type
== conv_unspecified
)
719 throw parse_error("invalid or missing conversion specifier");
726 // If there's a remaining partly-composed conversion, fail.
727 if (!curr
.is_empty())
729 if (curr
.type
== conv_literal
)
732 throw parse_error("trailing incomplete print format conversion");
739 void print_format::print (ostream
& o
) const
741 o
<< tok
->content
<< "(";
742 if (print_with_format
)
743 o
<< lex_cast_qstring (raw_components
);
744 if (print_with_delim
)
745 o
<< lex_cast_qstring (delimiter
.literal_string
);
748 for (vector
<expression
*>::const_iterator i
= args
.begin();
749 i
!= args
.end(); ++i
)
751 if (i
!= args
.begin() || print_with_format
|| print_with_delim
)
758 void stat_op::print (ostream
& o
) const
788 hist_op::print (ostream
& o
) const
794 assert(params
.size() == 3);
797 for (size_t i
= 0; i
< params
.size(); ++i
)
799 o
<< ", " << params
[i
];
805 assert(params
.size() == 0);
813 ostream
& operator << (ostream
& o
, const statement
& k
)
820 void embeddedcode::print (ostream
&o
) const
827 void block::print (ostream
& o
) const
830 for (unsigned i
=0; i
<statements
.size(); i
++)
831 o
<< *statements
[i
] << endl
;
835 block::block (statement
* car
, statement
* cdr
)
837 statements
.push_back(car
);
838 statements
.push_back(cdr
);
839 this->tok
= car
->tok
;
844 void for_loop::print (ostream
& o
) const
847 if (init
) init
->print (o
);
851 if (incr
) incr
->print (o
);
857 void foreach_loop::print (ostream
& o
) const
860 for (unsigned i
=0; i
<indexes
.size(); i
++)
862 if (i
> 0) o
<< ", ";
863 indexes
[i
]->print (o
);
864 if (sort_direction
!= 0 && sort_column
== i
+1)
865 o
<< (sort_direction
> 0 ? "+" : "-");
868 base
->print_indexable (o
);
869 if (sort_direction
!= 0 && sort_column
== 0)
870 o
<< (sort_direction
> 0 ? "+" : "-");
881 void null_statement::print (ostream
& o
) const
887 void expr_statement::print (ostream
& o
) const
893 void return_statement::print (ostream
& o
) const
895 o
<< "return " << *value
;
899 void delete_statement::print (ostream
& o
) const
901 o
<< "delete " << *value
;
904 void next_statement::print (ostream
& o
) const
909 void break_statement::print (ostream
& o
) const
914 void continue_statement::print (ostream
& o
) const
919 void if_statement::print (ostream
& o
) const
921 o
<< "if (" << *condition
<< ") "
922 << *thenblock
<< endl
;
924 o
<< "else " << *elseblock
<< endl
;
928 void stapfile::print (ostream
& o
) const
930 o
<< "# file " << name
<< endl
;
932 for (unsigned i
=0; i
<embeds
.size(); i
++)
933 embeds
[i
]->print (o
);
935 for (unsigned i
=0; i
<globals
.size(); i
++)
938 globals
[i
]->print (o
);
942 for (unsigned i
=0; i
<aliases
.size(); i
++)
944 aliases
[i
]->print (o
);
948 for (unsigned i
=0; i
<probes
.size(); i
++)
950 probes
[i
]->print (o
);
954 for (unsigned j
= 0; j
< functions
.size(); j
++)
956 functions
[j
]->print (o
);
962 void probe::print (ostream
& o
) const
970 void probe::printsig (ostream
& o
) const
972 const probe_alias
*alias
= get_alias ();
979 for (unsigned i
=0; i
<locations
.size(); i
++)
982 locations
[i
]->print (o
);
988 probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
)
990 probes_list
.push_back(this);
994 void probe_point::print (ostream
& o
) const
996 for (unsigned i
=0; i
<components
.size(); i
++)
999 probe_point::component
* c
= components
[i
];
1002 o
<< "(" << *c
->arg
<< ")";
1006 else if (optional
) // sufficient implies optional
1009 o
<< " if (" << *condition
<< ")";
1012 string
probe_point::str ()
1015 for (unsigned i
=0; i
<components
.size(); i
++)
1018 probe_point::component
* c
= components
[i
];
1021 o
<< "(" << *c
->arg
<< ")";
1025 else if (optional
) // sufficient implies optional
1028 o
<< " if (" << *condition
<< ")";
1033 probe_alias::probe_alias(std::vector
<probe_point
*> const & aliases
):
1034 probe (), alias_names (aliases
)
1038 void probe_alias::printsig (ostream
& o
) const
1040 for (unsigned i
=0; i
<alias_names
.size(); i
++)
1042 o
<< (i
>0 ? " = " : "");
1043 alias_names
[i
]->print (o
);
1046 for (unsigned i
=0; i
<locations
.size(); i
++)
1048 if (i
> 0) o
<< ", ";
1049 locations
[i
]->print (o
);
1054 ostream
& operator << (ostream
& o
, const probe_point
& k
)
1061 ostream
& operator << (ostream
& o
, const symboldecl
& k
)
1069 // ------------------------------------------------------------------------
1074 block::visit (visitor
* u
)
1076 u
->visit_block (this);
1081 embeddedcode::visit (visitor
* u
)
1083 u
->visit_embeddedcode (this);
1088 for_loop::visit (visitor
* u
)
1090 u
->visit_for_loop (this);
1094 foreach_loop::visit (visitor
* u
)
1096 u
->visit_foreach_loop (this);
1100 null_statement::visit (visitor
* u
)
1102 u
->visit_null_statement (this);
1106 expr_statement::visit (visitor
* u
)
1108 u
->visit_expr_statement (this);
1112 return_statement::visit (visitor
* u
)
1114 u
->visit_return_statement (this);
1118 delete_statement::visit (visitor
* u
)
1120 u
->push_active_lvalue (this->value
);
1121 u
->visit_delete_statement (this);
1122 u
->pop_active_lvalue ();
1126 if_statement::visit (visitor
* u
)
1128 u
->visit_if_statement (this);
1132 next_statement::visit (visitor
* u
)
1134 u
->visit_next_statement (this);
1138 break_statement::visit (visitor
* u
)
1140 u
->visit_break_statement (this);
1144 continue_statement::visit (visitor
* u
)
1146 u
->visit_continue_statement (this);
1150 literal_string::visit(visitor
* u
)
1152 u
->visit_literal_string (this);
1156 literal_number::visit(visitor
* u
)
1158 u
->visit_literal_number (this);
1162 binary_expression::visit (visitor
* u
)
1164 u
->visit_binary_expression (this);
1168 unary_expression::visit (visitor
* u
)
1170 u
->visit_unary_expression (this);
1174 pre_crement::visit (visitor
* u
)
1176 u
->push_active_lvalue (this->operand
);
1177 u
->visit_pre_crement (this);
1178 u
->pop_active_lvalue ();
1182 post_crement::visit (visitor
* u
)
1184 u
->push_active_lvalue (this->operand
);
1185 u
->visit_post_crement (this);
1186 u
->pop_active_lvalue ();
1190 logical_or_expr::visit (visitor
* u
)
1192 u
->visit_logical_or_expr (this);
1196 logical_and_expr::visit (visitor
* u
)
1198 u
->visit_logical_and_expr (this);
1202 array_in::visit (visitor
* u
)
1204 u
->visit_array_in (this);
1208 comparison::visit (visitor
* u
)
1210 u
->visit_comparison (this);
1214 concatenation::visit (visitor
* u
)
1216 u
->visit_concatenation (this);
1220 ternary_expression::visit (visitor
* u
)
1222 u
->visit_ternary_expression (this);
1226 assignment::visit (visitor
* u
)
1228 u
->push_active_lvalue (this->left
);
1229 u
->visit_assignment (this);
1230 u
->pop_active_lvalue ();
1234 symbol::visit (visitor
* u
)
1236 u
->visit_symbol (this);
1240 target_symbol::visit (visitor
* u
)
1242 u
->visit_target_symbol(this);
1246 cast_op::visit (visitor
* u
)
1248 u
->visit_cast_op(this);
1252 arrayindex::visit (visitor
* u
)
1254 u
->visit_arrayindex (this);
1258 functioncall::visit (visitor
* u
)
1260 u
->visit_functioncall (this);
1264 print_format::visit (visitor
*u
)
1266 u
->visit_print_format (this);
1270 stat_op::visit (visitor
*u
)
1272 u
->visit_stat_op (this);
1276 hist_op::visit (visitor
*u
)
1278 u
->visit_hist_op (this);
1282 indexable::print_indexable (std::ostream
& o
) const
1285 const hist_op
*hist
;
1286 classify_const_indexable(this, sym
, hist
);
1297 indexable::visit_indexable (visitor
* u
)
1301 classify_indexable(this, sym
, hist
);
1313 indexable::is_symbol(symbol
*& sym_out
)
1320 indexable::is_hist_op(hist_op
*& hist_out
)
1327 indexable::is_const_symbol(const symbol
*& sym_out
) const
1334 indexable::is_const_hist_op(const hist_op
*& hist_out
) const
1341 symbol::is_symbol(symbol
*& sym_out
)
1348 symbol::is_const_symbol(const symbol
*& sym_out
) const
1355 symbol::get_tok() const
1361 hist_op::is_hist_op(hist_op
*& hist_out
)
1368 hist_op::is_const_hist_op(const hist_op
*& hist_out
) const
1375 hist_op::get_tok() const
1381 classify_indexable(indexable
* ix
,
1382 symbol
*& array_out
,
1383 hist_op
*& hist_out
)
1387 if (!(ix
->is_symbol (array_out
) || ix
->is_hist_op (hist_out
)))
1388 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1389 if (ix
&& !(hist_out
|| array_out
))
1390 throw semantic_error("Failed to classify indexable", ix
->get_tok());
1394 classify_const_indexable(const indexable
* ix
,
1395 const symbol
*& array_out
,
1396 const hist_op
*& hist_out
)
1400 if (!(ix
->is_const_symbol(array_out
) || ix
->is_const_hist_op(hist_out
)))
1401 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1404 // ------------------------------------------------------------------------
1407 visitor::is_active_lvalue(expression
*e
)
1409 for (unsigned i
= 0; i
< active_lvalues
.size(); ++i
)
1411 if (active_lvalues
[i
] == e
)
1418 visitor::push_active_lvalue(expression
*e
)
1420 active_lvalues
.push_back(e
);
1424 visitor::pop_active_lvalue()
1426 assert(!active_lvalues
.empty());
1427 active_lvalues
.pop_back();
1432 // ------------------------------------------------------------------------
1435 traversing_visitor::visit_block (block
* s
)
1437 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
1438 s
->statements
[i
]->visit (this);
1442 traversing_visitor::visit_embeddedcode (embeddedcode
*)
1447 traversing_visitor::visit_null_statement (null_statement
*)
1452 traversing_visitor::visit_expr_statement (expr_statement
* s
)
1454 s
->value
->visit (this);
1458 traversing_visitor::visit_if_statement (if_statement
* s
)
1460 s
->condition
->visit (this);
1461 s
->thenblock
->visit (this);
1463 s
->elseblock
->visit (this);
1467 traversing_visitor::visit_for_loop (for_loop
* s
)
1469 if (s
->init
) s
->init
->visit (this);
1470 s
->cond
->visit (this);
1471 if (s
->incr
) s
->incr
->visit (this);
1472 s
->block
->visit (this);
1476 traversing_visitor::visit_foreach_loop (foreach_loop
* s
)
1478 symbol
*array
= NULL
;
1479 hist_op
*hist
= NULL
;
1480 classify_indexable (s
->base
, array
, hist
);
1486 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1487 s
->indexes
[i
]->visit (this);
1490 s
->limit
->visit (this);
1492 s
->block
->visit (this);
1496 traversing_visitor::visit_return_statement (return_statement
* s
)
1498 s
->value
->visit (this);
1502 traversing_visitor::visit_delete_statement (delete_statement
* s
)
1504 s
->value
->visit (this);
1508 traversing_visitor::visit_next_statement (next_statement
*)
1513 traversing_visitor::visit_break_statement (break_statement
*)
1518 traversing_visitor::visit_continue_statement (continue_statement
*)
1523 traversing_visitor::visit_literal_string (literal_string
*)
1528 traversing_visitor::visit_literal_number (literal_number
*)
1533 traversing_visitor::visit_binary_expression (binary_expression
* e
)
1535 e
->left
->visit (this);
1536 e
->right
->visit (this);
1540 traversing_visitor::visit_unary_expression (unary_expression
* e
)
1542 e
->operand
->visit (this);
1546 traversing_visitor::visit_pre_crement (pre_crement
* e
)
1548 e
->operand
->visit (this);
1552 traversing_visitor::visit_post_crement (post_crement
* e
)
1554 e
->operand
->visit (this);
1559 traversing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
1561 e
->left
->visit (this);
1562 e
->right
->visit (this);
1566 traversing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
1568 e
->left
->visit (this);
1569 e
->right
->visit (this);
1573 traversing_visitor::visit_array_in (array_in
* e
)
1575 e
->operand
->visit (this);
1579 traversing_visitor::visit_comparison (comparison
* e
)
1581 e
->left
->visit (this);
1582 e
->right
->visit (this);
1586 traversing_visitor::visit_concatenation (concatenation
* e
)
1588 e
->left
->visit (this);
1589 e
->right
->visit (this);
1593 traversing_visitor::visit_ternary_expression (ternary_expression
* e
)
1595 e
->cond
->visit (this);
1596 e
->truevalue
->visit (this);
1597 e
->falsevalue
->visit (this);
1601 traversing_visitor::visit_assignment (assignment
* e
)
1603 e
->left
->visit (this);
1604 e
->right
->visit (this);
1608 traversing_visitor::visit_symbol (symbol
*)
1613 traversing_visitor::visit_target_symbol (target_symbol
*)
1618 traversing_visitor::visit_cast_op (cast_op
* e
)
1620 e
->operand
->visit (this);
1624 traversing_visitor::visit_arrayindex (arrayindex
* e
)
1626 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
1627 e
->indexes
[i
]->visit (this);
1629 symbol
*array
= NULL
;
1630 hist_op
*hist
= NULL
;
1631 classify_indexable(e
->base
, array
, hist
);
1633 return array
->visit(this);
1635 return hist
->visit(this);
1639 traversing_visitor::visit_functioncall (functioncall
* e
)
1641 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1642 e
->args
[i
]->visit (this);
1646 traversing_visitor::visit_print_format (print_format
* e
)
1648 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1649 e
->args
[i
]->visit (this);
1651 e
->hist
->visit(this);
1655 traversing_visitor::visit_stat_op (stat_op
* e
)
1657 e
->stat
->visit (this);
1661 traversing_visitor::visit_hist_op (hist_op
* e
)
1663 e
->stat
->visit (this);
1668 functioncall_traversing_visitor::visit_functioncall (functioncall
* e
)
1670 traversing_visitor::visit_functioncall (e
);
1672 // prevent infinite recursion
1673 if (traversed
.find (e
->referent
) == traversed
.end ())
1675 traversed
.insert (e
->referent
);
1677 functiondecl
* last_current_function
= current_function
;
1678 current_function
= e
->referent
;
1679 e
->referent
->body
->visit (this);
1680 current_function
= last_current_function
;
1686 varuse_collecting_visitor::visit_embeddedcode (embeddedcode
*s
)
1688 assert (current_function
); // only they get embedded code
1690 // Don't allow embedded C functions in unprivileged mode unless
1691 // they are tagged with /* unprivileged */
1692 if (session
.unprivileged
&& s
->code
.find ("/* unprivileged */") == string::npos
)
1693 throw semantic_error ("function may not be used when --unprivileged is specified",
1694 current_function
->tok
);
1696 // We want to elide embedded-C functions when possible. For
1697 // example, each $target variable access is expanded to an
1698 // embedded-C function call. Yet, for safety reasons, we should
1699 // presume that embedded-C functions have intentional side-effects.
1701 // To tell these two types of functions apart, we apply a
1702 // Kludge(tm): we look for a magic string within the function body.
1703 // $target variables as rvalues will have this; lvalues won't.
1704 // Also, explicit side-effect-free tapset functions will have this.
1706 if (s
->code
.find ("/* pure */") != string::npos
)
1709 embedded_seen
= true;
1713 varuse_collecting_visitor::visit_target_symbol (target_symbol
*e
)
1715 // Still-unresolved target symbol assignments get treated as
1716 // generating side-effects like embedded-C, to prevent premature
1717 // elision and later error message suppression (PR5516). rvalue use
1718 // of unresolved target symbols is OTOH not considered a side-effect.
1720 if (is_active_lvalue (e
))
1721 embedded_seen
= true;
1725 varuse_collecting_visitor::visit_cast_op (cast_op
*e
)
1727 // As with target_symbols, unresolved cast assignments need to preserved
1728 // for later error handling.
1729 if (is_active_lvalue (e
))
1730 embedded_seen
= true;
1732 functioncall_traversing_visitor::visit_cast_op (e
);
1736 varuse_collecting_visitor::visit_print_format (print_format
* e
)
1738 // NB: Instead of being top-level statements, "print" and "printf"
1739 // are implemented as statement-expressions containing a
1740 // print_format. They have side-effects, but not via the
1741 // embedded-code detection method above.
1743 // But sprint and sprintf don't have side-effects.
1745 if (e
->print_to_stream
)
1746 embedded_seen
= true; // a proxy for "has unknown side-effects"
1748 functioncall_traversing_visitor::visit_print_format (e
);
1753 varuse_collecting_visitor::visit_assignment (assignment
*e
)
1755 if (e
->op
== "=" || e
->op
== "<<<") // pure writes
1757 expression
* last_lvalue
= current_lvalue
;
1758 current_lvalue
= e
->left
; // leave a mark for ::visit_symbol
1759 functioncall_traversing_visitor::visit_assignment (e
);
1760 current_lvalue
= last_lvalue
;
1762 else // read-modify-writes
1764 expression
* last_lrvalue
= current_lrvalue
;
1765 current_lrvalue
= e
->left
; // leave a mark for ::visit_symbol
1766 functioncall_traversing_visitor::visit_assignment (e
);
1767 current_lrvalue
= last_lrvalue
;
1772 varuse_collecting_visitor::visit_symbol (symbol
*e
)
1774 if (e
->referent
== 0)
1775 throw semantic_error ("symbol without referent", e
->tok
);
1777 // We could handle initialized globals by marking them as "written".
1778 // However, this current visitor may be called for a function or
1779 // probe body, from the point of view of which this global is
1780 // already initialized, so not written.
1782 if (e->referent->init)
1783 written.insert (e->referent);
1786 if (current_lvalue
== e
|| current_lrvalue
== e
)
1788 written
.insert (e
->referent
);
1789 // clog << "write ";
1791 if (current_lvalue
!= e
|| current_lrvalue
== e
)
1793 read
.insert (e
->referent
);
1796 // clog << *e->tok << endl;
1799 // NB: stat_op need not be overridden, since it will get to
1800 // visit_symbol and only as a possible rvalue.
1804 varuse_collecting_visitor::visit_arrayindex (arrayindex
*e
)
1806 // Hooking this callback is necessary because of the hacky
1807 // statistics representation. For the expression "i[4] = 5", the
1808 // incoming lvalue will point to this arrayindex. However, the
1809 // symbol corresponding to the "i[4]" is multiply inherited with
1810 // arrayindex. If the symbol base part of this object is not at
1811 // offset 0, then static_cast<symbol*>(e) may result in a different
1812 // address, and not match lvalue by number when we recurse that way.
1813 // So we explicitly override the incoming lvalue/lrvalue values to
1814 // point at the embedded objects' actual base addresses.
1816 expression
* last_lrvalue
= current_lrvalue
;
1817 expression
* last_lvalue
= current_lvalue
;
1819 symbol
*array
= NULL
;
1820 hist_op
*hist
= NULL
;
1821 classify_indexable(e
->base
, array
, hist
);
1825 if (current_lrvalue
== e
) current_lrvalue
= array
;
1826 if (current_lvalue
== e
) current_lvalue
= array
;
1827 functioncall_traversing_visitor::visit_arrayindex (e
);
1831 if (current_lrvalue
== e
) current_lrvalue
= hist
->stat
;
1832 if (current_lvalue
== e
) current_lvalue
= hist
->stat
;
1833 functioncall_traversing_visitor::visit_arrayindex (e
);
1836 current_lrvalue
= last_lrvalue
;
1837 current_lvalue
= last_lvalue
;
1842 varuse_collecting_visitor::visit_pre_crement (pre_crement
*e
)
1844 expression
* last_lrvalue
= current_lrvalue
;
1845 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1846 functioncall_traversing_visitor::visit_pre_crement (e
);
1847 current_lrvalue
= last_lrvalue
;
1851 varuse_collecting_visitor::visit_post_crement (post_crement
*e
)
1853 expression
* last_lrvalue
= current_lrvalue
;
1854 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1855 functioncall_traversing_visitor::visit_post_crement (e
);
1856 current_lrvalue
= last_lrvalue
;
1860 varuse_collecting_visitor::visit_foreach_loop (foreach_loop
* s
)
1862 // NB: we duplicate so don't bother call
1863 // functioncall_traversing_visitor::visit_foreach_loop (s);
1865 symbol
*array
= NULL
;
1866 hist_op
*hist
= NULL
;
1867 classify_indexable (s
->base
, array
, hist
);
1873 // If the collection is sorted, imply a "write" access to the
1874 // array in addition to the "read" one already noted above.
1875 if (s
->sort_direction
)
1877 symbol
*array
= NULL
;
1878 hist_op
*hist
= NULL
;
1879 classify_indexable (s
->base
, array
, hist
);
1880 if (array
) this->written
.insert (array
->referent
);
1881 // XXX: Can hist_op iterations be sorted?
1884 // NB: don't forget to visit the index expressions, which are lvalues.
1885 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1887 expression
* last_lvalue
= current_lvalue
;
1888 current_lvalue
= s
->indexes
[i
]; // leave a mark for ::visit_symbol
1889 s
->indexes
[i
]->visit (this);
1890 current_lvalue
= last_lvalue
;
1894 s
->limit
->visit (this);
1896 s
->block
->visit (this);
1901 varuse_collecting_visitor::visit_delete_statement (delete_statement
* s
)
1903 // Ideally, this would be treated like an assignment: a plain write
1904 // to the underlying value ("lvalue"). XXX: However, the
1905 // optimization pass is not smart enough to remove an unneeded
1906 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
1907 // should protect the underlying value from optimizional mischief.
1908 expression
* last_lrvalue
= current_lrvalue
;
1909 current_lrvalue
= s
->value
; // leave a mark for ::visit_symbol
1910 functioncall_traversing_visitor::visit_delete_statement (s
);
1911 current_lrvalue
= last_lrvalue
;
1915 varuse_collecting_visitor::side_effect_free ()
1917 return (written
.empty() && !embedded_seen
);
1922 varuse_collecting_visitor::side_effect_free_wrt (const set
<vardecl
*>& vars
)
1924 // A looser notion of side-effect-freeness with respect to a given
1925 // list of variables.
1927 // That's useful because the written list may consist of local
1928 // variables of called functions. But visible side-effects only
1929 // occur if the client's locals, or any globals are written-to.
1931 set
<vardecl
*> intersection
;
1932 insert_iterator
<set
<vardecl
*> > int_it (intersection
, intersection
.begin());
1933 set_intersection (written
.begin(), written
.end(),
1934 vars
.begin(), vars
.end(),
1937 return (intersection
.empty() && !embedded_seen
);
1943 // ------------------------------------------------------------------------
1946 throwing_visitor::throwing_visitor (const std::string
& m
): msg (m
) {}
1947 throwing_visitor::throwing_visitor (): msg ("invalid element") {}
1951 throwing_visitor::throwone (const token
* t
)
1953 throw semantic_error (msg
, t
);
1957 throwing_visitor::visit_block (block
* s
)
1963 throwing_visitor::visit_embeddedcode (embeddedcode
* s
)
1969 throwing_visitor::visit_null_statement (null_statement
* s
)
1975 throwing_visitor::visit_expr_statement (expr_statement
* s
)
1981 throwing_visitor::visit_if_statement (if_statement
* s
)
1987 throwing_visitor::visit_for_loop (for_loop
* s
)
1993 throwing_visitor::visit_foreach_loop (foreach_loop
* s
)
1999 throwing_visitor::visit_return_statement (return_statement
* s
)
2005 throwing_visitor::visit_delete_statement (delete_statement
* s
)
2011 throwing_visitor::visit_next_statement (next_statement
* s
)
2017 throwing_visitor::visit_break_statement (break_statement
* s
)
2023 throwing_visitor::visit_continue_statement (continue_statement
* s
)
2029 throwing_visitor::visit_literal_string (literal_string
* e
)
2035 throwing_visitor::visit_literal_number (literal_number
* e
)
2041 throwing_visitor::visit_binary_expression (binary_expression
* e
)
2047 throwing_visitor::visit_unary_expression (unary_expression
* e
)
2053 throwing_visitor::visit_pre_crement (pre_crement
* e
)
2059 throwing_visitor::visit_post_crement (post_crement
* e
)
2066 throwing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2072 throwing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2078 throwing_visitor::visit_array_in (array_in
* e
)
2084 throwing_visitor::visit_comparison (comparison
* e
)
2090 throwing_visitor::visit_concatenation (concatenation
* e
)
2096 throwing_visitor::visit_ternary_expression (ternary_expression
* e
)
2102 throwing_visitor::visit_assignment (assignment
* e
)
2108 throwing_visitor::visit_symbol (symbol
* e
)
2114 throwing_visitor::visit_target_symbol (target_symbol
* e
)
2120 throwing_visitor::visit_cast_op (cast_op
* e
)
2126 throwing_visitor::visit_arrayindex (arrayindex
* e
)
2132 throwing_visitor::visit_functioncall (functioncall
* e
)
2138 throwing_visitor::visit_print_format (print_format
* e
)
2144 throwing_visitor::visit_stat_op (stat_op
* e
)
2150 throwing_visitor::visit_hist_op (hist_op
* e
)
2156 // ------------------------------------------------------------------------
2160 update_visitor::visit_block (block
* s
)
2162 for (unsigned i
= 0; i
< s
->statements
.size(); ++i
)
2163 s
->statements
[i
] = require (s
->statements
[i
]);
2168 update_visitor::visit_embeddedcode (embeddedcode
* s
)
2174 update_visitor::visit_null_statement (null_statement
* s
)
2180 update_visitor::visit_expr_statement (expr_statement
* s
)
2182 s
->value
= require (s
->value
);
2187 update_visitor::visit_if_statement (if_statement
* s
)
2189 s
->condition
= require (s
->condition
);
2190 s
->thenblock
= require (s
->thenblock
);
2191 s
->elseblock
= require (s
->elseblock
);
2196 update_visitor::visit_for_loop (for_loop
* s
)
2198 s
->init
= require (s
->init
);
2199 s
->cond
= require (s
->cond
);
2200 s
->incr
= require (s
->incr
);
2201 s
->block
= require (s
->block
);
2206 update_visitor::visit_foreach_loop (foreach_loop
* s
)
2208 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
2209 s
->indexes
[i
] = require (s
->indexes
[i
]);
2210 s
->base
= require (s
->base
);
2211 s
->limit
= require (s
->limit
);
2212 s
->block
= require (s
->block
);
2217 update_visitor::visit_return_statement (return_statement
* s
)
2219 s
->value
= require (s
->value
);
2224 update_visitor::visit_delete_statement (delete_statement
* s
)
2226 s
->value
= require (s
->value
);
2231 update_visitor::visit_next_statement (next_statement
* s
)
2237 update_visitor::visit_break_statement (break_statement
* s
)
2243 update_visitor::visit_continue_statement (continue_statement
* s
)
2249 update_visitor::visit_literal_string (literal_string
* e
)
2255 update_visitor::visit_literal_number (literal_number
* e
)
2261 update_visitor::visit_binary_expression (binary_expression
* e
)
2263 e
->left
= require (e
->left
);
2264 e
->right
= require (e
->right
);
2269 update_visitor::visit_unary_expression (unary_expression
* e
)
2271 e
->operand
= require (e
->operand
);
2276 update_visitor::visit_pre_crement (pre_crement
* e
)
2278 e
->operand
= require (e
->operand
);
2283 update_visitor::visit_post_crement (post_crement
* e
)
2285 e
->operand
= require (e
->operand
);
2291 update_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2293 e
->left
= require (e
->left
);
2294 e
->right
= require (e
->right
);
2299 update_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2301 e
->left
= require (e
->left
);
2302 e
->right
= require (e
->right
);
2307 update_visitor::visit_array_in (array_in
* e
)
2309 e
->operand
= require (e
->operand
);
2314 update_visitor::visit_comparison (comparison
* e
)
2316 e
->left
= require (e
->left
);
2317 e
->right
= require (e
->right
);
2322 update_visitor::visit_concatenation (concatenation
* e
)
2324 e
->left
= require (e
->left
);
2325 e
->right
= require (e
->right
);
2330 update_visitor::visit_ternary_expression (ternary_expression
* e
)
2332 e
->cond
= require (e
->cond
);
2333 e
->truevalue
= require (e
->truevalue
);
2334 e
->falsevalue
= require (e
->falsevalue
);
2339 update_visitor::visit_assignment (assignment
* e
)
2341 e
->left
= require (e
->left
);
2342 e
->right
= require (e
->right
);
2347 update_visitor::visit_symbol (symbol
* e
)
2353 update_visitor::visit_target_symbol (target_symbol
* e
)
2359 update_visitor::visit_cast_op (cast_op
* e
)
2361 e
->operand
= require (e
->operand
);
2366 update_visitor::visit_arrayindex (arrayindex
* e
)
2368 e
->base
= require (e
->base
);
2369 for (unsigned i
= 0; i
< e
->indexes
.size(); ++i
)
2370 e
->indexes
[i
] = require (e
->indexes
[i
]);
2375 update_visitor::visit_functioncall (functioncall
* e
)
2377 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2378 e
->args
[i
] = require (e
->args
[i
]);
2383 update_visitor::visit_print_format (print_format
* e
)
2385 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2386 e
->args
[i
] = require (e
->args
[i
]);
2387 e
->hist
= require (e
->hist
);
2392 update_visitor::visit_stat_op (stat_op
* e
)
2394 e
->stat
= require (e
->stat
);
2399 update_visitor::visit_hist_op (hist_op
* e
)
2401 e
->stat
= require (e
->stat
);
2405 template <> indexable
*
2406 update_visitor::require
<indexable
*> (indexable
* src
, bool clearok
)
2408 indexable
*dst
= NULL
;
2411 symbol
*array_src
=NULL
;
2412 hist_op
*hist_src
=NULL
;
2414 classify_indexable(src
, array_src
, hist_src
);
2417 dst
= require (array_src
);
2419 dst
= require (hist_src
);
2420 assert(clearok
|| dst
);
2426 // ------------------------------------------------------------------------
2430 deep_copy_visitor::visit_block (block
* s
)
2432 update_visitor::visit_block(new block(*s
));
2436 deep_copy_visitor::visit_embeddedcode (embeddedcode
* s
)
2438 update_visitor::visit_embeddedcode(new embeddedcode(*s
));
2442 deep_copy_visitor::visit_null_statement (null_statement
* s
)
2444 update_visitor::visit_null_statement(new null_statement(*s
));
2448 deep_copy_visitor::visit_expr_statement (expr_statement
* s
)
2450 update_visitor::visit_expr_statement(new expr_statement(*s
));
2454 deep_copy_visitor::visit_if_statement (if_statement
* s
)
2456 update_visitor::visit_if_statement(new if_statement(*s
));
2460 deep_copy_visitor::visit_for_loop (for_loop
* s
)
2462 update_visitor::visit_for_loop(new for_loop(*s
));
2466 deep_copy_visitor::visit_foreach_loop (foreach_loop
* s
)
2468 update_visitor::visit_foreach_loop(new foreach_loop(*s
));
2472 deep_copy_visitor::visit_return_statement (return_statement
* s
)
2474 update_visitor::visit_return_statement(new return_statement(*s
));
2478 deep_copy_visitor::visit_delete_statement (delete_statement
* s
)
2480 update_visitor::visit_delete_statement(new delete_statement(*s
));
2484 deep_copy_visitor::visit_next_statement (next_statement
* s
)
2486 update_visitor::visit_next_statement(new next_statement(*s
));
2490 deep_copy_visitor::visit_break_statement (break_statement
* s
)
2492 update_visitor::visit_break_statement(new break_statement(*s
));
2496 deep_copy_visitor::visit_continue_statement (continue_statement
* s
)
2498 update_visitor::visit_continue_statement(new continue_statement(*s
));
2502 deep_copy_visitor::visit_literal_string (literal_string
* e
)
2504 update_visitor::visit_literal_string(new literal_string(*e
));
2508 deep_copy_visitor::visit_literal_number (literal_number
* e
)
2510 update_visitor::visit_literal_number(new literal_number(*e
));
2514 deep_copy_visitor::visit_binary_expression (binary_expression
* e
)
2516 update_visitor::visit_binary_expression(new binary_expression(*e
));
2520 deep_copy_visitor::visit_unary_expression (unary_expression
* e
)
2522 update_visitor::visit_unary_expression(new unary_expression(*e
));
2526 deep_copy_visitor::visit_pre_crement (pre_crement
* e
)
2528 update_visitor::visit_pre_crement(new pre_crement(*e
));
2532 deep_copy_visitor::visit_post_crement (post_crement
* e
)
2534 update_visitor::visit_post_crement(new post_crement(*e
));
2539 deep_copy_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2541 update_visitor::visit_logical_or_expr(new logical_or_expr(*e
));
2545 deep_copy_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2547 update_visitor::visit_logical_and_expr(new logical_and_expr(*e
));
2551 deep_copy_visitor::visit_array_in (array_in
* e
)
2553 update_visitor::visit_array_in(new array_in(*e
));
2557 deep_copy_visitor::visit_comparison (comparison
* e
)
2559 update_visitor::visit_comparison(new comparison(*e
));
2563 deep_copy_visitor::visit_concatenation (concatenation
* e
)
2565 update_visitor::visit_concatenation(new concatenation(*e
));
2569 deep_copy_visitor::visit_ternary_expression (ternary_expression
* e
)
2571 update_visitor::visit_ternary_expression(new ternary_expression(*e
));
2575 deep_copy_visitor::visit_assignment (assignment
* e
)
2577 update_visitor::visit_assignment(new assignment(*e
));
2581 deep_copy_visitor::visit_symbol (symbol
* e
)
2583 symbol
* n
= new symbol(*e
);
2584 n
->referent
= NULL
; // don't copy!
2585 update_visitor::visit_symbol(n
);
2589 deep_copy_visitor::visit_target_symbol (target_symbol
* e
)
2591 target_symbol
* n
= new target_symbol(*e
);
2592 n
->referent
= NULL
; // don't copy!
2593 update_visitor::visit_target_symbol(n
);
2597 deep_copy_visitor::visit_cast_op (cast_op
* e
)
2599 update_visitor::visit_cast_op(new cast_op(*e
));
2603 deep_copy_visitor::visit_arrayindex (arrayindex
* e
)
2605 update_visitor::visit_arrayindex(new arrayindex(*e
));
2609 deep_copy_visitor::visit_functioncall (functioncall
* e
)
2611 functioncall
* n
= new functioncall(*e
);
2612 n
->referent
= NULL
; // don't copy!
2613 update_visitor::visit_functioncall(n
);
2617 deep_copy_visitor::visit_print_format (print_format
* e
)
2619 update_visitor::visit_print_format(new print_format(*e
));
2623 deep_copy_visitor::visit_stat_op (stat_op
* e
)
2625 update_visitor::visit_stat_op(new stat_op(*e
));
2629 deep_copy_visitor::visit_hist_op (hist_op
* e
)
2631 update_visitor::visit_hist_op(new hist_op(*e
));
2634 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */