summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-07-31 17:00:09 -0700
committerJosh Stone <jistone@redhat.com>2009-07-31 17:08:07 -0700
commitc67847a0d05f8c7207513e79378fc8d84563e109 (patch)
tree799f8f524dab1175e1a2a5ffce03774f7adc4259
parent81931eaba5dcd0727f33328bf4b0ff511b791990 (diff)
downloadsystemtap-steved-c67847a0d05f8c7207513e79378fc8d84563e109.tar.gz
systemtap-steved-c67847a0d05f8c7207513e79378fc8d84563e109.tar.xz
systemtap-steved-c67847a0d05f8c7207513e79378fc8d84563e109.zip
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.
-rw-r--r--dwflpp.cxx64
-rw-r--r--dwflpp.h3
-rw-r--r--parse.cxx17
-rw-r--r--staptree.cxx45
-rw-r--r--staptree.h19
-rw-r--r--tapset-mark.cxx4
-rw-r--r--tapset-perfmon.cxx2
-rw-r--r--tapset-procfs.cxx2
-rw-r--r--tapset-utrace.cxx4
-rw-r--r--tapsets.cxx6
10 files changed, 94 insertions, 72 deletions
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<Dwarf_Attribute>& 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) ?: "<anonymous>")
+ 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<Dwarf_Word>(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<string>(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<string>(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) ?: "<anonymous>"),
- e->tok);
+ c.tok);
*die_mem = *tmpdie;
}
{
vector<Dwarf_Attribute> 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) ?: "<unknown>")
+ 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<string>(c)
+ "' vs. enum type "
+ string(dwarf_diename_integrate (die) ?: "<anonymous type>"),
- 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<string>(c)
+ "' vs. base type "
+ string(dwarf_diename_integrate (die) ?: "<anonymous type>"),
- 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) ?: "<anonymous type>")
+ ": unexpected type tag "
+ lex_cast<string>(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;
diff --git a/dwflpp.h b/dwflpp.h
index 20bcc0d0..3cada4f8 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -333,9 +333,8 @@ private:
struct location **tail,
const target_symbol *e);
- bool find_struct_member(const std::string& member,
+ bool find_struct_member(const target_symbol::component& c,
Dwarf_Die *parentdie,
- const target_symbol *e,
Dwarf_Die *memberdie,
std::vector<Dwarf_Attribute>& locs);
diff --git a/parse.cxx b/parse.cxx
index 29d97589..9d4a06a6 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -2571,21 +2571,20 @@ parser::parse_target_symbol_components (target_symbol* e)
{
while (true)
{
- string c;
if (peek_op ("->"))
{
- next();
- expect_ident_or_keyword (c);
- e->components.push_back
- (make_pair (target_symbol::comp_struct_member, c));
+ const token* t = next();
+ string member;
+ expect_ident_or_keyword (member);
+ e->components.push_back (target_symbol::component(t, member));
}
else if (peek_op ("["))
{
- next();
- expect_unknown (tok_number, c);
+ const token* t = next();
+ int64_t index;
+ expect_number (index);
+ e->components.push_back (target_symbol::component(t, index));
expect_op ("]");
- e->components.push_back
- (make_pair (target_symbol::comp_literal_array_index, c));
}
else
break;
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];
}
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<std::pair<component_type, std::string> > components;
+ std::vector<component> 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
{
diff --git a/tapset-mark.cxx b/tapset-mark.cxx
index a358a20e..fcde9ed5 100644
--- a/tapset-mark.cxx
+++ b/tapset-mark.cxx
@@ -105,7 +105,7 @@ mark_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("marker argument may not be used as array",
@@ -140,7 +140,7 @@ mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("marker '" + sname + "' may not be used as array",
diff --git a/tapset-perfmon.cxx b/tapset-perfmon.cxx
index 0fb567f7..dfdc55e6 100644
--- a/tapset-perfmon.cxx
+++ b/tapset-perfmon.cxx
@@ -69,7 +69,7 @@ perfmon_var_expanding_visitor::visit_target_symbol (target_symbol *e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("perfmon probe '$counter' variable may not be used as array",
diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx
index a996ee32..58bb0f0d 100644
--- a/tapset-procfs.cxx
+++ b/tapset-procfs.cxx
@@ -360,7 +360,7 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("procfs target variable '$value' may not be used as array",
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index a3a4ca3d..3befcbd5 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -457,7 +457,7 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("utrace target variable '$argN' may not be used as array",
@@ -507,7 +507,7 @@ utrace_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
if (e->components.size() > 0)
{
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("utrace target variable '" + sname + "' may not be used as array",
diff --git a/tapsets.cxx b/tapsets.cxx
index bd33fb0b..70edc7d8 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2244,7 +2244,6 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e)
// quietly.
provide (e);
semantic_error* saveme = new semantic_error (er); // copy it
- saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines
// NB: we can have multiple errors, since a $target variable
// may be expanded in several different contexts:
// function ("*") { $var }
@@ -5263,7 +5262,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
// make sure we're not dereferencing base types
if (!e->components.empty() && !arg->isptr)
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("tracepoint variable '" + e->base_name
@@ -5323,7 +5322,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
// up not being referenced after all, so it can be optimized out
// quietly.
semantic_error* saveme = new semantic_error (er); // copy it
- saveme->tok1 = e->tok; // XXX: token not passed to dw code generation routines
// NB: we can have multiple errors, since a target variable
// may be expanded in several different contexts:
// trace ("*") { $foo->bar }
@@ -5396,7 +5394,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
throw semantic_error("write to tracepoint '" + e->base_name + "' not permitted", e->tok);
if (!e->components.empty())
- switch (e->components[0].first)
+ switch (e->components[0].type)
{
case target_symbol::comp_literal_array_index:
throw semantic_error("tracepoint '" + e->base_name + "' may not be used as array",