From 4b6455e82679becf3ad12e4f12abb70de1ee271d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 5 Feb 2009 20:02:35 -0800 Subject: 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. --- staptree.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'staptree.h') diff --git a/staptree.h b/staptree.h index 29196828..00809ed0 100644 --- a/staptree.h +++ b/staptree.h @@ -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 T require (T src) { @@ -837,11 +834,7 @@ struct deep_copy_visitor: public visitor targets.push(static_cast(src)); } - template 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* src); +update_visitor::require (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 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 -- cgit