summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog27
-rw-r--r--elaborate.cxx35
-rw-r--r--elaborate.h1
-rw-r--r--parse.cxx18
-rw-r--r--staptree.cxx38
-rw-r--r--staptree.h4
-rw-r--r--tapsets.cxx17
7 files changed, 128 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index eae8dda8..83e56786 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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*) {}
diff --git a/parse.cxx b/parse.cxx
index 228f9a2c..2732194c 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -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;
+}
diff --git a/staptree.h b/staptree.h
index d8c97633..9e32d16b 100644
--- a/staptree.h
+++ b/staptree.h
@@ -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);
}
}