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. --- dwflpp.cxx | 64 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 28 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index e6e7b471..090aa70a 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1620,9 +1620,8 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) bool -dwflpp::find_struct_member(const string& member, +dwflpp::find_struct_member(const target_symbol::component& c, Dwarf_Die *parentdie, - const target_symbol *e, Dwarf_Die *memberdie, vector& locs) { @@ -1640,7 +1639,7 @@ dwflpp::find_struct_member(const string& member, throw semantic_error (string (dwarf_tag(&die) == DW_TAG_union_type ? "union" : "struct") + string (dwarf_diename_integrate (&die) ?: "") + string (dwarf_errmsg (-1)), - e->tok); + c.tok); } do @@ -1658,10 +1657,10 @@ dwflpp::find_struct_member(const string& member, !dwarf_formref_die (&attr, &subdie)) continue; - if (find_struct_member(member, &subdie, e, memberdie, locs)) + if (find_struct_member(c, &subdie, memberdie, locs)) goto success; } - else if (name == member) + else if (name == c.member) { *memberdie = die; goto success; @@ -1680,9 +1679,9 @@ success: /* Union members don't usually have a location, * but just use the containing union's location. */ else if (dwarf_tag(parentdie) != DW_TAG_union_type) - throw semantic_error ("no location for field '" + member + throw semantic_error ("no location for field '" + c.member + "': " + string(dwarf_errmsg (-1)), - e->tok); + c.tok); return true; } @@ -1709,6 +1708,8 @@ dwflpp::translate_components(struct obstack *pool, while (i < e->components.size()) { + const target_symbol::component& c = e->components[i]; + /* XXX: This would be desirable, but we don't get the target_symbol token, and printing that gives us the file:line number too early anyway. */ #if 0 @@ -1730,39 +1731,45 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_pointer_type: c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); - if (e->components[i].first != target_symbol::comp_literal_array_index) + if (c.type != target_symbol::comp_literal_array_index) break; /* else fall through as an array access */ case DW_TAG_array_type: - if (e->components[i].first == target_symbol::comp_literal_array_index) + if (c.type == target_symbol::comp_literal_array_index) { c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, - NULL, lex_cast(e->components[i].second)); + NULL, c.num_index); ++i; } else - throw semantic_error("bad field '" - + e->components[i].second - + "' for array type", - e->tok); + throw semantic_error ("invalid access '" + + lex_cast(c) + + "' for array type", + c.tok); break; case DW_TAG_structure_type: case DW_TAG_union_type: + if (c.type != target_symbol::comp_struct_member) + throw semantic_error ("invalid access '" + + lex_cast(c) + + "' for struct/union type", + c.tok); + if (dwarf_hasattr(die, DW_AT_declaration)) { Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die)); if (tmpdie == NULL) throw semantic_error ("unresolved struct " + string (dwarf_diename_integrate (die) ?: ""), - e->tok); + c.tok); *die_mem = *tmpdie; } { vector locs; - if (!find_struct_member(e->components[i].second, die, e, die, locs)) + if (!find_struct_member(c, die, die, locs)) { string alternatives; stringstream members; @@ -1770,10 +1777,10 @@ dwflpp::translate_components(struct obstack *pool, if (members.str().size() != 0) alternatives = " (alternatives:" + members.str(); throw semantic_error("unable to find member '" + - e->components[i].second + "' for struct " + c.member + "' for struct " + string(dwarf_diename_integrate(die) ?: "") + alternatives, - e->tok); + c.tok); } for (unsigned j = 0; j < locs.size(); ++j) @@ -1784,39 +1791,40 @@ dwflpp::translate_components(struct obstack *pool, break; case DW_TAG_enumeration_type: - throw semantic_error ("field '" - + e->components[i].second + throw semantic_error ("invalid access '" + + lex_cast(c) + "' vs. enum type " + string(dwarf_diename_integrate (die) ?: ""), - e->tok); + c.tok); break; case DW_TAG_base_type: - throw semantic_error ("field '" - + e->components[i].second + throw semantic_error ("invalid access '" + + lex_cast(c) + "' vs. base type " + string(dwarf_diename_integrate (die) ?: ""), - e->tok); + c.tok); break; case -1: throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)), - e->tok); + c.tok); break; default: throw semantic_error (string(dwarf_diename_integrate (die) ?: "") + ": unexpected type tag " + lex_cast(dwarf_tag (die)), - e->tok); + c.tok); break; } /* Now iterate on the type in DIE's attribute. */ if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL) - throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), e->tok); + throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), + c.tok); } /* For an array index, we need to dereference the final DIE */ - if (e->components.back().first == target_symbol::comp_literal_array_index) + if (e->components.back().type == target_symbol::comp_literal_array_index) die = dwarf_formref_die (attr_mem, die_mem); return die; -- 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. --- dwflpp.cxx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 090aa70a..6ede1d68 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1731,7 +1731,8 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_pointer_type: c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); - if (c.type != target_symbol::comp_literal_array_index) + if (c.type != target_symbol::comp_literal_array_index && + c.type != target_symbol::comp_expression_array_index) break; /* else fall through as an array access */ @@ -1742,6 +1743,13 @@ dwflpp::translate_components(struct obstack *pool, NULL, c.num_index); ++i; } + else if (c.type == target_symbol::comp_expression_array_index) + { + string index = "THIS->index" + lex_cast(i); + c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, + index.c_str(), 0); + ++i; + } else throw semantic_error ("invalid access '" + lex_cast(c) @@ -1824,7 +1832,8 @@ dwflpp::translate_components(struct obstack *pool, } /* For an array index, we need to dereference the final DIE */ - if (e->components.back().type == target_symbol::comp_literal_array_index) + if (e->components.back().type == target_symbol::comp_literal_array_index || + e->components.back().type == target_symbol::comp_expression_array_index) die = dwarf_formref_die (attr_mem, die_mem); return die; -- cgit