From 9b5af2958a35174a67076c0f27cff0ed5950736d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 11 Feb 2009 14:34:32 -0800 Subject: 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. --- staptree.cxx | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'staptree.cxx') 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; @@ -1219,6 +1241,12 @@ target_symbol::visit (visitor* u) u->visit_target_symbol(this); } +void +cast_op::visit (visitor* u) +{ + u->visit_cast_op(this); +} + void arrayindex::visit (visitor* u) { @@ -1585,6 +1613,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) { @@ -1679,6 +1713,17 @@ varuse_collecting_visitor::visit_target_symbol (target_symbol *e) embedded_seen = true; } +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) { @@ -2063,6 +2108,12 @@ throwing_visitor::visit_target_symbol (target_symbol* e) throwone (e->tok); } +void +throwing_visitor::visit_cast_op (cast_op* e) +{ + throwone (e->tok); +} + void throwing_visitor::visit_arrayindex (arrayindex* e) { @@ -2296,6 +2347,13 @@ update_visitor::visit_target_symbol (target_symbol* e) provide (e); } +void +update_visitor::visit_cast_op (cast_op* e) +{ + e->operand = require (e->operand); + provide (e); +} + void update_visitor::visit_arrayindex (arrayindex* e) { @@ -2527,6 +2585,12 @@ deep_copy_visitor::visit_target_symbol (target_symbol* e) update_visitor::visit_target_symbol(n); } +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) { -- cgit