summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-02-18 12:53:08 -0800
committerJosh Stone <jistone@redhat.com>2009-02-18 12:53:08 -0800
commit23ad66b41ded81502948584816390c634f66c5ee (patch)
treedb900ca0141a16152c3bf27395cd4975cad6a1ab /parse.cxx
parent2aa2ccb83142c3bf98ac8ee1558a0ee72dff3a1f (diff)
parent482fe2af17347b472232c5d7c4b26e53606e395e (diff)
downloadsystemtap-steved-23ad66b41ded81502948584816390c634f66c5ee.tar.gz
systemtap-steved-23ad66b41ded81502948584816390c634f66c5ee.tar.xz
systemtap-steved-23ad66b41ded81502948584816390c634f66c5ee.zip
Enable typecasting with @cast
println(@cast(myptr, "task_struct")->pid) println(@cast(myptr, "task_struct", "kernel")->pid) Merge branch 'typecast', bump ChangeLog entries to push date
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx51
1 files changed, 49 insertions, 2 deletions
diff --git a/parse.cxx b/parse.cxx
index 0419dcb9..ac7e652c 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1,5 +1,5 @@
// recursive descent parser for systemtap scripts
-// Copyright (C) 2005-2007 Red Hat Inc.
+// Copyright (C) 2005-2009 Red Hat Inc.
// Copyright (C) 2006 Intel Corporation.
// Copyright (C) 2007 Bull S.A.S
//
@@ -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")