diff options
author | Josh Stone <jistone@redhat.com> | 2009-02-05 20:02:35 -0800 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-02-10 16:49:35 -0800 |
commit | 4b6455e82679becf3ad12e4f12abb70de1ee271d (patch) | |
tree | 41ab74c39b45203c8ce9552674bc409094e0a82a | |
parent | 4ed05b152284d9d4b8545f6e70c57ebdcd993f46 (diff) | |
download | systemtap-steved-4b6455e82679becf3ad12e4f12abb70de1ee271d.tar.gz systemtap-steved-4b6455e82679becf3ad12e4f12abb70de1ee271d.tar.xz systemtap-steved-4b6455e82679becf3ad12e4f12abb70de1ee271d.zip |
Create update_visitor for modifying trees
* staptree.h (update_visitor): A new visitor to make it easier to
rewrite parts of a probe or function without making a full copy.
* staptree.cxx (update_visitor::*): Each child is recursed with a
require() call, and then the parent returns itself with provide().
* staptree.h (deep_copy_visitor): Inherit from update_visitor to get
the recursive descent while updating nodes.
* staptree.cxx (deep_copy_visitor::*): Use the implicit copy
constructors to copy all fields, then defer to update_visitor for the
recursion. Referents are still cleared from the copies of symbols and
function calls.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | staptree.cxx | 498 | ||||
-rw-r--r-- | staptree.h | 65 |
3 files changed, 367 insertions, 209 deletions
@@ -1,5 +1,18 @@ 2009-02-05 Josh Stone <jistone@redhat.com> + * staptree.h (update_visitor): A new visitor to make it easier to + rewrite parts of a probe or function without making a full copy. + * staptree.cxx (update_visitor::*): Each child is recursed with a + require() call, and then the parent returns itself with provide(). + * staptree.h (deep_copy_visitor): Inherit from update_visitor to get + the recursive descent while updating nodes. + * staptree.cxx (deep_copy_visitor::*): Use the implicit copy + constructors to copy all fields, then defer to update_visitor for the + recursion. Referents are still cleared from the copies of symbols and + function calls. + +2009-02-05 Josh Stone <jistone@redhat.com> + * staptree.h (require, provide): Simplify stack operations with less pointer magic, and move to be deep_copy_visitor members. * staptree.h (deep_copy_visitor::deep_copy): Templatize diff --git a/staptree.cxx b/staptree.cxx index 869af80a..2b963bc3 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -2098,361 +2098,465 @@ throwing_visitor::visit_hist_op (hist_op* e) void -deep_copy_visitor::visit_block (block* s) +update_visitor::visit_block (block* s) { - block* n = new block; - n->tok = s->tok; for (unsigned i = 0; i < s->statements.size(); ++i) - n->statements.push_back(require (s->statements[i])); - provide (n); + s->statements[i] = require (s->statements[i]); + provide (s); +} + +void +update_visitor::visit_embeddedcode (embeddedcode* s) +{ + provide (s); +} + +void +update_visitor::visit_null_statement (null_statement* s) +{ + provide (s); +} + +void +update_visitor::visit_expr_statement (expr_statement* s) +{ + s->value = require (s->value); + provide (s); +} + +void +update_visitor::visit_if_statement (if_statement* s) +{ + s->condition = require (s->condition); + s->thenblock = require (s->thenblock); + s->elseblock = require (s->elseblock); + provide (s); +} + +void +update_visitor::visit_for_loop (for_loop* s) +{ + s->init = require (s->init); + s->cond = require (s->cond); + s->incr = require (s->incr); + s->block = require (s->block); + provide (s); +} + +void +update_visitor::visit_foreach_loop (foreach_loop* s) +{ + for (unsigned i = 0; i < s->indexes.size(); ++i) + s->indexes[i] = require (s->indexes[i]); + s->base = require (s->base); + s->limit = require (s->limit); + s->block = require (s->block); + provide (s); +} + +void +update_visitor::visit_return_statement (return_statement* s) +{ + s->value = require (s->value); + provide (s); +} + +void +update_visitor::visit_delete_statement (delete_statement* s) +{ + s->value = require (s->value); + provide (s); +} + +void +update_visitor::visit_next_statement (next_statement* s) +{ + provide (s); +} + +void +update_visitor::visit_break_statement (break_statement* s) +{ + provide (s); +} + +void +update_visitor::visit_continue_statement (continue_statement* s) +{ + provide (s); +} + +void +update_visitor::visit_literal_string (literal_string* e) +{ + provide (e); +} + +void +update_visitor::visit_literal_number (literal_number* e) +{ + provide (e); +} + +void +update_visitor::visit_binary_expression (binary_expression* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_unary_expression (unary_expression* e) +{ + e->operand = require (e->operand); + provide (e); +} + +void +update_visitor::visit_pre_crement (pre_crement* e) +{ + e->operand = require (e->operand); + provide (e); +} + +void +update_visitor::visit_post_crement (post_crement* e) +{ + e->operand = require (e->operand); + provide (e); +} + + +void +update_visitor::visit_logical_or_expr (logical_or_expr* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_logical_and_expr (logical_and_expr* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_array_in (array_in* e) +{ + e->operand = require (e->operand); + provide (e); +} + +void +update_visitor::visit_comparison (comparison* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_concatenation (concatenation* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_ternary_expression (ternary_expression* e) +{ + e->cond = require (e->cond); + e->truevalue = require (e->truevalue); + e->falsevalue = require (e->falsevalue); + provide (e); +} + +void +update_visitor::visit_assignment (assignment* e) +{ + e->left = require (e->left); + e->right = require (e->right); + provide (e); +} + +void +update_visitor::visit_symbol (symbol* e) +{ + provide (e); +} + +void +update_visitor::visit_target_symbol (target_symbol* e) +{ + provide (e); +} + +void +update_visitor::visit_arrayindex (arrayindex* e) +{ + e->base = require (e->base); + for (unsigned i = 0; i < e->indexes.size(); ++i) + e->indexes[i] = require (e->indexes[i]); + provide (e); +} + +void +update_visitor::visit_functioncall (functioncall* e) +{ + for (unsigned i = 0; i < e->args.size(); ++i) + e->args[i] = require (e->args[i]); + provide (e); +} + +void +update_visitor::visit_print_format (print_format* e) +{ + for (unsigned i = 0; i < e->args.size(); ++i) + e->args[i] = require (e->args[i]); + e->hist = require (e->hist); + provide (e); +} + +void +update_visitor::visit_stat_op (stat_op* e) +{ + e->stat = require (e->stat); + provide (e); +} + +void +update_visitor::visit_hist_op (hist_op* e) +{ + e->stat = require (e->stat); + provide (e); +} + +template <> indexable* +update_visitor::require <indexable*> (indexable* src) +{ + indexable *dst = NULL; + if (src != NULL) + { + symbol *array_src=NULL; + hist_op *hist_src=NULL; + + classify_indexable(src, array_src, hist_src); + + if (array_src) + dst = require (array_src); + else + dst = require (hist_src); + assert (dst); + } + return dst; +} + + +// ------------------------------------------------------------------------ + + +void +deep_copy_visitor::visit_block (block* s) +{ + update_visitor::visit_block(new block(*s)); } void deep_copy_visitor::visit_embeddedcode (embeddedcode* s) { - embeddedcode* n = new embeddedcode; - n->tok = s->tok; - n->code = s->code; - provide (n); + update_visitor::visit_embeddedcode(new embeddedcode(*s)); } void deep_copy_visitor::visit_null_statement (null_statement* s) { - null_statement* n = new null_statement; - n->tok = s->tok; - provide (n); + update_visitor::visit_null_statement(new null_statement(*s)); } void deep_copy_visitor::visit_expr_statement (expr_statement* s) { - expr_statement* n = new expr_statement; - n->tok = s->tok; - n->value = require (s->value); - provide (n); + update_visitor::visit_expr_statement(new expr_statement(*s)); } void deep_copy_visitor::visit_if_statement (if_statement* s) { - if_statement* n = new if_statement; - n->tok = s->tok; - n->condition = require (s->condition); - n->thenblock = require (s->thenblock); - n->elseblock = require (s->elseblock); - provide (n); + update_visitor::visit_if_statement(new if_statement(*s)); } void deep_copy_visitor::visit_for_loop (for_loop* s) { - for_loop* n = new for_loop; - n->tok = s->tok; - n->init = require (s->init); - n->cond = require (s->cond); - n->incr = require (s->incr); - n->block = require (s->block); - provide (n); + update_visitor::visit_for_loop(new for_loop(*s)); } void deep_copy_visitor::visit_foreach_loop (foreach_loop* s) { - foreach_loop* n = new foreach_loop; - n->tok = s->tok; - for (unsigned i = 0; i < s->indexes.size(); ++i) - n->indexes.push_back(require (s->indexes[i])); - - n->base = require (s->base); - - n->sort_direction = s->sort_direction; - n->sort_column = s->sort_column; - n->limit = require (s->limit); - - n->block = require (s->block); - provide (n); + update_visitor::visit_foreach_loop(new foreach_loop(*s)); } void deep_copy_visitor::visit_return_statement (return_statement* s) { - return_statement* n = new return_statement; - n->tok = s->tok; - n->value = require (s->value); - provide (n); + update_visitor::visit_return_statement(new return_statement(*s)); } void deep_copy_visitor::visit_delete_statement (delete_statement* s) { - delete_statement* n = new delete_statement; - n->tok = s->tok; - n->value = require (s->value); - provide (n); + update_visitor::visit_delete_statement(new delete_statement(*s)); } void deep_copy_visitor::visit_next_statement (next_statement* s) { - next_statement* n = new next_statement; - n->tok = s->tok; - provide (n); + update_visitor::visit_next_statement(new next_statement(*s)); } void deep_copy_visitor::visit_break_statement (break_statement* s) { - break_statement* n = new break_statement; - n->tok = s->tok; - provide (n); + update_visitor::visit_break_statement(new break_statement(*s)); } void deep_copy_visitor::visit_continue_statement (continue_statement* s) { - continue_statement* n = new continue_statement; - n->tok = s->tok; - provide (n); + update_visitor::visit_continue_statement(new continue_statement(*s)); } void deep_copy_visitor::visit_literal_string (literal_string* e) { - literal_string* n = new literal_string(e->value); - n->tok = e->tok; - provide (n); + update_visitor::visit_literal_string(new literal_string(*e)); } void deep_copy_visitor::visit_literal_number (literal_number* e) { - literal_number* n = new literal_number(e->value); - n->tok = e->tok; - provide (n); + update_visitor::visit_literal_number(new literal_number(*e)); } void deep_copy_visitor::visit_binary_expression (binary_expression* e) { - binary_expression* n = new binary_expression; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_binary_expression(new binary_expression(*e)); } void deep_copy_visitor::visit_unary_expression (unary_expression* e) { - unary_expression* n = new unary_expression; - n->op = e->op; - n->tok = e->tok; - n->operand = require (e->operand); - provide (n); + update_visitor::visit_unary_expression(new unary_expression(*e)); } void deep_copy_visitor::visit_pre_crement (pre_crement* e) { - pre_crement* n = new pre_crement; - n->op = e->op; - n->tok = e->tok; - n->operand = require (e->operand); - provide (n); + update_visitor::visit_pre_crement(new pre_crement(*e)); } void deep_copy_visitor::visit_post_crement (post_crement* e) { - post_crement* n = new post_crement; - n->op = e->op; - n->tok = e->tok; - n->operand = require (e->operand); - provide (n); + update_visitor::visit_post_crement(new post_crement(*e)); } void deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e) { - logical_or_expr* n = new logical_or_expr; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_logical_or_expr(new logical_or_expr(*e)); } void deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e) { - logical_and_expr* n = new logical_and_expr; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_logical_and_expr(new logical_and_expr(*e)); } void deep_copy_visitor::visit_array_in (array_in* e) { - array_in* n = new array_in; - n->tok = e->tok; - n->operand = require (e->operand); - provide (n); + update_visitor::visit_array_in(new array_in(*e)); } void deep_copy_visitor::visit_comparison (comparison* e) { - comparison* n = new comparison; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_comparison(new comparison(*e)); } void deep_copy_visitor::visit_concatenation (concatenation* e) { - concatenation* n = new concatenation; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_concatenation(new concatenation(*e)); } void deep_copy_visitor::visit_ternary_expression (ternary_expression* e) { - ternary_expression* n = new ternary_expression; - n->tok = e->tok; - n->cond = require (e->cond); - n->truevalue = require (e->truevalue); - n->falsevalue = require (e->falsevalue); - provide (n); + update_visitor::visit_ternary_expression(new ternary_expression(*e)); } void deep_copy_visitor::visit_assignment (assignment* e) { - assignment* n = new assignment; - n->op = e->op; - n->tok = e->tok; - n->left = require (e->left); - n->right = require (e->right); - provide (n); + update_visitor::visit_assignment(new assignment(*e)); } void deep_copy_visitor::visit_symbol (symbol* e) { - symbol* n = new symbol; - n->tok = e->tok; - n->name = e->name; - n->referent = NULL; - provide (n); + symbol* n = new symbol(*e); + n->referent = NULL; // don't copy! + update_visitor::visit_symbol(n); } void deep_copy_visitor::visit_target_symbol (target_symbol* e) { - target_symbol* n = new target_symbol; - n->tok = e->tok; - n->base_name = e->base_name; - n->components = e->components; - provide (n); + target_symbol* n = new target_symbol(*e); + n->referent = NULL; // don't copy! + update_visitor::visit_target_symbol(n); } void deep_copy_visitor::visit_arrayindex (arrayindex* e) { - arrayindex* n = new arrayindex; - n->tok = e->tok; - - n->base = require (e->base); - - for (unsigned i = 0; i < e->indexes.size(); ++i) - n->indexes.push_back(require (e->indexes[i])); - provide (n); + update_visitor::visit_arrayindex(new arrayindex(*e)); } void deep_copy_visitor::visit_functioncall (functioncall* e) { - functioncall* n = new functioncall; - n->tok = e->tok; - n->function = e->function; - n->referent = NULL; - for (unsigned i = 0; i < e->args.size(); ++i) - n->args.push_back(require (e->args[i])); - provide (n); + functioncall* n = new functioncall(*e); + n->referent = NULL; // don't copy! + update_visitor::visit_functioncall(n); } void deep_copy_visitor::visit_print_format (print_format* e) { - print_format* n = new print_format; - n->tok = e->tok; - n->print_to_stream = e->print_to_stream; - n->print_with_format = e->print_with_format; - n->print_with_delim = e->print_with_delim; - n->print_with_newline = e->print_with_newline; - n->print_char = e->print_char; - n->raw_components = e->raw_components; - n->components = e->components; - n->delimiter = e->delimiter; - for (unsigned i = 0; i < e->args.size(); ++i) - n->args.push_back(require (e->args[i])); - if (e->hist) - n->hist = require (e->hist); - provide (n); + update_visitor::visit_print_format(new print_format(*e)); } void deep_copy_visitor::visit_stat_op (stat_op* e) { - stat_op* n = new stat_op; - n->tok = e->tok; - n->ctype = e->ctype; - n->stat = require (e->stat); - provide (n); + update_visitor::visit_stat_op(new stat_op(*e)); } void deep_copy_visitor::visit_hist_op (hist_op* e) { - hist_op* n = new hist_op; - n->tok = e->tok; - n->htype = e->htype; - n->params = e->params; - n->stat = require (e->stat); - provide (n); -} - -template <> indexable* -deep_copy_visitor::require <indexable*> (indexable* src) -{ - indexable *dst = NULL; - if (src != NULL) - { - symbol *array_src=NULL; - hist_op *hist_src=NULL; - - classify_indexable(src, array_src, hist_src); - - if (array_src) - dst = require (array_src); - else - dst = require (hist_src); - assert (dst); - } - return dst; + update_visitor::visit_hist_op(new hist_op(*e)); } /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ @@ -810,13 +810,10 @@ struct throwing_visitor: public visitor void visit_hist_op (hist_op* e); }; -// A visitor which performs a deep copy of the root node it's applied -// to. NB: It does not copy any of the variable or function -// declarations; those fields are set to NULL, assuming you want to -// re-infer the declarations in a new context (the one you're copying -// to). +// A visitor similar to a traversing_visitor, but with the ability to rewrite +// parts of the tree through require/provide. -struct deep_copy_visitor: public visitor +struct update_visitor: public visitor { template <typename T> T require (T src) { @@ -837,11 +834,7 @@ struct deep_copy_visitor: public visitor targets.push(static_cast<void*>(src)); } - template <typename T> static T deep_copy (T e) - { - deep_copy_visitor v; - return v.require (e); - } + virtual ~update_visitor() { assert(targets.empty()); } virtual void visit_block (block *s); virtual void visit_embeddedcode (embeddedcode *s); @@ -881,7 +874,55 @@ private: }; template <> indexable* -deep_copy_visitor::require <indexable*> (indexable* src); +update_visitor::require <indexable*> (indexable* src); + +// A visitor which performs a deep copy of the root node it's applied +// to. NB: It does not copy any of the variable or function +// declarations; those fields are set to NULL, assuming you want to +// re-infer the declarations in a new context (the one you're copying +// to). + +struct deep_copy_visitor: public update_visitor +{ + template <typename T> static T deep_copy (T e) + { + deep_copy_visitor v; + return v.require (e); + } + + virtual void visit_block (block *s); + virtual void visit_embeddedcode (embeddedcode *s); + virtual void visit_null_statement (null_statement *s); + virtual void visit_expr_statement (expr_statement *s); + virtual void visit_if_statement (if_statement* s); + virtual void visit_for_loop (for_loop* s); + virtual void visit_foreach_loop (foreach_loop* s); + virtual void visit_return_statement (return_statement* s); + virtual void visit_delete_statement (delete_statement* s); + virtual void visit_next_statement (next_statement* s); + virtual void visit_break_statement (break_statement* s); + virtual void visit_continue_statement (continue_statement* s); + virtual void visit_literal_string (literal_string* e); + virtual void visit_literal_number (literal_number* e); + virtual void visit_binary_expression (binary_expression* e); + virtual void visit_unary_expression (unary_expression* e); + virtual void visit_pre_crement (pre_crement* e); + virtual void visit_post_crement (post_crement* e); + virtual void visit_logical_or_expr (logical_or_expr* e); + virtual void visit_logical_and_expr (logical_and_expr* e); + virtual void visit_array_in (array_in* e); + virtual void visit_comparison (comparison* e); + virtual void visit_concatenation (concatenation* e); + virtual void visit_ternary_expression (ternary_expression* e); + virtual void visit_assignment (assignment* e); + virtual void visit_symbol (symbol* e); + virtual void visit_target_symbol (target_symbol* e); + virtual void visit_arrayindex (arrayindex* e); + virtual void visit_functioncall (functioncall* e); + virtual void visit_print_format (print_format* e); + virtual void visit_stat_op (stat_op* e); + virtual void visit_hist_op (hist_op* e); +}; #endif // STAPTREE_H |