summaryrefslogtreecommitdiffstats
path: root/staptree.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'staptree.cxx')
-rw-r--r--staptree.cxx614
1 files changed, 365 insertions, 249 deletions
diff --git a/staptree.cxx b/staptree.cxx
index fafefc4e..8d251731 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -1,5 +1,5 @@
// parse tree functions
-// Copyright (C) 2005-2008 Red Hat Inc.
+// Copyright (C) 2005-2009 Red Hat Inc.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -277,6 +277,28 @@ void target_symbol::print (std::ostream& o) const
}
+void cast_op::print (std::ostream& o) const
+{
+ o << base_name << '(' << *operand;
+ o << ", " << lex_cast_qstring (type);
+ if (module.length() > 0)
+ o << ", " << lex_cast_qstring (module);
+ o << ')';
+ for (unsigned i = 0; i < components.size(); ++i)
+ {
+ switch (components[i].first)
+ {
+ case comp_literal_array_index:
+ o << '[' << components[i].second << ']';
+ break;
+ case comp_struct_member:
+ o << "->" << components[i].second;
+ break;
+ }
+ }
+}
+
+
void vardecl::print (ostream& o) const
{
o << name;
@@ -1220,6 +1242,12 @@ target_symbol::visit (visitor* u)
}
void
+cast_op::visit (visitor* u)
+{
+ u->visit_cast_op(this);
+}
+
+void
arrayindex::visit (visitor* u)
{
u->visit_arrayindex (this);
@@ -1586,6 +1614,12 @@ traversing_visitor::visit_target_symbol (target_symbol*)
}
void
+traversing_visitor::visit_cast_op (cast_op* e)
+{
+ e->operand->visit (this);
+}
+
+void
traversing_visitor::visit_arrayindex (arrayindex* e)
{
for (unsigned i=0; i<e->indexes.size(); i++)
@@ -1680,6 +1714,17 @@ varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
}
void
+varuse_collecting_visitor::visit_cast_op (cast_op *e)
+{
+ // As with target_symbols, unresolved cast assignments need to preserved
+ // for later error handling.
+ if (is_active_lvalue (e))
+ embedded_seen = true;
+
+ functioncall_traversing_visitor::visit_cast_op (e);
+}
+
+void
varuse_collecting_visitor::visit_print_format (print_format* e)
{
// NB: Instead of being top-level statements, "print" and "printf"
@@ -2064,6 +2109,12 @@ throwing_visitor::visit_target_symbol (target_symbol* e)
}
void
+throwing_visitor::visit_cast_op (cast_op* e)
+{
+ throwone (e->tok);
+}
+
+void
throwing_visitor::visit_arrayindex (arrayindex* e)
{
throwone (e->tok);
@@ -2098,413 +2149,478 @@ 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)
+ 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_cast_op (cast_op* e)
+{
+ e->operand = require (e->operand);
+ 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, bool clearok)
+{
+ indexable *dst = NULL;
+ if (src != NULL)
{
- statement* ns;
- require <statement*> (this, &ns, s->statements[i]);
- n->statements.push_back(ns);
+ 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(clearok || dst);
}
- provide <block*> (this, n);
+ 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 <embeddedcode*> (this, 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 <null_statement*> (this, 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;
- require <expression*> (this, &(n->value), s->value);
- provide <expr_statement*> (this, 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;
- 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);
+ 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;
- 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);
+ 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)
- {
- symbol* sym;
- require <symbol*> (this, &sym, s->indexes[i]);
- n->indexes.push_back(sym);
- }
-
- require <indexable*> (this, &(n->base), s->base);
-
- n->sort_direction = s->sort_direction;
- n->sort_column = s->sort_column;
- require <expression*> (this, &(n->limit), s->limit);
-
- require <statement*> (this, &(n->block), s->block);
- provide <foreach_loop*> (this, 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;
- require <expression*> (this, &(n->value), s->value);
- provide <return_statement*> (this, 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;
- require <expression*> (this, &(n->value), s->value);
- provide <delete_statement*> (this, 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 <next_statement*> (this, 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 <break_statement*> (this, 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 <continue_statement*> (this, 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 <literal_string*> (this, 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 <literal_number*> (this, 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <binary_expression*> (this, 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;
- require <expression*> (this, &(n->operand), e->operand);
- provide <unary_expression*> (this, 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;
- require <expression*> (this, &(n->operand), e->operand);
- provide <pre_crement*> (this, 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;
- require <expression*> (this, &(n->operand), e->operand);
- provide <post_crement*> (this, 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <logical_or_expr*> (this, 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <logical_and_expr*> (this, 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;
- require <arrayindex*> (this, &(n->operand), e->operand);
- provide <array_in*> (this, 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <comparison*> (this, 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <concatenation*> (this, 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;
- 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);
+ 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;
- require <expression*> (this, &(n->left), e->left);
- require <expression*> (this, &(n->right), e->right);
- provide <assignment*> (this, 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 <symbol*> (this, 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 <target_symbol*> (this, 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)
+deep_copy_visitor::visit_cast_op (cast_op* e)
{
- arrayindex* n = new arrayindex;
- n->tok = e->tok;
-
- require <indexable*> (this, &(n->base), e->base);
+ update_visitor::visit_cast_op(new cast_op(*e));
+}
- 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_arrayindex (arrayindex* e)
+{
+ 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)
- {
- expression* na;
- require <expression*> (this, &na, e->args[i]);
- n->args.push_back(na);
- }
- provide <functioncall*> (this, 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)
- {
- expression* na;
- require <expression*> (this, &na, e->args[i]);
- n->args.push_back(na);
- }
- if (e->hist)
- require <hist_op*> (this, &n->hist, e->hist);
- provide <print_format*> (this, 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;
- require <expression*> (this, &(n->stat), e->stat);
- provide <stat_op*> (this, 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;
- require <expression*> (this, &(n->stat), e->stat);
- provide <hist_op*> (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;
-}
-
-expression*
-deep_copy_visitor::deep_copy (expression* s)
-{
- expression* n;
- deep_copy_visitor v;
- require <expression*> (&v, &n, s);
- return n;
-}
-
-template <> void
-require <indexable *> (deep_copy_visitor* v, indexable** dst, indexable* src)
-{
- if (src != NULL)
- {
- symbol *array_src=NULL, *array_dst=NULL;
- hist_op *hist_src=NULL, *hist_dst=NULL;
-
- classify_indexable(src, array_src, hist_src);
-
- *dst = NULL;
-
- if (array_src)
- {
- require <symbol*> (v, &array_dst, array_src);
- *dst = array_dst;
- }
- else
- {
- require <hist_op*> (v, &hist_dst, hist_src);
- *dst = hist_dst;
- }
- assert (*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 : */