From 57b73400d06052b179335059c2f440350fd28c99 Mon Sep 17 00:00:00 2001 From: graydon Date: Thu, 20 Oct 2005 22:11:33 +0000 Subject: 2005-10-20 Graydon Hoare PR 917 (incomplete) * staptree.h (struct statistic_decl): New struct. (stapfile::stat_decls): New member. * parse.h, parse.cxx (parser::expect_known): Fix typo. (parser::expect_number): New method. (parser::parse_global): Parse global statistic_decls. * elaborate.h (systemtap_session::stat_decls): New member. * elaborate.cxx (semantic_pass_symbols): Copy per-file stat_decls to session-wide. (typeresolution_info::visit_assignment): Detect some semantic stats errors in type resolution pass. * translate.cxx (var::sd): New private member. (var::var): Initialize it. (var::sdecl): New accessor. (var::init): Handle stats values. (mapvar::mapvar): Pass through statistic_decl to var ctor. (mapvar::get): Test for long explicitly. (mapvar::set): Likewise. (mapvar::init): Handle stats values. (c_unparser::emit_common_header): Remove typedef of stats_t, include stat.c when necessary. (mapvar::key_typename): Typo. (c_unparser::emit_map_type_instantiations): Thinko: value_typename not key_typename. (c_unparser::c_typename): Implementation typename is "Stat", not "stats_t". (c_unparser::c_assign): Fix bad error message. (c_unparser_assignment::c_assignop): Handle operator <<<. (c_unparser::getvar): Feed session statistic_decl into var. (c_unparser::getmap): Likewise. (c_unparser::visit_assignment): Handle operator <<<. (c_tmpcounter_assignment::visit_symbol): Derive type from rvalue when present. (c_unparser_assignment::visit_symbol) (c_tmpcounter_assignment::visit_arrayindex) (c_unparser_assignment::load_map_indices): Likewise. (c_unparser::visit_arrayindex): Likewise, and Prohibit statistic rvalues. (c_unparser_assignment::visit_arrayindex): Handle operator <<<. * testsuite/semko/twentyfour.stp: * testsuite/semko/twentyfive.stp: * testsuite/semko/twentysix.stp: * testsuite/semko/twentyseven.stp: * testsuite/semko/twentyeight.stp: * testsuite/semko/twentynine.stp: * testsuite/semko/thirty.stp: * testsuite/semko/thirtyone.stp: New tests for prohibited statistic contexts. * testsuite/buildok/twentytwo.stp: New test for legal statistic contexts. --- parse.cxx | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'parse.cxx') diff --git a/parse.cxx b/parse.cxx index dc9024c9..2bcf9231 100644 --- a/parse.cxx +++ b/parse.cxx @@ -15,6 +15,7 @@ #include #include #include +#include using namespace std; @@ -160,7 +161,7 @@ const token* parser::expect_known (token_type tt, string const & expected) { const token *t = next(); - if (! t && t->type == tt && t->content == expected) + if (! (t && t->type == tt && t->content == expected)) throw parse_error ("expected '" + expected + "'"); return t; } @@ -190,6 +191,16 @@ parser::expect_kw (std::string const & expected) return expect_known (tok_identifier, expected); } +const token* +parser::expect_number (int64_t & expected) +{ + std::string tmp; + token const * tt = expect_unknown (tok_number, tmp); + istringstream iss(tmp); + iss >> expected; + return tt; +} + const token* parser::expect_ident (std::string & target) @@ -507,7 +518,7 @@ parser::parse () if (t->type == tok_identifier && t->content == "probe") parse_probe (f->probes, f->aliases); else if (t->type == tok_identifier && t->content == "global") - parse_global (f->globals); + parse_global (f->globals, f->stat_decls); else if (t->type == tok_identifier && t->content == "function") parse_functiondecl (f->functions); else if (t->type == tok_embedded) @@ -713,7 +724,8 @@ parser::parse_statement () void -parser::parse_global (vector & globals) +parser::parse_global (vector & globals, + std::map &stat_decls) { const token* t0 = next (); if (! (t0->type == tok_identifier && t0->content == "global")) @@ -725,15 +737,48 @@ parser::parse_global (vector & globals) if (! (t->type == tok_identifier)) throw parse_error ("expected identifier"); + statistic_decl sd; + + if (t->content == "log_hist") + { + std::string tmp; + expect_op ("("); + t = expect_ident (tmp); + expect_op (","); + expect_number (sd.logarithmic_buckets); + expect_op (")"); + sd.type = statistic_decl::logarithmic; + } + else if (t->content == "linear_hist") + { + std::string tmp; + expect_op ("("); + t = expect_ident (tmp); + expect_op (","); + expect_number (sd.linear_low); + expect_op (","); + expect_number (sd.linear_high); + expect_op (","); + expect_number (sd.linear_step); + expect_op (")"); + sd.type = statistic_decl::linear; + } + for (unsigned i=0; iname == t->content) - throw parse_error ("duplicate global name"); - + throw parse_error ("duplicate global name"); + vardecl* d = new vardecl; d->name = t->content; d->tok = t; globals.push_back (d); + if (sd.type != statistic_decl::none) + { + d->type = pe_stats; + stat_decls[d->name] = sd; + } + t = peek (); if (t && t->type == tok_operator && t->content == ",") { @@ -1701,7 +1746,7 @@ parser::parse_symbol () { next(); expect_unknown (tok_number, c); - expect_op ("]"); + expect_op ("]"); tsym->components.push_back (make_pair (target_symbol::comp_literal_array_index, c)); } -- cgit