summaryrefslogtreecommitdiffstats
path: root/staptree.cxx
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2010-03-03 00:28:22 -0500
committerFrank Ch. Eigler <fche@elastic.org>2010-03-03 00:33:43 -0500
commitf4fe2e932cc8f445e9e1bc52863e11b669e3afc9 (patch)
treeba062952c0a37f02ebcf0eb2f533d44ee41fdb25 /staptree.cxx
parentd105f6642677bd9ef1b20d1ba180ba0163cb0fa6 (diff)
downloadsystemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.tar.gz
systemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.tar.xz
systemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.zip
PR11004: try / catch error-handling script syntax
* parse.h (try_block): New class. Update basic visitors. * staptree.cxx: Implement basic visitors. * parse.cxx (expect_kw): Fix to actually look for keywords. (parse_try_block): New function. (lexer ctor): Designate 'try' and 'catch' as keywords. * elaborate.cxx (dead_assignment_remover, dead_statmtexpr_remover): Optimize. (other visitors): Implement. * translate.cxx (c_unparser): Implement via super-handy __local__ labels. (emit_probe, emit_function): Make outer out: label also __local__. * testsuite/buildok/fortyone.stp, semko/fortynine.stp, systemtap.base/trycatch.exp: Test it. * NEWS, doc/langref.txt, stap.1.in: Document it.
Diffstat (limited to 'staptree.cxx')
-rw-r--r--staptree.cxx69
1 files changed, 68 insertions, 1 deletions
diff --git a/staptree.cxx b/staptree.cxx
index 9276586b..cca79981 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -1,5 +1,5 @@
// parse tree functions
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
//
// This file is part of systemtap, and is free software. You can
// redistribute it and/or modify it under the terms of the GNU General
@@ -903,6 +903,18 @@ block::block (statement* car, statement* cdr)
+void try_block::print (ostream& o) const
+{
+ o << "try {" << endl;
+ if (try_block) o << *try_block << endl;
+ o << "} catch ";
+ if (catch_error_var) o << "(" << *catch_error_var << ") ";
+ o << "{" << endl;
+ if (catch_block) o << *catch_block << endl;
+ o << "}" << endl;
+}
+
+
void for_loop::print (ostream& o) const
{
o << "for (";
@@ -1140,6 +1152,13 @@ block::visit (visitor* u)
void
+try_block::visit (visitor* u)
+{
+ u->visit_try_block (this);
+}
+
+
+void
embeddedcode::visit (visitor* u)
{
u->visit_embeddedcode (this);
@@ -1525,6 +1544,17 @@ traversing_visitor::visit_block (block* s)
}
void
+traversing_visitor::visit_try_block (try_block* s)
+{
+ if (s->try_block)
+ s->try_block->visit (this);
+ if (s->catch_error_var)
+ s->catch_error_var->visit (this);
+ if (s->catch_block)
+ s->catch_block->visit (this);
+}
+
+void
traversing_visitor::visit_embeddedcode (embeddedcode*)
{
}
@@ -1778,6 +1808,21 @@ functioncall_traversing_visitor::visit_functioncall (functioncall* e)
void
+varuse_collecting_visitor::visit_try_block (try_block *s)
+{
+ if (s->try_block)
+ s->try_block->visit (this);
+ if (s->catch_error_var)
+ written.insert (s->catch_error_var->referent);
+ if (s->catch_block)
+ s->catch_block->visit (this);
+
+ // NB: don't functioncall_traversing_visitor::visit_try_block (s);
+ // since that would count s->catch_error_var as a read also.
+}
+
+
+void
varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
{
assert (current_function); // only they get embedded code
@@ -2067,6 +2112,13 @@ throwing_visitor::visit_block (block* s)
}
void
+throwing_visitor::visit_try_block (try_block* s)
+{
+ throwone (s->tok);
+}
+
+
+void
throwing_visitor::visit_embeddedcode (embeddedcode* s)
{
throwone (s->tok);
@@ -2279,6 +2331,15 @@ update_visitor::visit_block (block* s)
}
void
+update_visitor::visit_try_block (try_block* s)
+{
+ replace (s->try_block);
+ replace (s->catch_error_var);
+ replace (s->catch_block);
+ provide (s);
+}
+
+void
update_visitor::visit_embeddedcode (embeddedcode* s)
{
provide (s);
@@ -2556,6 +2617,12 @@ deep_copy_visitor::visit_block (block* s)
}
void
+deep_copy_visitor::visit_try_block (try_block* s)
+{
+ update_visitor::visit_try_block(new try_block(*s));
+}
+
+void
deep_copy_visitor::visit_embeddedcode (embeddedcode* s)
{
update_visitor::visit_embeddedcode(new embeddedcode(*s));