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 /elaborate.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 'elaborate.cxx')
-rw-r--r-- | elaborate.cxx | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index ba50defb..981fc7c7 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -701,6 +701,11 @@ struct symbol_fetcher e->base->visit_indexable (this); } + void visit_cast_op (cast_op* e) + { + sym = e; + } + void throwone (const token* t) { throw semantic_error ("Expecting symbol or array index expression", t); @@ -2505,6 +2510,7 @@ struct void_statement_reducer: public update_visitor void visit_concatenation (concatenation* e); void visit_functioncall (functioncall* e); void visit_print_format (print_format* e); + void visit_cast_op (cast_op* e); // these are a bit hairy to grok due to the intricacies of indexables and // stats, so I'm chickening out and skipping them... @@ -2772,6 +2778,19 @@ void_statement_reducer::visit_print_format (print_format* e) provide (e); } +void +void_statement_reducer::visit_cast_op (cast_op* e) +{ + // When the result of a cast operation isn't needed, it's just as good to + // evaluate the operand directly + + if (session.verbose>2) + clog << "Eliding unused typecast " << *e->tok << endl; + + relaxed_p = false; + e->operand->visit(this); +} + void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p) { @@ -3399,6 +3418,18 @@ typeresolution_info::visit_target_symbol (target_symbol* e) void +typeresolution_info::visit_cast_op (cast_op* e) +{ + // Like target_symbol, a cast_op shouldn't survive this far + // unless it was not resolved and its value is really needed. + if (e->saved_conversion_error) + throw (* (e->saved_conversion_error)); + else + throw semantic_error("unresolved cast expression", e->tok); +} + + +void typeresolution_info::visit_arrayindex (arrayindex* e) { |