]> sourceware.org Git - systemtap.git/blobdiff - elaborate.cxx
PR 9716, replaced pkgconfig checks with AC macros in configure.ac for server deps.
[systemtap.git] / elaborate.cxx
index edd4668d842ebacab37e53267f8aef68215ef1ae..ba50defb427eb9b4565ce4ae76a5e87acc90dbca 100644 (file)
@@ -395,7 +395,8 @@ match_node::find_and_build (systemtap_session& s,
 
          throw semantic_error(string("probe point mismatch at position ") +
                               lex_cast<string> (pos) +
-                              " (alternatives:" + alternatives + ")",
+                              " (alternatives:" + alternatives + ")" +
+                              " didn't find any wildcard matches",
                                loc->tok);
        }
     }
@@ -1167,7 +1168,7 @@ void add_global_var_display (systemtap_session& s)
           || vut.written.find (l) == vut.written.end())
        continue;
 
-      // Don't generate synthetic end probes for unread globals 
+      // Don't generate synthetic end probes for unread globals
       // declared only within tapsets. (RHBZ 468139), but rather
       // only within the end-user script.
 
@@ -2090,59 +2091,30 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
 
 // ------------------------------------------------------------------------
 
-struct dead_assignment_remover: public traversing_visitor
+struct dead_assignment_remover: public update_visitor
 {
   systemtap_session& session;
   bool& relaxed_p;
   const varuse_collecting_visitor& vut;
-  expression** current_expr;
 
   dead_assignment_remover(systemtap_session& s, bool& r,
                           const varuse_collecting_visitor& v):
-    session(s), relaxed_p(r), vut(v), current_expr(0) {}
-
-  void visit_expr_statement (expr_statement* s);
-  // XXX: other places where an assignment may be nested should be
-  // handled too (e.g., loop/if conditionals, array indexes, function
-  // parameters).  Until then, they result in visit_assignment() being
-  // called with null current_expr.
+    session(s), relaxed_p(r), vut(v) {}
 
   void visit_assignment (assignment* e);
-  void visit_binary_expression (binary_expression* e);
-  void visit_arrayindex (arrayindex* e);
-  void visit_functioncall (functioncall* e);
-  void visit_if_statement (if_statement* e);
-  void visit_for_loop (for_loop* e);
 };
 
 
