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.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 16f0256a..70746f31 100644 --- a/staptree.h +++ b/staptree.h @@ -229,9 +229,24 @@ struct target_symbol: public symbol comp_struct_member, comp_literal_array_index }; + + struct component + { + const token* tok; + component_type type; + std::string member; // comp_struct_member + int64_t num_index; // comp_literal_array_index + + component(const token* t, const std::string& m): + tok(t), type(comp_struct_member), member(m), num_index(0) {} + component(const token* t, int64_t n): + tok(t), type(comp_literal_array_index), num_index(n) {} + void print (std::ostream& o) const; + }; + bool addressof; std::string base_name; - std::vector > components; + std::vector components; std::string probe_context_var; semantic_error* saved_conversion_error; target_symbol(): addressof(false), saved_conversion_error (0) {} @@ -239,6 +254,8 @@ struct target_symbol: public symbol void visit (visitor* u); }; +std::ostream& operator << (std::ostream& o, const target_symbol::component& c); + struct cast_op: public target_symbol { -- 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.h | 1 + 1 file changed, 1 insertion(+) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 70746f31..9ade2a42 100644 --- a/staptree.h +++ b/staptree.h @@ -252,6 +252,7 @@ struct target_symbol: public symbol target_symbol(): addressof(false), saved_conversion_error (0) {} void print (std::ostream& o) const; void visit (visitor* u); + void assert_no_components(const std::string& tapset); }; std::ostream& operator << (std::ostream& o, const target_symbol::component& c); -- 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.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 9ade2a42..146d0e34 100644 --- a/staptree.h +++ b/staptree.h @@ -58,6 +58,7 @@ std::ostream& operator << (std::ostream& o, const exp_type& e); struct token; struct visitor; +struct update_visitor; struct expression { @@ -227,7 +228,8 @@ struct target_symbol: public symbol enum component_type { comp_struct_member, - comp_literal_array_index + comp_literal_array_index, + comp_expression_array_index, }; struct component @@ -236,11 +238,14 @@ struct target_symbol: public symbol component_type type; std::string member; // comp_struct_member int64_t num_index; // comp_literal_array_index + expression* expr_index; // comp_expression_array_index component(const token* t, const std::string& m): - tok(t), type(comp_struct_member), member(m), num_index(0) {} + tok(t), type(comp_struct_member), member(m) {} component(const token* t, int64_t n): tok(t), type(comp_literal_array_index), num_index(n) {} + component(const token* t, expression* e): + tok(t), type(comp_expression_array_index), expr_index(e) {} void print (std::ostream& o) const; }; @@ -252,6 +257,8 @@ struct target_symbol: public symbol target_symbol(): addressof(false), saved_conversion_error (0) {} void print (std::ostream& o) const; void visit (visitor* u); + void visit_components (visitor* u); + void visit_components (update_visitor* u); void assert_no_components(const std::string& tapset); }; -- 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.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 146d0e34..bc479559 100644 --- a/staptree.h +++ b/staptree.h @@ -855,21 +855,21 @@ struct throwing_visitor: public visitor struct update_visitor: public visitor { - template T require (T src, bool clearok=false) + template T* require (T* src, bool clearok=false) { - T dst = NULL; + T* dst = NULL; if (src != NULL) { src->visit(this); assert(!targets.empty()); - dst = static_cast(targets.top()); + dst = static_cast(targets.top()); targets.pop(); assert(clearok || dst); } return dst; } - template void provide (T src) + template void provide (T* src) { targets.push(static_cast(src)); } @@ -915,7 +915,7 @@ private: }; template <> indexable* -update_visitor::require (indexable* src, bool clearok); +update_visitor::require (indexable* src, bool clearok); // A visitor which performs a deep copy of the root node it's applied // to. NB: It does not copy any of the variable or function @@ -925,7 +925,7 @@ update_visitor::require (indexable* src, bool clearok); struct deep_copy_visitor: public update_visitor { - template static T deep_copy (T e) + template static T* deep_copy (T* e) { deep_copy_visitor v; return v.require (e); -- 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.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index bc479559..c9b2bdce 100644 --- a/staptree.h +++ b/staptree.h @@ -874,6 +874,11 @@ struct update_visitor: public visitor targets.push(static_cast(src)); } + template void replace (T*& src, bool clearok=false) + { + src = require(src, clearok); + } + virtual ~update_visitor() { assert(targets.empty()); } virtual void visit_block (block *s); -- cgit