summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authorgraydon <graydon>2005-12-08 02:33:55 +0000
committergraydon <graydon>2005-12-08 02:33:55 +0000
commit71572ba8dfa3b045dfdcd0c8e0a2db168659ea10 (patch)
tree099a29d98018d4ca2e56a1e3cdf476680871eca0 /translate.cxx
parent90b474e36fdcb17b1d57f8bb0c01d87b0f5e0a96 (diff)
downloadsystemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.tar.gz
systemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.tar.xz
systemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.zip
2005-12-07 Graydon Hoare <graydon@redhat.com>
* staptree.cxx (traversing_visitor::visit_foreach_loop): Visit the base indexable of the foreach loop. * translate.cxx (c_tmpcounter::visit_foreach_loop): Implement histogram bucket iteration arm. (c_unparser::visit_foreach_loop): Likewise. (c_tmpcounter::visit_arrayindex): Fix typo. * testsuite/buildok/iterate_histogram_buckets.stp: New test.
Diffstat (limited to 'translate.cxx')
-rw-r--r--translate.cxx125
1 files changed, 86 insertions, 39 deletions
diff --git a/translate.cxx b/translate.cxx
index fe1de0a5..a4ca176d 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -1814,6 +1814,38 @@ c_unparser::visit_for_loop (for_loop *s)
}
+struct arrayindex_downcaster
+ : public traversing_visitor
+{
+ arrayindex *& arr;
+
+ arrayindex_downcaster (arrayindex *& arr)
+ : arr(arr)
+ {}
+
+ void visit_arrayindex (arrayindex* e)
+ {
+ arr = e;
+ }
+};
+
+
+static bool
+expression_is_arrayindex (expression *e,
+ arrayindex *& hist)
+{
+ arrayindex *h = NULL;
+ arrayindex_downcaster d(h);
+ e->visit (&d);
+ if (static_cast<void*>(h) == static_cast<void*>(e))
+ {
+ hist = h;
+ return true;
+ }
+ return false;
+}
+
+
void
c_tmpcounter::visit_foreach_loop (foreach_loop *s)
{
@@ -1825,13 +1857,44 @@ c_tmpcounter::visit_foreach_loop (foreach_loop *s)
{
itervar iv = parent->getiter (array);
parent->o->newline() << iv.declare();
- s->block->visit (this);
}
else
- {
- // FIXME: fill in some logic here!
- assert(false);
+ {
+ // See commentary in c_tmpcounter::visit_arrayindex for
+ // discussion of tmpvars required to look into @hist_op(...)
+ // expressions.
+
+ // First make sure we have exactly one pe_long variable to use as
+ // our bucket index.
+
+ if (s->indexes.size() != 1 || s->indexes[0]->referent->type != pe_long)
+ throw semantic_error("Invalid indexing of histogram", s->tok);
+
+ // Then declare what we need to form the aggregate we're
+ // iterating over, and all the tmpvars needed by our call to
+ // load_aggregate().
+
+ aggvar agg = parent->gensym_aggregate ();
+ agg.declare(*(this->parent));
+
+ symbol *sym = get_symbol_within_expression (hist->stat);
+ var v = parent->getvar(sym->referent, sym->tok);
+ if (sym->referent->arity != 0)
+ {
+ arrayindex *arr = NULL;
+ if (!expression_is_arrayindex (hist->stat, arr))
+ throw semantic_error("expected arrayindex expression in iterated hist_op", s->tok);
+
+ for (unsigned i=0; i<sym->referent->index_types.size(); i++)
+ {
+ tmpvar ix = parent->gensym (sym->referent->index_types[i]);
+ ix.declare (*parent);
+ arr->indexes[i]->visit(this);
+ }
+ }
}
+
+ s->block->visit (this);
}
void
@@ -1921,8 +1984,24 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
}
else
{
- // FIXME: fill in some logic here!
- assert(false);
+ // Iterating over buckets in a histogram.
+ assert(s->indexes.size() == 1);
+ assert(s->indexes[0]->referent->type == pe_long);
+ var bucketvar = getvar (s->indexes[0]->referent);
+
+ aggvar agg = gensym_aggregate ();
+ load_aggregate(hist->stat, agg);
+
+ symbol *sym = get_symbol_within_expression (hist->stat);
+ var v = getvar(sym->referent, sym->tok);
+ v.assert_hist_compatible(*hist);
+
+ o->newline() << "for (" << bucketvar << " = 0; "
+ << bucketvar << " < " << v.buckets() << "; "
+ << bucketvar << "++) { ";
+ o->newline(1);
+ s->block->visit (this);
+ o->newline(-1) << "}";
}
}
@@ -2556,38 +2635,6 @@ c_unparser::load_map_indices(arrayindex *e,
}
-struct arrayindex_downcaster
- : public traversing_visitor
-{
- arrayindex *& arr;
-
- arrayindex_downcaster (arrayindex *& arr)
- : arr(arr)
- {}
-
- void visit_arrayindex (arrayindex* e)
- {
- arr = e;
- }
-};
-
-
-static bool
-expression_is_arrayindex (expression *e,
- arrayindex *& hist)
-{
- arrayindex *h = NULL;
- arrayindex_downcaster d(h);
- e->visit (&d);
- if (static_cast<void*>(h) == static_cast<void*>(e))
- {
- hist = h;
- return true;
- }
- return false;
-}
-
-
void
c_unparser::load_aggregate (expression *e, aggvar & agg)
{
@@ -2702,7 +2749,7 @@ c_tmpcounter::visit_arrayindex (arrayindex *e)
{
arrayindex *arr = NULL;
if (!expression_is_arrayindex (hist->stat, arr))
- throw semantic_error("expected arrayindex expression in printed hist_op", e->tok);
+ throw semantic_error("expected arrayindex expression in indexed hist_op", e->tok);
for (unsigned i=0; i<sym->referent->index_types.size(); i++)
{