changeset 23469:2699c5974844

handle global and persistent in tree_decl_command, not as separate classes * pt-decl.h, pt-decl.cc (tree_decl_command::mark_as_global, tree_decl_command::mark_as_persistent, tree_decl_command::dup): New functions. (tree_global_command, tree_persistent_command): Delete classes. (tree_decl_elt::decl_type): New enum. Store command type in each initializer list element. (tree_decl_elt::mark_as_global, tree_decl_elt::is_global, tree_decl_elt::mark_as_persistent, tree_decl_elt::is_persistent): New functions. (tree_decl_init_list::mark_as_global, tree_decl_init_list::is_global, tree_decl_init_list::mark_as_persistent, tree_decl_init_list::is_persistent): New functions. * pt-walk.h (tree_walker::visit_decl_command): New function. (tree_walker::visit_global_command, tree_walker::visit_persistent_command): Delete. Update all derived classes. * oct-parse.in.yy (base_parser::make_decl_command): Tag initialization lists as global or persistent here. * pt-eval.cc (tree_evaluator::visit_decl_command): New function. Visit initialization list instead of looping here. (tree_evaluator::visit_decl_init_list): Loop and visit elements here. (tree_evaluator::visit_decl_elt): Handle evaluation of elements here.
author John W. Eaton <jwe@octave.org>
date Thu, 04 May 2017 15:02:46 -0400
parents f267a982478f
children a41fdb801db6
files libinterp/octave-value/ov-classdef.cc libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-bp.cc libinterp/parse-tree/pt-bp.h libinterp/parse-tree/pt-check.cc libinterp/parse-tree/pt-check.h libinterp/parse-tree/pt-decl.cc libinterp/parse-tree/pt-decl.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h libinterp/parse-tree/pt-jit.h libinterp/parse-tree/pt-pr-code.cc libinterp/parse-tree/pt-pr-code.h libinterp/parse-tree/pt-walk.h
diffstat 14 files changed, 153 insertions(+), 285 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/octave-value/ov-classdef.cc	Thu May 04 15:02:46 2017 -0400
@@ -1915,10 +1915,9 @@
   void visit_break_command (octave::tree_break_command&) { }
   void visit_colon_expression (octave::tree_colon_expression&) { }
   void visit_continue_command (octave::tree_continue_command&) { }
-  void visit_global_command (octave::tree_global_command&) { }
-  void visit_persistent_command (octave::tree_persistent_command&) { }
+  void visit_decl_command (octave::tree_decl_command&) { }
+  void visit_decl_init_list (octave::tree_decl_init_list&) { }
   void visit_decl_elt (octave::tree_decl_elt&) { }
-  void visit_decl_init_list (octave::tree_decl_init_list&) { }
   void visit_simple_for_command (octave::tree_simple_for_command&) { }
   void visit_complex_for_command (octave::tree_complex_for_command&) { }
   void visit_octave_user_script (octave_user_script&) { }
