summaryrefslogtreecommitdiffstats
path: root/staptree.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-02-11 14:34:32 -0800
committerJosh Stone <jistone@redhat.com>2009-02-18 12:47:25 -0800
commit9b5af2958a35174a67076c0f27cff0ed5950736d (patch)
treeedd1da26e8e47d033c6ad29fc2e797243b7ba1d0 /staptree.cxx
parentbbc46bf643491173b9086907cf0820b3fd2c1fe3 (diff)
downloadsystemtap-steved-9b5af2958a35174a67076c0f27cff0ed5950736d.tar.gz
systemtap-steved-9b5af2958a35174a67076c0f27cff0ed5950736d.tar.xz
systemtap-steved-9b5af2958a35174a67076c0f27cff0ed5950736d.zip
Add high-level support for @cast()ing
This handles all of the parsing, traversal, and optimization. It doesn't actually resolve the cast yet though. * staptree.h (struct cast_op, visitor::visit_cast_op): New. * staptree.cxx (cast_op::print/visit, various visitor::visit_cast_op's): Incorporate cast_op into the basic tree operations. * parse.cxx (parser::parse_symbol): Parse @cast operator with an expression operand, type string, and optional module string. * translate.cxx (c_unparser::visit_cast_op): Error out if a @cast survives to translation. * elaborate.cxx (typeresolution_info::visit_cast_op): Error out if a @cast survives to type resolution. (symbol_fetcher::visit_cast_op): treat @casts as a symbol target (void_statement_reducer::visit_cast_op): unused @casts can be discarded, but the operand should still be evaluated.
Diffstat (limited to 'staptree.cxx')
-rw-r--r--staptree.cxx64
1 files changed, 64 insertions, 0 deletions
diff --git a/staptree.cxx b/staptree.cxx
index 9ffbaf09..d6586d86 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -277,6 +277,28 @@ void target_symbol::print (std::ostream& o) const
}
+void cast_op::print (std::ostream& o) const
+{
+ o << base_name << '(' << *operand;
+ o << ", " << lex_cast_qstring (type);
+ if (module.length() > 0)
+ 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;
+ }
+ }
+}
+
+
void vardecl::print (ostream& o) const
{
o << name;
@@ -1220,6 +1242,12 @@ target_symbol::visit (visitor* u)
}
void
+cast_op::visit (visitor* u)
+{
+ u->visit_cast_op(this);
+}
+
+void
arrayindex::visit (visitor* u)
{
u->visit_arrayindex (this);
@@ -1586,6 +1614,12 @@ traversing_visitor::visit_target_symbol (target_symbol*)
}
void
+traversing_visitor::visit_cast_op (cast_op* e)
+{
+ e->operand->visit (this);
+}
+
+void
traversing_visitor::visit_arrayindex (arrayindex* e)
{
for (unsigned i=0; i<e->indexes.size(); i++)
@@ -1680,6 +1714,17 @@ varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
}
void
+varuse_collecting_visitor::visit_cast_op (cast_op *e)
+{
+ // As with target_symbols, unresolved cast assignments need to preserved
+ // for later error handling.
+ if (is_active_lvalue (e))
+ embedded_seen = true;
+
+ functioncall_traversing_visitor::visit_cast_op (e);
+}
+
+void
varuse_collecting_visitor::visit_print_format (print_format* e)
{
// NB: Instead of being top-level statements, "print" and "printf"
@@ -2064,6 +2109,12 @@ throwing_visitor::visit_target_symbol (target_symbol* e)
}
void
+throwing_visitor::visit_cast_op (cast_op* e)
+{
+ throwone (e->tok);
+}
+
+void
throwing_visitor::visit_arrayindex (arrayindex* e)
{
throwone (e->tok);
@@ -2297,6 +2348,13 @@ update_visitor::visit_target_symbol (target_symbol* e)
}
void
+update_visitor::visit_cast_op (cast_op* e)
+{
+ e->operand = require (e->operand);
+ provide (e);
+}
+
+void
update_visitor::visit_arrayindex (arrayindex* e)
{
e->base = require (e->base);
@@ -2528,6 +2586,12 @@ deep_copy_visitor::visit_target_symbol (target_symbol* e)
}
void
+deep_copy_visitor::visit_cast_op (cast_op* e)
+{
+ update_visitor::visit_cast_op(new cast_op(*e));
+}
+
+void
deep_copy_visitor::visit_arrayindex (arrayindex* e)
{
update_visitor::visit_arrayindex(new arrayindex(*e));