diff options
Diffstat (limited to 'staptree.cxx')
-rw-r--r-- | staptree.cxx | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/staptree.cxx b/staptree.cxx index e64c3710..94c04894 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -979,3 +979,296 @@ throwing_visitor::visit_functioncall (functioncall* e) { throwone (e->tok); } + + +// ------------------------------------------------------------------------ + +template <typename T> static void +require (deep_copy_visitor *v, T *dst, T src) +{ + *dst = NULL; + v->targets.push(static_cast<void *>(dst)); + src->visit(v); + v->targets.pop(); + assert(*dst); +} + +template <typename T> static void +provide (deep_copy_visitor *v, T src) +{ + assert(!v->targets.empty()); + *(static_cast<T*>(v->targets.top())) = src; +} + +void +deep_copy_visitor::visit_block (block *s) +{ + block *n = new block; + for (unsigned i = 0; i < s->statements.size(); ++i) + { + statement *ns; + require <statement*> (this, &ns, s->statements[i]); + n->statements.push_back(ns); + } + provide <block*> (this, n); +} + +void +deep_copy_visitor::visit_null_statement (null_statement *s) +{ + provide <null_statement*> (this, new null_statement); +} + +void +deep_copy_visitor::visit_expr_statement (expr_statement *s) +{ + expr_statement *n = new expr_statement; + require <expression*> (this, &(n->value), s->value); + provide <expr_statement*> (this, n); +} + +void +deep_copy_visitor::visit_if_statement (if_statement* s) +{ + if_statement *n = new if_statement; + require <expression*> (this, &(n->condition), s->condition); + require <statement*> (this, &(n->thenblock), s->thenblock); + require <statement*> (this, &(n->elseblock), s->elseblock); + provide <if_statement*> (this, n); +} + +void +deep_copy_visitor::visit_for_loop (for_loop* s) +{ + for_loop *n = new for_loop; + require <expr_statement*> (this, &(n->init), s->init); + require <expression*> (this, &(n->cond), s->cond); + require <expr_statement*> (this, &(n->incr), s->incr); + require <statement*> (this, &(n->block), s->block); + provide <for_loop*> (this, n); +} + +void +deep_copy_visitor::visit_foreach_loop (foreach_loop* s) +{ + foreach_loop *n = new foreach_loop; + for (unsigned i = 0; i < s->indexes.size(); ++i) + { + symbol *sym; + require <symbol*> (this, &sym, s->indexes[i]); + n->indexes.push_back(sym); + } + n->base = s->base; + n->base_referent = NULL; + require <statement*> (this, &(n->block), s->block); + provide <foreach_loop*> (this, n); +} + +void +deep_copy_visitor::visit_return_statement (return_statement* s) +{ + return_statement *n = new return_statement; + require <expression*> (this, &(n->value), s->value); + provide <return_statement*> (this, n); +} + +void +deep_copy_visitor::visit_delete_statement (delete_statement* s) +{ + delete_statement *n = new delete_statement; + require <expression*> (this, &(n->value), s->value); + provide <delete_statement*> (this, n); +} + +void +deep_copy_visitor::visit_next_statement (next_statement* s) +{ + provide <next_statement*> (this, new next_statement); +} + +void +deep_copy_visitor::visit_break_statement (break_statement* s) +{ + provide <break_statement*> (this, new break_statement); +} + +void +deep_copy_visitor::visit_continue_statement (continue_statement* s) +{ + provide <continue_statement*> (this, new continue_statement); +} + +void +deep_copy_visitor::visit_literal_string (literal_string* e) +{ + provide <literal_string*> (this, new literal_string(e->value)); +} + +void +deep_copy_visitor::visit_literal_number (literal_number* e) +{ + provide <literal_number*> (this, new literal_number(e->value)); +} + +void +deep_copy_visitor::visit_binary_expression (binary_expression* e) +{ + binary_expression *n = new binary_expression; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <binary_expression*> (this, n); +} + +void +deep_copy_visitor::visit_unary_expression (unary_expression* e) +{ + unary_expression *n = new unary_expression; + n->op = e->op; + require <expression*> (this, &(n->operand), e->operand); + provide <unary_expression*> (this, n); +} + +void +deep_copy_visitor::visit_pre_crement (pre_crement* e) +{ + pre_crement *n = new pre_crement; + n->op = e->op; + require <expression*> (this, &(n->operand), e->operand); + provide <pre_crement*> (this, n); +} + +void +deep_copy_visitor::visit_post_crement (post_crement* e) +{ + post_crement *n = new post_crement; + n->op = e->op; + require <expression*> (this, &(n->operand), e->operand); + provide <post_crement*> (this, n); +} + + +void +deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e) +{ + logical_or_expr *n = new logical_or_expr; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <logical_or_expr*> (this, n); +} + +void +deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e) +{ + logical_and_expr *n = new logical_and_expr; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <logical_and_expr*> (this, n); +} + +void +deep_copy_visitor::visit_array_in (array_in* e) +{ + array_in *n = new array_in; + require <arrayindex*> (this, &(n->operand), e->operand); + provide <array_in*> (this, n); +} + +void +deep_copy_visitor::visit_comparison (comparison* e) +{ + comparison *n = new comparison; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <comparison*> (this, n); +} + +void +deep_copy_visitor::visit_concatenation (concatenation* e) +{ + concatenation *n = new concatenation; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <concatenation*> (this, n); +} + +void +deep_copy_visitor::visit_ternary_expression (ternary_expression* e) +{ + ternary_expression *n = new ternary_expression; + require <expression*> (this, &(n->cond), e->cond); + require <expression*> (this, &(n->truevalue), e->truevalue); + require <expression*> (this, &(n->falsevalue), e->falsevalue); + provide <ternary_expression*> (this, n); +} + +void +deep_copy_visitor::visit_assignment (assignment* e) +{ + assignment *n = new assignment; + n->op = e->op; + require <expression*> (this, &(n->left), e->left); + require <expression*> (this, &(n->right), e->right); + provide <assignment*> (this, n); +} + +void +deep_copy_visitor::visit_symbol (symbol* e) +{ + symbol *n = new symbol; + n->name = e->name; + n->referent = NULL; + provide <symbol*> (this, n); +} + +void +deep_copy_visitor::visit_arrayindex (arrayindex* e) +{ + arrayindex *n = new arrayindex; + n->base = e->base; + n->referent = NULL; + for (unsigned i = 0; i < e->indexes.size(); ++i) + { + expression *ne; + require <expression*> (this, &ne, e->indexes[i]); + n->indexes.push_back(ne); + } + provide <arrayindex*> (this, n); +} + +void +deep_copy_visitor::visit_functioncall (functioncall* e) +{ + functioncall *n = new functioncall; + n->function = e->function; + n->referent = NULL; + for (unsigned i = 0; i < e->args.size(); ++i) + { + expression *na; + require <expression*> (this, &na, e->args[i]); + n->args.push_back(na); + } + provide <functioncall*> (this, n); +} + +block * +deep_copy_visitor::deep_copy (block *b) +{ + block *n; + deep_copy_visitor v; + require <block*> (&v, &n, b); + return n; +} + +statement * +deep_copy_visitor::deep_copy (statement *s) +{ + statement *n; + deep_copy_visitor v; + require <statement*> (&v, &n, s); + return n; +} |