--- a/libinterp/parse-tree/oct-parse.in.yy	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/oct-parse.in.yy	Thu May 04 15:02:46 2017 -0400
@@ -3859,12 +3859,18 @@
     switch (tok)
       {
       case GLOBAL:
-        retval = new tree_global_command (lst, l, c);
+        {
+          retval = new tree_decl_command ("global", lst, l, c);
+          retval->mark_as_global ();
+        }
         break;
 
       case PERSISTENT:
         if (curr_fcn_depth > 0)
-          retval = new tree_persistent_command (lst, l, c);
+          {
+            retval = new tree_decl_command ("persistent", lst, l, c);
+            retval->mark_as_persistent ();
+          }
         else
           {
             if (lexer.reading_script_file)
--- a/libinterp/parse-tree/pt-bp.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-bp.cc	Thu May 04 15:02:46 2017 -0400
@@ -100,32 +100,20 @@
   }
 
   void
-  tree_breakpoint::do_decl_command (tree_decl_command& cmd)
+  tree_breakpoint::visit_decl_command (tree_decl_command& cmd)
   {
     if (cmd.line () >= line)
       take_action (cmd);
   }
 
   void
-  tree_breakpoint::visit_global_command (tree_global_command& cmd)
-  {
-    do_decl_command (cmd);
-  }
-
-  void
-  tree_breakpoint::visit_persistent_command (tree_persistent_command& cmd)
-  {
-    do_decl_command (cmd);
-  }
-
-  void
-  tree_breakpoint::visit_decl_elt (tree_decl_elt&)
+  tree_breakpoint::visit_decl_init_list (tree_decl_init_list&)
   {
     panic_impossible ();
   }
 
   void
-  tree_breakpoint::visit_decl_init_list (tree_decl_init_list&)
+  tree_breakpoint::visit_decl_elt (tree_decl_elt&)
   {
     panic_impossible ();
   }
--- a/libinterp/parse-tree/pt-bp.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-bp.h	Thu May 04 15:02:46 2017 -0400
@@ -65,14 +65,12 @@
 
     void visit_continue_command (tree_continue_command&);
 
-    void visit_global_command (tree_global_command&);
+    void visit_decl_command (tree_decl_command&);
 
-    void visit_persistent_command (tree_persistent_command&);
+    void visit_decl_init_list (tree_decl_init_list&);
 
     void visit_decl_elt (tree_decl_elt&);
 
-    void visit_decl_init_list (tree_decl_init_list&);
-
     void visit_while_command (tree_while_command&);
 
     void visit_do_until_command (tree_do_until_command&);
@@ -150,8 +148,6 @@
 
   private:
 
-    void do_decl_command (tree_decl_command&);
-
     void take_action (tree& tr);
 
     void take_action (tree_statement& stmt);
--- a/libinterp/parse-tree/pt-check.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-check.cc	Thu May 04 15:02:46 2017 -0400
@@ -90,7 +90,7 @@
   { }
 
   void
-  tree_checker::do_decl_command (tree_decl_command& cmd)
+  tree_checker::visit_decl_command (tree_decl_command& cmd)
   {
     tree_decl_init_list *init_list = cmd.initializer_list ();
 
@@ -99,15 +99,17 @@
   }
 
   void
-  tree_checker::visit_global_command (tree_global_command& cmd)
+  tree_checker::visit_decl_init_list (tree_decl_init_list& lst)
   {
-    do_decl_command (cmd);
-  }
+    tree_decl_init_list::iterator p = lst.begin ();
 
-  void
-  tree_checker::visit_persistent_command (tree_persistent_command& cmd)
-  {
-    do_decl_command (cmd);
+    while (p != lst.end ())
+      {
+        tree_decl_elt *elt = *p++;
+
+        if (elt)
+          elt->accept (*this);
+      }
   }
 
   void
@@ -125,20 +127,6 @@
   }
 
   void
-  tree_checker::visit_decl_init_list (tree_decl_init_list& lst)
-  {
-    tree_decl_init_list::iterator p = lst.begin ();
-
-    while (p != lst.end ())
-      {
-        tree_decl_elt *elt = *p++;
-
-        if (elt)
-          elt->accept (*this);
-      }
-  }
-
-  void
   tree_checker::visit_simple_for_command (tree_simple_for_command& cmd)
   {
     tree_expression *lhs = cmd.left_hand_side ();
--- a/libinterp/parse-tree/pt-check.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-check.h	Thu May 04 15:02:46 2017 -0400
@@ -60,14 +60,12 @@
 
     void visit_continue_command(tree_continue_command&);
 
-    void visit_global_command (tree_global_command&);
+    void visit_decl_command (tree_decl_command&);
 
-    void visit_persistent_command (tree_persistent_command&);
+    void visit_decl_init_list (tree_decl_init_list&);
 
     void visit_decl_elt (tree_decl_elt&);
 
-    void visit_decl_init_list (tree_decl_init_list&);
-
     void visit_simple_for_command (tree_simple_for_command&);
 
     void visit_complex_for_command (tree_complex_for_command&);
@@ -140,8 +138,6 @@
 
     std::string file_name;
 
-    void do_decl_command (tree_decl_command&);
-
     OCTAVE_NORETURN void errmsg (const std::string& msg, int line);
   };
 }
