From: fche Date: Fri, 4 Mar 2005 20:10:09 +0000 (+0000) Subject: 2005-03-04 Frank Ch. Eigler X-Git-Tag: release-0.2.2~246 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=0fefb486c5965e371cb52f55548123233da85f72;p=systemtap.git 2005-03-04 Frank Ch. Eigler * parse.cxx (scan): Support '$' characters in identifiers. (parse_symbol): Support thread-> / process-> shorthand. * staptree.cxx (symresolution_info::find): Split up into find_scalar, find_array, find_function. (resolve_symbols): Call the above for symbol/arrayindex/functioncall. (find_scalar): Add stub support for synthetic builtin variables. * staptree.h: Corresponding changes. * testsuite/*: Some new tests. --- diff --git a/ChangeLog b/ChangeLog index a03c482bc..d87b69ddd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-03-04 Frank Ch. Eigler + + * parse.cxx (scan): Support '$' characters in identifiers. + (parse_symbol): Support thread-> / process-> shorthand. + * staptree.cxx (symresolution_info::find): Split up into + find_scalar, find_array, find_function. + (resolve_symbols): Call the above for symbol/arrayindex/functioncall. + (find_scalar): Add stub support for synthetic builtin variables. + * staptree.h: Corresponding changes. + * testsuite/*: Some new tests. + 2005-03-03 Frank Ch. Eigler * parse.cxx (parse_assignment): Assert lvalueness of left diff --git a/parse.cxx b/parse.cxx index 41ec6fef9..640c37152 100644 --- a/parse.cxx +++ b/parse.cxx @@ -157,7 +157,7 @@ lexer::scan () if (isspace (c)) goto skip; - else if (isalpha (c)) + else if (isalpha (c) || c == '$') { n->type = tok_identifier; n->content = (char) c; @@ -166,7 +166,7 @@ lexer::scan () int c2 = input.peek (); if (! input) break; - if ((isalnum(c2) || c2 == '_')) + if ((isalnum(c2) || c2 == '_' || c2 == '$')) { n->content.push_back(c2); input_get (); @@ -247,6 +247,7 @@ lexer::scan () (c == '+' && c2 == '=') || (c == '-' && c2 == '=') || (c == ':' && c2 == ':') || + (c == '-' && c2 == '>') || false) // XXX: etc. n->content.push_back((char) input_get ()); @@ -947,8 +948,9 @@ parser::parse_value () } +// var, var[index], func(parms), thread->var, process->var expression* -parser::parse_symbol () // var, var[index], func(parms) +parser::parse_symbol () { const token* t = next (); if (t->type != tok_identifier) @@ -957,7 +959,34 @@ parser::parse_symbol () // var, var[index], func(parms) string name = t->content; t = peek (); - if (t && t->type == tok_operator && t->content == "[") // array + if (t && t->type == tok_operator && t->content == "->") + { + // shorthand for process- or thread-specific array element + // map "thread->VAR" to "VAR[$tid]", + // and "process->VAR" to "VAR[$pid]" + symbol* sym = new symbol; + if (name == "thread") + sym->name = "$tid"; + else if (name == "process") + sym->name = "$pid"; + else + throw parse_error ("expected 'thread->' or 'process->'"); + struct token* t2prime = new token (*t2); + t2prime->content = sym->name; + sym->tok = t2prime; + + next (); // swallow "->" + t = next (); + if (! (t->type == tok_identifier)) + throw parse_error ("expected identifier"); + + struct arrayindex* ai = new arrayindex; + ai->tok = t; + ai->base = t->content; + ai->indexes.push_back (sym); + return ai; + } + else if (t && t->type == tok_operator && t->content == "[") // array { next (); struct arrayindex* ai = new arrayindex; diff --git a/parse.h b/parse.h index ddfb19c1a..c8008bc77 100644 --- a/parse.h +++ b/parse.h @@ -22,6 +22,7 @@ enum token_type tok_junk, tok_identifier, tok_operator, tok_string, tok_number }; + struct token { source_loc location; @@ -29,6 +30,7 @@ struct token std::string content; }; + std::ostream& operator << (std::ostream& o, const token& t); diff --git a/staptree.cxx b/staptree.cxx index 8a4fc1483..2bbdea9fc 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -387,7 +387,7 @@ symbol::resolve_symbols (symresolution_info& r) if (referent) return; - vardecl* d = r.find (name); + vardecl* d = r.find_scalar (name); if (d) referent = d; else @@ -398,7 +398,6 @@ symbol::resolve_symbols (symresolution_info& r) v->tok = tok; r.locals.push_back (v); referent = v; - // XXX: check for conflicting function name } } @@ -412,7 +411,7 @@ arrayindex::resolve_symbols (symresolution_info& r) if (referent) return; - vardecl* d = r.find (base); + vardecl* d = r.find_array (base, indexes); if (d) referent = d; else @@ -423,7 +422,6 @@ arrayindex::resolve_symbols (symresolution_info& r) v->tok = tok; r.locals.push_back (v); referent = v; - // XXX: check for conflicting function name } } @@ -437,19 +435,7 @@ functioncall::resolve_symbols (symresolution_info& r) if (referent) return; - // find global functiondecl - functiondecl* d = 0; - for (unsigned j = 0; j < r.current_file->functions.size(); j++) - { - functiondecl* fd = r.current_file->functions[j]; - if (fd->name == function) - { - d = fd; - break; - } - } - // XXX: check for conflicting variable name - + functiondecl* d = r.find_function (function, args); if (d) referent = d; else @@ -492,13 +478,32 @@ expr_statement::resolve_symbols (symresolution_info& r) vardecl* -symresolution_info::find (const string& name) +symresolution_info::find_scalar (const string& name) { // search locals for (unsigned i=0; iname == name) return locals[i]; + // search builtins that become locals + // XXX: need to invent a proper formalism for this + if (name == "$pid" || name == "$tid") + { + vardecl_builtin* vb = new vardecl_builtin; + vb->name = name; + vb->type = pe_long; + + // XXX: need a better way to synthesize tokens + token* t = new token; + t->type = tok_identifier; + t->content = name; + t->location.file = ""; + vb->tok = t; + + locals.push_back (vb); + return vb; + } + // search function formal parameters (if any) if (current_function) { @@ -513,9 +518,54 @@ symresolution_info::find (const string& name) return globals[i]; return 0; + // XXX: add checking for conflicting array or function } +vardecl* +symresolution_info::find_array (const string& name, + const vector& indexes) +{ + // search locals + for (unsigned i=0; iname == name) + return locals[i]; + + // search function formal parameters (if any) + if (current_function) + { + for (unsigned i=0; iformal_args.size(); i++) + if (current_function->formal_args [i]->name == name) + return current_function->formal_args [i]; + } + + // search globals + for (unsigned i=0; iname == name) + return globals[i]; + + return 0; + // XXX: add checking for conflicting scalar or function +} + + +functiondecl* +symresolution_info::find_function (const string& name, + const vector& args) +{ + for (unsigned j = 0; j < current_file->functions.size(); j++) + { + functiondecl* fd = current_file->functions[j]; + if (fd->name == name) + return fd; + } + + return 0; + // XXX: add checking for conflicting variables +} + + + void symresolution_info::unresolved (const token* tok) { diff --git a/staptree.h b/staptree.h index a95d9f057..b38221bc1 100644 --- a/staptree.h +++ b/staptree.h @@ -209,7 +209,9 @@ struct symresolution_info vector& f, stapfile* cfil); - vardecl* find (const string& name); + vardecl* find_scalar (const string& name); + vardecl* find_array (const string& name, const vector&); + functiondecl* find_function (const string& name, const vector&); void unresolved (const token* tok); unsigned num_unresolved; @@ -257,6 +259,11 @@ struct vardecl: public symboldecl }; +struct vardecl_builtin: public vardecl +{ +}; + + struct block; struct functiondecl: public symboldecl { diff --git a/testsuite/parseko/four.stp b/testsuite/parseko/four.stp new file mode 100755 index 000000000..ad77239b1 --- /dev/null +++ b/testsuite/parseko/four.stp @@ -0,0 +1,5 @@ +#! semtest + +probe foo { + somethingawful->foo = 1; +} diff --git a/testsuite/parseok/three.stp b/testsuite/parseok/three.stp new file mode 100755 index 000000000..b2628d4d0 --- /dev/null +++ b/testsuite/parseok/three.stp @@ -0,0 +1,7 @@ +#! parsetest + +probe kernel:systemcall("foo") +{ + $a = a$a = a$a$ = 0; +} + diff --git a/testsuite/semok/six.stp b/testsuite/semok/six.stp new file mode 100755 index 000000000..53d695035 --- /dev/null +++ b/testsuite/semok/six.stp @@ -0,0 +1,7 @@ +#! parsetest + +probe foo +{ + thread->bar = 4; + process->baz = "5"; +}