summaryrefslogtreecommitdiffstats
path: root/elaborate.cxx
diff options
context:
space:
mode:
authorgraydon <graydon>2005-11-24 05:55:52 +0000
committergraydon <graydon>2005-11-24 05:55:52 +0000
commit07c17d677a8080492b4a67b664f4cc9557f5dda3 (patch)
treeddff61760db8a9d3067f3e559ce36eca9e642811 /elaborate.cxx
parent5bb3c2a0266268e63d373de4df3fed2bb7d3be67 (diff)
downloadsystemtap-steved-07c17d677a8080492b4a67b664f4cc9557f5dda3.tar.gz
systemtap-steved-07c17d677a8080492b4a67b664f4cc9557f5dda3.tar.xz
systemtap-steved-07c17d677a8080492b4a67b664f4cc9557f5dda3.zip
2005-11-23 Graydon Hoare <graydon@redhat.com>
* elaborate.h (get_symbol_within_expression): Make visible. * elaborate.cxx (get_symbol_within_expression): Make non-static. (stat_decl_collector): New struct. (semantic_pass_stats): New semantic pass. (semantic_pass): Call it. (semantic_pass_symbols): Remove collection of statistic_decls from files. (visit_stat_op): Only fail if inferred type is not pe_long. * parse.cxx (parser::parse): Don't pass per-file statistic_decl into parse_global. (parser::parse_global): Don't parse global statistic_decls, they're obsolete. * parse.hh (parser::parse_global): Adjust signature to match. * session.h (statistic_decl::operator==): New method. * staptree.h (print_format::is_empty): New method. (stapfile::stat_decls): Remove field. * staptree.cxx (string_to_components): Fix bugs in format-string parser. * translate.cxx (var): Make private fields protected. (var::init): Support HIST_NONE stats. (aggvar): New struct. (mapvar::is_parallel): New method. (mapvar::call_prefix): Use it. (mapvar::calculate_aggregate): New method. (mapvar::fetch_existing_aggregate): New method. (mapvar::get): Support pe_stats. (mapvar::init): Use is_parallel(), and support HIST_NONE. (itervar::itervar): Only fault on pe_unknown. (itervar::start): Use mapvar::is_parallel and mapvar::fetch_existing_aggregate. (emit_map_type_instantiations): Include alloc.c before pmap-gen.c. Include pmap-gen.c for pe_stats maps. (c_unparser::gensym_aggregate): New method. (c_unparser::visit_foreach_loop): Handle mapvar::is_parallel case. (arrayindex_downcaster): New struct. (expression_is_arrayindex): New function. (c_tmpcounter::visit_stat_op): New method. (c_unparser::visit_stat_op): Implement. (c_unparser::visit_hist_op): Add commentary, still not implemented. * testsuite/buildok/stat_{insert,extract}.stp: New tests. * testsuite/semok/ten.stp: Correct for changes to global declarations. * testsuite/semko/*.stp: Likewise.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r--elaborate.cxx131
1 files changed, 109 insertions, 22 deletions
diff --git a/elaborate.cxx b/elaborate.cxx
index 280fd92f..de469a4f 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -456,7 +456,7 @@ derive_probes (systemtap_session& s,
//
struct symbol_fetcher
- : virtual public throwing_visitor
+ : public throwing_visitor
{
symbol *&sym;
@@ -480,7 +480,7 @@ struct symbol_fetcher
}
};
-static symbol *
+symbol *
get_symbol_within_expression (expression *e)
{
symbol *sym = NULL;
@@ -504,7 +504,7 @@ get_symbol_within_indexable (indexable *ix)
}
struct mutated_var_collector
- : virtual public traversing_visitor
+ : public traversing_visitor
{
set<vardecl *> * mutated_vars;
@@ -539,7 +539,7 @@ struct mutated_var_collector
struct no_var_mutation_during_iteration_check
- : virtual public traversing_visitor
+ : public traversing_visitor
{
systemtap_session & session;
map<functiondecl *,set<vardecl *> *> & function_mutates_vars;
@@ -648,10 +648,113 @@ semantic_pass_vars (systemtap_session & sess)
// ------------------------------------------------------------------------
+struct stat_decl_collector
+ : public traversing_visitor
+{
+ systemtap_session & session;
+
+ stat_decl_collector(systemtap_session & sess)
+ : session(sess)
+ {}
+
+ void visit_stat_op (stat_op* e)
+ {
+ symbol *sym = get_symbol_within_expression (e->stat);
+ if (session.stat_decls.find(sym->name) == session.stat_decls.end())
+ session.stat_decls[sym->name] = statistic_decl();
+ }
+
+ void visit_assignment (assignment* e)
+ {
+ if (e->op == "<<<")
+ {
+ symbol *sym = get_symbol_within_expression (e->left);
+ if (session.stat_decls.find(sym->name) == session.stat_decls.end())
+ session.stat_decls[sym->name] = statistic_decl();
+ }
+ else
+ traversing_visitor::visit_assignment(e);
+ }
+
+ void visit_hist_op (hist_op* e)
+ {
+ symbol *sym = get_symbol_within_expression (e->stat);
+ statistic_decl new_stat;
+
+ if (e->htype == hist_linear)
+ {
+ new_stat.type = statistic_decl::linear;
+ assert (e->params.size() == 3);
+ new_stat.linear_low = e->params[0];
+ new_stat.linear_high = e->params[1];
+ new_stat.linear_step = e->params[2];
+ }
+ else
+ {
+ assert (e->htype == hist_log);
+ new_stat.type = statistic_decl::logarithmic;
+ assert (e->params.size() == 1);
+ new_stat.logarithmic_buckets = e->params[0];
+ }
+
+ map<string, statistic_decl>::iterator i = session.stat_decls.find(sym->name);
+ if (i == session.stat_decls.end())
+ session.stat_decls[sym->name] = new_stat;
+ else
+ {
+ statistic_decl & old_stat = i->second;
+ if (!(old_stat == new_stat))
+ {
+ if (old_stat.type == statistic_decl::none)
+ i->second = new_stat;
+ else
+ {
+ // FIXME: Support multiple co-declared histogram types
+ semantic_error se("multiple histogram types declared on '" + sym->name + "'",
+ e->tok);
+ session.print_error (se);
+ }
+ }
+ }
+ }
+
+};
+
+static int
+semantic_pass_stats (systemtap_session & sess)
+{
+ stat_decl_collector sdc(sess);
+
+ for (unsigned i = 0; i < sess.functions.size(); ++i)
+ sess.functions[i]->body->visit (&sdc);
+
+ for (unsigned i = 0; i < sess.probes.size(); ++i)
+ sess.probes[i]->body->visit (&sdc);
+
+ for (unsigned i = 0; i < sess.globals.size(); ++i)
+ {
+ vardecl *v = sess.globals[i];
+ if (v->type == pe_stats)
+ {
+
+ if (sess.stat_decls.find(v->name) == sess.stat_decls.end())
+ {
+ semantic_error se("unable to infer statistic parameters for global '" + v->name + "'");
+ sess.print_error (se);
+ }
+ }
+ }
+
+ return sess.num_errors;
+}
+
+// ------------------------------------------------------------------------
+
static int semantic_pass_symbols (systemtap_session&);
static int semantic_pass_types (systemtap_session&);
static int semantic_pass_vars (systemtap_session&);
+static int semantic_pass_stats (systemtap_session&);
@@ -684,23 +787,6 @@ semantic_pass_symbols (systemtap_session& s)
for (unsigned i=0; i<dome->embeds.size(); i++)
s.embeds.push_back (dome->embeds[i]);
- for (std::map<std::string, statistic_decl>::const_iterator i =
- dome->stat_decls.begin(); i != dome->stat_decls.end(); ++i)
- {
- try
- {
-
- if (s.stat_decls.find(i->first) != s.stat_decls.end())
- throw semantic_error("multiple statistic declarations for " + i->first);
- s.stat_decls.insert(std::make_pair(i->first,
- i->second));
- }
- catch (const semantic_error& e)
- {
- s.print_error (e);
- }
- }
-
// Pass 2: process functions
for (unsigned i=0; i<dome->functions.size(); i++)
@@ -768,6 +854,7 @@ semantic_pass (systemtap_session& s)
rc = semantic_pass_symbols (s);
if (rc == 0) rc = semantic_pass_types (s);
if (rc == 0) rc = semantic_pass_vars (s);
+ if (rc == 0) rc = semantic_pass_stats (s);
}
catch (const semantic_error& e)
{
@@ -1941,7 +2028,7 @@ typeresolution_info::visit_stat_op (stat_op* e)
e->type = pe_long;
resolved (e->tok, e->type);
}
- else
+ else if (e->type != pe_long)
mismatch (e->tok, e->type, pe_long);
}