--- a/libinterp/parse-tree/pt-decl.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-decl.cc	Thu May 04 15:02:46 2017 -0400
@@ -69,33 +69,35 @@
     return new_dil;
   }
 
-  // Base class for declaration commands (global, static).
+  // Declaration commands (global, static).
+
+  tree_decl_command::tree_decl_command (const std::string& n,
+                                        tree_decl_init_list *t, int l, int c)
+    : tree_command (l, c), cmd_name (n), init_list (t)
+  {
+    if (t)
+      {
+        if (cmd_name == "global")
+          mark_as_global ();
+        else if (cmd_name == "persistent")
+          mark_as_persistent ();
+        else
+          error ("tree_decl_command: unknown decl type: %s", cmd_name);
+      }
+  }
 
   tree_decl_command::~tree_decl_command (void)
   {
     delete init_list;
   }
 
-  // Global.
-
   tree_command *
-  tree_global_command::dup (symbol_table::scope_id scope,
-                            symbol_table::context_id context) const
+  tree_decl_command::dup (symbol_table::scope_id scope,
+                          symbol_table::context_id context) const
   {
-    return
-      new tree_global_command (init_list ? init_list->dup (scope, context) : 0,
-                               line (), column ());
-  }
+    tree_decl_init_list *new_init_list
+      = init_list ? init_list->dup (scope, context) : 0;
 
-  // Static.
-
-  tree_command *
-  tree_persistent_command::dup (symbol_table::scope_id scope,
-                                symbol_table::context_id context) const
-  {
-    return
-      new tree_persistent_command (init_list ? init_list->dup (scope, context)
-                                   : 0,
-                                   line (), column ());
+    return new tree_decl_command (name (), new_init_list, line (), column ());
   }
 }
--- a/libinterp/parse-tree/pt-decl.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-decl.h	Thu May 04 15:02:46 2017 -0400
@@ -46,8 +46,15 @@
   {
   public:
 
+    enum decl_type
+      {
+        unknown,
+        global,
+        persistent
+      };
+
     tree_decl_elt (tree_identifier *i = nullptr, tree_expression *e = nullptr)
-      : id (i), expr (e) { }
+      : type (unknown), id (i), expr (e) { }
 
     // No copying!
 
@@ -74,6 +81,12 @@
       return id ? id->lvalue (tw) : octave_lvalue ();
     }
 
+    void mark_as_global (void) { type = global; }
+    bool is_global (void) const { return type == global; }
+
+    void mark_as_persistent (void) { type = persistent; }
+    bool is_persistent (void) const { return type == persistent; }
+
     tree_identifier * ident (void) { return id; }
 
     std::string name (void) { return id ? id->name () : ""; }
@@ -90,6 +103,8 @@
 
   private:
 
+    decl_type type;
+
     // An identifier to tag with the declared property.
     tree_identifier *id;
 
@@ -121,6 +136,18 @@
         }
     }
 
+    void mark_as_global (void)
+    {
+      for (tree_decl_elt *elt : *this)
+        elt->mark_as_global ();
+    }
+
+    void mark_as_persistent (void)
+    {
+      for (tree_decl_elt *elt : *this)
+        elt->mark_as_persistent ();
+    }
+
     tree_decl_init_list * dup (symbol_table::scope_id scope,
                                symbol_table::context_id context) const;
 
@@ -140,8 +167,7 @@
       : tree_command (l, c), cmd_name (n), init_list (0) { }
 
     tree_decl_command (const std::string& n, tree_decl_init_list *t,
-                       int l = -1, int c = -1)
-      : tree_command (l, c), cmd_name (n), init_list (t) { }
+                       int l = -1, int c = -1);
 
     // No copying!
 
@@ -151,11 +177,31 @@
 
     ~tree_decl_command (void);
 
+    void mark_as_global (void)
+    {
+      if (init_list)
+        init_list->mark_as_global ();
+    }
+
+    void mark_as_persistent (void)
+    {
+      if (init_list)
+        init_list->mark_as_persistent ();
+    }
+
     tree_decl_init_list * initializer_list (void) { return init_list; }
 
