staptree.cxx - systemtap
Functions defined
Source code
#include "config.h"
#include "staptree.h"
#include "parse.h"
#include "util.h"
#include "session.h"
#include <iostream>
#include <typeinfo>
#include <sstream>
#include <cassert>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
visitable::~visitable ()
{
}
expression::expression ():
type (pe_unknown), tok (0)
{
}
expression::~expression ()
{
}
statement::statement ():
tok (0)
{
}
statement::statement (const token* tok):
tok (tok)
{
}
null_statement::null_statement (const token* tok):
statement(tok)
{
}
statement::~statement ()
{
}
symbol::symbol ():
referent (0)
{
}
arrayindex::arrayindex ():
base (0)
{
}
functioncall::functioncall ():
referent (0)
{
}
symboldecl::symboldecl ():
tok (0), systemtap_v_conditional (0),
type (pe_unknown)
{
}
symboldecl::~symboldecl ()
{
}
probe_point::probe_point (std::vector<component*> const & comps):
components(comps), optional (false), sufficient (false),
from_glob (false), well_formed (false), condition (0)
{
}
probe_point::probe_point (const probe_point& pp):
components(pp.components), optional (pp.optional), sufficient (pp.sufficient),
from_glob (pp.from_glob), well_formed (pp.well_formed),
condition (pp.condition)
{
}
probe_point::probe_point ():
optional (false), sufficient (false), from_glob (false),
well_formed (false), condition (0)
{
}
unsigned probe::last_probeidx = 0;
probe::probe ():
body (0), base (0), tok (0), systemtap_v_conditional (0), privileged (false)
{
this->name = string ("probe_") + lex_cast(last_probeidx ++);
}
probe::probe(probe* p, probe_point* l)
{
this->base = p;
this->name = string ("probe_") + lex_cast(last_probeidx ++);
this->tok = p->tok;
this->locations.push_back(l);
this->body = deep_copy_visitor::deep_copy(p->body);
this->privileged = p->privileged;
this->systemtap_v_conditional = p->systemtap_v_conditional;
assert (p->locals.size() == 0);
assert (p->unused_locals.size() == 0);
}
probe_point::component::component ():
arg (0), tok(0)
{
}
probe_point::component::component (std::string const & f, literal * a):
functor(f), arg(a), tok(0)
{
}
vardecl::vardecl ():
arity_tok(0), arity (-1), maxsize(0), init(NULL), synthetic(false), wrap(false),
char_ptr_arg(false)
{
}
void
vardecl::set_arity (int a, const token* t)
{
if (a < 0)
return;
if (a == 0 && maxsize > 0)
throw SEMANTIC_ERROR (_("inconsistent arity"), tok);
if (arity != a && arity >= 0)
{
semantic_error err (ERR_SRC, _F("inconsistent arity (%s vs %d)",
lex_cast(arity).c_str(), a), t?:tok);
if (arity_tok)
{
semantic_error chain(ERR_SRC, _F("arity %s first inferred here",
lex_cast(arity).c_str()), arity_tok);
err.set_chain(chain);
}
throw err;
}
if (arity != a)
{
arity_tok = t;
arity = a;
index_types.resize (arity);
for (int i=0; i<arity; i++)
index_types[i] = pe_unknown;
}
}
bool
vardecl::compatible_arity (int a)
{
if (a == 0 && maxsize > 0)
return false;
if (arity == -1 || a == -1)
return true;
return arity == a;
}
functiondecl::functiondecl ():
body (0), synthetic (false), mangle_oldstyle (false)
{
}
void
functiondecl::join (systemtap_session& s)
{
if (!synthetic)
throw SEMANTIC_ERROR (_("internal error, joining a non-synthetic function"), tok);
if (!s.functions.insert (make_pair (name, this)).second)
throw SEMANTIC_ERROR (_F("synthetic function '%s' conflicts with an existing function",
name.c_str()), tok);
tok->location.file->functions.push_back (this);
}
literal_number::literal_number (int64_t v, bool hex)
{
value = v;
print_hex = hex;
type = pe_long;
}
literal_string::literal_string (const string& v)
{
value = v;
type = pe_string;
}
ostream&
operator << (ostream& o, const exp_type& e)
{
switch (e)
{
case pe_unknown: o << "unknown"; break;
case pe_long: o << "long"; break;
case pe_string: o << "string"; break;
case pe_stats: o << "stats"; break;
default: o << "???"; break;
}
return o;
}
void
target_symbol::assert_no_components(const std::string& tapset, bool pretty_ok)
{
if (components.empty())
return;
switch (components[0].type)
{
case comp_literal_array_index:
case comp_expression_array_index:
throw SEMANTIC_ERROR(_F("%s variable '%s' may not be used as array",
tapset.c_str(), name.c_str()), components[0].tok);
case comp_struct_member:
throw SEMANTIC_ERROR(_F("%s variable '%s' may not be used as a structure",
tapset.c_str(), name.c_str()), components[0].tok);
case comp_pretty_print:
if (!pretty_ok)
throw SEMANTIC_ERROR(_F("%s variable '%s' may not be pretty-printed",
tapset.c_str(), name.c_str()), components[0].tok);
return;
default:
throw SEMANTIC_ERROR (_F("invalid use of %s variable '%s'",
tapset.c_str(), name.c_str()), components[0].tok);
}
}
size_t
target_symbol::pretty_print_depth () const
{
if (! components.empty ())
{
const component& last = components.back ();
if (last.type == comp_pretty_print)
return last.member.length ();
}
return 0;
}
bool
target_symbol::check_pretty_print (bool lvalue) const
{
if (pretty_print_depth () == 0)
return false;
if (lvalue)
throw SEMANTIC_ERROR(_("cannot write to pretty-printed variable"), tok);
return true;
}
void target_symbol::chain (const semantic_error &er)
{
semantic_error* e = new semantic_error(er);
if (!e->tok1)
e->tok1 = this->tok;
assert (e->get_chain() == 0);
if (this->saved_conversion_error)
{
e->set_chain(*this->saved_conversion_error);
delete this->saved_conversion_error;
}
this->saved_conversion_error = e;
}
string target_symbol::sym_name ()
{
return name.substr(1);
}
string atvar_op::sym_name ()
{
if (cu_name == "")
return target_name;
else
return target_name.substr(0, target_name.length() - cu_name.length() - 1);
}
ostream& operator << (ostream& o, const expression& k)
{
k.print (o);
return o;
}
void literal_string::print (ostream& o) const
{
o << '"';
for (unsigned i=0; i<value.size(); i++)
if (value[i] == '"') o << '\\' << '"';
else
o << value[i];
o << '"';
}
void literal_number::print (ostream& o) const
{
if (print_hex)
o << hex << showbase;
o << value;
if (print_hex)
o << dec << noshowbase;
}
void embedded_expr::print (ostream& o) const
{
o << "%{ " << code << " %}";
}
void binary_expression::print (ostream& o) const
{
o << "(" << *left << ") "
<< op
<< " (" << *right << ")";
}
void regex_query::print (ostream& o) const
{
o << "(" << *left << ") "
<< op
<< " " << *right;
}
void unary_expression::print (ostream& o) const
{
o << op << '(' << *operand << ")";
}
void array_in::print (ostream& o) const
{
o << "[";
for (unsigned i=0; i<operand->indexes.size(); i++)
{
if (i > 0) o << ", ";
if (operand->indexes[i])
operand->indexes[i]->print (o);
else
o << "*";
}
o << "] in ";
operand->base->print (o);
}
void post_crement::print (ostream& o) const
{
o << '(' << *operand << ")" << op;
}
void ternary_expression::print (ostream& o) const
{
o << "(" << *cond << ")?("
<< *truevalue << "):("
<< *falsevalue << ")";
}
void symbol::print (ostream& o) const
{
o << name;
}
void target_symbol::component::print (ostream& o) const
{
switch (type)
{
case comp_pretty_print:
case comp_struct_member:
o << "->" << member;
break;
case comp_literal_array_index:
o << '[' << num_index << ']';
break;
case comp_expression_array_index:
o << '[' << *expr_index << ']';
break;
}
}
std::ostream& operator << (std::ostream& o, const target_symbol::component& c)
{
c.print (o);
return o;
}
void target_symbol::print (ostream& o) const
{
if (addressof)
o << "&";
o << name;
for (unsigned i = 0; i < components.size(); ++i)
o << components[i];
}
void atvar_op::print (ostream& o) const
{
if (addressof)
o << "&";
o << name << "(\"" << target_name << "\")";
for (unsigned i = 0; i < components.size(); ++i)
o << components[i];
}
void cast_op::print (ostream& o) const
{
if (addressof)
o << "&";
o << name << '(' << *operand;
o << ", " << lex_cast_qstring (type_name);
if (module.length() > 0)
o << ", " << lex_cast_qstring (module);
o << ')';
for (unsigned i = 0; i < components.size(); ++i)
o << components[i];
}
void autocast_op::print (ostream& o) const
{
if (addressof)
o << "&";
o << '(' << *operand << ')';
for (unsigned i = 0; i < components.size(); ++i)
o << components[i];
}
void defined_op::print (ostream& o) const
{
o << "@defined(" << *operand << ")";
}
void entry_op::print (ostream& o) const
{
o << "@entry(" << *operand << ")";
}
void perf_op::print (ostream& o) const
{
o << "@perf(" << *operand << ")";
}
void vardecl::print (ostream& o) const
{
o << name;
if(wrap)
o << "%";
if (maxsize > 0)
o << "[" << maxsize << "]";
if (arity > 0 || index_types.size() > 0)
o << "[...]";
if (init)
{
o << " = ";
init->print(o);
}
}
void vardecl::printsig (ostream& o) const
{
o << name;
if(wrap)
o << "%";
if (maxsize > 0)
o << "[" << maxsize << "]";
o << ":" << type;
if (index_types.size() > 0)
{
o << " [";
for (unsigned i=0; i<index_types.size(); i++)
o << (i>0 ? ", " : "") << index_types[i];
o << "]";
}
}
void functiondecl::print (ostream& o) const
{
o << "function " << name << " (";
for (unsigned i=0; i<formal_args.size(); i++)
o << (i>0 ? ", " : "") << *formal_args[i];
o << ")" << endl;
body->print(o);
}
void functiondecl::printsig (ostream& o) const
{
o << name << ":" << type << " (";
for (unsigned i=0; i<formal_args.size(); i++)
o << (i>0 ? ", " : "")
<< *formal_args[i]
<< ":"
<< formal_args[i]->type;
o << ")";
}
embedded_tags_visitor::embedded_tags_visitor(bool all_tags)
{
available_tags.insert("/* guru */");
available_tags.insert("/* unprivileged */");
available_tags.insert("/* myproc-unprivileged */");
if (all_tags)
{
available_tags.insert("/* pure */");
available_tags.insert("/* unmangled */");
available_tags.insert("/* unmodified-fnargs */");
}
}
bool embedded_tags_visitor::tagged_p (const std::string& tag)
{
return tags.count(tag);
}
void embedded_tags_visitor::find_tags_in_code (const string& s)
{
set<string>::iterator tag;
for (tag = available_tags.begin(); tag != available_tags.end(); ++tag)
if(s.find(*tag) != string::npos)
tags.insert(*tag);
}
void embedded_tags_visitor::visit_embeddedcode (embeddedcode *s)
{
find_tags_in_code(s->code);
}
void embedded_tags_visitor::visit_embedded_expr (embedded_expr *e)
{
find_tags_in_code(e->code);
}
void functiondecl::printsigtags (ostream& o, bool all_tags) const
{
this->printsig(o);
embedded_tags_visitor etv(all_tags);
this->body->visit(&etv);
set<string, bool>::const_iterator tag;
for (tag = etv.available_tags.begin(); tag != etv.available_tags.end(); ++tag)
if (etv.tagged_p(*tag))
o << " " << *tag;
}
void arrayindex::print (ostream& o) const
{
base->print (o);
o << "[";
for (unsigned i=0; i<indexes.size(); i++)
{
o << (i>0 ? ", " : "");
if (indexes[i]==0)
o << "*";
else
o << *indexes[i];
}
o << "]";
}
void functioncall::print (ostream& o) const
{
o << function << "(";
for (unsigned i=0; i<args.size(); i++)
o << (i>0 ? ", " : "") << *args[i];
o << ")";
}
print_format*
print_format::create(const token *t, const char *n)
{
bool stream, format, delim, newline, _char;
if (n == NULL) n = t->content.c_str();
const char *o = n;
stream = true;
format = delim = newline = _char = false;
if (strcmp(n, "print_char") == 0)
_char = true;
else
{
if (*n == 's')
{
stream = false;
++n;
}
if (0 != strncmp(n, "print", 5))
return NULL;
n += 5;
if (*n == 'f')
{
format = true;
++n;
}
else
{
if (*n == 'd')
{
delim = true;
++n;
}
if (*n == 'l' && *(n+1) == 'n')
{
newline = true;
n += 2;
}
}
if (*n != '\0')
return NULL;
}
print_format *pf = new print_format(stream, format, delim, newline, _char, o);
pf->tok = t;
return pf;
}
string
print_format::components_to_string(vector<format_component> const & components)
{
ostringstream oss;
for (vector<format_component>::const_iterator i = components.begin();
i != components.end(); ++i)
{
assert (i->type != conv_unspecified);
if (i->type == conv_literal)
{
assert(!i->literal_string.empty());
for (string::const_iterator j = i->literal_string.begin();
j != i->literal_string.end(); ++j)
{
if (*j == '%')
oss << '%';
else if(*j == '"')
oss << '\\';
oss << *j;
}
}
else
{
oss << '%';
if (i->test_flag (fmt_flag_zeropad))
oss << '0';
if (i->test_flag (fmt_flag_plus))
oss << '+';
if (i->test_flag (fmt_flag_space))
oss << ' ';
if (i->test_flag (fmt_flag_left))
oss << '-';
if (i->test_flag (fmt_flag_special))
oss << '#';
if (i->widthtype == width_dynamic)
oss << '*';
else if (i->widthtype != width_unspecified && i->width > 0)
oss << i->width;
if (i->prectype == prec_dynamic)
oss << ".*";
else if (i->prectype != prec_unspecified && i->precision > 0)
oss << '.' << i->precision;
switch (i->type)
{
case conv_binary:
oss << "b";
break;
case conv_char:
oss << "llc";
break;
case conv_number:
if (i->base == 16)
{
if (i->test_flag (fmt_flag_large))
oss << "llX";
else
oss << "llx";
}
else if (i->base == 8)
oss << "llo";
else if (i->test_flag (fmt_flag_sign))
oss << "lld";
else
oss << "llu";
break;
case conv_pointer:
oss << "p";
break;
case conv_string:
oss << 's';
break;
case conv_memory:
oss << 'm';
break;
case conv_memory_hex:
oss << 'M';
break;
default:
break;
}
}
}
return oss.str ();
}
vector<print_format::format_component>
print_format::string_to_components(string const & str)
{
format_component curr;
vector<format_component> res;
curr.clear();
string::const_iterator i = str.begin();
while (i != str.end())
{
if (*i != '%')
{
assert (curr.type == conv_unspecified || curr.type == conv_literal);
curr.type = conv_literal;
curr.literal_string += *i;
++i;
continue;
}
else if (i+1 == str.end() || *(i+1) == '%')
{
assert(*i == '%');
assert (curr.type == conv_unspecified || curr.type == conv_literal);
curr.type = conv_literal;
curr.literal_string += '%';
i += 2;
continue;
}
else
{
assert(*i == '%');
if (curr.type != conv_unspecified)
{
assert (curr.type == conv_literal);
res.push_back(curr);
curr.clear();
}
}
++i;
if (i == str.end())
break;
switch (*i)
{
case '0':
curr.set_flag (fmt_flag_zeropad);
++i;
break;
case '+':
curr.set_flag (fmt_flag_plus);
++i;
break;
case '-':
curr.set_flag (fmt_flag_left);
++i;
break;
case ' ':
curr.set_flag (fmt_flag_space);
++i;
break;
case '#':
curr.set_flag (fmt_flag_special);
++i;
break;
default:
break;
}
if (i == str.end())
break;
if (*i == '*')
{
curr.widthtype = width_dynamic;
++i;
}
else if (isdigit(*i))
{
curr.widthtype = width_static;
curr.width = 0;
do
{
curr.width *= 10;
curr.width += (*i - '0');
++i;
}
while (i != str.end() && isdigit(*i));
}
if (i == str.end())
break;
if (*i == '.')
{
++i;
if (i == str.end())
break;
if (*i == '*')
{
curr.prectype = prec_dynamic;
++i;
}
else if (isdigit(*i))
{
curr.prectype = prec_static;
curr.precision = 0;
do
{
curr.precision *= 10;
curr.precision += (*i - '0');
++i;
}
while (i != str.end() && isdigit(*i));
}
}
if (i == str.end())
break;
switch (*i)
{
case 'l':
++i;
break;
}
if (i == str.end())
break;
switch (*i)
{
case 'b':
curr.type = conv_binary;
break;
case 'c':
curr.type = conv_char;
break;
case 's':
curr.type = conv_string;
break;
case 'm':
curr.type = conv_memory;
break;
case 'M':
curr.type = conv_memory_hex;
break;
case 'd':
case 'i':
curr.set_flag (fmt_flag_sign);
case 'u':
curr.type = conv_number;
curr.base = 10;
break;
case 'o':
curr.type = conv_number;
curr.base = 8;
break;
case 'X':
curr.set_flag (fmt_flag_large);
case 'x':
curr.type = conv_number;
curr.base = 16;
break;
case 'p':
curr.set_flag (fmt_flag_special);
curr.type = conv_pointer;
curr.base = 16;
break;
default:
break;
}
if (curr.type == conv_unspecified)
throw PARSE_ERROR(_("invalid or missing conversion specifier"));
++i;
res.push_back(curr);
curr.clear();
}
if (!curr.is_empty())
{
if (curr.type == conv_literal)
res.push_back(curr);
else
throw PARSE_ERROR(_("trailing incomplete print format conversion"));
}
return res;
}
void print_format::print (ostream& o) const
{
o << print_format_type << "(";
if (print_with_format)
o << lex_cast_qstring (raw_components);
if (print_with_delim)
o << lex_cast_qstring (delimiter.literal_string);
if (hist)
hist->print(o);
for (vector<expression*>::const_iterator i = args.begin();
i != args.end(); ++i)
{
if (i != args.begin() || print_with_format || print_with_delim)
o << ", ";
(*i)->print(o);
}
o << ")";
}
void stat_op::print (ostream& o) const
{
o << '@';
switch (ctype)
{
case sc_average:
o << "avg(";
break;
case sc_count:
o << "count(";
break;
case sc_sum:
o << "sum(";
break;
case sc_min:
o << "min(";
break;
case sc_max:
o << "max(";
break;
case sc_none:
assert (0); break;
}
stat->print(o);
o << ")";
}
void
hist_op::print (ostream& o) const
{
o << '@';
switch (htype)
{
case hist_linear:
assert(params.size() == 3);
o << "hist_linear(";
stat->print(o);
for (size_t i = 0; i < params.size(); ++i)
{
o << ", " << params[i];
}
o << ")";
break;
case hist_log:
assert(params.size() == 0);
o << "hist_log(";
stat->print(o);
o << ")";
break;
}
}
ostream& operator << (ostream& o, const statement& k)
{
k.print (o);
return o;
}
void embeddedcode::print (ostream &o) const
{
o << "%{";
o << code;
o << "%}";
}
void block::print (ostream& o) const
{
o << "{" << endl;
for (unsigned i=0; i<statements.size(); i++)
o << *statements [i] << endl;
o << "}";
}
block::block (statement* car, statement* cdr)
{
statements.push_back(car);
statements.push_back(cdr);
this->tok = car->tok;
}
void try_block::print (ostream& o) const
{
o << "try {" << endl;
if (try_block) o << *try_block << endl;
o << "} catch ";
if (catch_error_var) o << "(" << *catch_error_var << ") ";
o << "{" << endl;
if (catch_block) o << *catch_block << endl;
o << "}" << endl;
}
void for_loop::print (ostream& o) const
{
o << "for (";
if (init) init->print (o);
o << "; ";
cond->print (o);
o << "; ";
if (incr) incr->print (o);
o << ") ";
block->print (o);
}
void foreach_loop::print (ostream& o) const
{
o << "foreach (";
if (value)
{
value->print (o);
o << " = ";
}
o << "[";
for (unsigned i=0; i<indexes.size(); i++)
{
if (i > 0) o << ", ";
indexes[i]->print (o);
if (sort_direction != 0 && sort_column == i+1)
o << (sort_direction > 0 ? "+" : "-");
}
o << "] in ";
base->print (o);
if (!array_slice.empty())
{
o << "[";
for (unsigned i=0; i<array_slice.size(); i++)
{
if (i > 0) o << ", ";
if (array_slice[i])
array_slice[i]->print (o);
else
o << "*";
}
o << "]";
}
if (sort_direction != 0 && sort_column == 0)
{
switch (sort_aggr)
{
case sc_count: o << " @count"; break;
case sc_average: o << " @avg"; break;
case sc_min: o << " @min"; break;
case sc_max: o << " @max"; break;
case sc_sum: o << " @sum"; break;
case sc_none:
default:
;
}
o << (sort_direction > 0 ? "+" : "-");
}
if (limit)
{
o << " limit ";
limit->print (o);
}
o << ") ";
block->print (o);
}
void null_statement::print (ostream& o) const
{
o << ";";
}
void expr_statement::print (ostream& o) const
{
o << *value;
}
void return_statement::print (ostream& o) const
{
o << "return " << *value;
}
void delete_statement::print (ostream& o) const
{
o << "delete " << *value;
}
void next_statement::print (ostream& o) const
{
o << "next";
}
void break_statement::print (ostream& o) const
{
o << "break";
}
void continue_statement::print (ostream& o) const
{
o << "continue";
}
void if_statement::print (ostream& o) const
{
o << "if (" << *condition << ") "
<< *thenblock << endl;
if (elseblock)
o << "else " << *elseblock << endl;
}
void stapfile::print (ostream& o) const
{
o << "# file " << name << endl;
for (unsigned i=0; i<embeds.size(); i++)
embeds[i]->print (o);
for (unsigned i=0; i<globals.size(); i++)
{
o << "global ";
globals[i]->print (o);
o << endl;
}
for (unsigned i=0; i<aliases.size(); i++)
{
aliases[i]->print (o);
o << endl;
}
for (unsigned i=0; i<probes.size(); i++)
{
probes[i]->print (o);
o << endl;
}
for (unsigned j = 0; j < functions.size(); j++)
{
functions[j]->print (o);
o << endl;
}
}
void probe::print (ostream& o) const
{
o << "probe ";
printsig (o);
o << *body;
}
void probe::printsig (ostream& o) const
{
const probe_alias *alias = get_alias ();
if (alias)
{
alias->printsig (o);
return;
}
for (unsigned i=0; i<locations.size(); i++)
{
if (i > 0) o << ",";
locations[i]->print (o);
}
}
void
probe::collect_derivation_chain (std::vector<probe*> &probes_list) const
{
probes_list.push_back(const_cast<probe*>(this));
if (base)
base->collect_derivation_chain(probes_list);
}
void
probe::collect_derivation_pp_chain (std::vector<probe_point*> &pp_list) const
{
pp_list.push_back(const_cast<probe_point*>(this->locations[0]));
if (base)
base->collect_derivation_pp_chain(pp_list);
}
void probe_point::print (ostream& o, bool print_extras) const
{
for (unsigned i=0; i<components.size(); i++)
{
if (i>0) o << ".";
probe_point::component* c = components[i];
if (!c)
{
static int been_here = 0;
if (been_here == 0) {
been_here ++;
throw SEMANTIC_ERROR (_("internal error: missing probe point component"));
} else
continue; }
o << c->functor;
if (c->arg)
o << "(" << *c->arg << ")";
}
if (!print_extras)
return;
if (sufficient)
o << "!";
else if (optional) o << "?";
if (condition)
o<< " if (" << *condition << ")";
}
string probe_point::str (bool print_extras) const
{
ostringstream o;
print(o, print_extras);
return o.str();
}
probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
probe (), alias_names (aliases), epilogue_style(false)
{
}
void probe_alias::printsig (ostream& o) const
{
for (unsigned i=0; i<alias_names.size(); i++)
{
o << (i>0 ? " = " : "");
alias_names[i]->print (o);
}
o << (epilogue_style ? " += " : " = ");
for (unsigned i=0; i<locations.size(); i++)
{
if (i > 0) o << ", ";
locations[i]->print (o);
}
}
ostream& operator << (ostream& o, const probe_point& k)
{
k.print (o);
return o;
}
ostream& operator << (ostream& o, const symboldecl& k)
{
k.print (o);
return o;
}
void
block::visit (visitor* u)
{
u->visit_block (this);
}
void
try_block::visit (visitor* u)
{
u->visit_try_block (this);
}
void
embeddedcode::visit (visitor* u)
{
u->visit_embeddedcode (this);
}
void
for_loop::visit (visitor* u)
{
u->visit_for_loop (this);
}
void
foreach_loop::visit (visitor* u)
{
u->visit_foreach_loop (this);
}
void
null_statement::visit (visitor* u)
{
u->visit_null_statement (this);
}
void
expr_statement::visit (visitor* u)
{
u->visit_expr_statement (this);
}
void
return_statement::visit (visitor* u)
{
u->visit_return_statement (this);
}
void
delete_statement::visit (visitor* u)
{
u->push_active_lvalue (this->value);
u->visit_delete_statement (this);
u->pop_active_lvalue ();
}
void
if_statement::visit (visitor* u)
{
u->visit_if_statement (this);
}
void
next_statement::visit (visitor* u)
{
u->visit_next_statement (this);
}
void
break_statement::visit (visitor* u)
{
u->visit_break_statement (this);
}
void
continue_statement::visit (visitor* u)
{
u->visit_continue_statement (this);
}
void
literal_string::visit(visitor* u)
{
u->visit_literal_string (this);
}
void
literal_number::visit(visitor* u)
{
u->visit_literal_number (this);
}
void
binary_expression::visit (visitor* u)
{
u->visit_binary_expression (this);
}
void
embedded_expr::visit (visitor* u)
{
u->visit_embedded_expr (this);
}
void
unary_expression::visit (visitor* u)
{
u->visit_unary_expression (this);
}
void
pre_crement::visit (visitor* u)
{
u->push_active_lvalue (this->operand);
u->visit_pre_crement (this);
u->pop_active_lvalue ();
}
void
post_crement::visit (visitor* u)
{
u->push_active_lvalue (this->operand);
u->visit_post_crement (this);
u->pop_active_lvalue ();
}
void
logical_or_expr::visit (visitor* u)
{
u->visit_logical_or_expr (this);
}
void
logical_and_expr::visit (visitor* u)
{
u->visit_logical_and_expr (this);
}
void
array_in::visit (visitor* u)
{
u->visit_array_in (this);
}
void
regex_query::visit (visitor* u)
{
u->visit_regex_query (this);
}
void
comparison::visit (visitor* u)
{
u->visit_comparison (this);
}
void
concatenation::visit (visitor* u)
{
u->visit_concatenation (this);
}
void
ternary_expression::visit (visitor* u)
{
u->visit_ternary_expression (this);
}
void
assignment::visit (visitor* u)
{
u->push_active_lvalue (this->left);
u->visit_assignment (this);
u->pop_active_lvalue ();
}
void
symbol::visit (visitor* u)
{
u->visit_symbol (this);
}
void
target_symbol::visit (visitor* u)
{
u->visit_target_symbol(this);
}
void
target_symbol::visit_components (visitor* u)
{
for (unsigned i = 0; i < components.size(); ++i)
if (components[i].type == comp_expression_array_index)
components[i].expr_index->visit (u);
}
void
target_symbol::visit_components (update_visitor* u)
{
for (unsigned i = 0; i < components.size(); ++i)
if (components[i].type == comp_expression_array_index)
u->replace (components[i].expr_index);
}
void
cast_op::visit (visitor* u)
{
u->visit_cast_op(this);
}
void
autocast_op::visit (visitor* u)
{
u->visit_autocast_op(this);
}
void
atvar_op::visit (visitor* u)
{
u->visit_atvar_op(this);
}
void
defined_op::visit (visitor* u)
{
u->visit_defined_op(this);
}
void
entry_op::visit (visitor* u)
{
u->visit_entry_op(this);
}
void
perf_op::visit (visitor* u)
{
u->visit_perf_op(this);
}
void
arrayindex::visit (visitor* u)
{
u->visit_arrayindex (this);
}
void
functioncall::visit (visitor* u)
{
u->visit_functioncall (this);
}
void
print_format::visit (visitor *u)
{
u->visit_print_format (this);
}
void
stat_op::visit (visitor *u)
{
u->visit_stat_op (this);
}
void
hist_op::visit (visitor *u)
{
u->visit_hist_op (this);
}
bool
expression::is_symbol(symbol *& sym_out)
{
sym_out = NULL;
return false;
}
bool
indexable::is_symbol(symbol *& sym_out)
{
sym_out = NULL;
return false;
}
bool
indexable::is_hist_op(hist_op *& hist_out)
{
hist_out = NULL;
return false;
}
bool
symbol::is_symbol(symbol *& sym_out)
{
sym_out = this;
return true;
}
bool
hist_op::is_hist_op(hist_op *& hist_out)
{
hist_out = this;
return true;
}
void
classify_indexable(indexable* ix,
symbol *& array_out,
hist_op *& hist_out)
{
array_out = NULL;
hist_out = NULL;
assert(ix != NULL);
if (!(ix->is_symbol (array_out) || ix->is_hist_op (hist_out)))
throw SEMANTIC_ERROR(_("Expecting symbol or histogram operator"), ix->tok);
if (!(hist_out || array_out))
throw SEMANTIC_ERROR(_("Failed to classify indexable"), ix->tok);
}
bool
visitor::is_active_lvalue(expression *e)
{
for (unsigned i = 0; i < active_lvalues.size(); ++i)
{
if (active_lvalues[i] == e)
return true;
}
return false;
}
void
visitor::push_active_lvalue(expression *e)
{
active_lvalues.push_back(e);
}
void
visitor::pop_active_lvalue()
{
assert(!active_lvalues.empty());
active_lvalues.pop_back();
}
void
traversing_visitor::visit_block (block* s)
{
for (unsigned i=0; i<s->statements.size(); i++)
s->statements[i]->visit (this);
}
void
traversing_visitor::visit_try_block (try_block* s)
{
if (s->try_block)
s->try_block->visit (this);
if (s->catch_error_var)
s->catch_error_var->visit (this);
if (s->catch_block)
s->catch_block->visit (this);
}
void
traversing_visitor::visit_embeddedcode (embeddedcode*)
{
}
void
traversing_visitor::visit_null_statement (null_statement*)
{
}
void
traversing_visitor::visit_expr_statement (expr_statement* s)
{
s->value->visit (this);
}
void
traversing_visitor::visit_if_statement (if_statement* s)
{
s->condition->visit (this);
s->thenblock->visit (this);
if (s->elseblock)
s->elseblock->visit (this);
}
void
traversing_visitor::visit_for_loop (for_loop* s)
{
if (s->init) s->init->visit (this);
s->cond->visit (this);
if (s->incr) s->incr->visit (this);
s->block->visit (this);
}
void
traversing_visitor::visit_foreach_loop (foreach_loop* s)
{
s->base->visit(this);
for (unsigned i=0; i<s->indexes.size(); i++)
s->indexes[i]->visit (this);
if (s->value)
s->value->visit (this);
if (s->limit)
s->limit->visit (this);
s->block->visit (this);
}
void
traversing_visitor::visit_return_statement (return_statement* s)
{
s->value->visit (this);
}
void
traversing_visitor::visit_delete_statement (delete_statement* s)
{
s->value->visit (this);
}
void
traversing_visitor::visit_next_statement (next_statement*)
{
}
void
traversing_visitor::visit_break_statement (break_statement*)
{
}
void
traversing_visitor::visit_continue_statement (continue_statement*)
{
}
void
traversing_visitor::visit_literal_string (literal_string*)
{
}
void
traversing_visitor::visit_literal_number (literal_number*)
{
}
void
traversing_visitor::visit_embedded_expr (embedded_expr*)
{
}
void
traversing_visitor::visit_binary_expression (binary_expression* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_unary_expression (unary_expression* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_pre_crement (pre_crement* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_post_crement (post_crement* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_logical_or_expr (logical_or_expr* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_logical_and_expr (logical_and_expr* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_array_in (array_in* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_regex_query (regex_query* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_comparison (comparison* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_concatenation (concatenation* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_ternary_expression (ternary_expression* e)
{
e->cond->visit (this);
e->truevalue->visit (this);
e->falsevalue->visit (this);
}
void
traversing_visitor::visit_assignment (assignment* e)
{
e->left->visit (this);
e->right->visit (this);
}
void
traversing_visitor::visit_symbol (symbol*)
{
}
void
traversing_visitor::visit_target_symbol (target_symbol* e)
{
e->visit_components (this);
}
void
traversing_visitor::visit_cast_op (cast_op* e)
{
e->operand->visit (this);
e->visit_components (this);
}
void
traversing_visitor::visit_autocast_op (autocast_op* e)
{
e->operand->visit (this);
e->visit_components (this);
}
void
traversing_visitor::visit_atvar_op (atvar_op* e)
{
e->visit_components (this);
}
void
traversing_visitor::visit_defined_op (defined_op* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_entry_op (entry_op* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_perf_op (perf_op* e)
{
e->operand->visit (this);
}
void
traversing_visitor::visit_arrayindex (arrayindex* e)
{
for (unsigned i=0; i<e->indexes.size(); i++)
if (e->indexes[i])
e->indexes[i]->visit (this);
e->base->visit(this);
}
void
traversing_visitor::visit_functioncall (functioncall* e)
{
for (unsigned i=0; i<e->args.size(); i++)
e->args[i]->visit (this);
}
void
traversing_visitor::visit_print_format (print_format* e)
{
for (unsigned i=0; i<e->args.size(); i++)
e->args[i]->visit (this);
if (e->hist)
e->hist->visit(this);
}
void
traversing_visitor::visit_stat_op (stat_op* e)
{
e->stat->visit (this);
}
void
traversing_visitor::visit_hist_op (hist_op* e)
{
e->stat->visit (this);
}
void
expression_visitor::visit_literal_string (literal_string* e)
{
traversing_visitor::visit_literal_string (e);
visit_expression (e);
}
void
expression_visitor::visit_literal_number (literal_number* e)
{
traversing_visitor::visit_literal_number (e);
visit_expression (e);
}
void
expression_visitor::visit_embedded_expr (embedded_expr* e)
{
traversing_visitor::visit_embedded_expr (e);
visit_expression (e);
}
void
expression_visitor::visit_binary_expression (binary_expression* e)
{
traversing_visitor::visit_binary_expression (e);
visit_expression (e);
}
void
expression_visitor::visit_unary_expression (unary_expression* e)
{
traversing_visitor::visit_unary_expression (e);
visit_expression (e);
}
void
expression_visitor::visit_pre_crement (pre_crement* e)
{
traversing_visitor::visit_pre_crement (e);
visit_expression (e);
}
void
expression_visitor::visit_post_crement (post_crement* e)
{
traversing_visitor::visit_post_crement (e);
visit_expression (e);
}
void
expression_visitor::visit_logical_or_expr (logical_or_expr* e)
{
traversing_visitor::visit_logical_or_expr (e);
visit_expression (e);
}
void
expression_visitor::visit_logical_and_expr (logical_and_expr* e)
{
traversing_visitor::visit_logical_and_expr (e);
visit_expression (e);
}
void
expression_visitor::visit_array_in (array_in* e)
{
traversing_visitor::visit_array_in (e);
visit_expression (e);
}
void
expression_visitor::visit_regex_query (regex_query* e)
{
traversing_visitor::visit_regex_query (e);
visit_expression (e);
}
void
expression_visitor::visit_comparison (comparison* e)
{
traversing_visitor::visit_comparison (e);
visit_expression (e);
}
void
expression_visitor::visit_concatenation (concatenation* e)
{
traversing_visitor::visit_concatenation (e);
visit_expression (e);
}
void
expression_visitor::visit_ternary_expression (ternary_expression* e)
{
traversing_visitor::visit_ternary_expression (e);
visit_expression (e);
}
void
expression_visitor::visit_assignment (assignment* e)
{
traversing_visitor::visit_assignment (e);
visit_expression (e);
}
void
expression_visitor::visit_symbol (symbol* e)
{
traversing_visitor::visit_symbol (e);
visit_expression (e);
}
void
expression_visitor::visit_target_symbol (target_symbol* e)
{
traversing_visitor::visit_target_symbol (e);
visit_expression (e);
}
void
expression_visitor::visit_arrayindex (arrayindex* e)
{
traversing_visitor::visit_arrayindex (e);
visit_expression (e);
}
void
expression_visitor::visit_functioncall (functioncall* e)
{
traversing_visitor::visit_functioncall (e);
visit_expression (e);
}
void
expression_visitor::visit_print_format (print_format* e)
{
traversing_visitor::visit_print_format (e);
visit_expression (e);
}
void
expression_visitor::visit_stat_op (stat_op* e)
{
traversing_visitor::visit_stat_op (e);
visit_expression (e);
}
void
expression_visitor::visit_hist_op (hist_op* e)
{
traversing_visitor::visit_hist_op (e);
visit_expression (e);
}
void
expression_visitor::visit_cast_op (cast_op* e)
{
traversing_visitor::visit_cast_op (e);
visit_expression (e);
}
void
expression_visitor::visit_autocast_op (autocast_op* e)
{
traversing_visitor::visit_autocast_op (e);
visit_expression (e);
}
void
expression_visitor::visit_atvar_op (atvar_op* e)
{
traversing_visitor::visit_atvar_op (e);
visit_expression (e);
}
void
expression_visitor::visit_defined_op (defined_op* e)
{
traversing_visitor::visit_defined_op (e);
visit_expression (e);
}
void
expression_visitor::visit_entry_op (entry_op* e)
{
traversing_visitor::visit_entry_op (e);
visit_expression (e);
}
void
expression_visitor::visit_perf_op (perf_op* e)
{
traversing_visitor::visit_perf_op (e);
visit_expression (e);
}
void
functioncall_traversing_visitor::visit_functioncall (functioncall* e)
{
traversing_visitor::visit_functioncall (e);
if (nested.find (e->referent) == nested.end ())
{
if (seen.find(e->referent) == seen.end())
seen.insert (e->referent);
nested.insert (e->referent);
functiondecl* last_current_function = current_function;
current_function = e->referent;
e->referent->body->visit (this);
current_function = last_current_function;
nested.erase (e->referent);
}
else { this->note_recursive_functioncall(e); }
}
void
functioncall_traversing_visitor::note_recursive_functioncall (functioncall* e)
{
}
void
varuse_collecting_visitor::visit_try_block (try_block *s)
{
if (s->try_block)
s->try_block->visit (this);
if (s->catch_error_var)
written.insert (s->catch_error_var->referent);
if (s->catch_block)
s->catch_block->visit (this);
}
void
varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
{
assert (current_function);
if (! pr_contains (session.privilege, pr_stapdev) &&
! pr_contains (session.privilege, pr_stapsys) &&
! session.runtime_usermode_p () &&
s->code.find ("/* unprivileged */") == string::npos &&
s->code.find ("/* myproc-unprivileged */") == string::npos)
throw SEMANTIC_ERROR (_F("function may not be used when --privilege=%s is specified",
pr_name (session.privilege)),
current_function->tok);
if (!session.guru_mode && s->code.find ("/* guru */") != string::npos)
throw SEMANTIC_ERROR (_("function may not be used unless -g is specified"),
current_function->tok);
if (s->code.find ("/* unmangled */") != string::npos)
current_function->mangle_oldstyle = true;
if (s->code.find ("/* pure */") != string::npos)
return;
embedded_seen = true;
}
void
varuse_collecting_visitor::visit_embedded_expr (embedded_expr *e)
{
if (! pr_contains (session.privilege, pr_stapdev) &&
! pr_contains (session.privilege, pr_stapsys) &&
! session.runtime_usermode_p () &&
e->code.find ("/* unprivileged */") == string::npos &&
e->code.find ("/* myproc-unprivileged */") == string::npos)
throw SEMANTIC_ERROR (_F("embedded expression may not be used when --privilege=%s is specified",
pr_name (session.privilege)),
e->tok);
if (!session.guru_mode && e->code.find ("/* guru */") != string::npos)
throw SEMANTIC_ERROR (_("embedded expression may not be used unless -g is specified"),
e->tok);
if (e->code.find ("/* pure */") != string::npos)
return;
embedded_seen = true;
}
void
varuse_collecting_visitor::visit_target_symbol (target_symbol *e)
{
if (is_active_lvalue (e))
embedded_seen = true;
functioncall_traversing_visitor::visit_target_symbol (e);
}
void
varuse_collecting_visitor::visit_atvar_op (atvar_op *e)
{
if (is_active_lvalue (e))
embedded_seen = true;
functioncall_traversing_visitor::visit_atvar_op (e);
}
void
varuse_collecting_visitor::visit_cast_op (cast_op *e)
{
if (is_active_lvalue (e))
embedded_seen = true;
functioncall_traversing_visitor::visit_cast_op (e);
}
void
varuse_collecting_visitor::visit_autocast_op (autocast_op *e)
{
if (is_active_lvalue (e))
embedded_seen = true;
functioncall_traversing_visitor::visit_autocast_op (e);
}
void
varuse_collecting_visitor::visit_defined_op (defined_op *e)
{
XXX
functioncall_traversing_visitor::visit_defined_op (e);
}
void
varuse_collecting_visitor::visit_entry_op (entry_op *e)
{
XXX
functioncall_traversing_visitor::visit_entry_op (e);
}
void
varuse_collecting_visitor::visit_perf_op (perf_op *e)
{
functioncall_traversing_visitor::visit_perf_op (e);
}
void
varuse_collecting_visitor::visit_print_format (print_format* e)
{
bool last_lvalue_read = current_lvalue_read;
current_lvalue_read = true;
if (e->print_to_stream)
embedded_seen = true;
functioncall_traversing_visitor::visit_print_format (e);
current_lvalue_read = last_lvalue_read;
}
void
varuse_collecting_visitor::visit_assignment (assignment *e)
{
if (e->op == "=" || e->op == "<<<") {
expression* last_lvalue = current_lvalue;
bool last_lvalue_read = current_lvalue_read;
current_lvalue = e->left; current_lvalue_read = true;
functioncall_traversing_visitor::visit_assignment (e);
current_lvalue = last_lvalue;
current_lvalue_read = last_lvalue_read;
}
else {
expression* last_lrvalue = current_lrvalue;
current_lrvalue = e->left; functioncall_traversing_visitor::visit_assignment (e);
current_lrvalue = last_lrvalue;
}
}
void
varuse_collecting_visitor::visit_symbol (symbol *e)
{
if (e->referent == 0)
throw SEMANTIC_ERROR (_("symbol without referent"), e->tok);
if (current_lvalue == e || current_lrvalue == e)
{
written.insert (e->referent);
}
if (current_lvalue != e || current_lrvalue == e)
{
read.insert (e->referent);
}
if (current_lrvalue == e)
{
if (current_lvalue_read)
used.insert (e->referent);
}
else if (current_lvalue != e)
used.insert (e->referent);
}
void
varuse_collecting_visitor::visit_arrayindex (arrayindex *e)
{
expression* last_lrvalue = current_lrvalue;
expression* last_lvalue = current_lvalue;
symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable(e->base, array, hist);
expression *value = array ?: hist->stat;
if (current_lrvalue == e) current_lrvalue = value;
if (current_lvalue == e) current_lvalue = value;
functioncall_traversing_visitor::visit_arrayindex (e);
current_lrvalue = last_lrvalue;
current_lvalue = last_lvalue;
}
void
varuse_collecting_visitor::visit_pre_crement (pre_crement *e)
{
expression* last_lrvalue = current_lrvalue;
current_lrvalue = e->operand; functioncall_traversing_visitor::visit_pre_crement (e);
current_lrvalue = last_lrvalue;
}
void
varuse_collecting_visitor::visit_post_crement (post_crement *e)
{
expression* last_lrvalue = current_lrvalue;
current_lrvalue = e->operand; functioncall_traversing_visitor::visit_post_crement (e);
current_lrvalue = last_lrvalue;
}
void
varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
{
s->base->visit(this);
if (s->sort_direction)
{
symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable (s->base, array, hist);
if (array) this->written.insert (array->referent);
XXX }
for (unsigned i=0; i<s->indexes.size(); i++)
{
expression* last_lvalue = current_lvalue;
current_lvalue = s->indexes[i]; s->indexes[i]->visit (this);
current_lvalue = last_lvalue;
}
for (unsigned i=0; i<s->array_slice.size(); i++)
{
if (s->array_slice[i])
s->array_slice[i]->visit (this);
}
if (s->value)
{
expression* last_lvalue = current_lvalue;
current_lvalue = s->value; s->value->visit (this);
current_lvalue = last_lvalue;
}
if (s->limit)
s->limit->visit (this);
s->block->visit (this);
}
void
varuse_collecting_visitor::visit_delete_statement (delete_statement* s)
{
XXX expression* last_lrvalue = current_lrvalue;
bool last_lvalue_read = current_lvalue_read;
current_lrvalue = s->value; current_lvalue_read = true;
functioncall_traversing_visitor::visit_delete_statement (s);
current_lrvalue = last_lrvalue;
current_lvalue_read = last_lvalue_read;
}
bool
varuse_collecting_visitor::side_effect_free ()
{
return (written.empty() && !embedded_seen);
}
bool
varuse_collecting_visitor::side_effect_free_wrt (const set<vardecl*>& vars)
{
set<vardecl*> intersection;
insert_iterator<set<vardecl*> > int_it (intersection, intersection.begin());
set_intersection (written.begin(), written.end(),
vars.begin(), vars.end(),
int_it);
return (intersection.empty() && !embedded_seen);
}
throwing_visitor::throwing_visitor (const std::string& m): msg (m) {}
throwing_visitor::throwing_visitor (): msg (_("invalid element")) {}
void
throwing_visitor::throwone (const token* t)
{
throw SEMANTIC_ERROR (msg, t);
}
void
throwing_visitor::visit_block (block* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_try_block (try_block* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_embeddedcode (embeddedcode* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_null_statement (null_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_expr_statement (expr_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_if_statement (if_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_for_loop (for_loop* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_foreach_loop (foreach_loop* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_return_statement (return_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_delete_statement (delete_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_next_statement (next_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_break_statement (break_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_continue_statement (continue_statement* s)
{
throwone (s->tok);
}
void
throwing_visitor::visit_literal_string (literal_string* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_literal_number (literal_number* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_embedded_expr (embedded_expr* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_binary_expression (binary_expression* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_unary_expression (unary_expression* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_pre_crement (pre_crement* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_post_crement (post_crement* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_logical_or_expr (logical_or_expr* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_logical_and_expr (logical_and_expr* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_array_in (array_in* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_regex_query (regex_query* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_comparison (comparison* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_concatenation (concatenation* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_ternary_expression (ternary_expression* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_assignment (assignment* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_symbol (symbol* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_target_symbol (target_symbol* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_atvar_op (atvar_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_cast_op (cast_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_autocast_op (autocast_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_defined_op (defined_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_entry_op (entry_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_perf_op (perf_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_arrayindex (arrayindex* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_functioncall (functioncall* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_print_format (print_format* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_stat_op (stat_op* e)
{
throwone (e->tok);
}
void
throwing_visitor::visit_hist_op (hist_op* e)
{
throwone (e->tok);
}
void
update_visitor::visit_block (block* s)
{
for (unsigned i = 0; i < s->statements.size(); ++i)
replace (s->statements[i]);
provide (s);
}
void
update_visitor::visit_try_block (try_block* s)
{
replace (s->try_block);
replace (s->catch_error_var);
replace (s->catch_block);
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)
{
replace (s->value);
provide (s);
}
void
update_visitor::visit_if_statement (if_statement* s)
{
replace (s->condition);
replace (s->thenblock);
replace (s->elseblock);
provide (s);
}
void
update_visitor::visit_for_loop (for_loop* s)
{
replace (s->init);
replace (s->cond);
replace (s->incr);
replace (s->block);
provide (s);
}
void
update_visitor::visit_foreach_loop (foreach_loop* s)
{
for (unsigned i = 0; i < s->indexes.size(); ++i)
replace (s->indexes[i]);
replace (s->base);
replace (s->value);
replace (s->limit);
replace (s->block);
provide (s);
}
void
update_visitor::visit_return_statement (return_statement* s)
{
replace (s->value);
provide (s);
}
void
update_visitor::visit_delete_statement (delete_statement* s)
{
replace (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_embedded_expr (embedded_expr* e)
{
provide (e);
}
void
update_visitor::visit_binary_expression (binary_expression* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_unary_expression (unary_expression* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_pre_crement (pre_crement* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_post_crement (post_crement* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_logical_or_expr (logical_or_expr* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_logical_and_expr (logical_and_expr* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_array_in (array_in* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_regex_query (regex_query* e)
{
replace (e->left);
replace (e->right); XXX provide (e);
}
void
update_visitor::visit_comparison (comparison* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_concatenation (concatenation* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_ternary_expression (ternary_expression* e)
{
replace (e->cond);
replace (e->truevalue);
replace (e->falsevalue);
provide (e);
}
void
update_visitor::visit_assignment (assignment* e)
{
replace (e->left);
replace (e->right);
provide (e);
}
void
update_visitor::visit_symbol (symbol* e)
{
provide (e);
}
void
update_visitor::visit_target_symbol (target_symbol* e)
{
e->visit_components (this);
provide (e);
}
void
update_visitor::visit_cast_op (cast_op* e)
{
replace (e->operand);
e->visit_components (this);
provide (e);
}
void
update_visitor::visit_autocast_op (autocast_op* e)
{
replace (e->operand);
e->visit_components (this);
provide (e);
}
void
update_visitor::visit_atvar_op (atvar_op* e)
{
e->visit_components (this);
provide (e);
}
void
update_visitor::visit_defined_op (defined_op* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_entry_op (entry_op* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_perf_op (perf_op* e)
{
replace (e->operand);
provide (e);
}
void
update_visitor::visit_arrayindex (arrayindex* e)
{
replace (e->base);
for (unsigned i = 0; i < e->indexes.size(); ++i)
replace (e->indexes[i]);
provide (e);
}
void
update_visitor::visit_functioncall (functioncall* e)
{
for (unsigned i = 0; i < e->args.size(); ++i)
replace (e->args[i]);
provide (e);
}
void
update_visitor::visit_print_format (print_format* e)
{
for (unsigned i = 0; i < e->args.size(); ++i)
replace (e->args[i]);
replace (e->hist);
provide (e);
}
void
update_visitor::visit_stat_op (stat_op* e)
{
replace (e->stat);
provide (e);
}
void
update_visitor::visit_hist_op (hist_op* e)
{
replace (e->stat);
provide (e);
}
void
deep_copy_visitor::visit_block (block* s)
{
update_visitor::visit_block(new block(*s));
}
void
deep_copy_visitor::visit_try_block (try_block* s)
{
update_visitor::visit_try_block(new try_block(*s));
}
void
deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
{
update_visitor::visit_embeddedcode(new embeddedcode(*s));
}
void
deep_copy_visitor::visit_null_statement (null_statement* s)
{
update_visitor::visit_null_statement(new null_statement(*s));
}
void
deep_copy_visitor::visit_expr_statement (expr_statement* s)
{
update_visitor::visit_expr_statement(new expr_statement(*s));
}
void
deep_copy_visitor::visit_if_statement (if_statement* s)
{
update_visitor::visit_if_statement(new if_statement(*s));
}
void
deep_copy_visitor::visit_for_loop (for_loop* s)
{
update_visitor::visit_for_loop(new for_loop(*s));
}
void
deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
{
update_visitor::visit_foreach_loop(new foreach_loop(*s));
}
void
deep_copy_visitor::visit_return_statement (return_statement* s)
{
update_visitor::visit_return_statement(new return_statement(*s));
}
void
deep_copy_visitor::visit_delete_statement (delete_statement* s)
{
update_visitor::visit_delete_statement(new delete_statement(*s));
}
void
deep_copy_visitor::visit_next_statement (next_statement* s)
{
update_visitor::visit_next_statement(new next_statement(*s));
}
void
deep_copy_visitor::visit_break_statement (break_statement* s)
{
update_visitor::visit_break_statement(new break_statement(*s));
}
void
deep_copy_visitor::visit_continue_statement (continue_statement* s)
{
update_visitor::visit_continue_statement(new continue_statement(*s));
}
void
deep_copy_visitor::visit_literal_string (literal_string* e)
{
update_visitor::visit_literal_string(new literal_string(*e));
}
void
deep_copy_visitor::visit_literal_number (literal_number* e)
{
update_visitor::visit_literal_number(new literal_number(*e));
}
void
deep_copy_visitor::visit_embedded_expr (embedded_expr* e)
{
update_visitor::visit_embedded_expr(new embedded_expr(*e));
}
void
deep_copy_visitor::visit_binary_expression (binary_expression* e)
{
update_visitor::visit_binary_expression(new binary_expression(*e));
}
void
deep_copy_visitor::visit_unary_expression (unary_expression* e)
{
update_visitor::visit_unary_expression(new unary_expression(*e));
}
void
deep_copy_visitor::visit_pre_crement (pre_crement* e)
{
update_visitor::visit_pre_crement(new pre_crement(*e));
}
void
deep_copy_visitor::visit_post_crement (post_crement* e)
{
update_visitor::visit_post_crement(new post_crement(*e));
}
void
deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
{
update_visitor::visit_logical_or_expr(new logical_or_expr(*e));
}
void
deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
{
update_visitor::visit_logical_and_expr(new logical_and_expr(*e));
}
void
deep_copy_visitor::visit_array_in (array_in* e)
{
update_visitor::visit_array_in(new array_in(*e));
}
void
deep_copy_visitor::visit_regex_query (regex_query* e)
{
update_visitor::visit_regex_query(new regex_query(*e));
}
void
deep_copy_visitor::visit_comparison (comparison* e)
{
update_visitor::visit_comparison(new comparison(*e));
}
void
deep_copy_visitor::visit_concatenation (concatenation* e)
{
update_visitor::visit_concatenation(new concatenation(*e));
}
void
deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
{
update_visitor::visit_ternary_expression(new ternary_expression(*e));
}
void
deep_copy_visitor::visit_assignment (assignment* e)
{
update_visitor::visit_assignment(new assignment(*e));
}
void
deep_copy_visitor::visit_symbol (symbol* e)
{
symbol* n = new symbol(*e);
n->referent = NULL; update_visitor::visit_symbol(n);
}
void
deep_copy_visitor::visit_target_symbol (target_symbol* e)
{
target_symbol* n = new target_symbol(*e);
update_visitor::visit_target_symbol(n);
}
void
deep_copy_visitor::visit_cast_op (cast_op* e)
{
update_visitor::visit_cast_op(new cast_op(*e));
}
void
deep_copy_visitor::visit_autocast_op (autocast_op* e)
{
update_visitor::visit_autocast_op(new autocast_op(*e));
}
void
deep_copy_visitor::visit_atvar_op (atvar_op* e)
{
update_visitor::visit_atvar_op(new atvar_op(*e));
}
void
deep_copy_visitor::visit_defined_op (defined_op* e)
{
update_visitor::visit_defined_op(new defined_op(*e));
}
void
deep_copy_visitor::visit_entry_op (entry_op* e)
{
update_visitor::visit_entry_op(new entry_op(*e));
}
void
deep_copy_visitor::visit_perf_op (perf_op* e)
{
update_visitor::visit_perf_op(new perf_op(*e));
}
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(*e);
n->referent = NULL; update_visitor::visit_functioncall(n);
}
void
deep_copy_visitor::visit_print_format (print_format* e)
{
update_visitor::visit_print_format(new print_format(*e));
}
void
deep_copy_visitor::visit_stat_op (stat_op* e)
{
update_visitor::visit_stat_op(new stat_op(*e));
}
void
deep_copy_visitor::visit_hist_op (hist_op* e)
{
update_visitor::visit_hist_op(new hist_op(*e));
}