summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--elaborate.cxx36
-rw-r--r--parse.cxx20
-rw-r--r--stap.1.in22
-rw-r--r--staptree.h1
5 files changed, 71 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index e7478a9b..eaaddd5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-05-08 Li Guanglei <guanglei@cn.ibm.com>
+ PR 2627
+ * elaborate.cxx: epilogue style alias expansion
+ * parse.cxx: parse += alias definition
+ * staptree.h: add epilogue_style member to probe_alias
+ * stap.1.in: add the description of epilogue style alias
+ * testsuite/parseok/fifteen.stp: testcase for epilogue style alias
+
2006-05-05 Roland McGrath <roland@redhat.com>
* configure.ac (build_elfutils): Pass CFLAGS to elfutils configure,
diff --git a/elaborate.cxx b/elaborate.cxx
index f5b0496b..abb91540 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -344,17 +344,33 @@ alias_expansion_builder
// there's concatenated code here and we only want one vardecl per
// resulting variable.
- for (unsigned i = 0; i < alias->body->statements.size(); ++i)
- {
- statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]);
- n->body->statements.push_back(s);
- }
+ if(alias->epilogue_style == true) {
+ for (unsigned i = 0; i < use->body->statements.size(); ++i)
+ {
+ statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]);
+ n->body->statements.push_back(s);
+ }
- for (unsigned i = 0; i < use->body->statements.size(); ++i)
- {
- statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]);
- n->body->statements.push_back(s);
- }
+ for (unsigned i = 0; i < alias->body->statements.size(); ++i)
+ {
+ statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]);
+ n->body->statements.push_back(s);
+ }
+
+ } else {
+
+ for (unsigned i = 0; i < alias->body->statements.size(); ++i)
+ {
+ statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]);
+ n->body->statements.push_back(s);
+ }
+
+ for (unsigned i = 0; i < use->body->statements.size(); ++i)
+ {
+ statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]);
+ n->body->statements.push_back(s);
+ }
+ }
derive_probes (sess, n, finished_results, false);
}
diff --git a/parse.cxx b/parse.cxx
index 30c59b45..96d9a5d4 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -782,6 +782,8 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
bool equals_ok = true;
+ int epilogue_alias = 0;
+
while (1)
{
probe_point * pp = parse_probe_point ();
@@ -794,6 +796,15 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
next ();
continue;
}
+ else if (equals_ok && t
+ && t->type == tok_operator && t->content == "+=")
+ {
+ aliases.push_back(pp);
+ epilogue_alias = 1;
+ next ();
+ continue;
+ }
+
else if (t && t->type == tok_operator && t->content == ",")
{
locations.push_back(pp);
@@ -821,6 +832,10 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
else
{
probe_alias* p = new probe_alias (aliases);
+ if(epilogue_alias)
+ p->epilogue_style = true;
+ else
+ p->epilogue_style = false;
p->tok = t0;
p->locations = locations;
p->body = parse_stmt_block ();
@@ -1068,7 +1083,8 @@ parser::parse_probe_point ()
t = peek ();
if (t && t->type == tok_operator
- && (t->content == "{" || t->content == "," || t->content == "="))
+ && (t->content == "{" || t->content == "," || t->content == "="
+ || t->content == "+=" ))
break;
if (t && t->type == tok_operator && t->content == "(")
@@ -1093,7 +1109,7 @@ parser::parse_probe_point ()
if (t && t->type == tok_operator && t->content == ".")
next ();
else
- throw parse_error ("expected '.' or ',' or '(' or '{' or '='");
+ throw parse_error ("expected '.' or ',' or '(' or '{' or '=' or '+='");
}
return pl;
diff --git a/stap.1.in b/stap.1.in
index 31e38819..65b4b312 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -403,10 +403,16 @@ with optimized code. Some other events have very little context.
New probe points may be defined using "aliases". Probe point aliases
look similar to probe definitions, but instead of activating a probe
at the given point, it just defines a new probe point name as an alias
-to an existing one. This is identified by the "=" assignment
-operator. In addition, the statement block that follows an alias
+to an existing one. There are two types of alias, i.e. the prologue
+style and the epilogue style which are identified by "=" and "+="
+respectively.
+
+For prologue style alias, the statement block that follows an alias
definition is implicitly added as a prologue to any probe that refers
-to the alias. For example:
+to the alias. While for the epilogue style alias, the statement block
+that follows an alias definition is implicitly added as an epilogue to
+any probe that refers to the alias. For example:
+
.SAMPLE
probe syscall.read = kernel.function("sys_read") {
fildes = $fd
@@ -420,7 +426,15 @@ which expands to
.nh
.IR kernel.function("sys_read") ,
.hy
-with the given assignment as a prologue. Another probe definition
+with the given statement as a prologue. And
+.SAMPLE
+probe syscall.read += kernel.function("sys_read") {
+ fildes = $fd
+}
+.ESAMPLE
+defines a new probe point with the given statement as an epilogue.
+
+Another probe definition
may use the alias like this:
.SAMPLE
probe syscall.read {
diff --git a/staptree.h b/staptree.h
index 3221e43b..4eed068d 100644
--- a/staptree.h
+++ b/staptree.h
@@ -585,6 +585,7 @@ struct probe_alias: public probe
probe_alias(std::vector<probe_point*> const & aliases);
std::vector<probe_point*> alias_names;
virtual void printsig (std::ostream &o) const;
+ bool epilogue_style;
};