]> sourceware.org Git - systemtap.git/commitdiff
Add a nop_visitor, and use it for expression_is_functioncall
authorJosh Stone <jistone@redhat.com>
Thu, 26 Nov 2015 00:31:09 +0000 (16:31 -0800)
committerJosh Stone <jistone@redhat.com>
Thu, 26 Nov 2015 00:31:09 +0000 (16:31 -0800)
In expression_is_functioncall, it only cares if the immediate expression
is a functioncall, but the expression_visitor it was derived from would
fully traverse all other expressions.  All it really wanted was like a
visitor-patterned dynamic_cast.

The new nop_visitor better enables this.  It does nothing at all for any
node types, and then expression_is_functioncall can override just for the
functioncall it cares about.

(We haven't yet settled whether to prefer a visitor pattern like this,
or more direct virtual calls like expression::is_symbol, or just plain
dynamic_cast<>.  Try to avoid the need for downcasts if possible.)

staptree.h
translate.cxx

index f007aaa52e73ab79e48d7f5da8cabec4b9f21565..20d2c622363bae85f127bf7df15a09357db703b9 100644 (file)
@@ -914,6 +914,55 @@ struct visitor
 };
 
 
+// A NOP visitor doesn't do anything.  It's a useful base class if you need to
+// take action only for specific types, without even traversing the rest.
+struct nop_visitor: public visitor
+{
+  virtual ~nop_visitor () {}
+  virtual void visit_block (block *s) {};
+  virtual void visit_try_block (try_block *s) {};
+  virtual void visit_embeddedcode (embeddedcode *s) {};
+  virtual void visit_null_statement (null_statement *s) {};
+  virtual void visit_expr_statement (expr_statement *s) {};
+  virtual void visit_if_statement (if_statement* s) {};
+  virtual void visit_for_loop (for_loop* s) {};
+  virtual void visit_foreach_loop (foreach_loop* s) {};
+  virtual void visit_return_statement (return_statement* s) {};
+  virtual void visit_delete_statement (delete_statement* s) {};
+  virtual void visit_next_statement (next_statement* s) {};
+  virtual void visit_break_statement (break_statement* s) {};
+  virtual void visit_continue_statement (continue_statement* s) {};
+  virtual void visit_literal_string (literal_string* e) {};
+  virtual void visit_literal_number (literal_number* e) {};
+  virtual void visit_embedded_expr (embedded_expr* e) {};
+  virtual void visit_binary_expression (binary_expression* e) {};
+  virtual void visit_unary_expression (unary_expression* e) {};
+  virtual void visit_pre_crement (pre_crement* e) {};
+  virtual void visit_post_crement (post_crement* e) {};
+  virtual void visit_logical_or_expr (logical_or_expr* e) {};
+  virtual void visit_logical_and_expr (logical_and_expr* e) {};
+  virtual void visit_array_in (array_in* e) {};
+  virtual void visit_regex_query (regex_query* e) {};
+  virtual void visit_comparison (comparison* e) {};
+  virtual void visit_concatenation (concatenation* e) {};
+  virtual void visit_ternary_expression (ternary_expression* e) {};
+  virtual void visit_assignment (assignment* e) {};
+  virtual void visit_symbol (symbol* e) {};
+  virtual void visit_target_symbol (target_symbol* e) {};
+  virtual void visit_arrayindex (arrayindex* e) {};
+  virtual void visit_functioncall (functioncall* e) {};
+  virtual void visit_print_format (print_format* e) {};
+  virtual void visit_stat_op (stat_op* e) {};
+  virtual void visit_hist_op (hist_op* e) {};
+  virtual void visit_cast_op (cast_op* e) {};
+  virtual void visit_autocast_op (autocast_op* e) {};
+  virtual void visit_atvar_op (atvar_op* e) {};
+  virtual void visit_defined_op (defined_op* e) {};
+  virtual void visit_entry_op (entry_op* e) {};
+  virtual void visit_perf_op (perf_op* e) {};
+};
+
+
 // A simple kind of visitor, which travels down to the leaves of the
 // statement/expression tree, up to but excluding following vardecls
 // and functioncalls.
index dd044cbf5def5f0b9b5e534884750ee3af09a6f7..359ced23c45201ddd10a98f6e1f26c3bc69ac251 100644 (file)
@@ -3129,19 +3129,12 @@ c_unparser::c_assign(tmpvar& t, expression *e, const char* msg)
 }
 
 
-struct expression_is_functioncall : public expression_visitor
+struct expression_is_functioncall : public nop_visitor
 {
-  c_unparser* parent;
   functioncall* fncall;
-  expression_is_functioncall (c_unparser* p)
-    : parent(p), fncall(NULL) {}
+  expression_is_functioncall ()
+    : fncall(NULL) {}
 
-  void visit_expression (expression* e)
-    {
-      // works on the basis that every expression will, by default, call this
-      // function, except for functioncall, as the visitor is overwritten
-      fncall = NULL;
-    }
   void visit_functioncall (functioncall* e)
     {
       fncall = e;
@@ -3160,7 +3153,7 @@ c_unparser::c_assign (const string& lvalue, expression* rvalue,
     }
   else if (rvalue->type == pe_string)
     {
-      expression_is_functioncall eif (this);
+      expression_is_functioncall eif;
       rvalue->visit(& eif);
       if (!session->unoptimized && eif.fncall)
         {
@@ -5350,14 +5343,15 @@ c_unparser::visit_functioncall (functioncall* e)
 
   // return result from retvalue slot NB: this must be last, for the
   // enclosing statement-expression ({ ... }) to carry this value.
-  if (r->type == pe_unknown)
-    // If we passed typechecking, then nothing will use this return value
+  if (r->type == pe_unknown || tmp_ret.is_overridden())
+    // If we passed typechecking with pe_unknown, or if we directly assigned
+    // the functioncall retval, then nothing will use this return value
     o->newline() << "(void) 0;";
   else if (!pointer_ret)
     o->newline() << "c->locals[c->nesting+1]"
                  << "." << c_funcname (r->name)
                  << ".__retvalue;";
-  else if (!tmp_ret.is_overridden())
+  else
     o->newline() << tmp_ret.value() << ";";
 
 }
This page took 0.041955 seconds and 5 git commands to generate.