-    std::string name (void) { return cmd_name; }
+    std::string name (void) const { return cmd_name; }
+
+    tree_command *dup (symbol_table::scope_id scope,
+                       symbol_table::context_id context) const;
 
-  protected:
+    void accept (tree_walker& tw)
+    {
+      tw.visit_decl_command (*this);
+    }
+
+  private:
 
     // The name of this command -- global, static, etc.
     std::string cmd_name;
@@ -163,72 +209,6 @@
     // The list of variables or initializers in this declaration command.
     tree_decl_init_list *init_list;
   };
-
-  // Global.
-
-  class tree_global_command : public tree_decl_command
-  {
-  public:
-
-    tree_global_command (int l = -1, int c = -1)
-      : tree_decl_command ("global", l, c) { }
-
-    tree_global_command (tree_decl_init_list *t, int l = -1, int c = -1)
-      : tree_decl_command ("global", t, l, c) { }
-
-    // No copying!
-
-    tree_global_command (const tree_global_command&) = delete;
-
-    tree_global_command& operator = (const tree_global_command&) = delete;
-
-    ~tree_global_command (void) = default;
-
-    tree_command * dup (symbol_table::scope_id scope,
-                        symbol_table::context_id context) const;
-
-    void accept (tree_walker& tw)
-    {
-      tw.visit_global_command (*this);
-    }
-
-  private:
-
-    static void do_init (tree_decl_elt& elt);
-  };
-
-  // Persistent.
-
-  class tree_persistent_command : public tree_decl_command
-  {
-  public:
-
-    tree_persistent_command (int l = -1, int c = -1)
-      : tree_decl_command ("persistent", l, c) { }
-
-    tree_persistent_command (tree_decl_init_list *t, int l = -1, int c = -1)
-      : tree_decl_command ("persistent", t, l, c) { }
-
-    // No copying!
-
-    tree_persistent_command (const tree_persistent_command&) = delete;
-
-    tree_persistent_command& operator = (const tree_persistent_command&) = delete;
-
-    ~tree_persistent_command (void) = default;
-
-    tree_command * dup (symbol_table::scope_id scope,
-                        symbol_table::context_id context) const;
-
-    void accept (tree_walker& tw)
-    {
-      tw.visit_persistent_command (*this);
-    }
-
-  private:
-
-    static void do_init (tree_decl_elt& elt);
-  };
 }
 
 #if defined (OCTAVE_USE_DEPRECATED_FUNCTIONS)
@@ -241,12 +221,6 @@
 OCTAVE_DEPRECATED ("use 'octave::tree_decl_command' instead")
 typedef octave::tree_decl_command tree_decl_command;
 
-OCTAVE_DEPRECATED ("use 'octave::tree_global_command' instead")
-typedef octave::tree_global_command tree_global_command;
-
-OCTAVE_DEPRECATED ("use 'octave::tree_persistent_command' instead")
-typedef octave::tree_persistent_command tree_persistent_command;
-
 #endif
 
 #endif
--- a/libinterp/parse-tree/pt-eval.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-eval.cc	Thu May 04 15:02:46 2017 -0400
@@ -608,40 +608,37 @@
   }
 
   void
