summaryrefslogtreecommitdiffstats
path: root/elaborate.cxx
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 /elaborate.cxx
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.
Diffstat (limited to 'elaborate.cxx')
-rw-r--r--elaborate.cxx75
1 files changed, 69 insertions, 6 deletions
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);
}