diff options
author | Josh Stone <jistone@redhat.com> | 2009-02-11 14:34:32 -0800 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-02-18 12:47:25 -0800 |
commit | 9b5af2958a35174a67076c0f27cff0ed5950736d (patch) | |
tree | edd1da26e8e47d033c6ad29fc2e797243b7ba1d0 /staptree.cxx | |
parent | bbc46bf643491173b9086907cf0820b3fd2c1fe3 (diff) | |
download | systemtap-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.cxx | 64 |
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)); |