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)
103 static unsigned last_probeidx
= 0;
104 this->name
= string ("probe_") + lex_cast(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;
191 target_symbol::assert_no_components(const std::string
& tapset
)
193 if (components
.empty())
196 switch (components
[0].type
)
198 case target_symbol::comp_literal_array_index
:
199 case target_symbol::comp_expression_array_index
:
200 throw semantic_error(tapset
+ " variable '" + base_name
+
201 "' may not be used as array",
203 case target_symbol::comp_struct_member
:
204 throw semantic_error(tapset
+ " variable '" + base_name
+
205 "' may not be used as a structure",
208 throw semantic_error ("invalid use of " + tapset
+
209 " variable '" + base_name
+ "'",
215 // ------------------------------------------------------------------------
216 // parse tree printing
218 ostream
& operator << (ostream
& o
, const expression
& k
)
225 void literal_string::print (ostream
& o
) const
228 for (unsigned i
=0; i
<value
.size(); i
++)
229 if (value
[i
] == '"') // or other escapeworthy characters?
237 void literal_number::print (ostream
& o
) const
243 void binary_expression::print (ostream
& o
) const
245 o
<< "(" << *left
<< ") "
247 << " (" << *right
<< ")";
251 void unary_expression::print (ostream
& o
) const
253 o
<< op
<< '(' << *operand
<< ")";
256 void array_in::print (ostream
& o
) const
259 for (unsigned i
=0; i
<operand
->indexes
.size(); i
++)
261 if (i
> 0) o
<< ", ";
262 operand
->indexes
[i
]->print (o
);
265 operand
->base
->print_indexable (o
);
268 void post_crement::print (ostream
& o
) const
270 o
<< '(' << *operand
<< ")" << op
;
274 void ternary_expression::print (ostream
& o
) const
276 o
<< "(" << *cond
<< ")?("
277 << *truevalue
<< "):("
278 << *falsevalue
<< ")";
282 void symbol::print (ostream
& o
) const
288 void target_symbol::component::print (ostream
& o
) const
292 case comp_struct_member
:
295 case comp_literal_array_index
:
296 o
<< '[' << num_index
<< ']';
298 case comp_expression_array_index
:
299 o
<< '[' << *expr_index
<< ']';
305 std::ostream
& operator << (std::ostream
& o
, const target_symbol::component
& c
)
312 void target_symbol::print (ostream
& o
) const
317 for (unsigned i
= 0; i
< components
.size(); ++i
)
322 void cast_op::print (ostream
& o
) const
326 o
<< base_name
<< '(' << *operand
;
327 o
<< ", " << lex_cast_qstring (type
);
328 if (module
.length() > 0)
329 o
<< ", " << lex_cast_qstring (module
);
331 for (unsigned i
= 0; i
< components
.size(); ++i
)
336 void vardecl::print (ostream
& o
) const
340 o
<< "[" << maxsize
<< "]";
341 if (arity
> 0 || index_types
.size() > 0)
351 void vardecl::printsig (ostream
& o
) const
355 o
<< "[" << maxsize
<< "]";
357 if (index_types
.size() > 0)
360 for (unsigned i
=0; i
<index_types
.size(); i
++)
361 o
<< (i
>0 ? ", " : "") << index_types
[i
];
367 void functiondecl::print (ostream
& o
) const
369 o
<< "function " << name
<< " (";
370 for (unsigned i
=0; i
<formal_args
.size(); i
++)
371 o
<< (i
>0 ? ", " : "") << *formal_args
[i
];
377 void functiondecl::printsig (ostream
& o
) const
379 o
<< name
<< ":" << type
<< " (";
380 for (unsigned i
=0; i
<formal_args
.size(); i
++)
381 o
<< (i
>0 ? ", " : "")
384 << formal_args
[i
]->type
;
389 void arrayindex::print (ostream
& o
) const
391 base
->print_indexable (o
);
393 for (unsigned i
=0; i
<indexes
.size(); i
++)
394 o
<< (i
>0 ? ", " : "") << *indexes
[i
];
399 void functioncall::print (ostream
& o
) const
401 o
<< function
<< "(";
402 for (unsigned i
=0; i
<args
.size(); i
++)
403 o
<< (i
>0 ? ", " : "") << *args
[i
];
409 print_format::parse_print(const std::string
&name
,
410 bool &stream
, bool &format
, bool &delim
, bool &newline
, bool &_char
)
412 const char *n
= name
.c_str();
415 format
= delim
= newline
= _char
= false;
417 if (strcmp(n
, "print_char") == 0)
429 if (0 != strncmp(n
, "print", 5))
446 if (*n
== 'l' && *(n
+1) == 'n')
458 print_format::components_to_string(vector
<format_component
> const & components
)
462 for (vector
<format_component
>::const_iterator i
= components
.begin();
463 i
!= components
.end(); ++i
)
466 assert (i
->type
!= conv_unspecified
);
468 if (i
->type
== conv_literal
)
470 assert(!i
->literal_string
.empty());
471 for (string::const_iterator j
= i
->literal_string
.begin();
472 j
!= i
->literal_string
.end(); ++j
)
474 // See also: c_unparser::visit_literal_string and lex_cast_qstring
486 if (i
->flags
& static_cast<unsigned long>(fmt_flag_zeropad
))
489 if (i
->flags
& static_cast<unsigned long>(fmt_flag_plus
))
492 if (i
->flags
& static_cast<unsigned long>(fmt_flag_space
))
495 if (i
->flags
& static_cast<unsigned long>(fmt_flag_left
))
498 if (i
->flags
& static_cast<unsigned long>(fmt_flag_special
))
501 if (i
->widthtype
== width_dynamic
)
503 else if (i
->widthtype
!= width_unspecified
&& i
->width
> 0)
506 if (i
->prectype
== prec_dynamic
)
508 else if (i
->prectype
!= prec_unspecified
&& i
->precision
> 0)
509 oss
<< '.' << i
->precision
;
521 case conv_signed_decimal
:
525 case conv_unsigned_decimal
:
529 case conv_unsigned_octal
:
533 case conv_unsigned_ptr
:
537 case conv_unsigned_uppercase_hex
:
541 case conv_unsigned_lowercase_hex
:
553 case conv_memory_hex
:
565 vector
<print_format::format_component
>
566 print_format::string_to_components(string
const & str
)
568 format_component curr
;
569 vector
<format_component
> res
;
573 string::const_iterator i
= str
.begin();
575 while (i
!= str
.end())
579 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
580 curr
.type
= conv_literal
;
581 curr
.literal_string
+= *i
;
585 else if (i
+1 == str
.end() || *(i
+1) == '%')
588 // *i == '%' and *(i+1) == '%'; append only one '%' to the literal string
589 assert (curr
.type
== conv_unspecified
|| curr
.type
== conv_literal
);
590 curr
.type
= conv_literal
;
591 curr
.literal_string
+= '%';
598 if (curr
.type
!= conv_unspecified
)
600 // Flush any component we were previously accumulating
601 assert (curr
.type
== conv_literal
);
611 // Now we are definitely parsing a conversion.
612 // Begin by parsing flags (which are optional).
617 curr
.flags
|= static_cast<unsigned long>(fmt_flag_zeropad
);
622 curr
.flags
|= static_cast<unsigned long>(fmt_flag_plus
);
627 curr
.flags
|= static_cast<unsigned long>(fmt_flag_left
);
632 curr
.flags
|= static_cast<unsigned long>(fmt_flag_space
);
637 curr
.flags
|= static_cast<unsigned long>(fmt_flag_special
);
648 // Parse optional width
651 curr
.widthtype
= width_dynamic
;
654 else if (isdigit(*i
))
656 curr
.widthtype
= width_static
;
661 curr
.width
+= (*i
- '0');
664 while (i
!= str
.end() && isdigit(*i
));
670 // Parse optional precision
678 curr
.prectype
= prec_dynamic
;
681 else if (isdigit(*i
))
683 curr
.prectype
= prec_static
;
687 curr
.precision
*= 10;
688 curr
.precision
+= (*i
- '0');
691 while (i
!= str
.end() && isdigit(*i
));
698 // Parse the actual conversion specifier (bcsmdioupxXn)
701 // Valid conversion types
703 curr
.type
= conv_binary
;
707 curr
.type
= conv_char
;
711 curr
.type
= conv_string
;
715 curr
.type
= conv_memory
;
719 curr
.type
= conv_memory_hex
;
724 curr
.type
= conv_signed_decimal
;
728 curr
.type
= conv_unsigned_octal
;
732 curr
.type
= conv_unsigned_decimal
;
736 curr
.type
= conv_unsigned_ptr
;
740 curr
.type
= conv_unsigned_uppercase_hex
;
744 curr
.type
= conv_unsigned_lowercase_hex
;
751 if (curr
.type
== conv_unspecified
)
752 throw parse_error("invalid or missing conversion specifier");
759 // If there's a remaining partly-composed conversion, fail.
760 if (!curr
.is_empty())
762 if (curr
.type
== conv_literal
)
765 throw parse_error("trailing incomplete print format conversion");
772 void print_format::print (ostream
& o
) const
774 o
<< tok
->content
<< "(";
775 if (print_with_format
)
776 o
<< lex_cast_qstring (raw_components
);
777 if (print_with_delim
)
778 o
<< lex_cast_qstring (delimiter
.literal_string
);
781 for (vector
<expression
*>::const_iterator i
= args
.begin();
782 i
!= args
.end(); ++i
)
784 if (i
!= args
.begin() || print_with_format
|| print_with_delim
)
791 void stat_op::print (ostream
& o
) const
821 hist_op::print (ostream
& o
) const
827 assert(params
.size() == 3);
830 for (size_t i
= 0; i
< params
.size(); ++i
)
832 o
<< ", " << params
[i
];
838 assert(params
.size() == 0);
846 ostream
& operator << (ostream
& o
, const statement
& k
)
853 void embeddedcode::print (ostream
&o
) const
860 void block::print (ostream
& o
) const
863 for (unsigned i
=0; i
<statements
.size(); i
++)
864 o
<< *statements
[i
] << endl
;
868 block::block (statement
* car
, statement
* cdr
)
870 statements
.push_back(car
);
871 statements
.push_back(cdr
);
872 this->tok
= car
->tok
;
877 void for_loop::print (ostream
& o
) const
880 if (init
) init
->print (o
);
884 if (incr
) incr
->print (o
);
890 void foreach_loop::print (ostream
& o
) const
893 for (unsigned i
=0; i
<indexes
.size(); i
++)
895 if (i
> 0) o
<< ", ";
896 indexes
[i
]->print (o
);
897 if (sort_direction
!= 0 && sort_column
== i
+1)
898 o
<< (sort_direction
> 0 ? "+" : "-");
901 base
->print_indexable (o
);
902 if (sort_direction
!= 0 && sort_column
== 0)
903 o
<< (sort_direction
> 0 ? "+" : "-");
914 void null_statement::print (ostream
& o
) const
920 void expr_statement::print (ostream
& o
) const
926 void return_statement::print (ostream
& o
) const
928 o
<< "return " << *value
;
932 void delete_statement::print (ostream
& o
) const
934 o
<< "delete " << *value
;
937 void next_statement::print (ostream
& o
) const
942 void break_statement::print (ostream
& o
) const
947 void continue_statement::print (ostream
& o
) const
952 void if_statement::print (ostream
& o
) const
954 o
<< "if (" << *condition
<< ") "
955 << *thenblock
<< endl
;
957 o
<< "else " << *elseblock
<< endl
;
961 void stapfile::print (ostream
& o
) const
963 o
<< "# file " << name
<< endl
;
965 for (unsigned i
=0; i
<embeds
.size(); i
++)
966 embeds
[i
]->print (o
);
968 for (unsigned i
=0; i
<globals
.size(); i
++)
971 globals
[i
]->print (o
);
975 for (unsigned i
=0; i
<aliases
.size(); i
++)
977 aliases
[i
]->print (o
);
981 for (unsigned i
=0; i
<probes
.size(); i
++)
983 probes
[i
]->print (o
);
987 for (unsigned j
= 0; j
< functions
.size(); j
++)
989 functions
[j
]->print (o
);
995 void probe::print (ostream
& o
) const
1003 void probe::printsig (ostream
& o
) const
1005 const probe_alias
*alias
= get_alias ();
1008 alias
->printsig (o
);
1012 for (unsigned i
=0; i
<locations
.size(); i
++)
1014 if (i
> 0) o
<< ",";
1015 locations
[i
]->print (o
);
1021 probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
)
1023 probes_list
.push_back(this);
1027 void probe_point::print (ostream
& o
) const
1029 for (unsigned i
=0; i
<components
.size(); i
++)
1032 probe_point::component
* c
= components
[i
];
1035 o
<< "(" << *c
->arg
<< ")";
1039 else if (optional
) // sufficient implies optional
1042 o
<< " if (" << *condition
<< ")";
1045 string
probe_point::str ()
1048 for (unsigned i
=0; i
<components
.size(); i
++)
1051 probe_point::component
* c
= components
[i
];
1054 o
<< "(" << *c
->arg
<< ")";
1058 else if (optional
) // sufficient implies optional
1061 o
<< " if (" << *condition
<< ")";
1066 probe_alias::probe_alias(std::vector
<probe_point
*> const & aliases
):
1067 probe (), alias_names (aliases
)
1071 void probe_alias::printsig (ostream
& o
) const
1073 for (unsigned i
=0; i
<alias_names
.size(); i
++)
1075 o
<< (i
>0 ? " = " : "");
1076 alias_names
[i
]->print (o
);
1079 for (unsigned i
=0; i
<locations
.size(); i
++)
1081 if (i
> 0) o
<< ", ";
1082 locations
[i
]->print (o
);
1087 ostream
& operator << (ostream
& o
, const probe_point
& k
)
1094 ostream
& operator << (ostream
& o
, const symboldecl
& k
)
1102 // ------------------------------------------------------------------------
1107 block::visit (visitor
* u
)
1109 u
->visit_block (this);
1114 embeddedcode::visit (visitor
* u
)
1116 u
->visit_embeddedcode (this);
1121 for_loop::visit (visitor
* u
)
1123 u
->visit_for_loop (this);
1127 foreach_loop::visit (visitor
* u
)
1129 u
->visit_foreach_loop (this);
1133 null_statement::visit (visitor
* u
)
1135 u
->visit_null_statement (this);
1139 expr_statement::visit (visitor
* u
)
1141 u
->visit_expr_statement (this);
1145 return_statement::visit (visitor
* u
)
1147 u
->visit_return_statement (this);
1151 delete_statement::visit (visitor
* u
)
1153 u
->push_active_lvalue (this->value
);
1154 u
->visit_delete_statement (this);
1155 u
->pop_active_lvalue ();
1159 if_statement::visit (visitor
* u
)
1161 u
->visit_if_statement (this);
1165 next_statement::visit (visitor
* u
)
1167 u
->visit_next_statement (this);
1171 break_statement::visit (visitor
* u
)
1173 u
->visit_break_statement (this);
1177 continue_statement::visit (visitor
* u
)
1179 u
->visit_continue_statement (this);
1183 literal_string::visit(visitor
* u
)
1185 u
->visit_literal_string (this);
1189 literal_number::visit(visitor
* u
)
1191 u
->visit_literal_number (this);
1195 binary_expression::visit (visitor
* u
)
1197 u
->visit_binary_expression (this);
1201 unary_expression::visit (visitor
* u
)
1203 u
->visit_unary_expression (this);
1207 pre_crement::visit (visitor
* u
)
1209 u
->push_active_lvalue (this->operand
);
1210 u
->visit_pre_crement (this);
1211 u
->pop_active_lvalue ();
1215 post_crement::visit (visitor
* u
)
1217 u
->push_active_lvalue (this->operand
);
1218 u
->visit_post_crement (this);
1219 u
->pop_active_lvalue ();
1223 logical_or_expr::visit (visitor
* u
)
1225 u
->visit_logical_or_expr (this);
1229 logical_and_expr::visit (visitor
* u
)
1231 u
->visit_logical_and_expr (this);
1235 array_in::visit (visitor
* u
)
1237 u
->visit_array_in (this);
1241 comparison::visit (visitor
* u
)
1243 u
->visit_comparison (this);
1247 concatenation::visit (visitor
* u
)
1249 u
->visit_concatenation (this);
1253 ternary_expression::visit (visitor
* u
)
1255 u
->visit_ternary_expression (this);
1259 assignment::visit (visitor
* u
)
1261 u
->push_active_lvalue (this->left
);
1262 u
->visit_assignment (this);
1263 u
->pop_active_lvalue ();
1267 symbol::visit (visitor
* u
)
1269 u
->visit_symbol (this);
1273 target_symbol::visit (visitor
* u
)
1275 u
->visit_target_symbol(this);
1279 target_symbol::visit_components (visitor
* u
)
1281 for (unsigned i
= 0; i
< components
.size(); ++i
)
1282 if (components
[i
].type
== comp_expression_array_index
)
1283 components
[i
].expr_index
->visit (u
);
1287 target_symbol::visit_components (update_visitor
* u
)
1289 for (unsigned i
= 0; i
< components
.size(); ++i
)
1290 if (components
[i
].type
== comp_expression_array_index
)
1291 u
->replace (components
[i
].expr_index
);
1295 cast_op::visit (visitor
* u
)
1297 u
->visit_cast_op(this);
1301 arrayindex::visit (visitor
* u
)
1303 u
->visit_arrayindex (this);
1307 functioncall::visit (visitor
* u
)
1309 u
->visit_functioncall (this);
1313 print_format::visit (visitor
*u
)
1315 u
->visit_print_format (this);
1319 stat_op::visit (visitor
*u
)
1321 u
->visit_stat_op (this);
1325 hist_op::visit (visitor
*u
)
1327 u
->visit_hist_op (this);
1331 indexable::print_indexable (std::ostream
& o
) const
1334 const hist_op
*hist
;
1335 classify_const_indexable(this, sym
, hist
);
1346 indexable::visit_indexable (visitor
* u
)
1350 classify_indexable(this, sym
, hist
);
1362 indexable::is_symbol(symbol
*& sym_out
)
1369 indexable::is_hist_op(hist_op
*& hist_out
)
1376 indexable::is_const_symbol(const symbol
*& sym_out
) const
1383 indexable::is_const_hist_op(const hist_op
*& hist_out
) const
1390 symbol::is_symbol(symbol
*& sym_out
)
1397 symbol::is_const_symbol(const symbol
*& sym_out
) const
1404 symbol::get_tok() const
1410 hist_op::is_hist_op(hist_op
*& hist_out
)
1417 hist_op::is_const_hist_op(const hist_op
*& hist_out
) const
1424 hist_op::get_tok() const
1430 classify_indexable(indexable
* ix
,
1431 symbol
*& array_out
,
1432 hist_op
*& hist_out
)
1436 if (!(ix
->is_symbol (array_out
) || ix
->is_hist_op (hist_out
)))
1437 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1438 if (ix
&& !(hist_out
|| array_out
))
1439 throw semantic_error("Failed to classify indexable", ix
->get_tok());
1443 classify_const_indexable(const indexable
* ix
,
1444 const symbol
*& array_out
,
1445 const hist_op
*& hist_out
)
1449 if (!(ix
->is_const_symbol(array_out
) || ix
->is_const_hist_op(hist_out
)))
1450 throw semantic_error("Expecting symbol or histogram operator", ix
->get_tok());
1453 // ------------------------------------------------------------------------
1456 visitor::is_active_lvalue(expression
*e
)
1458 for (unsigned i
= 0; i
< active_lvalues
.size(); ++i
)
1460 if (active_lvalues
[i
] == e
)
1467 visitor::push_active_lvalue(expression
*e
)
1469 active_lvalues
.push_back(e
);
1473 visitor::pop_active_lvalue()
1475 assert(!active_lvalues
.empty());
1476 active_lvalues
.pop_back();
1481 // ------------------------------------------------------------------------
1484 traversing_visitor::visit_block (block
* s
)
1486 for (unsigned i
=0; i
<s
->statements
.size(); i
++)
1487 s
->statements
[i
]->visit (this);
1491 traversing_visitor::visit_embeddedcode (embeddedcode
*)
1496 traversing_visitor::visit_null_statement (null_statement
*)
1501 traversing_visitor::visit_expr_statement (expr_statement
* s
)
1503 s
->value
->visit (this);
1507 traversing_visitor::visit_if_statement (if_statement
* s
)
1509 s
->condition
->visit (this);
1510 s
->thenblock
->visit (this);
1512 s
->elseblock
->visit (this);
1516 traversing_visitor::visit_for_loop (for_loop
* s
)
1518 if (s
->init
) s
->init
->visit (this);
1519 s
->cond
->visit (this);
1520 if (s
->incr
) s
->incr
->visit (this);
1521 s
->block
->visit (this);
1525 traversing_visitor::visit_foreach_loop (foreach_loop
* s
)
1527 symbol
*array
= NULL
;
1528 hist_op
*hist
= NULL
;
1529 classify_indexable (s
->base
, array
, hist
);
1535 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1536 s
->indexes
[i
]->visit (this);
1539 s
->limit
->visit (this);
1541 s
->block
->visit (this);
1545 traversing_visitor::visit_return_statement (return_statement
* s
)
1547 s
->value
->visit (this);
1551 traversing_visitor::visit_delete_statement (delete_statement
* s
)
1553 s
->value
->visit (this);
1557 traversing_visitor::visit_next_statement (next_statement
*)
1562 traversing_visitor::visit_break_statement (break_statement
*)
1567 traversing_visitor::visit_continue_statement (continue_statement
*)
1572 traversing_visitor::visit_literal_string (literal_string
*)
1577 traversing_visitor::visit_literal_number (literal_number
*)
1582 traversing_visitor::visit_binary_expression (binary_expression
* e
)
1584 e
->left
->visit (this);
1585 e
->right
->visit (this);
1589 traversing_visitor::visit_unary_expression (unary_expression
* e
)
1591 e
->operand
->visit (this);
1595 traversing_visitor::visit_pre_crement (pre_crement
* e
)
1597 e
->operand
->visit (this);
1601 traversing_visitor::visit_post_crement (post_crement
* e
)
1603 e
->operand
->visit (this);
1608 traversing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
1610 e
->left
->visit (this);
1611 e
->right
->visit (this);
1615 traversing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
1617 e
->left
->visit (this);
1618 e
->right
->visit (this);
1622 traversing_visitor::visit_array_in (array_in
* e
)
1624 e
->operand
->visit (this);
1628 traversing_visitor::visit_comparison (comparison
* e
)
1630 e
->left
->visit (this);
1631 e
->right
->visit (this);
1635 traversing_visitor::visit_concatenation (concatenation
* e
)
1637 e
->left
->visit (this);
1638 e
->right
->visit (this);
1642 traversing_visitor::visit_ternary_expression (ternary_expression
* e
)
1644 e
->cond
->visit (this);
1645 e
->truevalue
->visit (this);
1646 e
->falsevalue
->visit (this);
1650 traversing_visitor::visit_assignment (assignment
* e
)
1652 e
->left
->visit (this);
1653 e
->right
->visit (this);
1657 traversing_visitor::visit_symbol (symbol
*)
1662 traversing_visitor::visit_target_symbol (target_symbol
* e
)
1664 e
->visit_components (this);
1668 traversing_visitor::visit_cast_op (cast_op
* e
)
1670 e
->operand
->visit (this);
1671 e
->visit_components (this);
1675 traversing_visitor::visit_arrayindex (arrayindex
* e
)
1677 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
1678 e
->indexes
[i
]->visit (this);
1680 symbol
*array
= NULL
;
1681 hist_op
*hist
= NULL
;
1682 classify_indexable(e
->base
, array
, hist
);
1684 return array
->visit(this);
1686 return hist
->visit(this);
1690 traversing_visitor::visit_functioncall (functioncall
* e
)
1692 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1693 e
->args
[i
]->visit (this);
1697 traversing_visitor::visit_print_format (print_format
* e
)
1699 for (unsigned i
=0; i
<e
->args
.size(); i
++)
1700 e
->args
[i
]->visit (this);
1702 e
->hist
->visit(this);
1706 traversing_visitor::visit_stat_op (stat_op
* e
)
1708 e
->stat
->visit (this);
1712 traversing_visitor::visit_hist_op (hist_op
* e
)
1714 e
->stat
->visit (this);
1719 functioncall_traversing_visitor::visit_functioncall (functioncall
* e
)
1721 traversing_visitor::visit_functioncall (e
);
1723 // prevent infinite recursion
1724 if (traversed
.find (e
->referent
) == traversed
.end ())
1726 traversed
.insert (e
->referent
);
1728 functiondecl
* last_current_function
= current_function
;
1729 current_function
= e
->referent
;
1730 e
->referent
->body
->visit (this);
1731 current_function
= last_current_function
;
1737 varuse_collecting_visitor::visit_embeddedcode (embeddedcode
*s
)
1739 assert (current_function
); // only they get embedded code
1741 // Don't allow embedded C functions in unprivileged mode unless
1742 // they are tagged with /* unprivileged */
1743 if (session
.unprivileged
&& s
->code
.find ("/* unprivileged */") == string::npos
)
1744 throw semantic_error ("function may not be used when --unprivileged is specified",
1745 current_function
->tok
);
1747 // We want to elide embedded-C functions when possible. For
1748 // example, each $target variable access is expanded to an
1749 // embedded-C function call. Yet, for safety reasons, we should
1750 // presume that embedded-C functions have intentional side-effects.
1752 // To tell these two types of functions apart, we apply a
1753 // Kludge(tm): we look for a magic string within the function body.
1754 // $target variables as rvalues will have this; lvalues won't.
1755 // Also, explicit side-effect-free tapset functions will have this.
1757 if (s
->code
.find ("/* pure */") != string::npos
)
1760 embedded_seen
= true;
1764 varuse_collecting_visitor::visit_target_symbol (target_symbol
*e
)
1766 // Still-unresolved target symbol assignments get treated as
1767 // generating side-effects like embedded-C, to prevent premature
1768 // elision and later error message suppression (PR5516). rvalue use
1769 // of unresolved target symbols is OTOH not considered a side-effect.
1771 if (is_active_lvalue (e
))
1772 embedded_seen
= true;
1774 functioncall_traversing_visitor::visit_target_symbol (e
);
1778 varuse_collecting_visitor::visit_cast_op (cast_op
*e
)
1780 // As with target_symbols, unresolved cast assignments need to preserved
1781 // for later error handling.
1782 if (is_active_lvalue (e
))
1783 embedded_seen
= true;
1785 functioncall_traversing_visitor::visit_cast_op (e
);
1789 varuse_collecting_visitor::visit_print_format (print_format
* e
)
1791 // NB: Instead of being top-level statements, "print" and "printf"
1792 // are implemented as statement-expressions containing a
1793 // print_format. They have side-effects, but not via the
1794 // embedded-code detection method above.
1796 // But sprint and sprintf don't have side-effects.
1798 if (e
->print_to_stream
)
1799 embedded_seen
= true; // a proxy for "has unknown side-effects"
1801 functioncall_traversing_visitor::visit_print_format (e
);
1806 varuse_collecting_visitor::visit_assignment (assignment
*e
)
1808 if (e
->op
== "=" || e
->op
== "<<<") // pure writes
1810 expression
* last_lvalue
= current_lvalue
;
1811 current_lvalue
= e
->left
; // leave a mark for ::visit_symbol
1812 functioncall_traversing_visitor::visit_assignment (e
);
1813 current_lvalue
= last_lvalue
;
1815 else // read-modify-writes
1817 expression
* last_lrvalue
= current_lrvalue
;
1818 current_lrvalue
= e
->left
; // leave a mark for ::visit_symbol
1819 functioncall_traversing_visitor::visit_assignment (e
);
1820 current_lrvalue
= last_lrvalue
;
1825 varuse_collecting_visitor::visit_symbol (symbol
*e
)
1827 if (e
->referent
== 0)
1828 throw semantic_error ("symbol without referent", e
->tok
);
1830 // We could handle initialized globals by marking them as "written".
1831 // However, this current visitor may be called for a function or
1832 // probe body, from the point of view of which this global is
1833 // already initialized, so not written.
1835 if (e->referent->init)
1836 written.insert (e->referent);
1839 if (current_lvalue
== e
|| current_lrvalue
== e
)
1841 written
.insert (e
->referent
);
1842 // clog << "write ";
1844 if (current_lvalue
!= e
|| current_lrvalue
== e
)
1846 read
.insert (e
->referent
);
1849 // clog << *e->tok << endl;
1852 // NB: stat_op need not be overridden, since it will get to
1853 // visit_symbol and only as a possible rvalue.
1857 varuse_collecting_visitor::visit_arrayindex (arrayindex
*e
)
1859 // Hooking this callback is necessary because of the hacky
1860 // statistics representation. For the expression "i[4] = 5", the
1861 // incoming lvalue will point to this arrayindex. However, the
1862 // symbol corresponding to the "i[4]" is multiply inherited with
1863 // arrayindex. If the symbol base part of this object is not at
1864 // offset 0, then static_cast<symbol*>(e) may result in a different
1865 // address, and not match lvalue by number when we recurse that way.
1866 // So we explicitly override the incoming lvalue/lrvalue values to
1867 // point at the embedded objects' actual base addresses.
1869 expression
* last_lrvalue
= current_lrvalue
;
1870 expression
* last_lvalue
= current_lvalue
;
1872 symbol
*array
= NULL
;
1873 hist_op
*hist
= NULL
;
1874 classify_indexable(e
->base
, array
, hist
);
1878 if (current_lrvalue
== e
) current_lrvalue
= array
;
1879 if (current_lvalue
== e
) current_lvalue
= array
;
1880 functioncall_traversing_visitor::visit_arrayindex (e
);
1884 if (current_lrvalue
== e
) current_lrvalue
= hist
->stat
;
1885 if (current_lvalue
== e
) current_lvalue
= hist
->stat
;
1886 functioncall_traversing_visitor::visit_arrayindex (e
);
1889 current_lrvalue
= last_lrvalue
;
1890 current_lvalue
= last_lvalue
;
1895 varuse_collecting_visitor::visit_pre_crement (pre_crement
*e
)
1897 expression
* last_lrvalue
= current_lrvalue
;
1898 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1899 functioncall_traversing_visitor::visit_pre_crement (e
);
1900 current_lrvalue
= last_lrvalue
;
1904 varuse_collecting_visitor::visit_post_crement (post_crement
*e
)
1906 expression
* last_lrvalue
= current_lrvalue
;
1907 current_lrvalue
= e
->operand
; // leave a mark for ::visit_symbol
1908 functioncall_traversing_visitor::visit_post_crement (e
);
1909 current_lrvalue
= last_lrvalue
;
1913 varuse_collecting_visitor::visit_foreach_loop (foreach_loop
* s
)
1915 // NB: we duplicate so don't bother call
1916 // functioncall_traversing_visitor::visit_foreach_loop (s);
1918 symbol
*array
= NULL
;
1919 hist_op
*hist
= NULL
;
1920 classify_indexable (s
->base
, array
, hist
);
1926 // If the collection is sorted, imply a "write" access to the
1927 // array in addition to the "read" one already noted above.
1928 if (s
->sort_direction
)
1930 symbol
*array
= NULL
;
1931 hist_op
*hist
= NULL
;
1932 classify_indexable (s
->base
, array
, hist
);
1933 if (array
) this->written
.insert (array
->referent
);
1934 // XXX: Can hist_op iterations be sorted?
1937 // NB: don't forget to visit the index expressions, which are lvalues.
1938 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
1940 expression
* last_lvalue
= current_lvalue
;
1941 current_lvalue
= s
->indexes
[i
]; // leave a mark for ::visit_symbol
1942 s
->indexes
[i
]->visit (this);
1943 current_lvalue
= last_lvalue
;
1947 s
->limit
->visit (this);
1949 s
->block
->visit (this);
1954 varuse_collecting_visitor::visit_delete_statement (delete_statement
* s
)
1956 // Ideally, this would be treated like an assignment: a plain write
1957 // to the underlying value ("lvalue"). XXX: However, the
1958 // optimization pass is not smart enough to remove an unneeded
1959 // "delete" yet, so we pose more like a *crement ("lrvalue"). This
1960 // should protect the underlying value from optimizional mischief.
1961 expression
* last_lrvalue
= current_lrvalue
;
1962 current_lrvalue
= s
->value
; // leave a mark for ::visit_symbol
1963 functioncall_traversing_visitor::visit_delete_statement (s
);
1964 current_lrvalue
= last_lrvalue
;
1968 varuse_collecting_visitor::side_effect_free ()
1970 return (written
.empty() && !embedded_seen
);
1975 varuse_collecting_visitor::side_effect_free_wrt (const set
<vardecl
*>& vars
)
1977 // A looser notion of side-effect-freeness with respect to a given
1978 // list of variables.
1980 // That's useful because the written list may consist of local
1981 // variables of called functions. But visible side-effects only
1982 // occur if the client's locals, or any globals are written-to.
1984 set
<vardecl
*> intersection
;
1985 insert_iterator
<set
<vardecl
*> > int_it (intersection
, intersection
.begin());
1986 set_intersection (written
.begin(), written
.end(),
1987 vars
.begin(), vars
.end(),
1990 return (intersection
.empty() && !embedded_seen
);
1996 // ------------------------------------------------------------------------
1999 throwing_visitor::throwing_visitor (const std::string
& m
): msg (m
) {}
2000 throwing_visitor::throwing_visitor (): msg ("invalid element") {}
2004 throwing_visitor::throwone (const token
* t
)
2006 throw semantic_error (msg
, t
);
2010 throwing_visitor::visit_block (block
* s
)
2016 throwing_visitor::visit_embeddedcode (embeddedcode
* s
)
2022 throwing_visitor::visit_null_statement (null_statement
* s
)
2028 throwing_visitor::visit_expr_statement (expr_statement
* s
)
2034 throwing_visitor::visit_if_statement (if_statement
* s
)
2040 throwing_visitor::visit_for_loop (for_loop
* s
)
2046 throwing_visitor::visit_foreach_loop (foreach_loop
* s
)
2052 throwing_visitor::visit_return_statement (return_statement
* s
)
2058 throwing_visitor::visit_delete_statement (delete_statement
* s
)
2064 throwing_visitor::visit_next_statement (next_statement
* s
)
2070 throwing_visitor::visit_break_statement (break_statement
* s
)
2076 throwing_visitor::visit_continue_statement (continue_statement
* s
)
2082 throwing_visitor::visit_literal_string (literal_string
* e
)
2088 throwing_visitor::visit_literal_number (literal_number
* e
)
2094 throwing_visitor::visit_binary_expression (binary_expression
* e
)
2100 throwing_visitor::visit_unary_expression (unary_expression
* e
)
2106 throwing_visitor::visit_pre_crement (pre_crement
* e
)
2112 throwing_visitor::visit_post_crement (post_crement
* e
)
2119 throwing_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2125 throwing_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2131 throwing_visitor::visit_array_in (array_in
* e
)
2137 throwing_visitor::visit_comparison (comparison
* e
)
2143 throwing_visitor::visit_concatenation (concatenation
* e
)
2149 throwing_visitor::visit_ternary_expression (ternary_expression
* e
)
2155 throwing_visitor::visit_assignment (assignment
* e
)
2161 throwing_visitor::visit_symbol (symbol
* e
)
2167 throwing_visitor::visit_target_symbol (target_symbol
* e
)
2173 throwing_visitor::visit_cast_op (cast_op
* e
)
2179 throwing_visitor::visit_arrayindex (arrayindex
* e
)
2185 throwing_visitor::visit_functioncall (functioncall
* e
)
2191 throwing_visitor::visit_print_format (print_format
* e
)
2197 throwing_visitor::visit_stat_op (stat_op
* e
)
2203 throwing_visitor::visit_hist_op (hist_op
* e
)
2209 // ------------------------------------------------------------------------
2213 update_visitor::visit_block (block
* s
)
2215 for (unsigned i
= 0; i
< s
->statements
.size(); ++i
)
2216 replace (s
->statements
[i
]);
2221 update_visitor::visit_embeddedcode (embeddedcode
* s
)
2227 update_visitor::visit_null_statement (null_statement
* s
)
2233 update_visitor::visit_expr_statement (expr_statement
* s
)
2240 update_visitor::visit_if_statement (if_statement
* s
)
2242 replace (s
->condition
);
2243 replace (s
->thenblock
);
2244 replace (s
->elseblock
);
2249 update_visitor::visit_for_loop (for_loop
* s
)
2259 update_visitor::visit_foreach_loop (foreach_loop
* s
)
2261 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
2262 replace (s
->indexes
[i
]);
2270 update_visitor::visit_return_statement (return_statement
* s
)
2277 update_visitor::visit_delete_statement (delete_statement
* s
)
2284 update_visitor::visit_next_statement (next_statement
* s
)
2290 update_visitor::visit_break_statement (break_statement
* s
)
2296 update_visitor::visit_continue_statement (continue_statement
* s
)
2302 update_visitor::visit_literal_string (literal_string
* e
)
2308 update_visitor::visit_literal_number (literal_number
* e
)
2314 update_visitor::visit_binary_expression (binary_expression
* e
)
2322 update_visitor::visit_unary_expression (unary_expression
* e
)
2324 replace (e
->operand
);
2329 update_visitor::visit_pre_crement (pre_crement
* e
)
2331 replace (e
->operand
);
2336 update_visitor::visit_post_crement (post_crement
* e
)
2338 replace (e
->operand
);
2344 update_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2352 update_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2360 update_visitor::visit_array_in (array_in
* e
)
2362 replace (e
->operand
);
2367 update_visitor::visit_comparison (comparison
* e
)
2375 update_visitor::visit_concatenation (concatenation
* e
)
2383 update_visitor::visit_ternary_expression (ternary_expression
* e
)
2386 replace (e
->truevalue
);
2387 replace (e
->falsevalue
);
2392 update_visitor::visit_assignment (assignment
* e
)
2400 update_visitor::visit_symbol (symbol
* e
)
2406 update_visitor::visit_target_symbol (target_symbol
* e
)
2408 e
->visit_components (this);
2413 update_visitor::visit_cast_op (cast_op
* e
)
2415 replace (e
->operand
);
2416 e
->visit_components (this);
2421 update_visitor::visit_arrayindex (arrayindex
* e
)
2424 for (unsigned i
= 0; i
< e
->indexes
.size(); ++i
)
2425 replace (e
->indexes
[i
]);
2430 update_visitor::visit_functioncall (functioncall
* e
)
2432 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2433 replace (e
->args
[i
]);
2438 update_visitor::visit_print_format (print_format
* e
)
2440 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
2441 replace (e
->args
[i
]);
2447 update_visitor::visit_stat_op (stat_op
* e
)
2454 update_visitor::visit_hist_op (hist_op
* e
)
2460 template <> indexable
*
2461 update_visitor::require
<indexable
> (indexable
* src
, bool clearok
)
2463 indexable
*dst
= NULL
;
2466 symbol
*array_src
=NULL
;
2467 hist_op
*hist_src
=NULL
;
2469 classify_indexable(src
, array_src
, hist_src
);
2472 dst
= require (array_src
);
2474 dst
= require (hist_src
);
2475 assert(clearok
|| dst
);
2481 // ------------------------------------------------------------------------
2485 deep_copy_visitor::visit_block (block
* s
)
2487 update_visitor::visit_block(new block(*s
));
2491 deep_copy_visitor::visit_embeddedcode (embeddedcode
* s
)
2493 update_visitor::visit_embeddedcode(new embeddedcode(*s
));
2497 deep_copy_visitor::visit_null_statement (null_statement
* s
)
2499 update_visitor::visit_null_statement(new null_statement(*s
));
2503 deep_copy_visitor::visit_expr_statement (expr_statement
* s
)
2505 update_visitor::visit_expr_statement(new expr_statement(*s
));
2509 deep_copy_visitor::visit_if_statement (if_statement
* s
)
2511 update_visitor::visit_if_statement(new if_statement(*s
));
2515 deep_copy_visitor::visit_for_loop (for_loop
* s
)
2517 update_visitor::visit_for_loop(new for_loop(*s
));
2521 deep_copy_visitor::visit_foreach_loop (foreach_loop
* s
)
2523 update_visitor::visit_foreach_loop(new foreach_loop(*s
));
2527 deep_copy_visitor::visit_return_statement (return_statement
* s
)
2529 update_visitor::visit_return_statement(new return_statement(*s
));
2533 deep_copy_visitor::visit_delete_statement (delete_statement
* s
)
2535 update_visitor::visit_delete_statement(new delete_statement(*s
));
2539 deep_copy_visitor::visit_next_statement (next_statement
* s
)
2541 update_visitor::visit_next_statement(new next_statement(*s
));
2545 deep_copy_visitor::visit_break_statement (break_statement
* s
)
2547 update_visitor::visit_break_statement(new break_statement(*s
));
2551 deep_copy_visitor::visit_continue_statement (continue_statement
* s
)
2553 update_visitor::visit_continue_statement(new continue_statement(*s
));
2557 deep_copy_visitor::visit_literal_string (literal_string
* e
)
2559 update_visitor::visit_literal_string(new literal_string(*e
));
2563 deep_copy_visitor::visit_literal_number (literal_number
* e
)
2565 update_visitor::visit_literal_number(new literal_number(*e
));
2569 deep_copy_visitor::visit_binary_expression (binary_expression
* e
)
2571 update_visitor::visit_binary_expression(new binary_expression(*e
));
2575 deep_copy_visitor::visit_unary_expression (unary_expression
* e
)
2577 update_visitor::visit_unary_expression(new unary_expression(*e
));
2581 deep_copy_visitor::visit_pre_crement (pre_crement
* e
)
2583 update_visitor::visit_pre_crement(new pre_crement(*e
));
2587 deep_copy_visitor::visit_post_crement (post_crement
* e
)
2589 update_visitor::visit_post_crement(new post_crement(*e
));
2594 deep_copy_visitor::visit_logical_or_expr (logical_or_expr
* e
)
2596 update_visitor::visit_logical_or_expr(new logical_or_expr(*e
));
2600 deep_copy_visitor::visit_logical_and_expr (logical_and_expr
* e
)
2602 update_visitor::visit_logical_and_expr(new logical_and_expr(*e
));
2606 deep_copy_visitor::visit_array_in (array_in
* e
)
2608 update_visitor::visit_array_in(new array_in(*e
));
2612 deep_copy_visitor::visit_comparison (comparison
* e
)
2614 update_visitor::visit_comparison(new comparison(*e
));
2618 deep_copy_visitor::visit_concatenation (concatenation
* e
)
2620 update_visitor::visit_concatenation(new concatenation(*e
));
2624 deep_copy_visitor::visit_ternary_expression (ternary_expression
* e
)
2626 update_visitor::visit_ternary_expression(new ternary_expression(*e
));
2630 deep_copy_visitor::visit_assignment (assignment
* e
)
2632 update_visitor::visit_assignment(new assignment(*e
));
2636 deep_copy_visitor::visit_symbol (symbol
* e
)
2638 symbol
* n
= new symbol(*e
);
2639 n
->referent
= NULL
; // don't copy!
2640 update_visitor::visit_symbol(n
);
2644 deep_copy_visitor::visit_target_symbol (target_symbol
* e
)
2646 target_symbol
* n
= new target_symbol(*e
);
2647 n
->referent
= NULL
; // don't copy!
2648 update_visitor::visit_target_symbol(n
);
2652 deep_copy_visitor::visit_cast_op (cast_op
* e
)
2654 update_visitor::visit_cast_op(new cast_op(*e
));
2658 deep_copy_visitor::visit_arrayindex (arrayindex
* e
)
2660 update_visitor::visit_arrayindex(new arrayindex(*e
));
2664 deep_copy_visitor::visit_functioncall (functioncall
* e
)
2666 functioncall
* n
= new functioncall(*e
);
2667 n
->referent
= NULL
; // don't copy!
2668 update_visitor::visit_functioncall(n
);
2672 deep_copy_visitor::visit_print_format (print_format
* e
)
2674 update_visitor::visit_print_format(new print_format(*e
));
2678 deep_copy_visitor::visit_stat_op (stat_op
* e
)
2680 update_visitor::visit_stat_op(new stat_op(*e
));
2684 deep_copy_visitor::visit_hist_op (hist_op
* e
)
2686 update_visitor::visit_hist_op(new hist_op(*e
));
2689 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */