From 8eb285ac4ec3a34b29ebf20fde0e28cc647d940f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 31 Jul 2009 13:29:18 -0700 Subject: Drop a couple of unnecessary std:: qualifiers * staptree.cxx (target_symbol::print): Drop std:: from parameter o. (cast_op::print): Ditto. --- staptree.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index 9e2ca8da..b14a5c44 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -259,7 +259,7 @@ void symbol::print (ostream& o) const } -void target_symbol::print (std::ostream& o) const +void target_symbol::print (ostream& o) const { if (addressof) o << "&"; @@ -279,7 +279,7 @@ void target_symbol::print (std::ostream& o) const } -void cast_op::print (std::ostream& o) const +void cast_op::print (ostream& o) const { if (addressof) o << "&"; -- cgit From c67847a0d05f8c7207513e79378fc8d84563e109 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 31 Jul 2009 17:00:09 -0700 Subject: Make a real type for target_symbol->components Now the dereferences on target_symbol and cast_op are tracked with a struct instead of just a generic pair. The first immediate benefit is that we can track the token for more exact error reporting. * staptree.h (target_symbol): Add a new component type. * staptree.cxx (target_symbol::component::print): New. (operator<<(ostream&, target_symbol::component&): New. (target_symbol::print): Adapt component printing. (cast_op::print): Ditto. * parse.cxx (parser::parse_target_symbol_components): Adapt to the new component construction. * dwflpp.cxx (dwflpp::find_struct_member): take the component as a parameter for a better token in error messages (dwflpp::translate_components): Adapt to the new component type. * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol): Don't overwrite the token in target_symbol saved errors. (tracepoint_var_expanding_visitor::visit_target_symbol_arg): Ditto. --- staptree.cxx | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index b14a5c44..1231f74d 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -259,23 +259,34 @@ void symbol::print (ostream& o) const } +void target_symbol::component::print (ostream& o) const +{ + switch (type) + { + case comp_struct_member: + o << "->" << member; + break; + case comp_literal_array_index: + o << '[' << num_index << ']'; + break; + } +} + + +std::ostream& operator << (std::ostream& o, const target_symbol::component& c) +{ + c.print (o); + return o; +} + + void target_symbol::print (ostream& o) const { if (addressof) o << "&"; o << base_name; for (unsigned i = 0; i < components.size(); ++i) - { - switch (components[i].first) - { - case comp_literal_array_index: - o << '[' << components[i].second << ']'; - break; - case comp_struct_member: - o << "->" << components[i].second; - break; - } - } + o << components[i]; } @@ -289,17 +300,7 @@ void cast_op::print (ostream& o) const o << ", " << lex_cast_qstring (module); o << ')'; for (unsigned i = 0; i < components.size(); ++i) - { - switch (components[i].first) - { - case comp_literal_array_index: - o << '[' << components[i].second << ']'; - break; - case comp_struct_member: - o << "->" << components[i].second; - break; - } - } + o << components[i]; } -- cgit From dc5a09fc9a61c8b33078164b6855dea54a33627c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 31 Jul 2009 17:24:13 -0700 Subject: Unify no-component assertions on target variables There are several tapsets that can't deal with component dereferences on their target variables, and they all check-and-throw in the same way. This refactors the checks into a target_symbol member. * staptree.cxx (target_symbol::assert_no_components): New. * tapsets.cxx (tracepoint_var_expanding_visitor::visit_target_symbol_arg, tracepoint_var_expanding_visitor::visit_target_symbol_context): Use the new assertion function to check for no components. * tapset-mark.cxx (mark_var_expanding_visitor::visit_target_symbol_arg, mark_var_expanding_visitor::visit_target_symbol_context): Ditto. * tapset-perfmon.cxx (perfmon_var_expanding_visitor::visit_target_symbol): Ditto. * tapset-procfs.cxx (procfs_var_expanding_visitor::visit_target_symbol): Ditto. * tapset-utrace.cxx (utrace_var_expanding_visitor::visit_target_symbol_arg, utrace_var_expanding_visitor::visit_target_symbol_context): Ditto. --- staptree.cxx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index 1231f74d..321650eb 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -186,6 +186,30 @@ operator << (ostream& o, const exp_type& e) } +void +target_symbol::assert_no_components(const std::string& tapset) +{ + if (components.empty()) + return; + + switch (components[0].type) + { + case target_symbol::comp_literal_array_index: + throw semantic_error(tapset + " variable '" + base_name + + "' may not be used as array", + components[0].tok); + case target_symbol::comp_struct_member: + throw semantic_error(tapset + " variable '" + base_name + + "' may not be used as a structure", + components[0].tok); + default: + throw semantic_error ("invalid use of " + tapset + + " variable '" + base_name + "'", + components[0].tok); + } +} + + // ------------------------------------------------------------------------ // parse tree printing -- cgit From 6fda2dff51c667a8c73545dd397b844108715310 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 3 Aug 2009 14:45:21 -0700 Subject: PR2049: support arbitrary $target-array indexing Rather than just numeric literals, we can now support arbitrary expressions for the index value. Note that loc2c won't allow this for noncontiguous arrays, as the access methods need to be statically computed, but for contiguous arrays and pointers-as-arrays it works just fine. * staptree.h (target_symbol::component): Add expression_array_index. * staptree.cxx (target_symbol::visit_components): New helper. (target_symbol::assert_no_components): Recognize new array type. (target_symbol::component::print): Print subexpressions. (traversing_visitor::visit_target_symbol, visit_cast_op): Visit the indexing components too. (varuse_collecting_visitor::visit_target_symbol): Ditto. (update_visitor::visit_target_symbol, visit_cast_op): Ditto. * elaborate.cxx (void_statement_reducer::visit_target_symbol): New. (void_statement_reducer::visit_cast_op): Save indexes too. * parse.cxx (parser::parse_target_symbol_components): Parse expressions. * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol): Pass expression-indexes as parameters (indexN) to the dwarf function. (dwarf_cast_expanding_visitor::visit_cast_op): Ditto. (tracepoint_var_expanding_visitor::visit_target_symbol_arg): Ditto. (sdt_var_expanding_visitor::visit_target_symbol): Visit the new @cast. * dwflpp.cxx (dwflpp::translate_components): Use THIS->indexN. * translate.cxx (c_unparser::visit_target_symbol): Correct error msg. * testsuite/systemtap.base/pointer_array.stp: Use a simple index. --- staptree.cxx | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index 321650eb..50d9980f 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -195,6 +195,7 @@ target_symbol::assert_no_components(const std::string& tapset) switch (components[0].type) { case target_symbol::comp_literal_array_index: + case target_symbol::comp_expression_array_index: throw semantic_error(tapset + " variable '" + base_name + "' may not be used as array", components[0].tok); @@ -293,6 +294,9 @@ void target_symbol::component::print (ostream& o) const case comp_literal_array_index: o << '[' << num_index << ']'; break; + case comp_expression_array_index: + o << '[' << *expr_index << ']'; + break; } } @@ -1270,6 +1274,22 @@ target_symbol::visit (visitor* u) u->visit_target_symbol(this); } +void +target_symbol::visit_components (visitor* u) +{ + for (unsigned i = 0; i < components.size(); ++i) + if (components[i].type == comp_expression_array_index) + components[i].expr_index->visit (u); +} + +void +target_symbol::visit_components (update_visitor* u) +{ + for (unsigned i = 0; i < components.size(); ++i) + if (components[i].type == comp_expression_array_index) + components[i].expr_index = u->require (components[i].expr_index); +} + void cast_op::visit (visitor* u) { @@ -1638,14 +1658,16 @@ traversing_visitor::visit_symbol (symbol*) } void -traversing_visitor::visit_target_symbol (target_symbol*) +traversing_visitor::visit_target_symbol (target_symbol* e) { + e->visit_components (this); } void traversing_visitor::visit_cast_op (cast_op* e) { e->operand->visit (this); + e->visit_components (this); } void @@ -1740,6 +1762,8 @@ varuse_collecting_visitor::visit_target_symbol (target_symbol *e) if (is_active_lvalue (e)) embedded_seen = true; + + functioncall_traversing_visitor::visit_target_symbol (e); } void @@ -2373,6 +2397,7 @@ update_visitor::visit_symbol (symbol* e) void update_visitor::visit_target_symbol (target_symbol* e) { + e->visit_components (this); provide (e); } @@ -2380,6 +2405,7 @@ void update_visitor::visit_cast_op (cast_op* e) { e->operand = require (e->operand); + e->visit_components (this); provide (e); } -- cgit From 3a4235b9897b75a188753419a29f0616c1686249 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 3 Aug 2009 15:20:19 -0700 Subject: Strengthen the template types in update_visitor * staptree.h (update_visitor::require, provide): Make the parameters and return values a T*, to make it explicit that we want pointer types. --- staptree.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index 50d9980f..11661442 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -2450,7 +2450,7 @@ update_visitor::visit_hist_op (hist_op* e) } template <> indexable* -update_visitor::require (indexable* src, bool clearok) +update_visitor::require (indexable* src, bool clearok) { indexable *dst = NULL; if (src != NULL) -- cgit From 8b095b454b34e88c04592be6c651153f802eced6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 3 Aug 2009 15:49:40 -0700 Subject: Add update_visitor::replace I noticed that most uses of update_visitor::require() were simply writing the value back to the same place, i.e. foo = require(foo). The new replace() method just encapsulates that paradigm, so we don't have the duplication between the LHS and RHS. * staptree.h (update_visitor::replace): New. * elaborate.cxx, staptree.cxx, tapset-mark.cxx, tapset-perfmon.cxx, tapset-procfs.cxx, tapset-utrace.cxx, tapsets.cxx: Update all require calls that are simply updating the value in-place. --- staptree.cxx | 86 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) (limited to 'staptree.cxx') diff --git a/staptree.cxx b/staptree.cxx index 11661442..8a589167 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -1287,7 +1287,7 @@ target_symbol::visit_components (update_visitor* u) { for (unsigned i = 0; i < components.size(); ++i) if (components[i].type == comp_expression_array_index) - components[i].expr_index = u->require (components[i].expr_index); + u->replace (components[i].expr_index); } void @@ -2205,7 +2205,7 @@ void update_visitor::visit_block (block* s) { for (unsigned i = 0; i < s->statements.size(); ++i) - s->statements[i] = require (s->statements[i]); + replace (s->statements[i]); provide (s); } @@ -2224,26 +2224,26 @@ update_visitor::visit_null_statement (null_statement* s) void update_visitor::visit_expr_statement (expr_statement* s) { - s->value = require (s->value); + replace (s->value); provide (s); } void update_visitor::visit_if_statement (if_statement* s) { - s->condition = require (s->condition); - s->thenblock = require (s->thenblock); - s->elseblock = require (s->elseblock); + replace (s->condition); + replace (s->thenblock); + replace (s->elseblock); provide (s); } void update_visitor::visit_for_loop (for_loop* s) { - s->init = require (s->init); - s->cond = require (s->cond); - s->incr = require (s->incr); - s->block = require (s->block); + replace (s->init); + replace (s->cond); + replace (s->incr); + replace (s->block); provide (s); } @@ -2251,24 +2251,24 @@ void update_visitor::visit_foreach_loop (foreach_loop* s) { for (unsigned i = 0; i < s->indexes.size(); ++i) - s->indexes[i] = require (s->indexes[i]); - s->base = require (s->base); - s->limit = require (s->limit); - s->block = require (s->block); + replace (s->indexes[i]); + replace (s->base); + replace (s->limit); + replace (s->block); provide (s); } void update_visitor::visit_return_statement (return_statement* s) { - s->value = require (s->value); + replace (s->value); provide (s); } void update_visitor::visit_delete_statement (delete_statement* s) { - s->value = require (s->value); + replace (s->value); provide (s); } @@ -2305,29 +2305,29 @@ update_visitor::visit_literal_number (literal_number* e) void update_visitor::visit_binary_expression (binary_expression* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } void update_visitor::visit_unary_expression (unary_expression* e) { - e->operand = require (e->operand); + replace (e->operand); provide (e); } void update_visitor::visit_pre_crement (pre_crement* e) { - e->operand = require (e->operand); + replace (e->operand); provide (e); } void update_visitor::visit_post_crement (post_crement* e) { - e->operand = require (e->operand); + replace (e->operand); provide (e); } @@ -2335,56 +2335,56 @@ update_visitor::visit_post_crement (post_crement* e) void update_visitor::visit_logical_or_expr (logical_or_expr* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } void update_visitor::visit_logical_and_expr (logical_and_expr* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } void update_visitor::visit_array_in (array_in* e) { - e->operand = require (e->operand); + replace (e->operand); provide (e); } void update_visitor::visit_comparison (comparison* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } void update_visitor::visit_concatenation (concatenation* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } void update_visitor::visit_ternary_expression (ternary_expression* e) { - e->cond = require (e->cond); - e->truevalue = require (e->truevalue); - e->falsevalue = require (e->falsevalue); + replace (e->cond); + replace (e->truevalue); + replace (e->falsevalue); provide (e); } void update_visitor::visit_assignment (assignment* e) { - e->left = require (e->left); - e->right = require (e->right); + replace (e->left); + replace (e->right); provide (e); } @@ -2404,7 +2404,7 @@ update_visitor::visit_target_symbol (target_symbol* e) void update_visitor::visit_cast_op (cast_op* e) { - e->operand = require (e->operand); + replace (e->operand); e->visit_components (this); provide (e); } @@ -2412,9 +2412,9 @@ update_visitor::visit_cast_op (cast_op* e) void update_visitor::visit_arrayindex (arrayindex* e) { - e->base = require (e->base); + replace (e->base); for (unsigned i = 0; i < e->indexes.size(); ++i) - e->indexes[i] = require (e->indexes[i]); + replace (e->indexes[i]); provide (e); } @@ -2422,7 +2422,7 @@ void update_visitor::visit_functioncall (functioncall* e) { for (unsigned i = 0; i < e->args.size(); ++i) - e->args[i] = require (e->args[i]); + replace (e->args[i]); provide (e); } @@ -2430,22 +2430,22 @@ void update_visitor::visit_print_format (print_format* e) { for (unsigned i = 0; i < e->args.size(); ++i) - e->args[i] = require (e->args[i]); - e->hist = require (e->hist); + replace (e->args[i]); + replace (e->hist); provide (e); } void update_visitor::visit_stat_op (stat_op* e) { - e->stat = require (e->stat); + replace (e->stat); provide (e); } void update_visitor::visit_hist_op (hist_op* e) { - e->stat = require (e->stat); + replace (e->stat); provide (e); } -- cgit