-void
-dead_assignment_remover::visit_expr_statement (expr_statement* s)
-{
-  expression** last_expr = current_expr;
-  current_expr = & s->value;
-  s->value->visit (this);
-  s->tok = s->value->tok; // in case it was replaced
-  current_expr = last_expr;
-}
-
-
 void
 dead_assignment_remover::visit_assignment (assignment* e)
 {
+  e->left = require (e->left);
+  e->right = require (e->right);
+
   symbol* left = get_symbol_within_expression (e->left);
   vardecl* leftvar = left->referent; // NB: may be 0 for unresolved $target
-  if (current_expr && // see XXX above: this case represents a missed
-                      // optimization opportunity
-      *current_expr == e && // we're not nested any deeper than expected
-      leftvar) // not unresolved $target; intended sideeffect cannot be elided
+  if (leftvar) // not unresolved $target, so intended sideeffect may be elided
     {
-      expression** last_expr = current_expr;
-      e->left->visit (this);
-      current_expr = &e->right;
-      e->right->visit (this);
-      current_expr = last_expr;
-
       if (vut.read.find(leftvar) == vut.read.end()) // var never read?
         {
           // NB: Not so fast!  The left side could be an array whose
@@ -2162,9 +2134,9 @@ dead_assignment_remover::visit_assignment (assignment* e)
                break;
              }
 
-          varuse_collecting_visitor vut;
-          e->left->visit (& vut);
-          if (vut.side_effect_free () && !is_global) // XXX: use _wrt() once we track focal_vars
+          varuse_collecting_visitor lvut;
+          e->left->visit (& lvut);
+          if (lvut.side_effect_free () && !is_global) // XXX: use _wrt() once we track focal_vars
             {
               /* PR 1119: NB: This is not necessary here.  A write-only
                  variable will also be elided soon at the next _opt2 iteration.
@@ -2177,77 +2149,13 @@ dead_assignment_remover::visit_assignment (assignment* e)
                 clog << "Eliding assignment to " << leftvar->name
                      << " at " << *e->tok << endl;
 
-              *current_expr = e->right; // goodbye assignment*
+              provide (e->right); // goodbye assignment*
               relaxed_p = false;
+              return;
             }
         }
     }
-}
-
-void
-dead_assignment_remover::visit_binary_expression (binary_expression* e)
-{
-  expression** last_expr = current_expr;
-  current_expr = &e->left;
-  e->left->visit (this);
-  current_expr = &e->right;
-  e->right->visit (this);
-  current_expr = last_expr;
-}
-
-void
-dead_assignment_remover::visit_arrayindex (arrayindex *e)
-{
-  symbol *array = NULL;
-  hist_op *hist = NULL;
-  classify_indexable(e->base, array, hist);
-
-  if (array)
-    {
-      expression** last_expr = current_expr;
-      for (unsigned i=0; i < e->indexes.size(); i++)
-       {
-         current_expr = & e->indexes[i];
-         e->indexes[i]->visit (this);
-       }
-      current_expr = last_expr;
-    }
-}
-
-void
-dead_assignment_remover::visit_functioncall (functioncall* e)
-{
-  expression** last_expr = current_expr;
-  for (unsigned i=0; i<e->args.size(); i++)
-    {
-      current_expr = & e->args[i];
-      e->args[i]->visit (this);
-    }
-  current_expr = last_expr;
-}
-
-void
-dead_assignment_remover::visit_if_statement (if_statement* s)
-{
-  expression** last_expr = current_expr;
-  current_expr = & s->condition;
-  s->condition->visit (this);
-  s->thenblock->visit (this);
-  if (s->elseblock)
-    s->elseblock->visit (this);
-  current_expr = last_expr;
-}
-
-void
-dead_assignment_remover::visit_for_loop (for_loop* s)
-{
-  expression** last_expr = current_expr;
-  if (s->init) s->init->visit (this);
-  current_expr = & s->cond;
-  s->cond->visit (this);
-  if (s->incr) s->incr->visit (this);
-  s->block->visit (this);
-  current_expr = last_expr;
+  provide (e);
 }
 
 // Let's remove assignments to variables that are never read.  We
@@ -2267,9 +2175,10 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p)
   // This instance may be reused for multiple probe/function body trims.
 
   for (unsigned i=0; i<s.probes.size(); i++)
-    s.probes[i]->body->visit (& dar);
-  for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
-    it->second->body->visit (& dar);
+    s.probes[i]->body = dar.require (s.probes[i]->body);
+  for (map<string,functiondecl*>::iterator it = s.functions.begin();
+       it != s.functions.end(); it++)
+    it->second->body = dar.require (it->second->body);
   // The rewrite operation is performed within the visitor.
 
   // XXX: we could also zap write-only globals here
@@ -2278,15 +2187,14 @@ void semantic_pass_opt3 (systemtap_session& s, bool& relaxed_p)
 
 // ------------------------------------------------------------------------
 
-struct dead_stmtexpr_remover: public traversing_visitor
+struct dead_stmtexpr_remover: public update_visitor
 {
   systemtap_session& session;
   bool& relaxed_p;
-  statement** current_stmt; // pointer to current stmt* being iterated
   set<vardecl*> focal_vars; // vars considered subject to side-effects
 
   dead_stmtexpr_remover(systemtap_session& s, bool& r):
-    session(s), relaxed_p(r), current_stmt(0) {}
+    session(s), relaxed_p(r) {}
 
   void visit_block (block *s);
   void visit_null_statement (null_statement *s);
@@ -2305,7 +2213,8 @@ dead_stmtexpr_remover::visit_null_statement (null_statement *s)
   // easy!
   if (session.verbose>2)
     clog << "Eliding side-effect-free null statement " << *s->tok << endl;
-  *current_stmt = 0;
+  s = 0;
+  provide (s);
 }
 
 
@@ -2315,13 +2224,11 @@ dead_stmtexpr_remover::visit_block (block *s)
   vector<statement*> new_stmts;
   for (unsigned i=0; i<s->statements.size(); i++ )
     {
-      statement** last_stmt = current_stmt;
-      current_stmt = & s->statements[i];
-      s->statements[i]->visit (this);
-      if (*current_stmt != 0)
+      statement* new_stmt = require (s->statements[i], true);
+      if (new_stmt != 0)
         {
           // flatten nested blocks into this one
-          block *b = dynamic_cast<block *>(*current_stmt);
+          block *b = dynamic_cast<block *>(new_stmt);
           if (b)
             {
               if (session.verbose>2)
@@ -2331,42 +2238,32 @@ dead_stmtexpr_remover::visit_block (block *s)
               relaxed_p = false;
             }
           else
-            new_stmts.push_back (*current_stmt);
+            new_stmts.push_back (new_stmt);
         }
-      current_stmt = last_stmt;
     }
   if (new_stmts.size() == 0)
     {
       if (session.verbose>2)
         clog << "Eliding side-effect-free empty block " << *s->tok << endl;
-      *current_stmt = 0;
+      s = 0;
     }
   else if (new_stmts.size() == 1)
     {
       if (session.verbose>2)
         clog << "Eliding side-effect-free singleton block " << *s->tok << endl;
-      *current_stmt = new_stmts[0];
+      provide (new_stmts[0]);
+      return;
     }
   else
-    {
-      s->statements = new_stmts;
-    }
+    s->statements = new_stmts;
+  provide (s);
 }
 
 void
 dead_stmtexpr_remover::visit_if_statement (if_statement *s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->thenblock;
-  s->thenblock->visit (this);
-
-  if (s->elseblock)
-    {
-      current_stmt = & s->elseblock;
-      s->elseblock->visit (this);
-      // null *current_stmt is OK here.
-    }
-  current_stmt = last_stmt;
+  s->thenblock = require (s->thenblock, true);
+  s->elseblock = require (s->elseblock, true);
 
   if (s->thenblock == 0)
     {
@@ -2381,7 +2278,7 @@ dead_stmtexpr_remover::visit_if_statement (if_statement *s)
               if (session.verbose>2)
                 clog << "Eliding side-effect-free if statement "
                      << *s->tok << endl;
-              *current_stmt = 0; // yeah, baby
+              s = 0; // yeah, baby
             }
           else
             {
@@ -2392,7 +2289,8 @@ dead_stmtexpr_remover::visit_if_statement (if_statement *s)
               expr_statement *es = new expr_statement;
               es->value = s->condition;
               es->tok = es->value->tok;
-              *current_stmt = es;
+              provide (es);
+              return;
             }
         }
       else
@@ -2411,31 +2309,27 @@ dead_stmtexpr_remover::visit_if_statement (if_statement *s)
           s->elseblock = 0;
         }
     }
+  provide (s);
 }
 
 void
 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop *s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->block;
-  s->block->visit (this);
-  current_stmt = last_stmt;
+  s->block = require(s->block, true);
 
   if (s->block == 0)
     {
       if (session.verbose>2)
         clog << "Eliding side-effect-free foreach statement " << *s->tok << endl;
-      *current_stmt = 0; // yeah, baby
+      s = 0; // yeah, baby
     }
+  provide (s);
 }
 
 void
 dead_stmtexpr_remover::visit_for_loop (for_loop *s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->block;
-  s->block->visit (this);
-  current_stmt = last_stmt;
+  s->block = require(s->block, true);
 
   if (s->block == 0)
     {
@@ -2449,14 +2343,16 @@ dead_stmtexpr_remover::visit_for_loop (for_loop *s)
         {
           if (session.verbose>2)
             clog << "Eliding side-effect-free for statement " << *s->tok << endl;
-          *current_stmt = 0; // yeah, baby
-          return;
+          s = 0; // yeah, baby
+        }
+      else
+        {
+          // Can't elide this whole statement; put a null in there.
+          s->block = new null_statement();
+          s->block->tok = s->tok;
         }
-
-      // Can't elide this whole statement; put a null in there.
-      s->block = new null_statement();
-      s->block->tok = s->tok;
     }
+  provide (s);
 }
 
 
@@ -2466,8 +2362,7 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s)
 {
   // Run a varuse query against the operand expression.  If it has no
   // side-effects, replace the entire statement expression by a null
-  // statement.  This replacement is done by overwriting the
-  // current_stmt pointer.
+  // statement with the provide() call.
   //
   // Unlike many other visitors, we do *not* traverse this outermost
   // one into the expression subtrees.  There is no need - no
@@ -2480,8 +2375,7 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s)
   varuse_collecting_visitor vut;
   s->value->visit (& vut);
 
- if (vut.side_effect_free_wrt (focal_vars) &&
-      *current_stmt == s) // we're not nested any deeper than expected
+  if (vut.side_effect_free_wrt (focal_vars))
     {
       /* PR 1119: NB: this message is not a good idea here.  It can
          name some arbitrary RHS expression of an assignment.
@@ -2496,10 +2390,10 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s)
 
       // NB: this 0 pointer is invalid to leave around for any length of
       // time, but the parent parse tree objects above handle it.
-      * current_stmt = 0;
-
+      s = 0;
       relaxed_p = false;
     }
+  provide (s);
 }
 
 
@@ -2524,8 +2418,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
       duv.focal_vars.insert (p->locals.begin(),
                              p->locals.end());
 
-      duv.current_stmt = & p->body;
-      p->body->visit (& duv);
+      p->body = duv.require(p->body, true);
       if (p->body == 0)
         {
           if (! s.suppress_warnings)
@@ -2550,8 +2443,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
       duv.focal_vars.insert (s.globals.begin(),
                              s.globals.end());
 
-      duv.current_stmt = & fn->body;
-      fn->body->visit (& duv);
+      fn->body = duv.require(fn->body, true);
       if (fn->body == 0)
         {
           if (! s.suppress_warnings)
@@ -2576,21 +2468,27 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
 // into separate statements that evaluate each subcomponent of the expression.
 // The dead-statement-remover can later remove some parts if they have no side
 // effects.
-struct void_statement_reducer: public traversing_visitor
+//
+// All expressions must be overridden here so we never visit their subexpressions
+// accidentally.  Thus, the only visited expressions should be value of an
+// expr_statement.
+//
+// For an expression to replace its expr_statement with something else, it will
+// let the new statement provide(), and then provide(0) for itself.  The
+// expr_statement will take this as a sign that it's been replaced.
+struct void_statement_reducer: public update_visitor
 {
   systemtap_session& session;
   bool& relaxed_p;
-  statement** current_stmt; // pointer to current stmt* being iterated
-  expr_statement* current_expr; // pointer to current expr being iterated
   set<vardecl*> focal_vars; // vars considered subject to side-effects
 
   void_statement_reducer(systemtap_session& s, bool& r):
-    session(s), relaxed_p(r), current_stmt(0), current_expr(0) {}
+    session(s), relaxed_p(r) {}
 
-  // these just maintain current_stmt while recursing, but don't visit
-  // expressions in the conditional / loop controls.
   void visit_expr_statement (expr_statement* s);
-  void visit_block (block *s);
+
+  // expressions in conditional / loop controls are definitely a side effect,
+  // but still recurse into the child statements
   void visit_if_statement (if_statement* s);
   void visit_for_loop (for_loop* s);
   void visit_foreach_loop (foreach_loop* s);
@@ -2610,72 +2508,54 @@ struct void_statement_reducer: public traversing_visitor
 
   // these are a bit hairy to grok due to the intricacies of indexables and
   // stats, so I'm chickening out and skipping them...
-  void visit_array_in (array_in* e) {}
-  void visit_arrayindex (arrayindex* e) {}
-  void visit_stat_op (stat_op* e) {}
-  void visit_hist_op (hist_op* e) {}
+  void visit_array_in (array_in* e) { provide (e); }
+  void visit_arrayindex (arrayindex* e) { provide (e); }
+  void visit_stat_op (stat_op* e) { provide (e); }
+  void visit_hist_op (hist_op* e) { provide (e); }
 
   // these can't be reduced because they always have an effect
-  void visit_return_statement (return_statement* s) {}
-  void visit_delete_statement (delete_statement* s) {}
-  void visit_pre_crement (pre_crement* e) {}
-  void visit_post_crement (post_crement* e) {}
-  void visit_assignment (assignment* e) {}
+  void visit_return_statement (return_statement* s) { provide (s); }
+  void visit_delete_statement (delete_statement* s) { provide (s); }
+  void visit_pre_crement (pre_crement* e) { provide (e); }
+  void visit_post_crement (post_crement* e) { provide (e); }
+  void visit_assignment (assignment* e) { provide (e); }
 };
 
 
 void
 void_statement_reducer::visit_expr_statement (expr_statement* s)
 {
-  assert(!current_expr); // it shouldn't be possible to have nested expr's
-  current_expr = s;
-  s->value->visit (this);
-  current_expr = NULL;
-}
+  s->value = require (s->value, true);
 
-void
-void_statement_reducer::visit_block (block *s)
-{
-  statement** last_stmt = current_stmt;
-  for (unsigned i=0; i<s->statements.size(); i++ )
-    {
-      current_stmt = & s->statements[i];
-      s->statements[i]->visit (this);
-    }
-  current_stmt = last_stmt;
+  // if the expression provides 0, that's our signal that a new
+  // statement has been provided, so we shouldn't provide this one.
+  if (s->value != 0)
+    provide(s);
 }
 
 void
 void_statement_reducer::visit_if_statement (if_statement* s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->thenblock;
-  s->thenblock->visit (this);
-
-  if (s->elseblock)
-    {
-      current_stmt = & s->elseblock;
-      s->elseblock->visit (this);
-    }
-  current_stmt = last_stmt;
+  // s->condition is never void
+  s->thenblock = require (s->thenblock);
+  s->elseblock = require (s->elseblock);
+  provide (s);
 }
 
 void
 void_statement_reducer::visit_for_loop (for_loop* s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->block;
-  s->block->visit (this);
-  current_stmt = last_stmt;
+  // s->init/cond/incr are never void
+  s->block = require (s->block);
+  provide (s);
 }
 
 void
 void_statement_reducer::visit_foreach_loop (foreach_loop* s)
 {
-  statement** last_stmt = current_stmt;
-  current_stmt = & s->block;
-  s->block->visit (this);
-  current_stmt = last_stmt;
+  // s->indexes/base/limit are never void
+  s->block = require (s->block);
+  provide (s);
 }
 
 void
@@ -2684,8 +2564,6 @@ void_statement_reducer::visit_logical_or_expr (logical_or_expr* e)
   // In void context, the evaluation of "a || b" is exactly like
   // "if (!a) b", so let's do that instead.
 
-  assert(current_expr && current_expr->value == e);
-
   if (session.verbose>2)
     clog << "Creating if statement from unused logical-or "
          << *e->tok << endl;
@@ -2693,8 +2571,6 @@ void_statement_reducer::visit_logical_or_expr (logical_or_expr* e)
   if_statement *is = new if_statement;
   is->tok = e->tok;
   is->elseblock = 0;
-  *current_stmt = is;
-  current_expr = NULL;
 
   unary_expression *ue = new unary_expression;
   ue->operand = e->left;
@@ -2709,6 +2585,8 @@ void_statement_reducer::visit_logical_or_expr (logical_or_expr* e)
 
   is->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 void
@@ -2717,8 +2595,6 @@ void_statement_reducer::visit_logical_and_expr (logical_and_expr* e)
   // In void context, the evaluation of "a && b" is exactly like
   // "if (a) b", so let's do that instead.
 
-  assert(current_expr && current_expr->value == e);
-
   if (session.verbose>2)
     clog << "Creating if statement from unused logical-and "
          << *e->tok << endl;
@@ -2727,8 +2603,6 @@ void_statement_reducer::visit_logical_and_expr (logical_and_expr* e)
   is->tok = e->tok;
   is->elseblock = 0;
   is->condition = e->left;
-  *current_stmt = is;
-  current_expr = NULL;
 
   expr_statement *es = new expr_statement;
   es->value = e->right;
@@ -2737,6 +2611,8 @@ void_statement_reducer::visit_logical_and_expr (logical_and_expr* e)
 
   is->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 void
@@ -2745,8 +2621,6 @@ void_statement_reducer::visit_ternary_expression (ternary_expression* e)
   // In void context, the evaluation of "a ? b : c" is exactly like
   // "if (a) b else c", so let's do that instead.
 
-  assert(current_expr && current_expr->value == e);
-
   if (session.verbose>2)
     clog << "Creating if statement from unused ternary expression "
          << *e->tok << endl;
@@ -2754,8 +2628,6 @@ void_statement_reducer::visit_ternary_expression (ternary_expression* e)
   if_statement *is = new if_statement;
   is->tok = e->tok;
   is->condition = e->cond;
-  *current_stmt = is;
-  current_expr = NULL;
 
   expr_statement *es = new expr_statement;
   es->value = e->truevalue;
@@ -2769,6 +2641,8 @@ void_statement_reducer::visit_ternary_expression (ternary_expression* e)
 
   is->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 void
@@ -2777,15 +2651,11 @@ void_statement_reducer::visit_binary_expression (binary_expression* e)
   // When the result of a binary operation isn't needed, it's just as good to
   // evaluate the operands as sequential statements in a block.
 
-  assert(current_expr && current_expr->value == e);
-
   if (session.verbose>2)
     clog << "Eliding unused binary " << *e->tok << endl;
 
   block *b = new block;
-  b->tok = current_expr->tok;
-  *current_stmt = b;
-  current_expr = NULL;
+  b->tok = e->tok;
 
   expr_statement *es = new expr_statement;
   es->value = e->left;
@@ -2799,6 +2669,8 @@ void_statement_reducer::visit_binary_expression (binary_expression* e)
 
   b->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 void
@@ -2807,16 +2679,11 @@ void_statement_reducer::visit_unary_expression (unary_expression* e)
   // When the result of a unary operation isn't needed, it's just as good to
   // evaluate the operand directly
 
-  assert(current_expr && current_expr->value == e);
-
   if (session.verbose>2)
     clog << "Eliding unused unary " << *e->tok << endl;
 
-  current_expr->value = e->operand;
-  current_expr->tok = current_expr->value->tok;
-  current_expr->value->visit(this);
-
   relaxed_p = false;
+  e->operand->visit(this);
 }
 
 void
@@ -2838,24 +2705,26 @@ void_statement_reducer::visit_functioncall (functioncall* e)
   // and just evaluate the arguments in sequence
 
   if (!e->args.size())
-    return;
+    {
+      provide (e);
+      return;
+    }
 
   varuse_collecting_visitor vut;
   vut.traversed.insert (e->referent);
   vut.current_function = e->referent;
   e->referent->body->visit (& vut);
   if (!vut.side_effect_free_wrt (focal_vars))
-    return;
-
-  assert(current_expr && current_expr->value == e);
+    {
+      provide (e);
+      return;
+    }
 
   if (session.verbose>2)
     clog << "Eliding side-effect-free function call " << *e->tok << endl;
 
   block *b = new block;
   b->tok = e->tok;
-  *current_stmt = b;
-  current_expr = NULL;
 
   for (unsigned i=0; i<e->args.size(); i++ )
     {
@@ -2867,6 +2736,8 @@ void_statement_reducer::visit_functioncall (functioncall* e)
 
   b->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 void
@@ -2876,17 +2747,16 @@ void_statement_reducer::visit_print_format (print_format* e)
   // arguments in sequence
 
   if (e->print_to_stream || !e->args.size())
-    return;
-
-  assert(current_expr && current_expr->value == e);
+    {
+      provide (e);
+      return;
+    }
 
   if (session.verbose>2)
     clog << "Eliding unused print " << *e->tok << endl;
 
   block *b = new block;
   b->tok = e->tok;
-  *current_stmt = b;
-  current_expr = NULL;
 
   for (unsigned i=0; i<e->args.size(); i++ )
     {
@@ -2898,6 +2768,8 @@ void_statement_reducer::visit_print_format (print_format* e)
 
   b->visit(this);
   relaxed_p = false;
+  e = 0;
+  provide (e);
 }
 
 
@@ -2911,17 +2783,10 @@ void semantic_pass_opt5 (systemtap_session& s, bool& relaxed_p)
   vuv.focal_vars.insert (s.globals.begin(), s.globals.end());
 
   for (unsigned i=0; i<s.probes.size(); i++)
-    {
-      derived_probe* p = s.probes[i];
-      vuv.current_stmt = & p->body;
-      p->body->visit (& vuv);
-    }
-  for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
-    {
-      functiondecl* fn = it->second;
-      vuv.current_stmt = & fn->body;
-      fn->body->visit (& vuv);
-    }
+    s.probes[i]->body = vuv.require (s.probes[i]->body);
+  for (map<string,functiondecl*>::iterator it = s.functions.begin();
+       it != s.functions.end(); it++)
+    it->second->body = vuv.require (it->second->body);
 }
 
 
@@ -3902,8 +3767,7 @@ typeresolution_info::visit_print_format (print_format* e)
          if (e->components[i].type == print_format::conv_unspecified)
            throw semantic_error ("Unspecified conversion in print operator format string",
                                  e->tok);
-         else if (e->components[i].type == print_format::conv_literal
-                  || e->components[i].type == print_format::conv_size)
+         else if (e->components[i].type == print_format::conv_literal)
            continue;
          components.push_back(e->components[i]);
          ++expected_num_args;
@@ -3945,7 +3809,6 @@ typeresolution_info::visit_print_format (print_format* e)
            {
            case print_format::conv_unspecified:
            case print_format::conv_literal:
-           case print_format::conv_size:
              assert (false);
              break;
 
@@ -3958,6 +3821,7 @@ typeresolution_info::visit_print_format (print_format* e)
            case print_format::conv_binary:
            case print_format::conv_char:
            case print_format::conv_memory:
+           case print_format::conv_memory_hex:
              wanted = pe_long;
              break;
 
@@ -4106,3 +3970,4 @@ typeresolution_info::resolved (const token*, exp_type)
   num_newly_resolved ++;
 }
 
+/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.045526 seconds and 5 git commands to generate.