-  tree_evaluator::do_global_init (octave::tree_decl_elt& elt)
+  tree_evaluator::visit_decl_command (tree_decl_command& cmd)
+  {
+    if (debug_mode)
+      do_breakpoint (cmd.is_breakpoint (true));
+
+    tree_decl_init_list *init_list = cmd.initializer_list ();
+
+    if (init_list)
+      init_list->accept (*this);
+  }
+
+  void
+  tree_evaluator::visit_decl_init_list (tree_decl_init_list& lst)
+  {
+    for (tree_decl_elt *elt : lst)
+      elt->accept (*this);
+  }
+
+  void
+  tree_evaluator::visit_decl_elt (tree_decl_elt& elt)
   {
     octave::tree_identifier *id = elt.ident ();
 
     if (id)
       {
-        id->mark_global ();
-
-        octave_lvalue ult = id->lvalue (this);
-
-        if (ult.is_undefined ())
-          {
-            octave::tree_expression *expr = elt.expression ();
-
-            octave_value init_val;
-
-            if (expr)
-              init_val = evaluate (expr);
-            else
-              init_val = Matrix ();
-
-            ult.assign (octave_value::op_asn_eq, init_val);
-          }
-      }
-  }
-
-  void
-  tree_evaluator::do_static_init (octave::tree_decl_elt& elt)
-  {
-    octave::tree_identifier *id = elt.ident ();
-
-    if (id)
-      {
-        id->mark_as_static ();
+        if (elt.is_global ())
+          id->mark_global ();
+        else if (elt.is_persistent ())
+          id->mark_as_static ();
+        else
+          error ("declaration list element not global or persistent");
 
         octave_lvalue ult = id->lvalue (this);
 
@@ -660,56 +657,6 @@
           }
       }
   }
-
-  void
-  tree_evaluator::visit_global_command (tree_global_command& cmd)
-  {
-    if (debug_mode)
-      do_breakpoint (cmd.is_breakpoint (true));
-
-    tree_decl_init_list *init_list = cmd.initializer_list ();
-
-    if (init_list)
-      {
-        // If we called init_list->accept (*this), we would need a way
-        // to tell tree_evaluator::visit_decl_init_list that we are
-        // evaluating a global init list.
-
-        for (tree_decl_elt *elt : *init_list)
-          do_global_init (*elt);
-      }
-  }
-
-  void
-  tree_evaluator::visit_persistent_command (tree_persistent_command& cmd)
-  {
-    if (debug_mode)
-      do_breakpoint (cmd.is_breakpoint (true));
-
-    tree_decl_init_list *init_list = cmd.initializer_list ();
-
-    if (init_list)
-      {
-        // If we called init_list->accept (*this), we would need a way
-        // to tell tree_evaluator::visit_decl_init_list that we are
-        // evaluating a static init list.
-
-        for (tree_decl_elt *elt : *init_list)
-          do_static_init (*elt);
-      }
-  }
-
-  void
-  tree_evaluator::visit_decl_elt (tree_decl_elt&)
-  {
-    panic_impossible ();
-  }
-
-  void
-  tree_evaluator::visit_decl_init_list (tree_decl_init_list&)
-  {
-    panic_impossible ();
-  }
 }
 
 // Decide if it's time to quit a for or while loop.
--- a/libinterp/parse-tree/pt-eval.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-eval.h	Thu May 04 15:02:46 2017 -0400
@@ -118,14 +118,12 @@
 
     void visit_continue_command (tree_continue_command&);
 
-    void visit_global_command (tree_global_command&);
+    void visit_decl_command (tree_decl_command&);
 
-    void visit_persistent_command (tree_persistent_command&);
+    void visit_decl_init_list (tree_decl_init_list&);
 
     void visit_decl_elt (tree_decl_elt&);
 
-    void visit_decl_init_list (tree_decl_init_list&);
-
     void visit_simple_for_command (tree_simple_for_command&);
 
     void visit_complex_for_command (tree_complex_for_command&);
@@ -281,10 +279,6 @@
 
   private:
 
-    void do_global_init (octave::tree_decl_elt& elt);
-
-    void do_static_init (octave::tree_decl_elt& elt);
-
     void do_breakpoint (tree_statement& stmt) const;
 
     void do_breakpoint (bool is_breakpoint,
--- a/libinterp/parse-tree/pt-jit.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-jit.h	Thu May 04 15:02:46 2017 -0400
@@ -89,14 +89,12 @@
 
   void visit_continue_command (tree_continue_command&);
 
-  void visit_global_command (tree_global_command&);
+  void visit_decl_command (tree_decl_command&);
 
-  void visit_persistent_command (tree_persistent_command&);
+  void visit_decl_init_list (tree_decl_init_list&);
 
   void visit_decl_elt (tree_decl_elt&);
 
-  void visit_decl_init_list (tree_decl_init_list&);
-
   void visit_simple_for_command (tree_simple_for_command&);
 
   void visit_complex_for_command (tree_complex_for_command&);
--- a/libinterp/parse-tree/pt-pr-code.cc	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-pr-code.cc	Thu May 04 15:02:46 2017 -0400
@@ -148,7 +148,7 @@
   }
 
   void
