summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-07-26 22:40:14 +0000
committerfche <fche>2005-07-26 22:40:14 +0000
commit54dfabe9e604ec06cdb5550f58420c60d0cbdbd9 (patch)
tree2dc021fd5534f57a51235a9598cec6cec9ed2342
parentf05bc729c752cee5eb11fde9193eea12a21b0d12 (diff)
downloadsystemtap-steved-54dfabe9e604ec06cdb5550f58420c60d0cbdbd9.tar.gz
systemtap-steved-54dfabe9e604ec06cdb5550f58420c60d0cbdbd9.tar.xz
systemtap-steved-54dfabe9e604ec06cdb5550f58420c60d0cbdbd9.zip
2005-07-26 Frank Ch. Eigler <fche@redhat.com>
Support %{ embedded-c %} * staptree.h (embeddedcode): New statement subtype. Stub support in visitors. * staptree.cxx: Ditto. * parse.cxx: Parse %{ / %}. Accept "_" as identifier leading char. (parse_probe): Simplify calling convention. * elaborate.h: Store embedded code. * elaborate.cxx: Pass it. * translate.cxx: Transcribe it. Return some dropped module init/exit code. * Makefile.am: Add buildok/buildko tests. * Makefile.in: Regenerated. * main.cxx: Return EXIT_SUCCESS/FAILURE even for weird rc. * testsuite/parseok/nine.stp: Test _identifiers. * testsuite/transko/*.stp: Tweak to force -p3 rather than -p2 errors. * testsuite/semok/transko.stp: ... and keep it that way in the future. * testsuite/parse*/*: Some new tests for %{ %}. * testsuite/build*/*: New tests for -p4.
-rw-r--r--ChangeLog21
-rw-r--r--Makefile.am7
-rw-r--r--Makefile.in7
-rw-r--r--elaborate.cxx9
-rw-r--r--elaborate.h38
-rw-r--r--main.cxx2
-rw-r--r--parse.cxx96
-rw-r--r--parse.h8
-rw-r--r--staptree.cxx136
-rw-r--r--staptree.h24
-rwxr-xr-xtestsuite/buildko/one.stp17
-rwxr-xr-xtestsuite/buildok/one.stp16
-rwxr-xr-xtestsuite/buildok/two.stp16
-rwxr-xr-xtestsuite/parseko/ten.stp5
-rwxr-xr-xtestsuite/parseok/nine.stp4
-rwxr-xr-xtestsuite/parseok/twelve.stp9
-rwxr-xr-xtestsuite/semok/transko.stp10
-rwxr-xr-xtestsuite/transko/one.stp2
-rwxr-xr-xtestsuite/transko/two.stp3
-rwxr-xr-xtestsuite/transok/nine.stp12
-rw-r--r--translate.cxx74
-rw-r--r--translate.h2
22 files changed, 384 insertions, 134 deletions
diff --git a/ChangeLog b/ChangeLog
index 022d9377..916f6ba2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2005-07-26 Frank Ch. Eigler <fche@redhat.com>
+
+ Support %{ embedded-c %}
+ * staptree.h (embeddedcode): New statement subtype. Stub support in
+ visitors.
+ * staptree.cxx: Ditto.
+ * parse.cxx: Parse %{ / %}. Accept "_" as identifier leading char.
+ (parse_probe): Simplify calling convention.
+ * elaborate.h: Store embedded code.
+ * elaborate.cxx: Pass it.
+ * translate.cxx: Transcribe it. Return some dropped module init/exit
+ code.
+ * Makefile.am: Add buildok/buildko tests.
+ * Makefile.in: Regenerated.
+ * main.cxx: Return EXIT_SUCCESS/FAILURE even for weird rc.
+ * testsuite/parseok/nine.stp: Test _identifiers.
+ * testsuite/transko/*.stp: Tweak to force -p3 rather than -p2 errors.
+ * testsuite/semok/transko.stp: ... and keep it that way in the future.
+ * testsuite/parse*/*: Some new tests for %{ %}.
+ * testsuite/build*/*: New tests for -p4.
+
2005-07-26 Martin Hunt <hunt@redhat.com>
* Makefile.am (AM_CPPFLAGS): Set PKGLIBDIR correctly.
diff --git a/Makefile.am b/Makefile.am
index a689999d..de152e92 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,12 +38,15 @@ install-data-local:
p=$(srcdir)/testsuite/parse
s=$(srcdir)/testsuite/sem
t=$(srcdir)/testsuite/trans
+b=$(srcdir)/testsuite/build
TESTS = $(wildcard $(p)ok/*.stp) $(wildcard $(p)ko/*.stp) \
$(wildcard $(s)ok/*.stp) $(wildcard $(s)ko/*.stp) \
- $(wildcard $(t)ok/*.stp) $(wildcard $(t)ko/*.stp)
+ $(wildcard $(t)ok/*.stp) $(wildcard $(t)ko/*.stp) \
+ $(wildcard $(b)ok/*.stp) $(wildcard $(b)ko/*.stp)
XFAIL_TESTS = $(wildcard $(p)ko/*.stp) \
$(wildcard $(s)ko/*.stp) \
- $(wildcard $(t)ko/*.stp)
+ $(wildcard $(t)ko/*.stp) \
+ $(wildcard $(b)ko/*.stp)
TESTS_ENVIRONMENT = $(srcdir)/runtest.sh
diff --git a/Makefile.in b/Makefile.in
index 730161e1..4ca59a02 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -198,13 +198,16 @@ EXTRA_DIST = testsuite runtime $(wildcard $(srcdir)/*.h) systemtap.spec
p = $(srcdir)/testsuite/parse
s = $(srcdir)/testsuite/sem
t = $(srcdir)/testsuite/trans
+b = $(srcdir)/testsuite/build
TESTS = $(wildcard $(p)ok/*.stp) $(wildcard $(p)ko/*.stp) \
$(wildcard $(s)ok/*.stp) $(wildcard $(s)ko/*.stp) \
- $(wildcard $(t)ok/*.stp) $(wildcard $(t)ko/*.stp)
+ $(wildcard $(t)ok/*.stp) $(wildcard $(t)ko/*.stp) \
+ $(wildcard $(b)ok/*.stp) $(wildcard $(b)ko/*.stp)
XFAIL_TESTS = $(wildcard $(p)ko/*.stp) \
$(wildcard $(s)ko/*.stp) \
- $(wildcard $(t)ko/*.stp)
+ $(wildcard $(t)ko/*.stp) \
+ $(wildcard $(b)ko/*.stp)
TESTS_ENVIRONMENT = $(srcdir)/runtest.sh
all: config.h
diff --git a/elaborate.cxx b/elaborate.cxx
index 8980895f..e7d9f967 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -580,6 +580,9 @@ semantic_pass_symbols (systemtap_session& s)
for (unsigned i=0; i<dome->functions.size(); i++)
s.functions.push_back (dome->functions[i]);
+ for (unsigned i=0; i<dome->embeds.size(); i++)
+ s.embeds.push_back (dome->embeds[i]);
+
// Pass 2: process functions
for (unsigned i=0; i<dome->functions.size(); i++)
@@ -1385,6 +1388,12 @@ typeresolution_info::visit_block (block* e)
void
+typeresolution_info::visit_embeddedcode (embeddedcode* e)
+{
+}
+
+
+void
typeresolution_info::visit_if_statement (if_statement* e)
{
t = pe_long;
diff --git a/elaborate.h b/elaborate.h
index a4c9f2cf..599bc230 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -65,9 +65,10 @@ struct typeresolution_info: public visitor
exp_type t; // implicit parameter for nested visit call; may clobber
- void visit_block (block *s);
- void visit_null_statement (null_statement *s);
- void visit_expr_statement (expr_statement *s);
+ void visit_block (block* s);
+ void visit_embeddedcode (embeddedcode* s);
+ void visit_null_statement (null_statement* s);
+ void visit_expr_statement (expr_statement* s);
void visit_if_statement (if_statement* s);
void visit_for_loop (for_loop* s);
void visit_foreach_loop (foreach_loop* s);
@@ -140,11 +141,11 @@ struct
derived_probe_builder
{
virtual void build(systemtap_session & sess,
- probe * base,
- probe_point * location,
- std::map<std::string, literal *> const & parameters,
- std::vector<probe *> & results_to_expand_further,
- std::vector<derived_probe *> & finished_results) = 0;
+ probe* base,
+ probe_point* location,
+ std::map<std::string, literal*> const & parameters,
+ std::vector<probe*> & results_to_expand_further,
+ std::vector<derived_probe*> & finished_results) = 0;
virtual ~derived_probe_builder() {}
};
@@ -169,20 +170,20 @@ match_key
class
match_node
{
- std::map<match_key, match_node *> sub;
- derived_probe_builder * end;
+ std::map<match_key, match_node*> sub;
+ derived_probe_builder* end;
public:
match_node();
- derived_probe_builder * find_builder(std::vector<probe_point::component *> const & components,
+ derived_probe_builder* find_builder(std::vector<probe_point::component*> const & components,
unsigned pos,
- std::vector< std::pair<std::string, literal *> > & parameters);
+ std::vector< std::pair<std::string, literal*> > & parameters);
- match_node * bind(match_key const & k);
- match_node * bind(std::string const & k);
- match_node * bind_str(std::string const & k);
- match_node * bind_num(std::string const & k);
- void bind(derived_probe_builder * e);
+ match_node* bind(match_key const & k);
+ match_node* bind(std::string const & k);
+ match_node* bind_str(std::string const & k);
+ match_node* bind_num(std::string const & k);
+ void bind(derived_probe_builder* e);
};
// ------------------------------------------------------------------------
@@ -211,7 +212,7 @@ struct systemtap_session
std::string tmpdir;
std::string translated_source; // C source code
- match_node * pattern_root;
+ match_node* pattern_root;
void register_library_aliases();
// parse trees for the various script files
@@ -223,6 +224,7 @@ struct systemtap_session
std::vector<vardecl*> globals;
std::vector<functiondecl*> functions;
std::vector<derived_probe*> probes;
+ std::vector<embeddedcode*> embeds;
// unparser data
translator_output* op;
diff --git a/main.cxx b/main.cxx
index a35bbc9c..7e118cc6 100644
--- a/main.cxx
+++ b/main.cxx
@@ -381,5 +381,5 @@ main (int argc, char * const argv [])
}
}
- return rc;
+ return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/parse.cxx b/parse.cxx
index 5d09a657..988262ce 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -63,8 +63,10 @@ operator << (ostream& o, const token& t)
t.type == tok_operator ? "operator" :
t.type == tok_string ? "string" :
t.type == tok_number ? "number" :
+ t.type == tok_embedded ? "embedded-code" :
"unknown token");
+ // XXX: filter out embedded-code contents?
o << " '";
for (unsigned i=0; i<t.content.length(); i++)
{
@@ -194,7 +196,7 @@ lexer::scan ()
if (isspace (c))
goto skip;
- else if (isalpha (c) || c == '$')
+ else if (isalpha (c) || c == '$' || c == '_')
{
n->type = tok_identifier;
n->content = (char) c;
@@ -300,6 +302,31 @@ lexer::scan ()
}
goto skip;
}
+ else if (c == '%' && c2 == '{') // embedded code
+ {
+ n->type = tok_embedded;
+ (void) input_get (); // swallow '{' already in c2
+ while (true)
+ {
+ c = input_get ();
+ if (c == 0) // EOF
+ {
+ n->type = tok_junk;
+ break;
+ }
+ if (c == '%')
+ {
+ c2 = input_peek ();
+ if (c2 == '}')
+ {
+ (void) input_get (); // swallow '}' too
+ break;
+ }
+ }
+ n->content += c;
+ }
+ return n;
+ }
// We're committed to recognizing at least the first character
// as an operator.
@@ -373,21 +400,15 @@ parser::parse ()
empty = false;
if (t->type == tok_identifier && t->content == "probe")
- {
- probe * p;
- probe_alias * a;
- parse_probe (p, a);
- if (a)
- f->aliases.push_back(a);
- else
- f->probes.push_back (p);
- }
+ parse_probe (f->probes, f->aliases);
else if (t->type == tok_identifier && t->content == "global")
parse_global (f->globals);
else if (t->type == tok_identifier && t->content == "function")
f->functions.push_back (parse_functiondecl ());
+ else if (t->type == tok_embedded)
+ f->embeds.push_back (parse_embeddedcode ());
else
- throw parse_error ("expected 'probe', 'global', or 'function'");
+ throw parse_error ("expected 'probe', 'global', 'function', or embedded code");
}
catch (parse_error& pe)
{
@@ -423,16 +444,13 @@ parser::parse ()
void
-parser::parse_probe (probe * & probe_ret,
- probe_alias * & alias_ret)
+parser::parse_probe (std::vector<probe *> & probe_ret,
+ std::vector<probe_alias *> & alias_ret)
{
const token* t0 = next ();
if (! (t0->type == tok_identifier && t0->content == "probe"))
throw parse_error ("expected 'probe'");
- probe_ret = NULL;
- alias_ret = NULL;
-
vector<probe_point *> aliases;
vector<probe_point *> locations;
@@ -473,21 +491,36 @@ parser::parse_probe (probe * & probe_ret,
throw parse_error ("expected probe point specifier");
}
- probe *p;
if (aliases.empty())
{
- probe_ret = new probe;
- p = probe_ret;
+ probe* p = new probe;
+ p->tok = t0;
+ p->locations = locations;
+ p->body = parse_stmt_block ();
+ probe_ret.push_back (p);
}
else
{
- alias_ret = new probe_alias(aliases);;
- p = alias_ret;
+ probe_alias* p = new probe_alias (aliases);
+ p->tok = t0;
+ p->locations = locations;
+ p->body = parse_stmt_block ();
+ alias_ret.push_back (p);
}
+}
- p->tok = t0;
- p->locations = locations;
- p->body = parse_stmt_block ();
+
+embeddedcode*
+parser::parse_embeddedcode ()
+{
+ embeddedcode* e = new embeddedcode;
+ const token* t = next ();
+ if (t->type != tok_embedded)
+ throw parse_error ("expected embedded code");
+
+ e->tok = t;
+ e->code = t->content;
+ return e;
}
@@ -518,15 +551,15 @@ parser::parse_stmt_block ()
catch (parse_error& pe)
{
print_error (pe);
+
// Quietly swallow all tokens until the next ';' or '}'.
while (1)
{
const token* t = peek ();
- if (! t)
- return 0;
+ if (! t) return 0;
next ();
- if (t->type == tok_operator && (t->content == "}"
- || t->content == ";"))
+ if (t->type == tok_operator
+ && (t->content == "}" || t->content == ";"))
break;
}
}
@@ -572,6 +605,7 @@ parser::parse_statement ()
t->type == tok_number ||
t->type == tok_string))
return parse_expr_statement ();
+ // XXX: consider generally accepting tok_embedded here too
else
throw parse_error ("expected statement");
}
@@ -657,7 +691,11 @@ parser::parse_functiondecl ()
throw parse_error ("expected ',' or ')'");
}
- fd->body = parse_stmt_block ();
+ t = peek ();
+ if (t && t->type == tok_embedded)
+ fd->body = parse_embeddedcode ();
+ else
+ fd->body = parse_stmt_block ();
return fd;
}
diff --git a/parse.h b/parse.h
index 26cac17d..701034ec 100644
--- a/parse.h
+++ b/parse.h
@@ -27,7 +27,8 @@ struct source_loc
enum token_type
{
- tok_junk, tok_identifier, tok_operator, tok_string, tok_number
+ tok_junk, tok_identifier, tok_operator, tok_string, tok_number,
+ tok_embedded
// XXX: add tok_keyword throughout
};
@@ -95,10 +96,11 @@ private:
unsigned num_errors;
private: // nonterminals
- void parse_probe (probe *&, probe_alias *&);
+ void parse_probe (std::vector<probe*>&, std::vector<probe_alias*>&);
+ void parse_global (std::vector<vardecl*>&);
+ embeddedcode* parse_embeddedcode ();
probe_point* parse_probe_point ();
literal* parse_literal ();
- void parse_global (std::vector<vardecl*>&);
functiondecl* parse_functiondecl ();
block* parse_stmt_block ();
statement* parse_statement ();
diff --git a/staptree.cxx b/staptree.cxx
index 9a6d72bd..fb7c56aa 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -288,6 +288,13 @@ ostream& operator << (ostream& o, statement& k)
}
+void embeddedcode::print (ostream &o)
+{
+ o << "%{";
+ o << code;
+ o << "%}";
+}
+
void block::print (ostream& o)
{
o << "{" << endl;
@@ -374,6 +381,9 @@ void stapfile::print (ostream& o)
{
o << "# file " << name << endl;
+ for (unsigned i=0; i<embeds.size(); i++)
+ embeds[i]->print (o);
+
for (unsigned i=0; i<globals.size(); i++)
{
o << "global ";
@@ -477,6 +487,14 @@ block::visit (visitor* u)
u->visit_block (this);
}
+
+void
+embeddedcode::visit (visitor* u)
+{
+ u->visit_embeddedcode (this);
+}
+
+
void
for_loop::visit (visitor* u)
{
@@ -637,19 +655,24 @@ functioncall::visit (visitor* u)
// ------------------------------------------------------------------------
void
-traversing_visitor::visit_block (block *s)
+traversing_visitor::visit_block (block* s)
{
for (unsigned i=0; i<s->statements.size(); i++)
s->statements[i]->visit (this);
}
void
-traversing_visitor::visit_null_statement (null_statement *s)
+traversing_visitor::visit_embeddedcode (embeddedcode* s)
+{
+}
+
+void
+traversing_visitor::visit_null_statement (null_statement* s)
{
}
void
-traversing_visitor::visit_expr_statement (expr_statement *s)
+traversing_visitor::visit_expr_statement (expr_statement* s)
{
s->value->visit (this);
}
@@ -826,19 +849,25 @@ throwing_visitor::throwone (const token* t)
}
void
-throwing_visitor::visit_block (block *s)
+throwing_visitor::visit_block (block* s)
+{
+ throwone (s->tok);
+}
+
+void
+throwing_visitor::visit_embeddedcode (embeddedcode* s)
{
throwone (s->tok);
}
void
-throwing_visitor::visit_null_statement (null_statement *s)
+throwing_visitor::visit_null_statement (null_statement* s)
{
throwone (s->tok);
}
void
-throwing_visitor::visit_expr_statement (expr_statement *s)
+throwing_visitor::visit_expr_statement (expr_statement* s)
{
throwone (s->tok);
}
@@ -992,12 +1021,12 @@ throwing_visitor::visit_functioncall (functioncall* e)
// ------------------------------------------------------------------------
template <typename T> static void
-require (deep_copy_visitor *v, T *dst, T src)
+require (deep_copy_visitor* v, T* dst, T src)
{
*dst = NULL;
if (src != NULL)
{
- v->targets.push(static_cast<void *>(dst));
+ v->targets.push(static_cast<void* >(dst));
src->visit(v);
v->targets.pop();
assert(*dst);
@@ -1005,20 +1034,20 @@ require (deep_copy_visitor *v, T *dst, T src)
}
template <typename T> static void
-provide (deep_copy_visitor *v, T src)
+provide (deep_copy_visitor* v, T src)
{
assert(!v->targets.empty());
*(static_cast<T*>(v->targets.top())) = src;
}
void
-deep_copy_visitor::visit_block (block *s)
+deep_copy_visitor::visit_block (block* s)
{
- block *n = new block;
+ block* n = new block;
n->tok = s->tok;
for (unsigned i = 0; i < s->statements.size(); ++i)
{
- statement *ns;
+ statement* ns;
require <statement*> (this, &ns, s->statements[i]);
n->statements.push_back(ns);
}
@@ -1026,17 +1055,26 @@ deep_copy_visitor::visit_block (block *s)
}
void
-deep_copy_visitor::visit_null_statement (null_statement *s)
+deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
+{
+ embeddedcode* n = new embeddedcode;
+ n->tok = s->tok;
+ n->code = s->code;
+ provide <embeddedcode*> (this, n);
+}
+
+void
+deep_copy_visitor::visit_null_statement (null_statement* s)
{
- null_statement *n = new null_statement;
+ null_statement* n = new null_statement;
n->tok = s->tok;
provide <null_statement*> (this, n);
}
void
-deep_copy_visitor::visit_expr_statement (expr_statement *s)
+deep_copy_visitor::visit_expr_statement (expr_statement* s)
{
- expr_statement *n = new expr_statement;
+ expr_statement* n = new expr_statement;
n->tok = s->tok;
require <expression*> (this, &(n->value), s->value);
provide <expr_statement*> (this, n);
@@ -1045,7 +1083,7 @@ deep_copy_visitor::visit_expr_statement (expr_statement *s)
void
deep_copy_visitor::visit_if_statement (if_statement* s)
{
- if_statement *n = new if_statement;
+ if_statement* n = new if_statement;
n->tok = s->tok;
require <expression*> (this, &(n->condition), s->condition);
require <statement*> (this, &(n->thenblock), s->thenblock);
@@ -1056,7 +1094,7 @@ deep_copy_visitor::visit_if_statement (if_statement* s)
void
deep_copy_visitor::visit_for_loop (for_loop* s)
{
- for_loop *n = new for_loop;
+ for_loop* n = new for_loop;
n->tok = s->tok;
require <expr_statement*> (this, &(n->init), s->init);
require <expression*> (this, &(n->cond), s->cond);
@@ -1068,11 +1106,11 @@ deep_copy_visitor::visit_for_loop (for_loop* s)
void
deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
{
- foreach_loop *n = new foreach_loop;
+ foreach_loop* n = new foreach_loop;
n->tok = s->tok;
for (unsigned i = 0; i < s->indexes.size(); ++i)
{
- symbol *sym;
+ symbol* sym;
require <symbol*> (this, &sym, s->indexes[i]);
n->indexes.push_back(sym);
}
@@ -1085,7 +1123,7 @@ deep_copy_visitor::visit_foreach_loop (foreach_loop* s)
void
deep_copy_visitor::visit_return_statement (return_statement* s)
{
- return_statement *n = new return_statement;
+ return_statement* n = new return_statement;
n->tok = s->tok;
require <expression*> (this, &(n->value), s->value);
provide <return_statement*> (this, n);
@@ -1094,7 +1132,7 @@ deep_copy_visitor::visit_return_statement (return_statement* s)
void
deep_copy_visitor::visit_delete_statement (delete_statement* s)
{
- delete_statement *n = new delete_statement;
+ delete_statement* n = new delete_statement;
n->tok = s->tok;
require <expression*> (this, &(n->value), s->value);
provide <delete_statement*> (this, n);
@@ -1103,7 +1141,7 @@ deep_copy_visitor::visit_delete_statement (delete_statement* s)
void
deep_copy_visitor::visit_next_statement (next_statement* s)
{
- next_statement *n = new next_statement;
+ next_statement* n = new next_statement;
n->tok = s->tok;
provide <next_statement*> (this, n);
}
@@ -1111,7 +1149,7 @@ deep_copy_visitor::visit_next_statement (next_statement* s)
void
deep_copy_visitor::visit_break_statement (break_statement* s)
{
- break_statement *n = new break_statement;
+ break_statement* n = new break_statement;
n->tok = s->tok;
provide <break_statement*> (this, n);
}
@@ -1119,7 +1157,7 @@ deep_copy_visitor::visit_break_statement (break_statement* s)
void
deep_copy_visitor::visit_continue_statement (continue_statement* s)
{
- continue_statement *n = new continue_statement;
+ continue_statement* n = new continue_statement;
n->tok = s->tok;
provide <continue_statement*> (this, n);
}
@@ -1127,7 +1165,7 @@ deep_copy_visitor::visit_continue_statement (continue_statement* s)
void
deep_copy_visitor::visit_literal_string (literal_string* e)
{
- literal_string *n = new literal_string(e->value);
+ literal_string* n = new literal_string(e->value);
n->tok = e->tok;
provide <literal_string*> (this, n);
}
@@ -1135,7 +1173,7 @@ deep_copy_visitor::visit_literal_string (literal_string* e)
void
deep_copy_visitor::visit_literal_number (literal_number* e)
{
- literal_number *n = new literal_number(e->value);
+ literal_number* n = new literal_number(e->value);
n->tok = e->tok;
provide <literal_number*> (this, n);
}
@@ -1143,7 +1181,7 @@ deep_copy_visitor::visit_literal_number (literal_number* e)
void
deep_copy_visitor::visit_binary_expression (binary_expression* e)
{
- binary_expression *n = new binary_expression;
+ binary_expression* n = new binary_expression;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1154,7 +1192,7 @@ deep_copy_visitor::visit_binary_expression (binary_expression* e)
void
deep_copy_visitor::visit_unary_expression (unary_expression* e)
{
- unary_expression *n = new unary_expression;
+ unary_expression* n = new unary_expression;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->operand), e->operand);
@@ -1164,7 +1202,7 @@ deep_copy_visitor::visit_unary_expression (unary_expression* e)
void
deep_copy_visitor::visit_pre_crement (pre_crement* e)
{
- pre_crement *n = new pre_crement;
+ pre_crement* n = new pre_crement;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->operand), e->operand);
@@ -1174,7 +1212,7 @@ deep_copy_visitor::visit_pre_crement (pre_crement* e)
void
deep_copy_visitor::visit_post_crement (post_crement* e)
{
- post_crement *n = new post_crement;
+ post_crement* n = new post_crement;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->operand), e->operand);
@@ -1185,7 +1223,7 @@ deep_copy_visitor::visit_post_crement (post_crement* e)
void
deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
{
- logical_or_expr *n = new logical_or_expr;
+ logical_or_expr* n = new logical_or_expr;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1196,7 +1234,7 @@ deep_copy_visitor::visit_logical_or_expr (logical_or_expr* e)
void
deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
{
- logical_and_expr *n = new logical_and_expr;
+ logical_and_expr* n = new logical_and_expr;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1207,7 +1245,7 @@ deep_copy_visitor::visit_logical_and_expr (logical_and_expr* e)
void
deep_copy_visitor::visit_array_in (array_in* e)
{
- array_in *n = new array_in;
+ array_in* n = new array_in;
n->tok = e->tok;
require <arrayindex*> (this, &(n->operand), e->operand);
provide <array_in*> (this, n);
@@ -1216,7 +1254,7 @@ deep_copy_visitor::visit_array_in (array_in* e)
void
deep_copy_visitor::visit_comparison (comparison* e)
{
- comparison *n = new comparison;
+ comparison* n = new comparison;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1227,7 +1265,7 @@ deep_copy_visitor::visit_comparison (comparison* e)
void
deep_copy_visitor::visit_concatenation (concatenation* e)
{
- concatenation *n = new concatenation;
+ concatenation* n = new concatenation;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1238,7 +1276,7 @@ deep_copy_visitor::visit_concatenation (concatenation* e)
void
deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
{
- ternary_expression *n = new ternary_expression;
+ ternary_expression* n = new ternary_expression;
n->tok = e->tok;
require <expression*> (this, &(n->cond), e->cond);
require <expression*> (this, &(n->truevalue), e->truevalue);
@@ -1249,7 +1287,7 @@ deep_copy_visitor::visit_ternary_expression (ternary_expression* e)
void
deep_copy_visitor::visit_assignment (assignment* e)
{
- assignment *n = new assignment;
+ assignment* n = new assignment;
n->op = e->op;
n->tok = e->tok;
require <expression*> (this, &(n->left), e->left);
@@ -1260,7 +1298,7 @@ deep_copy_visitor::visit_assignment (assignment* e)
void
deep_copy_visitor::visit_symbol (symbol* e)
{
- symbol *n = new symbol;
+ symbol* n = new symbol;
n->tok = e->tok;
n->name = e->name;
n->referent = NULL;
@@ -1270,13 +1308,13 @@ deep_copy_visitor::visit_symbol (symbol* e)
void
deep_copy_visitor::visit_arrayindex (arrayindex* e)
{
- arrayindex *n = new arrayindex;
+ arrayindex* n = new arrayindex;
n->tok = e->tok;
n->base = e->base;
n->referent = NULL;
for (unsigned i = 0; i < e->indexes.size(); ++i)
{
- expression *ne;
+ expression* ne;
require <expression*> (this, &ne, e->indexes[i]);
n->indexes.push_back(ne);
}
@@ -1286,32 +1324,32 @@ deep_copy_visitor::visit_arrayindex (arrayindex* e)
void
deep_copy_visitor::visit_functioncall (functioncall* e)
{
- functioncall *n = new functioncall;
+ functioncall* n = new functioncall;
n->tok = e->tok;
n->function = e->function;
n->referent = NULL;
for (unsigned i = 0; i < e->args.size(); ++i)
{
- expression *na;
+ expression* na;
require <expression*> (this, &na, e->args[i]);
n->args.push_back(na);
}
provide <functioncall*> (this, n);
}
-block *
-deep_copy_visitor::deep_copy (block *b)
+block*
+deep_copy_visitor::deep_copy (block* b)
{
- block *n;
+ block* n;
deep_copy_visitor v;
require <block*> (&v, &n, b);
return n;
}
-statement *
-deep_copy_visitor::deep_copy (statement *s)
+statement*
+deep_copy_visitor::deep_copy (statement* s)
{
- statement *n;
+ statement* n;
deep_copy_visitor v;
require <statement*> (&v, &n, s);
return n;
diff --git a/staptree.h b/staptree.h
index 62bd8dfe..cfc09eb3 100644
--- a/staptree.h
+++ b/staptree.h
@@ -236,12 +236,12 @@ struct vardecl_builtin: public vardecl
};
-struct block;
+struct statement;
struct functiondecl: public symboldecl
{
std::vector<vardecl*> formal_args;
std::vector<vardecl*> locals;
- block* body;
+ statement* body;
functiondecl ();
void print (std::ostream& o);
void printsig (std::ostream& o);
@@ -263,6 +263,14 @@ struct statement
std::ostream& operator << (std::ostream& o, statement& k);
+struct embeddedcode: public statement
+{
+ std::string code;
+ void print (std::ostream& o);
+ void visit (visitor* u);
+};
+
+
struct block: public statement
{
std::vector<statement*> statements;
@@ -358,6 +366,7 @@ struct next_statement: public statement
struct probe;
struct probe_alias;
+struct embeddedcode;
struct stapfile
{
std::string name;
@@ -365,10 +374,13 @@ struct stapfile
std::vector<probe_alias*> aliases;
std::vector<functiondecl*> functions;
std::vector<vardecl*> globals;
+ std::vector<embeddedcode*> embeds;
void print (std::ostream& o);
};
+
+
struct probe_point
{
struct component // XXX: sort of a restricted functioncall
@@ -398,13 +410,11 @@ struct probe
virtual ~probe() {}
};
-struct probe_alias
- : public probe
+struct probe_alias: public probe
{
probe_alias(std::vector<probe_point*> const & aliases);
std::vector<probe_point*> alias_names;
virtual void printsig (std::ostream &o);
- virtual ~probe_alias() {}
};
@@ -414,6 +424,7 @@ struct visitor
{
virtual ~visitor () {}
virtual void visit_block (block *s) = 0;
+ virtual void visit_embeddedcode (embeddedcode *s) = 0;
virtual void visit_null_statement (null_statement *s) = 0;
virtual void visit_expr_statement (expr_statement *s) = 0;
virtual void visit_if_statement (if_statement* s) = 0;
@@ -449,6 +460,7 @@ struct visitor
struct traversing_visitor: public visitor
{
void visit_block (block *s);
+ void visit_embeddedcode (embeddedcode *s);
void visit_null_statement (null_statement *s);
void visit_expr_statement (expr_statement *s);
void visit_if_statement (if_statement* s);
@@ -489,6 +501,7 @@ struct throwing_visitor: public visitor
virtual void throwone (const token* t);
void visit_block (block *s);
+ void visit_embeddedcode (embeddedcode *s);
void visit_null_statement (null_statement *s);
void visit_expr_statement (expr_statement *s);
void visit_if_statement (if_statement* s);
@@ -531,6 +544,7 @@ struct deep_copy_visitor: public visitor
static block *deep_copy (block *s);
void visit_block (block *s);
+ void visit_embeddedcode (embeddedcode *s);
void visit_null_statement (null_statement *s);
void visit_expr_statement (expr_statement *s);
void visit_if_statement (if_statement* s);
diff --git a/testsuite/buildko/one.stp b/testsuite/buildko/one.stp
new file mode 100755
index 00000000..b8d54c51
--- /dev/null
+++ b/testsuite/buildko/one.stp
@@ -0,0 +1,17 @@
+#! stap -p4
+
+%{
+#include <linux/version.h>
+%}
+
+function get_release () %{
+/* this is a type error, detected by gcc */
+THIS->__retvalue = 5;
+%}
+
+probe begin
+{
+ printk("hello from systemtap, kernel version " . get_release())
+}
+
+
diff --git a/testsuite/buildok/one.stp b/testsuite/buildok/one.stp
new file mode 100755
index 00000000..1f4f8f9b
--- /dev/null
+++ b/testsuite/buildok/one.stp
@@ -0,0 +1,16 @@
+#! stap -p4
+
+global foo, bar
+
+probe begin
+{
+ x = 10
+ foo["hello"] = 25
+ foo["hello"]++
+ ++foo["hello"]
+ x = foo["hello"]
+ foo["yo"] *= bar[x, foo["hello"], "goodbye"]++;
+ printk("hello from systemtap")
+}
+
+
diff --git a/testsuite/buildok/two.stp b/testsuite/buildok/two.stp
new file mode 100755
index 00000000..83a4705c
--- /dev/null
+++ b/testsuite/buildok/two.stp
@@ -0,0 +1,16 @@
+#! stap -p4
+
+%{
+#include <linux/version.h>
+%}
+
+function get_release () %{
+strncpy(THIS->__retvalue, UTS_RELEASE, MAXSTRINGLEN);
+%}
+
+probe begin
+{
+ printk("hello from systemtap, kernel version " . get_release())
+}
+
+
diff --git a/testsuite/parseko/ten.stp b/testsuite/parseko/ten.stp
new file mode 100755
index 00000000..a268db4e
--- /dev/null
+++ b/testsuite/parseko/ten.stp
@@ -0,0 +1,5 @@
+#! stap -p1
+
+probe foo {
+ %{ /* not a valid place for embedded code */ %}
+}
diff --git a/testsuite/parseok/nine.stp b/testsuite/parseok/nine.stp
index 13e40cbf..3582907a 100755
--- a/testsuite/parseok/nine.stp
+++ b/testsuite/parseok/nine.stp
@@ -9,7 +9,7 @@ probe two
{
a = b
c = d
- e = f();
- g = h;
+ _e = $f();
+ _g = h_;
;
}
diff --git a/testsuite/parseok/twelve.stp b/testsuite/parseok/twelve.stp
new file mode 100755
index 00000000..5b8a3932
--- /dev/null
+++ b/testsuite/parseok/twelve.stp
@@ -0,0 +1,9 @@
+#! stap -p1
+
+%{
+/* hello world */
+%}
+
+function foo (p1, p2) %{
+ /* goodbye world */
+%}
diff --git a/testsuite/semok/transko.stp b/testsuite/semok/transko.stp
new file mode 100755
index 00000000..9c78c6ef
--- /dev/null
+++ b/testsuite/semok/transko.stp
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+# make sure that we can *semcheck* all transko test files, to ensure
+# that it is translation-time checks that fail, not earlier ones errors
+
+set -e
+for file in ${SRCDIR}/testsuite/transko/*.stp
+do
+ ./stap -p2 $file
+done
diff --git a/testsuite/transko/one.stp b/testsuite/transko/one.stp
index b6bb3e89..3c69161d 100755
--- a/testsuite/transko/one.stp
+++ b/testsuite/transko/one.stp
@@ -1,6 +1,6 @@
#! stap -p3
-probe foo {
+probe begin {
1 = a
a+1 = 4
}
diff --git a/testsuite/transko/two.stp b/testsuite/transko/two.stp
index 77e1f6d0..5185281a 100755
--- a/testsuite/transko/two.stp
+++ b/testsuite/transko/two.stp
@@ -2,9 +2,10 @@
function bar () {
next
+ return 0
}
-probe foo {
+probe end {
break
for (a=0; a<10; a=a+1) for (b=0; b<10; b=b+1) ;
continue
diff --git a/testsuite/transok/nine.stp b/testsuite/transok/nine.stp
new file mode 100755
index 00000000..a75fad5e
--- /dev/null
+++ b/testsuite/transok/nine.stp
@@ -0,0 +1,12 @@
+#! stap -p3
+
+%{
+void just_some_declaration () {}
+%}
+
+function bar(foo) %{ just_some_declaration(); THIS->__retvalue = THIS->foo + 5; %}
+
+probe begin
+{
+ bar (5) + 0
+}
diff --git a/translate.cxx b/translate.cxx
index d794c6be..e4bf28b9 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -46,7 +46,7 @@ struct c_unparser: public unparser, public visitor
unsigned tmpvar_counter;
unsigned label_counter;
- c_unparser (systemtap_session *ss):
+ c_unparser (systemtap_session* ss):
session (ss), o (ss->op), current_probe(0), current_function (0),
tmpvar_counter (0), label_counter (0) {}
~c_unparser () {}
@@ -68,7 +68,7 @@ struct c_unparser: public unparser, public visitor
string c_typename (exp_type e);
string c_varname (const string& e);
- void c_assign (var& lvalue, const string& rvalue, const token *tok);
+ void c_assign (var& lvalue, const string& rvalue, const token* tok);
void c_assign (const string& lvalue, expression* rvalue, const string& msg);
void c_assign (const string& lvalue, const string& rvalue, exp_type type,
const string& msg, const token* tok);
@@ -82,23 +82,24 @@ struct c_unparser: public unparser, public visitor
void c_strcpy (const string& lvalue, const string& rvalue);
void c_strcpy (const string& lvalue, expression* rvalue);
- bool is_local (vardecl const *r, token const *tok);
+ bool is_local (vardecl const* r, token const* tok);
tmpvar gensym(exp_type ty);
- var getvar(vardecl *v, token const *tok = NULL);
- itervar getiter(foreach_loop *f);
- mapvar getmap(vardecl *v, token const *tok = NULL);
+ var getvar(vardecl* v, token const* tok = NULL);
+ itervar getiter(foreach_loop* f);
+ mapvar getmap(vardecl* v, token const* tok = NULL);
- void load_map_indices(arrayindex *e,
+ void load_map_indices(arrayindex* e,
vector<tmpvar> & idx);
- void collect_map_index_types(vector<vardecl *> const & vars,
+ void collect_map_index_types(vector<vardecl* > const & vars,
set< exp_type > & value_types,
set< vector<exp_type> > & index_types);
- void visit_block (block *s);
- void visit_null_statement (null_statement *s);
- void visit_expr_statement (expr_statement *s);
+ void visit_block (block* s);
+ void visit_embeddedcode (embeddedcode* s);
+ void visit_null_statement (null_statement* s);
+ void visit_expr_statement (expr_statement* s);
void visit_if_statement (if_statement* s);
void visit_for_loop (for_loop* s);
void visit_foreach_loop (foreach_loop* s);
@@ -174,16 +175,16 @@ struct c_unparser_assignment:
void prepare_rvalue (string const & op,
tmpvar const & rval,
- token const * tok);
+ token const* tok);
void c_assignop(tmpvar & res,
var const & lvar,
tmpvar const & tmp,
- token const * tok);
+ token const* tok);
// only symbols and arrayindex nodes are possible lvalues
- void visit_symbol (symbol *e);
- void visit_arrayindex (arrayindex *e);
+ void visit_symbol (symbol* e);
+ void visit_arrayindex (arrayindex* e);
};
@@ -198,8 +199,8 @@ struct c_tmpcounter_assignment:
parent (p), op (o), rvalue (e) {}
// only symbols and arrayindex nodes are possible lvalues
- void visit_symbol (symbol *e);
- void visit_arrayindex (arrayindex *e);
+ void visit_symbol (symbol* e);
+ void visit_arrayindex (arrayindex* e);
};
@@ -390,7 +391,7 @@ class itervar
public:
- itervar (foreach_loop *e, unsigned & counter)
+ itervar (foreach_loop* e, unsigned & counter)
: referent_ty(e->base_referent->type),
name("__tmp" + stringify(counter++))
{
@@ -742,6 +743,8 @@ c_unparser::emit_function (functiondecl* v)
<< "& c->locals[c->nesting].function_" << c_varname (v->name)
<< ";";
o->newline(-1) << "(void) l;"; // make sure "l" is marked used
+ o->newline() << "#define THIS l";
+ o->newline() << "if (0) goto out;"; // make sure out: is marked used
// initialize locals
for (unsigned i=0; i<v->locals.size(); i++)
@@ -762,6 +765,7 @@ c_unparser::emit_function (functiondecl* v)
o->newline(-1) << "out:";
o->newline(1) << ";";
+ o->newline() << "#undef THIS";
o->newline(-1) << "}" << endl;
}
@@ -1266,6 +1270,13 @@ c_unparser::visit_block (block *s)
void
+c_unparser::visit_embeddedcode (embeddedcode *s)
+{
+ o->newline() << s->code;
+}
+
+
+void
c_unparser::visit_null_statement (null_statement *s)
{
o->newline() << "/* null */;";
@@ -2073,10 +2084,18 @@ translate_pass (systemtap_session& s)
s.op->newline() << "#else";
s.op->newline() << "#include \"runtime.h\"";
s.op->newline() << "#include <linux/string.h>";
+ // XXX
+ s.op->newline() << "#define KALLSYMS_LOOKUP_NAME \"\"";
+ s.op->newline() << "#define KALLSYMS_LOOKUP 0";
s.op->newline() << "#endif";
s.up->emit_common_header ();
+ for (unsigned i=0; i<s.embeds.size(); i++)
+ {
+ s.op->newline() << s.embeds[i]->code << endl;
+ }
+
for (unsigned i=0; i<s.globals.size(); i++)
{
s.op->newline();
@@ -2113,13 +2132,28 @@ translate_pass (systemtap_session& s)
s.op->newline() << "/* test mode mainline */";
s.op->newline() << "int main () {";
- s.op->newline(1) << "int rc = probe_start ();";
- s.op->newline() << "if (!rc) probe_exit ();";
+ s.op->newline(1) << "int rc = systemtap_module_init ();";
+ s.op->newline() << "if (!rc) systemtap_module_exit ();";
s.op->newline() << "return rc;";
s.op->newline(-1) << "}";
s.op->newline() << "#else";
+
+ s.op->newline();
+ // XXX
+ s.op->newline() << "int probe_start () {";
+ s.op->newline(1) << "return systemtap_module_init ();";
+ s.op->newline(-1) << "}";
+ s.op->newline();
+ s.op->newline() << "void probe_exit () {";
+ // XXX: need to reference these static functions for -Werror avoidance
+ s.op->newline(1) << "if (0) next_fmt ((void *) 0, (void *) 0);";
+ s.op->newline() << "if (0) _stp_dbug(\"\", 0, \"\");";
+ s.op->newline() << "systemtap_module_exit ();";
+ s.op->newline(-1) << "}";
+
s.op->newline() << "MODULE_DESCRIPTION(\"systemtap probe\");";
+ s.op->newline() << "MODULE_LICENSE(\"GPL\");"; // XXX
s.op->newline() << "#endif";
s.op->line() << endl;
diff --git a/translate.h b/translate.h
index 0627994b..2a012273 100644
--- a/translate.h
+++ b/translate.h
@@ -53,9 +53,9 @@ struct unparser
// starting, begin, running, suspended, errored, ending, ended
// };
// static atomic_t session_state;
- // static atomic_t errorcount; /* subcategorize? */
//
// struct context {
+ // unsigned errorcount;
// unsigned busy;
// unsigned actioncount;
// unsigned nesting;