diff options
author | graydon <graydon> | 2005-11-24 05:55:52 +0000 |
---|---|---|
committer | graydon <graydon> | 2005-11-24 05:55:52 +0000 |
commit | 07c17d677a8080492b4a67b664f4cc9557f5dda3 (patch) | |
tree | ddff61760db8a9d3067f3e559ce36eca9e642811 /elaborate.cxx | |
parent | 5bb3c2a0266268e63d373de4df3fed2bb7d3be67 (diff) | |
download | systemtap-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.cxx | 131 |
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); } |