summaryrefslogtreecommitdiffstats
path: root/staptree.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'staptree.cxx')
-rw-r--r--staptree.cxx293
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;
+}