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 /parse.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 'parse.cxx')
-rw-r--r-- | parse.cxx | 49 |
1 files changed, 48 insertions, 1 deletions
@@ -2331,7 +2331,54 @@ parser::parse_symbol () bool pf_stream, pf_format, pf_delim, pf_newline, pf_char; - if (name.size() > 0 && name[0] == '@') + if (name == "@cast") + { + // type-punning time + cast_op *cop = new cast_op; + cop->tok = t; + cop->base_name = name; + expect_op("("); + cop->operand = parse_expression (); + expect_op(","); + expect_unknown(tok_string, cop->type); + if (peek_op (",")) + { + next(); + expect_unknown(tok_string, cop->module); + } + expect_op(")"); + while (true) + { + string c; + if (peek_op ("->")) + { + next(); + expect_ident_or_keyword (c); + cop->components.push_back + (make_pair (target_symbol::comp_struct_member, c)); + } + else if (peek_op ("[")) + { + next(); + expect_unknown (tok_number, c); + expect_op ("]"); + cop->components.push_back + (make_pair (target_symbol::comp_literal_array_index, c)); + } + else + break; + } + // if there aren't any dereferences, then the cast is pointless + if (cop->components.empty()) + { + expression *op = cop->operand; + delete cop; + return op; + } + return cop; + } + + else if (name.size() > 0 && name[0] == '@') { stat_op *sop = new stat_op; if (name == "@avg") |