diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | elaborate.cxx | 35 | ||||
-rw-r--r-- | elaborate.h | 1 | ||||
-rw-r--r-- | parse.cxx | 18 | ||||
-rw-r--r-- | staptree.cxx | 38 | ||||
-rw-r--r-- | staptree.h | 4 | ||||
-rw-r--r-- | tapsets.cxx | 17 |
7 files changed, 128 insertions, 12 deletions
@@ -1,3 +1,30 @@ +2007-11-20 Masami Hiramatsu <mhiramat@redhat.com> + + PR 4935. + * parse.cxx (parser::parse_probe_point): Parse "if" condition + following probe point. + * staptree.h (probe_point): Add "condition" field. + (probe): Add "condition" field and "add_condition" method. + (deep_copy_visitor): Add "deep_copy" method for the expression. + * staptree.cxx (probe_point::probe_point): Initalize it. + (probe::add_condition): Implement it. + (probe::print): Output "condition" field. + (probe::str): Ditto. + (deep_copy_visitor::deep_copy): Implement it. + * elaborate.h (derived_probe): Add "insert_condition_statement" + method. + * elaborate.cxx (derived_probe::derived_probe): Initialize "condition" + field, and insert a condition check routine on the top of body. + (derived_probe::insert_condition_statement): Implement it. + (alias_expansion_builder::build): Pass the condition from the alias + referer to new alias. + * tapsets.cxx (be_derived_probe): Remove unused constructor. + (dwarf_derived_probe::dwarf_derived_probe): Insert a condition check + routine on the top of body. + (mark_derived_probe::mark_derived_probe): Ditto. + (mark_builder::build): Pass the base location to mark_derived_probe. + + 2007-11-19 Frank Ch. Eigler <fche@elastic.org> PR 3887. diff --git a/elaborate.cxx b/elaborate.cxx index aa6529fa..d3bbe28d 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -39,7 +39,8 @@ derived_probe::derived_probe (probe *p): { if (p) { - this->locations = p->locations; + this->locations = p->locations; + this->condition = deep_copy_visitor::deep_copy(p->condition); this->tok = p->tok; this->privileged = p->privileged; this->body = deep_copy_visitor::deep_copy(p->body); @@ -50,17 +51,41 @@ derived_probe::derived_probe (probe *p): derived_probe::derived_probe (probe *p, probe_point *l): base (p) { - if (l) - this->locations.push_back (l); - if (p) { + this->condition = deep_copy_visitor::deep_copy(p->condition); this->tok = p->tok; this->privileged = p->privileged; this->body = deep_copy_visitor::deep_copy(p->body); } + + if (l) + { + probe_point *pp = new probe_point (l->components, l->tok); + this->locations.push_back (pp); + this->add_condition (l->condition); + this->insert_condition_statement (); + } } +void +derived_probe::insert_condition_statement (void) +{ + if (this->condition) + { + if_statement *ifs = new if_statement (); + ifs->tok = this->tok; + ifs->thenblock = new next_statement (); + ifs->thenblock->tok = this->tok; + ifs->elseblock = NULL; + unary_expression *notex = new unary_expression (); + notex->op = "!"; + notex->tok = this->tok; + notex->operand = this->condition; + ifs->condition = notex; + body->statements.insert (body->statements.begin(), ifs); + } +} void derived_probe::printsig (ostream& o) const @@ -435,6 +460,8 @@ alias_expansion_builder // the token location of the alias, n->tok = location->tok; n->body->tok = location->tok; + // The new probe takes over condition. + n->add_condition (location->condition); // and statements representing the concatenation of the alias' // body with the use's. diff --git a/elaborate.h b/elaborate.h index 6967e1e7..13246b86 100644 --- a/elaborate.h +++ b/elaborate.h @@ -118,6 +118,7 @@ struct derived_probe: public probe virtual probe_point* sole_location () const; virtual void printsig (std::ostream &o) const; void printsig_nested (std::ostream &o) const; + void insert_condition_statement (void); virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list); virtual void emit_probe_context_vars (translator_output*) {} @@ -1358,6 +1358,24 @@ parser::parse_probe_point () // fall through } + if (t && t->type == tok_keyword && t->content == "if") + { + next (); + t = peek (); + if (! (t->type == tok_operator && t->content == "(")) + throw parse_error ("expected '('"); + next (); + + pl->condition = parse_expression (); + + t = peek (); + if (! (t->type == tok_operator && t->content == ")")) + throw parse_error ("expected ')'"); + next (); + t = peek (); + // fall through + } + if (t && t->type == tok_operator && (t->content == "{" || t->content == "," || t->content == "=" || t->content == "+=" )) diff --git a/staptree.cxx b/staptree.cxx index 8b702306..42fc8c24 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -75,12 +75,13 @@ symboldecl::~symboldecl () probe_point::probe_point (std::vector<component*> const & comps, const token * t): - components(comps), tok(t), optional (false), sufficient (false) + components(comps), tok(t), optional (false), sufficient (false), + condition (NULL) { } probe_point::probe_point (): - tok (0), optional (false), sufficient (false) + tok (0), optional (false), sufficient (false), condition (NULL) { } @@ -897,6 +898,26 @@ probe::collect_derivation_chain (std::vector<derived_probe*> &probes_list) probes_list.push_back((derived_probe*)this); } +void +probe::add_condition (expression* e) +{ + if (e) + { + if (this->condition) + { + logical_and_expr *la = new logical_and_expr (); + la->op = "&&"; + la->left = this->condition; + la->right = e; + la->tok = e->tok; + this->condition = la; + } + else + { + this->condition = e; + } + } +} void probe_point::print (ostream& o) const { @@ -912,6 +933,8 @@ void probe_point::print (ostream& o) const o << "!"; else if (optional) // sufficient implies optional o << "?"; + if (condition) + o<< " if (" << *condition << ")"; } string probe_point::str () @@ -929,6 +952,8 @@ string probe_point::str () o << "!"; else if (optional) // sufficient implies optional o << "?"; + if (condition) + o<< " if (" << *condition << ")"; return o.str(); } @@ -2355,3 +2380,12 @@ deep_copy_visitor::deep_copy (statement* s) 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; +} @@ -574,6 +574,7 @@ struct probe_point const token* tok; // points to first component's functor bool optional; bool sufficient; + expression* condition; void print (std::ostream& o) const; probe_point (); probe_point(std::vector<component*> const & comps,const token * t); @@ -590,8 +591,10 @@ struct probe const token* tok; std::vector<vardecl*> locals; std::vector<vardecl*> unused_locals; + expression* condition; probe (); void print (std::ostream& o) const; + void add_condition (expression* e); virtual void printsig (std::ostream &o) const; virtual void collect_derivation_chain (std::vector<derived_probe*> &probes_list); virtual probe* basest () { return this; } @@ -794,6 +797,7 @@ struct deep_copy_visitor: public visitor { std::stack<void *> targets; + static expression *deep_copy (expression *s); static statement *deep_copy (statement *s); static block *deep_copy (block *s); diff --git a/tapsets.cxx b/tapsets.cxx index 6a145715..3b992d4d 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -81,8 +81,6 @@ struct be_derived_probe: public derived_probe be_t type; int64_t priority; - be_derived_probe (probe* p, be_t t, int64_t pr): - derived_probe (p), type (t), priority (pr) {} be_derived_probe (probe* p, probe_point* l, be_t t, int64_t pr): derived_probe (p, l), type (t), priority (pr) {} @@ -3720,6 +3718,9 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, (TOK_MAXACTIVE, new literal_number(maxactive_val))); locations.push_back(new probe_point(comps, q.base_loc->tok)); + if (q.base_loc->condition) + add_condition (q.base_loc->condition); + insert_condition_statement (); } @@ -4943,7 +4944,7 @@ struct mark_derived_probe: public derived_probe { mark_derived_probe (systemtap_session &s, const string& probe_name, const string& probe_sig, - probe* base_probe); + probe* base_probe, expression* cond); systemtap_session& sess; string probe_name, probe_sig; @@ -5076,7 +5077,7 @@ mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) mark_derived_probe::mark_derived_probe (systemtap_session &s, const string& p_n, const string& p_s, - probe* base): + probe* base, expression* cond): derived_probe (base, 0), sess (s), probe_name (p_n), probe_sig (p_s), target_symbol_seen (false) { @@ -5091,6 +5092,10 @@ mark_derived_probe::mark_derived_probe (systemtap_session &s, pp->components.push_back (c); this->locations.push_back (pp); + if (cond) + add_condition (cond); + insert_condition_statement (); + // expand the signature string parse_probe_sig(); @@ -5436,7 +5441,7 @@ public: void mark_builder::build(systemtap_session & sess, probe * base, - probe_point *, + probe_point *loc, std::map<std::string, literal *> const & parameters, vector<derived_probe *> & finished_results) { @@ -5491,7 +5496,7 @@ mark_builder::build(systemtap_session & sess, derived_probe *dp = new mark_derived_probe (sess, it->first, it->second, - base); + base, loc->condition); finished_results.push_back (dp); } } |