-  tree_print_code::do_decl_command (tree_decl_command& cmd)
+  tree_print_code::visit_decl_command (tree_decl_command& cmd)
   {
     indent ();
 
@@ -161,36 +161,6 @@
   }
 
   void
-  tree_print_code::visit_global_command (tree_global_command& cmd)
-  {
-    do_decl_command (cmd);
-  }
-
-  void
-  tree_print_code::visit_persistent_command (tree_persistent_command& cmd)
-  {
-    do_decl_command (cmd);
-  }
-
-  void
-  tree_print_code::visit_decl_elt (tree_decl_elt& cmd)
-  {
-    tree_identifier *id = cmd.ident ();
-
-    if (id)
-      id->accept (*this);
-
-    tree_expression *expr = cmd.expression ();
-
-    if (expr)
-      {
-        os << " = ";
-
-        expr->accept (*this);
-      }
-  }
-
-  void
   tree_print_code::visit_decl_init_list (tree_decl_init_list& lst)
   {
     tree_decl_init_list::iterator p = lst.begin ();
@@ -210,6 +180,24 @@
   }
 
   void
+  tree_print_code::visit_decl_elt (tree_decl_elt& cmd)
+  {
+    tree_identifier *id = cmd.ident ();
+
+    if (id)
+      id->accept (*this);
+
+    tree_expression *expr = cmd.expression ();
+
+    if (expr)
+      {
+        os << " = ";
+
+        expr->accept (*this);
+      }
+  }
+
+  void
   tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd)
   {
     print_comment_list (cmd.leading_comment ());
--- a/libinterp/parse-tree/pt-pr-code.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-pr-code.h	Thu May 04 15:02:46 2017 -0400
@@ -74,14 +74,12 @@
 
     void visit_continue_command (tree_continue_command&);
 
-    void visit_global_command (tree_global_command&);
+    void visit_decl_command (tree_decl_command&);
 
-    void visit_persistent_command (tree_persistent_command&);
+    void visit_decl_init_list (tree_decl_init_list&);
 
     void visit_decl_elt (tree_decl_elt&);
 
-    void visit_decl_init_list (tree_decl_init_list&);
-
     void visit_simple_for_command (tree_simple_for_command&);
 
     void visit_complex_for_command (tree_complex_for_command&);
@@ -171,8 +169,6 @@
     // Nonzero means we are not printing newlines and indenting.
     int suppress_newlines;
 
-    void do_decl_command (tree_decl_command& cmd);
-
     void reset_indent_level (void) { curr_print_indent_level = 0; }
 
     void increment_indent_level (void) { curr_print_indent_level += 2; }
--- a/libinterp/parse-tree/pt-walk.h	Thu May 04 10:29:51 2017 -0400
+++ b/libinterp/parse-tree/pt-walk.h	Thu May 04 15:02:46 2017 -0400
@@ -45,10 +45,9 @@
   class tree_break_command;
   class tree_colon_expression;
   class tree_continue_command;
-  class tree_global_command;
-  class tree_persistent_command;
+  class tree_decl_command;
+  class tree_decl_init_list;
   class tree_decl_elt;
-  class tree_decl_init_list;
   class tree_simple_for_command;
   class tree_complex_for_command;
   class tree_function_def;
@@ -139,10 +138,7 @@
     visit_continue_command (tree_continue_command&) = 0;
 
     virtual void
-    visit_global_command (tree_global_command&) = 0;
-
-    virtual void
-    visit_persistent_command (tree_persistent_command&) = 0;
+    visit_decl_command (tree_decl_command&) = 0;
 
     virtual void
     visit_decl_elt (tree_decl_elt&) = 0;