diff options
author | David Smith <dsmith@redhat.com> | 2010-02-23 12:48:49 -0600 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2010-02-23 12:48:49 -0600 |
commit | a50de93955fe1272731dccfb3520514a9545f434 (patch) | |
tree | 162aba6d10ab730eb1383c71f2745e00ab7cdad9 /tapsets.cxx | |
parent | d6c273473f7bea4d696c95ca48d55ca26e25ab2f (diff) | |
download | systemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.tar.gz systemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.tar.xz systemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.zip |
PR 10690 (partial fix). Handle '.=' operator in procfs probes.
* tapsets.h (var_expanding_visitor): Add 'valid_ops' and 'op' member
variables.
* tapsets.cxx (var_expanding_visitor::var_expanding_visitor): Set
'valid_ops' to '='. By default, var_expanding_visitor classes only
handle the '=' operator.
(var_expanding_visitor::visit_assignment): Remember what operator we're
handling. When an operator is found that isn't in the 'valid_ops' set,
error.
* tapset-procfs.cxx
(procfs_var_expanding_visitor::procfs_var_expanding_visitor): Add '.='
to the 'valid_ops' set.
(procfs_var_expanding_visitor::visit_target_symbol): Handle the '.='
operator when the target variable is an lvalue.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r-- | tapsets.cxx | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index 9184e288..62191c85 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1859,6 +1859,19 @@ private: unsigned var_expanding_visitor::tick = 0; + +var_expanding_visitor::var_expanding_visitor () +{ + // FIXME: for the time being, by default we only support plain '$foo + // = bar', not '+=' or any other op= variant. This is fixable, but a + // bit ugly. + // + // If derived classes desire to add additional operator support, add + // new operators to this list in the derived class constructor. + valid_ops.insert ("="); +} + + void var_expanding_visitor::visit_assignment (assignment* e) { @@ -1877,6 +1890,9 @@ var_expanding_visitor::visit_assignment (assignment* e) functioncall *fcall = NULL; expression *new_left, *new_right; + // Let visit_target_symbol know what operator it should handle. + op = &e->op; + target_symbol_setter_functioncalls.push (&fcall); new_left = require (e->left); target_symbol_setter_functioncalls.pop (); @@ -1890,12 +1906,20 @@ var_expanding_visitor::visit_assignment (assignment* e) // right child spliced in as sole argument -- in place of // ourselves, in the var expansion we're in the middle of making. - // FIXME: for the time being, we only support plan $foo = bar, - // not += or any other op= variant. This is fixable, but a bit - // ugly. - if (e->op != "=") - throw semantic_error ("Operator-assign expressions on target " - "variables not implemented", e->tok); + if (valid_ops.find (e->op) == valid_ops.end ()) + { + // Build up a list of supported operators. + string ops; + std::set<string>::iterator i; + for (i = valid_ops.begin(); i != valid_ops.end(); i++) + ops += " " + *i + ","; + ops.resize(ops.size() - 1); // chop off the last ',' + + // Throw the error. + throw semantic_error ("Only the following assign operators are" + " implemented on target variables:" + ops, + e->tok); + } assert (new_left == fcall); fcall->args.push_back (new_right); |