summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgraydon <graydon>2005-08-09 18:17:24 +0000
committergraydon <graydon>2005-08-09 18:17:24 +0000
commitd98d459c440fb476869b34a84bb8a75d28fbb188 (patch)
tree592d6ab998b1bab7c3d67ea23272884f78fc8860
parentdebd8982950caa54b27944775910dd282b82b338 (diff)
downloadsystemtap-steved-d98d459c440fb476869b34a84bb8a75d28fbb188.tar.gz
systemtap-steved-d98d459c440fb476869b34a84bb8a75d28fbb188.tar.xz
systemtap-steved-d98d459c440fb476869b34a84bb8a75d28fbb188.zip
2005-08-09 Graydon Hoare <graydon@redhat.com>
* elaborate.cxx: (delete_statement_symresolution_info): New struct. (symresolution_info::visit_delete_statement): Use it. (delete_statement_typeresolution_info): New struct. (typeresolution_info::visit_delete_statement): Use it. (symresolution_info::find_var): Accept -1 as 'unknown' arity. * elaborate.h: Update to reflect changes in .cxx. * translate.cxx (mapvar::del): New method. (c_unparser::getmap): Check arity >= 1; (delete_statement_operand_visitor): New struct. (c_unparser::visit_delete_statement): Use it. * staptree.cxx (vardecl::set_arity): Accept and ignore -1. (vardecl::compatible_arity): Likewise. * testsuite/buildok/eight.stp: New test for 'delete' operator.
-rw-r--r--ChangeLog17
-rw-r--r--elaborate.cxx75
-rw-r--r--elaborate.h5
-rw-r--r--staptree.cxx5
-rwxr-xr-xtestsuite/buildok/eight.stp10
-rw-r--r--translate.cxx48
6 files changed, 147 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 0dd8e82f..ef39160d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-08-09 Graydon Hoare <graydon@redhat.com>
+
+ * elaborate.cxx:
+ (delete_statement_symresolution_info): New struct.
+ (symresolution_info::visit_delete_statement): Use it.
+ (delete_statement_typeresolution_info): New struct.
+ (typeresolution_info::visit_delete_statement): Use it.
+ (symresolution_info::find_var): Accept -1 as 'unknown' arity.
+ * elaborate.h: Update to reflect changes in .cxx.
+ * translate.cxx (mapvar::del): New method.
+ (c_unparser::getmap): Check arity >= 1;
+ (delete_statement_operand_visitor): New struct.
+ (c_unparser::visit_delete_statement): Use it.
+ * staptree.cxx (vardecl::set_arity): Accept and ignore -1.
+ (vardecl::compatible_arity): Likewise.
+ * testsuite/buildok/eight.stp: New test for 'delete' operator.
+
2005-08-08 Roland McGrath <roland@redhat.com>
* loc2c-test.c: New file.
diff --git a/elaborate.cxx b/elaborate.cxx
index 8adcc2a7..c9f1fcd1 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -730,6 +730,45 @@ symresolution_info::visit_foreach_loop (foreach_loop* e)
e->block->visit (this);
}
+struct
+delete_statement_symresolution_info:
+ public traversing_visitor
+{
+ symresolution_info *parent;
+
+ delete_statement_symresolution_info (symresolution_info *p):
+ parent(p)
+ {}
+
+ void visit_arrayindex (arrayindex* e)
+ {
+ parent->visit_arrayindex (e);
+ }
+ void visit_functioncall (functioncall* e)
+ {
+ parent->visit_functioncall (e);
+ }
+
+ void visit_symbol (symbol* e)
+ {
+ if (e->referent)
+ return;
+
+ vardecl* d = parent->find_var (e->name, -1);
+ if (d)
+ e->referent = d;
+ else
+ throw semantic_error ("unresolved array in delete statement", e->tok);
+ }
+};
+
+void
+symresolution_info::visit_delete_statement (delete_statement* s)
+{
+ delete_statement_symresolution_info di (this);
+ s->value->visit (&di);
+}
+
void
symresolution_info::visit_symbol (symbol* e)
@@ -807,7 +846,7 @@ symresolution_info::visit_functioncall (functioncall* e)
vardecl*
-symresolution_info::find_var (const string& name, unsigned arity)
+symresolution_info::find_var (const string& name, int arity)
{
// search locals
@@ -837,12 +876,12 @@ symresolution_info::find_var (const string& name, unsigned arity)
// search processed globals
for (unsigned i=0; i<session.globals.size(); i++)
if (session.globals[i]->name == name
- && session.globals[i]->compatible_arity(arity))
+ && session.globals[i]->compatible_arity(arity))
{
session.globals[i]->set_arity (arity);
return session.globals[i];
}
-
+
// search library globals
for (unsigned i=0; i<session.library_files.size(); i++)
{
@@ -852,7 +891,7 @@ symresolution_info::find_var (const string& name, unsigned arity)
vardecl* g = f->globals[j];
if (g->name == name && g->compatible_arity (arity))
{
- g->set_arity (arity);
+ g->set_arity (arity);
// put library into the queue if not already there
if (find (session.files.begin(), session.files.end(), f)
@@ -1510,11 +1549,35 @@ typeresolution_info::visit_expr_statement (expr_statement* e)
}
+struct delete_statement_typeresolution_info:
+ public throwing_visitor
+{
+ typeresolution_info *parent;
+ delete_statement_typeresolution_info (typeresolution_info *p):
+ throwing_visitor ("invalid operand of delete expression"),
+ parent (p)
+ {}
+
+ void visit_arrayindex (arrayindex* e)
+ {
+ parent->visit_arrayindex (e);
+ }
+
+ void visit_symbol (symbol* e)
+ {
+ exp_type ignored = pe_unknown;
+ assert (e->referent != 0);
+ resolve_2types (e, e->referent, parent, ignored);
+ }
+};
+
+
void
typeresolution_info::visit_delete_statement (delete_statement* e)
{
- // XXX: not yet supported
- unresolved (e->tok);
+ delete_statement_typeresolution_info di (this);
+ t = pe_unknown;
+ e->value->visit (&di);
}
diff --git a/elaborate.h b/elaborate.h
index 4b42e0be..86da8b51 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -35,10 +35,8 @@ public:
// XXX: instead in systemtap_session?
void derive_probes (match_node * root, probe *p, std::vector<derived_probe*>& dps);
-
-protected:
- vardecl* find_var (const std::string& name, unsigned arity);
+ vardecl* find_var (const std::string& name, int arity);
functiondecl* find_function (const std::string& name, unsigned arity);
void visit_block (block *s);
@@ -46,6 +44,7 @@ protected:
void visit_foreach_loop (foreach_loop* e);
void visit_arrayindex (arrayindex* e);
void visit_functioncall (functioncall* e);
+ void visit_delete_statement (delete_statement* s);
};
diff --git a/staptree.cxx b/staptree.cxx
index b5a7ae49..31330017 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -106,7 +106,8 @@ vardecl::vardecl ():
void
vardecl::set_arity (int a)
{
- assert (a >= 0);
+ if (a < 0)
+ return;
if (arity != a && arity >= 0)
throw semantic_error ("inconsistent arity", tok);
@@ -123,7 +124,7 @@ vardecl::set_arity (int a)
bool
vardecl::compatible_arity (int a)
{
- if (arity == -1)
+ if (arity == -1 || a == -1)
return true;
return arity == a;
}
diff --git a/testsuite/buildok/eight.stp b/testsuite/buildok/eight.stp
new file mode 100755
index 00000000..84390270
--- /dev/null
+++ b/testsuite/buildok/eight.stp
@@ -0,0 +1,10 @@
+#! stap -p4
+
+global foo
+
+probe begin {
+ foo[1] = 1
+ delete foo[1]
+ delete foo[foo[foo[foo[1]]]]
+ delete foo
+}
diff --git a/translate.cxx b/translate.cxx
index 0bb56815..b013fc29 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -327,6 +327,11 @@ struct mapvar
static string key_typename(exp_type e);
static string value_typename(exp_type e);
+ string del () const
+ {
+ return "_stp_map_key_del (" + qname() + ")";
+ }
+
string seek (vector<tmpvar> const & indices) const
{
string result = "_stp_map_key" + mangled_indices() + " (";
@@ -1203,7 +1208,9 @@ c_unparser::getvar(vardecl *v, token const *tok)
mapvar
c_unparser::getmap(vardecl *v, token const *tok)
-{
+{
+ if (v->arity < 1)
+ throw new semantic_error("attempt to use scalar where map expected", tok);
return mapvar (is_local (v, tok), v->type, v->name, v->index_types);
}
@@ -1380,10 +1387,47 @@ c_unparser::visit_next_statement (next_statement* s)
}
+struct delete_statement_operand_visitor:
+ public throwing_visitor
+{
+ c_unparser *parent;
+ delete_statement_operand_visitor (c_unparser *p):
+ throwing_visitor ("invalid operand of delete expression"),
+ parent (p)
+ {}
+ void visit_symbol (symbol* e);
+ void visit_arrayindex (arrayindex* e);
+};
+
+void
+delete_statement_operand_visitor::visit_symbol (symbol* e)
+{
+ mapvar mvar = parent->getmap(e->referent, e->tok);
+ varlock guard (*parent, mvar);
+ parent->o->newline() << mvar.fini ();
+ parent->o->newline() << mvar.init ();
+}
+
+void
+delete_statement_operand_visitor::visit_arrayindex (arrayindex* e)
+{
+ vector<tmpvar> idx;
+ parent->load_map_indices (e, idx);
+ parent->o->newline() << "if (unlikely (c->errorcount)) goto out;";
+ {
+ mapvar mvar = parent->getmap (e->referent, e->tok);
+ varlock guard (*parent, mvar);
+ parent->o->newline() << mvar.seek (idx) << ";";
+ parent->o->newline() << mvar.del () << ";";
+ }
+}
+
+
void
c_unparser::visit_delete_statement (delete_statement* s)
{
- throw semantic_error ("delete statement not yet implemented", s->tok);
+ delete_statement_operand_visitor dv (this);
+ s->value->visit (&dv);
}