changeset 24067:5b88383b9a69

install local functions after classdef parse is complete (bug #52080) * parse.h, oct-parse.in.yy (base_parser::finish_classdef_file): New function. (file): Use it to install classdef object and local functions. (base_parser::finish_function): Don't install classdef file local functions here.
author John W. Eaton <jwe@octave.org>
date Thu, 21 Sep 2017 11:15:43 -0400
parents d9b0d8ae734f
children 0d7a7fc657ff
files libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h
diffstat 2 files changed, 36 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy	Wed Sep 20 17:23:50 2017 -0700
+++ b/libinterp/parse-tree/oct-parse.in.yy	Thu Sep 21 11:15:43 2017 -0400
@@ -1485,14 +1485,12 @@
                   {
                     YYUSE ($2);
                     YYUSE ($5);
-                    YYUSE ($6);
 
                     // Unused symbol table context.
                     delete lexer.symtab_context.curr_scope ();
                     lexer.symtab_context.pop ();
 
-                    if (lexer.reading_classdef_file)
-                      parser.m_classdef_object = $3;
+                    parser.finish_classdef_file ($3, $6);
 
                     $$ = nullptr;
                   }
@@ -3445,10 +3443,6 @@
         if (! file.empty ())
           tmp += ": " + file;
 
-        symbol_table& symtab
-          = __get_symbol_table__ ("base_parser::finish_function");
-
-
         symbol_table::scope *fcn_scope = fcn->scope ();
         fcn_scope->cache_name (tmp);
 
@@ -3478,9 +3472,6 @@
                }
           }
 
-        if (m_parsing_local_functions && m_curr_fcn_depth == 1)
-          symtab.install_local_function (nm, octave_value (fcn), file);
-
         if (m_curr_fcn_depth == 1)
           fcn_scope->update_nest ();
 
@@ -3822,6 +3813,37 @@
     return new tree_function_def (fcn, l, c);
   }
 
+  void
+  base_parser::finish_classdef_file (tree_classdef *cls,
+                                     tree_statement_list *local_fcns)
+  {
+    if (m_lexer.reading_classdef_file)
+      m_classdef_object = cls;
+
+    if (local_fcns)
+      {
+        symbol_table& symtab
+          = __get_symbol_table__ ("base_parser::finish_classdef_file");
+
+        for (tree_statement *elt : *local_fcns)
+          {
+            tree_command *cmd = elt->command ();
+
+            tree_function_def *fcn_def
+              = dynamic_cast<tree_function_def *> (cmd);
+
+            octave_value ov_fcn = fcn_def->function ();
+            octave_function *fcn = ov_fcn.function_value ();
+            std::string nm = fcn->name ();
+            std::string file = fcn->fcn_file_name ();
+
+            symtab.install_local_function (nm, ov_fcn, file);
+          }
+
+        delete local_fcns;
+      }
+  }
+
   // Make an index expression.
 
   tree_index_expression *
--- a/libinterp/parse-tree/parse.h	Wed Sep 20 17:23:50 2017 -0700
+++ b/libinterp/parse-tree/parse.h	Thu Sep 21 11:15:43 2017 -0400
@@ -350,6 +350,10 @@
                                      tree_parameter_list *ret_list,
                                      comment_list *cl);
 
+    void
+    finish_classdef_file (tree_classdef *cls,
+                          tree_statement_list *local_fcns);
+
     // Make an index expression.
     tree_index_expression *
     make_index_expression (tree_expression *expr,