From 07c17d677a8080492b4a67b664f4cc9557f5dda3 Mon Sep 17 00:00:00 2001 From: graydon Date: Thu, 24 Nov 2005 05:55:52 +0000 Subject: 2005-11-23 Graydon Hoare * 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. --- elaborate.cxx | 131 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 22 deletions(-) (limited to 'elaborate.cxx') 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 * 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 *> & 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::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; iembeds.size(); i++) s.embeds.push_back (dome->embeds[i]); - for (std::map::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; ifunctions.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); } -- cgit