summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorgraydon <graydon>2005-10-20 22:11:33 +0000
committergraydon <graydon>2005-10-20 22:11:33 +0000
commit57b73400d06052b179335059c2f440350fd28c99 (patch)
tree1fe125be909fd23d7591f63f96dd66018400b1ac /parse.cxx
parentf6f492468e2dfec286e3611e3e38ad070c91ae9d (diff)
downloadsystemtap-steved-57b73400d06052b179335059c2f440350fd28c99.tar.gz
systemtap-steved-57b73400d06052b179335059c2f440350fd28c99.tar.xz
systemtap-steved-57b73400d06052b179335059c2f440350fd28c99.zip
2005-10-20 Graydon Hoare <graydon@redhat.com>
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.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx57
1 files changed, 51 insertions, 6 deletions
diff --git a/parse.cxx b/parse.cxx
index dc9024c9..2bcf9231 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -15,6 +15,7 @@
#include <cstdlib>
#include <cerrno>
#include <climits>
+#include <sstream>
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 <vardecl*>& globals)
+parser::parse_global (vector <vardecl*>& globals,
+ std::map<std::string, statistic_decl> &stat_decls)
{
const token* t0 = next ();
if (! (t0->type == tok_identifier && t0->content == "global"))
@@ -725,15 +737,48 @@ parser::parse_global (vector <vardecl*>& 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; i<globals.size(); i++)
if (globals[i]->name == 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));
}