diff libinterp/corefcn/fcn-info.cc @ 31607:aac27ad79be6 stable

maint: Re-indent code after switch to using namespace macros. * build-env.h, build-env.in.cc, Cell.h, __betainc__.cc, __eigs__.cc, __ftp__.cc, __ichol__.cc, __ilu__.cc, __isprimelarge__.cc, __magick_read__.cc, __pchip_deriv__.cc, amd.cc, base-text-renderer.cc, base-text-renderer.h, besselj.cc, bitfcns.cc, bsxfun.cc, c-file-ptr-stream.h, call-stack.cc, call-stack.h, ccolamd.cc, cellfun.cc, chol.cc, colamd.cc, dasrt.cc, data.cc, debug.cc, defaults.cc, defaults.h, det.cc, display.cc, display.h, dlmread.cc, dynamic-ld.cc, dynamic-ld.h, ellipj.cc, environment.cc, environment.h, error.cc, error.h, errwarn.h, event-manager.cc, event-manager.h, event-queue.cc, event-queue.h, fcn-info.cc, fcn-info.h, fft.cc, fft2.cc, file-io.cc, filter.cc, find.cc, ft-text-renderer.cc, ft-text-renderer.h, gcd.cc, gl-render.cc, gl-render.h, gl2ps-print.cc, gl2ps-print.h, graphics-toolkit.cc, graphics-toolkit.h, graphics.cc, gsvd.cc, gtk-manager.cc, gtk-manager.h, help.cc, help.h, hook-fcn.cc, hook-fcn.h, input.cc, input.h, interpreter-private.cc, interpreter-private.h, interpreter.cc, interpreter.h, inv.cc, jsondecode.cc, jsonencode.cc, latex-text-renderer.cc, latex-text-renderer.h, load-path.cc, load-path.h, load-save.cc, load-save.h, lookup.cc, ls-hdf5.cc, ls-mat4.cc, ls-mat5.cc, lsode.cc, lu.cc, mappers.cc, matrix_type.cc, max.cc, mex.cc, mexproto.h, mxarray.h, mxtypes.in.h, oct-errno.in.cc, oct-hdf5-types.cc, oct-hist.cc, oct-hist.h, oct-map.cc, oct-map.h, oct-opengl.h, oct-prcstrm.h, oct-process.cc, oct-process.h, oct-stdstrm.h, oct-stream.cc, oct-stream.h, oct-strstrm.h, octave-default-image.h, ordqz.cc, ordschur.cc, pager.cc, pager.h, pinv.cc, pow2.cc, pr-output.cc, psi.cc, qr.cc, quadcc.cc, rand.cc, regexp.cc, settings.cc, settings.h, sighandlers.cc, sighandlers.h, sparse-xpow.cc, sqrtm.cc, stack-frame.cc, stack-frame.h, stream-euler.cc, strfns.cc, svd.cc, syminfo.cc, syminfo.h, symrcm.cc, symrec.cc, symrec.h, symscope.cc, symscope.h, symtab.cc, symtab.h, sysdep.cc, sysdep.h, text-engine.cc, text-engine.h, text-renderer.cc, text-renderer.h, time.cc, toplev.cc, typecast.cc, url-handle-manager.cc, url-handle-manager.h, urlwrite.cc, utils.cc, utils.h, variables.cc, variables.h, xdiv.cc, __delaunayn__.cc, __init_fltk__.cc, __init_gnuplot__.cc, __ode15__.cc, __voronoi__.cc, audioread.cc, convhulln.cc, gzip.cc, cdef-class.cc, cdef-class.h, cdef-fwd.h, cdef-manager.cc, cdef-manager.h, cdef-method.cc, cdef-method.h, cdef-object.cc, cdef-object.h, cdef-package.cc, cdef-package.h, cdef-property.cc, cdef-property.h, cdef-utils.cc, cdef-utils.h, ov-base-diag.cc, ov-base-int.cc, ov-base-mat.cc, ov-base-mat.h, ov-base-scalar.cc, ov-base.cc, ov-base.h, ov-bool-mat.cc, ov-bool-mat.h, ov-bool-sparse.cc, ov-bool.cc, ov-builtin.h, ov-cell.cc, ov-ch-mat.cc, ov-class.cc, ov-class.h, ov-classdef.cc, ov-classdef.h, ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-cx-sparse.cc, ov-dld-fcn.cc, ov-dld-fcn.h, ov-fcn-handle.cc, ov-fcn-handle.h, ov-fcn.h, ov-float.cc, ov-flt-complex.cc, ov-flt-cx-diag.cc, ov-flt-cx-mat.cc, ov-flt-re-diag.cc, ov-flt-re-mat.cc, ov-flt-re-mat.h, ov-intx.h, ov-java.cc, ov-lazy-idx.cc, ov-legacy-range.cc, ov-magic-int.cc, ov-mex-fcn.cc, ov-mex-fcn.h, ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc, ov-re-mat.h, ov-re-sparse.cc, ov-scalar.cc, ov-str-mat.cc, ov-struct.cc, ov-typeinfo.cc, ov-typeinfo.h, ov-usr-fcn.cc, ov-usr-fcn.h, ov.cc, ov.h, ovl.h, octave.cc, octave.h, op-b-sbm.cc, op-bm-sbm.cc, op-cs-scm.cc, op-fm-fcm.cc, op-fs-fcm.cc, op-s-scm.cc, op-scm-cs.cc, op-scm-s.cc, op-sm-cs.cc, ops.h, anon-fcn-validator.cc, anon-fcn-validator.h, bp-table.cc, bp-table.h, comment-list.cc, comment-list.h, filepos.h, lex.h, oct-lvalue.cc, oct-lvalue.h, parse.h, profiler.cc, profiler.h, pt-anon-scopes.cc, pt-anon-scopes.h, pt-arg-list.cc, pt-arg-list.h, pt-args-block.cc, pt-args-block.h, pt-array-list.cc, pt-array-list.h, pt-assign.cc, pt-assign.h, pt-binop.cc, pt-binop.h, pt-bp.cc, pt-bp.h, pt-cbinop.cc, pt-cbinop.h, pt-cell.cc, pt-cell.h, pt-check.cc, pt-check.h, pt-classdef.cc, pt-classdef.h, pt-cmd.h, pt-colon.cc, pt-colon.h, pt-const.cc, pt-const.h, pt-decl.cc, pt-decl.h, pt-eval.cc, pt-eval.h, pt-except.cc, pt-except.h, pt-exp.cc, pt-exp.h, pt-fcn-handle.cc, pt-fcn-handle.h, pt-id.cc, pt-id.h, pt-idx.cc, pt-idx.h, pt-jump.h, pt-loop.cc, pt-loop.h, pt-mat.cc, pt-mat.h, pt-misc.cc, pt-misc.h, pt-pr-code.cc, pt-pr-code.h, pt-select.cc, pt-select.h, pt-spmd.cc, pt-spmd.h, pt-stmt.cc, pt-stmt.h, pt-tm-const.cc, pt-tm-const.h, pt-unop.cc, pt-unop.h, pt-walk.cc, pt-walk.h, pt.cc, pt.h, token.cc, token.h, Range.cc, Range.h, idx-vector.cc, idx-vector.h, range-fwd.h, CollocWt.cc, CollocWt.h, aepbalance.cc, aepbalance.h, chol.cc, chol.h, gepbalance.cc, gepbalance.h, gsvd.cc, gsvd.h, hess.cc, hess.h, lo-mappers.cc, lo-mappers.h, lo-specfun.cc, lo-specfun.h, lu.cc, lu.h, oct-convn.cc, oct-convn.h, oct-fftw.cc, oct-fftw.h, oct-norm.cc, oct-norm.h, oct-rand.cc, oct-rand.h, oct-spparms.cc, oct-spparms.h, qr.cc, qr.h, qrp.cc, qrp.h, randgamma.cc, randgamma.h, randmtzig.cc, randmtzig.h, randpoisson.cc, randpoisson.h, schur.cc, schur.h, sparse-chol.cc, sparse-chol.h, sparse-lu.cc, sparse-lu.h, sparse-qr.cc, sparse-qr.h, svd.cc, svd.h, child-list.cc, child-list.h, dir-ops.cc, dir-ops.h, file-ops.cc, file-ops.h, file-stat.cc, file-stat.h, lo-sysdep.cc, lo-sysdep.h, lo-sysinfo.cc, lo-sysinfo.h, mach-info.cc, mach-info.h, oct-env.cc, oct-env.h, oct-group.cc, oct-group.h, oct-password.cc, oct-password.h, oct-syscalls.cc, oct-syscalls.h, oct-time.cc, oct-time.h, oct-uname.cc, oct-uname.h, action-container.cc, action-container.h, base-list.h, cmd-edit.cc, cmd-edit.h, cmd-hist.cc, cmd-hist.h, f77-fcn.h, file-info.cc, file-info.h, lo-array-errwarn.cc, lo-array-errwarn.h, lo-hash.cc, lo-hash.h, lo-ieee.h, lo-regexp.cc, lo-regexp.h, lo-utils.cc, lo-utils.h, oct-base64.cc, oct-base64.h, oct-glob.cc, oct-glob.h, oct-inttypes.h, oct-mutex.cc, oct-mutex.h, oct-refcount.h, oct-shlib.cc, oct-shlib.h, oct-sparse.cc, oct-sparse.h, oct-string.h, octave-preserve-stream-state.h, pathsearch.cc, pathsearch.h, quit.cc, quit.h, unwind-prot.cc, unwind-prot.h, url-transfer.cc, url-transfer.h: Re-indent code after switch to using namespace macros.
author Rik <rik@octave.org>
date Thu, 01 Dec 2022 18:02:15 -0800
parents e88a07dec498
children 597f3ee61a48
line wrap: on
line diff
--- a/libinterp/corefcn/fcn-info.cc	Thu Dec 01 14:23:45 2022 -0800
+++ b/libinterp/corefcn/fcn-info.cc	Thu Dec 01 18:02:15 2022 -0800
@@ -49,1089 +49,1090 @@
 
 OCTAVE_BEGIN_NAMESPACE(octave)
 
-  octave_value
-  fcn_info::fcn_info_rep::load_private_function (const std::string& dir_name)
-  {
-    octave_value retval;
-
-    load_path& lp = __get_load_path__ ();
-
-    std::string file_name = lp.find_private_fcn (dir_name, name);
-
-    if (file_name.empty ())
-      return retval;
+octave_value
+fcn_info::fcn_info_rep::load_private_function (const std::string& dir_name)
+{
+  octave_value retval;
 
-    octave_value ov_fcn = load_fcn_from_file (file_name, dir_name);
-
-    if (ov_fcn.is_undefined ())
-      return retval;
+  load_path& lp = __get_load_path__ ();
 
-    octave_function *tmpfcn = ov_fcn.function_value ();
+  std::string file_name = lp.find_private_fcn (dir_name, name);
 
-    if (! tmpfcn)
-      return retval;
-
-    std::string class_name;
+  if (file_name.empty ())
+    return retval;
 
-    std::size_t pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
-
-    if (pos != std::string::npos)
-      {
-        std::string tmp = dir_name.substr (pos+1);
+  octave_value ov_fcn = load_fcn_from_file (file_name, dir_name);
 
-        if (tmp[0] == '@')
-          class_name = tmp.substr (1);
-      }
+  if (ov_fcn.is_undefined ())
+    return retval;
 
-    tmpfcn->mark_as_private_function (class_name);
+  octave_function *tmpfcn = ov_fcn.function_value ();
 
-    private_functions[sys::canonicalize_file_name (dir_name)] = ov_fcn;
-
-    return ov_fcn;
-  }
+  if (! tmpfcn)
+    return retval;
 
-  octave_value
-  fcn_info::fcn_info_rep::load_class_constructor (void)
-  {
-    octave_value retval;
+  std::string class_name;
 
-    std::string dir_name;
+  std::size_t pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
 
-    load_path& lp = __get_load_path__ ();
-
-    std::string file_name = lp.find_method (name, name, dir_name, package_name);
+  if (pos != std::string::npos)
+    {
+      std::string tmp = dir_name.substr (pos+1);
 
-    if (! file_name.empty ())
-      {
-        octave_value ov_fcn
-          = load_fcn_from_file (file_name, dir_name, name,
-                                package_name);
+      if (tmp[0] == '@')
+        class_name = tmp.substr (1);
+    }
 
-        if (ov_fcn.is_defined ())
-          {
-            // Note: ov_fcn may be an octave_classdef_meta object instead
-            // of the actual constructor function.
+  tmpfcn->mark_as_private_function (class_name);
 
-            retval = ov_fcn;
+  private_functions[sys::canonicalize_file_name (dir_name)] = ov_fcn;
 
-            class_constructors[name] = retval;
-            class_methods[name] = retval;
-          }
-      }
-    else
-      {
-        // Classdef constructors can be defined anywhere in the path, not
-        // necessarily in @-folders.  Look for a normal function and load it.
-        // If the loaded function is a classdef constructor, store it as such
-        // and restore function_on_path to its previous value.
-
-        octave_value old_function_on_path = function_on_path;
-
-        octave_value maybe_cdef_ctor = find_user_function ();
+  return ov_fcn;
+}
 
-        if (maybe_cdef_ctor.is_defined ())
-          {
-            octave_function *fcn = maybe_cdef_ctor.function_value (true);
-
-            if (fcn && fcn->is_classdef_constructor ())
-              {
-                retval = maybe_cdef_ctor;
+octave_value
+fcn_info::fcn_info_rep::load_class_constructor (void)
+{
+  octave_value retval;
 
-                class_constructors[name] = retval;
-                class_methods[name] = retval;
+  std::string dir_name;
 
-                function_on_path = old_function_on_path;
-              }
-          }
-      }
+  load_path& lp = __get_load_path__ ();
+
+  std::string file_name = lp.find_method (name, name, dir_name, package_name);
 
-    return retval;
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::load_class_method (const std::string& dispatch_type)
-  {
-    octave_value retval;
+  if (! file_name.empty ())
+    {
+      octave_value ov_fcn
+        = load_fcn_from_file (file_name, dir_name, name,
+                              package_name);
 
-    if (full_name () == dispatch_type)
-      retval = load_class_constructor ();
-    else
-      {
-        cdef_manager& cdm = __get_cdef_manager__ ();
+      if (ov_fcn.is_defined ())
+        {
+          // Note: ov_fcn may be an octave_classdef_meta object instead
+          // of the actual constructor function.
 
-        retval = cdm.find_method_symbol (name, dispatch_type);
-
-        if (! retval.is_defined ())
-          {
-            std::string dir_name;
-
-            load_path& lp = __get_load_path__ ();
+          retval = ov_fcn;
 
-            std::string file_name = lp.find_method (dispatch_type, name,
-                                                    dir_name);
-
-            if (! file_name.empty ())
-              {
-                octave_value ov_fcn
-                  = load_fcn_from_file (file_name, dir_name,
-                                        dispatch_type);
-
-                if (ov_fcn.is_defined ())
-                  {
-                    octave_function *tmpfcn = ov_fcn.function_value ();
+          class_constructors[name] = retval;
+          class_methods[name] = retval;
+        }
+    }
+  else
+    {
+      // Classdef constructors can be defined anywhere in the path, not
+      // necessarily in @-folders.  Look for a normal function and load it.
+      // If the loaded function is a classdef constructor, store it as such
+      // and restore function_on_path to its previous value.
 
-                    if (tmpfcn && tmpfcn->is_class_method (dispatch_type))
-                      {
-                        retval = ov_fcn;
-
-                        class_methods[dispatch_type] = retval;
-                      }
-                  }
-              }
-
-            if (retval.is_undefined ())
-              {
-                // Search parent classes
+      octave_value old_function_on_path = function_on_path;
 
-                symbol_table& symtab = __get_symbol_table__ ();
+      octave_value maybe_cdef_ctor = find_user_function ();
 
-                const std::list<std::string>& plist
-                  = symtab.parent_classes (dispatch_type);
-
-                auto it = plist.begin ();
+      if (maybe_cdef_ctor.is_defined ())
+        {
+          octave_function *fcn = maybe_cdef_ctor.function_value (true);
 
-                while (it != plist.end ())
-                  {
-                    retval = find_method (*it);
+          if (fcn && fcn->is_classdef_constructor ())
+            {
+              retval = maybe_cdef_ctor;
 
-                    if (retval.is_defined ())
-                      {
-                        class_methods[dispatch_type] = retval;
-                        break;
-                      }
-
-                    it++;
-                  }
-              }
+              class_constructors[name] = retval;
+              class_methods[name] = retval;
 
-            if (retval.is_undefined ())
-              {
-                // Search for built-in functions that are declared to
-                // handle specific types.
-
-                if (built_in_function.is_defined ())
-                  {
-                    octave_function *fcn = built_in_function.function_value ();
-
-                    if (fcn && fcn->handles_dispatch_class (dispatch_type))
-                      {
-                        retval = built_in_function;
+              function_on_path = old_function_on_path;
+            }
+        }
+    }
 
-                        class_methods[dispatch_type] = retval;
-                      }
-                  }
-              }
-          }
-      }
+  return retval;
+}
 
-    return retval;
-  }
-
-  // :-) JWE, can you parse this? Returns a 2D array with second dimension equal
-  // to btyp_num_types (static constant).  Only the leftmost dimension can be
-  // variable in C/C++.  Typedefs are boring.
+octave_value
+fcn_info::fcn_info_rep::load_class_method (const std::string& dispatch_type)
+{
+  octave_value retval;
 
-  static builtin_type_t (*build_sup_table (void))[btyp_num_types]
-  {
-    static builtin_type_t sup_table[btyp_num_types][btyp_num_types];
-    for (int i = 0; i < btyp_num_types; i++)
-      for (int j = 0; j < btyp_num_types; j++)
+  if (full_name () == dispatch_type)
+    retval = load_class_constructor ();
+  else
+    {
+      cdef_manager& cdm = __get_cdef_manager__ ();
+
+      retval = cdm.find_method_symbol (name, dispatch_type);
+
+      if (! retval.is_defined ())
         {
-          builtin_type_t ityp = static_cast<builtin_type_t> (i);
-          builtin_type_t jtyp = static_cast<builtin_type_t> (j);
-          // FIXME: Is this really right?
-          bool use_j
-            = (jtyp == btyp_func_handle || ityp == btyp_bool
-               || (btyp_isarray (ityp)
-                   && (! btyp_isarray (jtyp)
-                       || (btyp_isinteger (jtyp) && ! btyp_isinteger (ityp))
-                       || ((ityp == btyp_double || ityp == btyp_complex
-                            || ityp == btyp_char)
-                           && (jtyp == btyp_float
-                               || jtyp == btyp_float_complex)))));
+          std::string dir_name;
+
+          load_path& lp = __get_load_path__ ();
 
-          sup_table[i][j] = (use_j ? jtyp : ityp);
-        }
-
-    return sup_table;
-  }
+          std::string file_name = lp.find_method (dispatch_type, name,
+                                                  dir_name);
 
-  std::string
-  get_dispatch_type (const octave_value_list& args,
-                     builtin_type_t& builtin_type)
-  {
-    static builtin_type_t (*sup_table)[btyp_num_types] = build_sup_table ();
-    std::string dispatch_type;
-
-    int n = args.length ();
+          if (! file_name.empty ())
+            {
+              octave_value ov_fcn
+                = load_fcn_from_file (file_name, dir_name,
+                                      dispatch_type);
 
-    if (n > 0)
-      {
-        int i = 0;
-        builtin_type = args(0).builtin_type ();
-        if (builtin_type != btyp_unknown)
-          {
-            for (i = 1; i < n; i++)
-              {
-                builtin_type_t bti = args(i).builtin_type ();
-                if (bti != btyp_unknown)
-                  builtin_type = sup_table[builtin_type][bti];
-                else
-                  {
-                    builtin_type = btyp_unknown;
-                    break;
-                  }
-              }
-          }
+              if (ov_fcn.is_defined ())
+                {
+                  octave_function *tmpfcn = ov_fcn.function_value ();
 
-        if (builtin_type == btyp_unknown)
-          {
-            // There's a non-builtin class in the argument list.
-            dispatch_type = args(i).class_name ();
+                  if (tmpfcn && tmpfcn->is_class_method (dispatch_type))
+                    {
+                      retval = ov_fcn;
 
-            symbol_table& symtab = __get_symbol_table__ ();
+                      class_methods[dispatch_type] = retval;
+                    }
+                }
+            }
 
-            for (int j = i+1; j < n; j++)
-              {
-                octave_value arg = args(j);
+          if (retval.is_undefined ())
+            {
+              // Search parent classes
 
-                if (arg.builtin_type () == btyp_unknown)
-                  {
-                    std::string cname = arg.class_name ();
+              symbol_table& symtab = __get_symbol_table__ ();
 
-                    // Only switch to type of ARG if it is marked superior
-                    // to the current DISPATCH_TYPE.
-                    if (! symtab.is_superiorto (dispatch_type, cname)
-                        && symtab.is_superiorto (cname, dispatch_type))
-                      dispatch_type = cname;
-                  }
-              }
-          }
-        else
-          dispatch_type = btyp_class_name[builtin_type];
-      }
-    else
-      builtin_type = btyp_unknown;
+              const std::list<std::string>& plist
+                = symtab.parent_classes (dispatch_type);
 
-    return dispatch_type;
-  }
+              auto it = plist.begin ();
 
-  std::string
-  get_dispatch_type (const octave_value_list& args)
-  {
-    builtin_type_t builtin_type;
-    return get_dispatch_type (args, builtin_type);
-  }
+              while (it != plist.end ())
+                {
+                  retval = find_method (*it);
 
-  // Find function definition according to the following precedence list:
-  //
-  //   nested functions (and subfunctions)
-  //   local functions in the current file
-  //   private function
-  //   class method
-  //   class constructor
-  //   command-line function
-  //   autoload function
-  //   functions on the load_path (current directory is always first)
-  //   package (FIXME: does this belong here?)
-  //   built-in function
+                  if (retval.is_defined ())
+                    {
+                      class_methods[dispatch_type] = retval;
+                      break;
+                    }
 
-  octave_value
-  fcn_info::fcn_info_rep::find (const symbol_scope& scope,
-                                const octave_value_list& args)
-  {
-    symbol_scope search_scope
-      = (scope
-         ? scope : __get_current_scope__ ());
+                  it++;
+                }
+            }
 
-    octave_value retval = xfind (search_scope, args);
+          if (retval.is_undefined ())
+            {
+              // Search for built-in functions that are declared to
+              // handle specific types.
+
+              if (built_in_function.is_defined ())
+                {
+                  octave_function *fcn = built_in_function.function_value ();
 
-    if (retval.is_undefined ())
-      {
-        // It is possible that the user created a file on the fly since
-        // the last prompt or chdir, so try updating the load path and
-        // searching again.
+                  if (fcn && fcn->handles_dispatch_class (dispatch_type))
+                    {
+                      retval = built_in_function;
 
-        load_path& lp = __get_load_path__ ();
-
-        lp.update ();
-
-        retval = xfind (search_scope, args);
-      }
+                      class_methods[dispatch_type] = retval;
+                    }
+                }
+            }
+        }
+    }
 
-    return retval;
-  }
-
+  return retval;
+}
 
-  static void
-  split_name_with_package (const std::string& name, std::string& fname,
-                           std::string& pname)
-  {
-    std::size_t pos = name.rfind ('.');
+// :-) JWE, can you parse this? Returns a 2D array with second dimension equal
+// to btyp_num_types (static constant).  Only the leftmost dimension can be
+// variable in C/C++.  Typedefs are boring.
 
-    fname.clear ();
-    pname.clear ();
-
-    if (pos != std::string::npos)
+static builtin_type_t (* build_sup_table (void))[btyp_num_types]
+{
+  static builtin_type_t sup_table[btyp_num_types][btyp_num_types];
+  for (int i = 0; i < btyp_num_types; i++)
+    for (int j = 0; j < btyp_num_types; j++)
       {
-        fname = name.substr (pos + 1);
-        pname = name.substr (0, pos);
-      }
-    else
-      fname = name;
-  }
-
-  // Check the load path to see if file that defined this is still
-  // visible.  If the file is no longer visible, then erase the
-  // definition and move on.  If the file is visible, then we also
-  // need to check to see whether the file has changed since the
-  // function was loaded/parsed.  However, this check should only
-  // happen once per prompt (for files found from relative path
-  // elements, we also check if the working directory has changed
-  // since the last time the function was loaded/parsed).
-  //
-  // FIXME: perhaps this should be done for all loaded functions when
-  // the prompt is printed or the directory has changed, and then we
-  // would not check for it when finding symbol definitions.
-
-  static inline bool
-  load_out_of_date_fcn (const std::string& file_name,
-                        const std::string& dir_name_arg,
-                        octave_value& function,
-                        const std::string& dispatch_type = "",
-                        const std::string& package_name = "")
-  {
-    bool retval = false;
+        builtin_type_t ityp = static_cast<builtin_type_t> (i);
+        builtin_type_t jtyp = static_cast<builtin_type_t> (j);
+        // FIXME: Is this really right?
+        bool use_j
+        = (jtyp == btyp_func_handle || ityp == btyp_bool
+           || (btyp_isarray (ityp)
+               && (! btyp_isarray (jtyp)
+                   || (btyp_isinteger (jtyp) && ! btyp_isinteger (ityp))
+                   || ((ityp == btyp_double || ityp == btyp_complex
+                        || ityp == btyp_char)
+                       && (jtyp == btyp_float
+                           || jtyp == btyp_float_complex)))));
 
-    std::string dir_name = dir_name_arg;
-
-    if (dir_name.empty ())
-      {
-        std::size_t pos = file_name.find_last_of (sys::file_ops::dir_sep_chars ());
-
-        dir_name = file_name.substr (0, pos);
-      }
-
-    // FIXME: do the following job of determining private status and
-    // class membership in a separate function?
-
-    std::size_t pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
-
-    bool is_private_fcn
-      = pos != std::string::npos && dir_name.substr (pos+1) == "private";
-
-    if (is_private_fcn)
-      dir_name = dir_name.substr (0, pos);
-
-    std::string class_name;
-
-    pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
-
-    if (pos != std::string::npos)
-      {
-        std::string tmp = dir_name.substr (pos+1);
-
-        if (tmp[0] == '@')
-          class_name = tmp.substr (1);
+        sup_table[i][j] = (use_j ? jtyp : ityp);
       }
 
-    octave_value ov_fcn
-      = load_fcn_from_file (file_name, dir_name, dispatch_type,
-                            package_name);
-
-    if (ov_fcn.is_defined ())
-      {
-        retval = true;
-
-        octave_function *fcn = ov_fcn.function_value ();
-
-        if (is_private_fcn)
-          fcn->mark_as_private_function (class_name);
-
-        function = ov_fcn;
-      }
-    else
-      function = octave_value ();
-
-    return retval;
-  }
-
-  static bool
-  out_of_date_check (octave_value& function,
-                     const std::string& dispatch_type = "",
-                     bool check_relative = true)
-  {
-    bool retval = false;
-
-    octave_function *fcn = function.function_value (true);
-
-    if (fcn)
-      {
-        // FIXME: we need to handle subfunctions properly here.
-
-        if (! (fcn->is_subfunction () || fcn->is_anonymous_function ()))
-          {
-            std::string ff = fcn->fcn_file_name ();
-
-            if (! ff.empty ())
-              {
-                sys::time tc = fcn->time_checked ();
-
-                bool relative = check_relative && fcn->is_relative ();
-
-                if (tc <= Vlast_prompt_time
-                    || (relative && tc < Vlast_chdir_time))
-                  {
-                    bool clear_breakpoints = false;
-                    std::string nm = fcn->name ();
-                    std::string pack = fcn->package_name ();
-                    std::string canonical_nm = fcn->canonical_name ();
-
-                    bool is_same_file = false;
-
-                    std::string file;
-                    std::string dir_name;
-
-                    if (check_relative)
-                      {
-                        int nm_len = nm.length ();
+  return sup_table;
+}
 
-                        if (sys::env::absolute_pathname (nm)
-                            && ((nm_len > 4
-                                 && (nm.substr (nm_len-4) == ".oct"
-                                     || nm.substr (nm_len-4) == ".mex"))
-                                || (nm_len > 2
-                                    && nm.substr (nm_len-2) == ".m")))
-                          file = nm;
-                        else
-                          {
-                            // We don't want to make this an absolute name,
-                            // because load_fcn_file looks at the name to
-                            // decide whether it came from a relative lookup.
-
-                            if (! dispatch_type.empty ())
-                              {
-                                load_path& lp = __get_load_path__ ();
-
-                                file = lp.find_method (dispatch_type, nm,
-                                                       dir_name, pack);
-
-                                if (file.empty ())
-                                  {
-                                    std::string s_name;
-                                    std::string s_pack;
-
-                                    symbol_table& symtab = __get_symbol_table__ ();
-
-                                    const std::list<std::string>& plist
-                                      = symtab.parent_classes (dispatch_type);
-
-                                    std::list<std::string>::const_iterator it
-                                      = plist.begin ();
-
-                                    while (it != plist.end ())
-                                      {
-                                        split_name_with_package (*it, s_name,
-                                                                 s_pack);
+std::string
+get_dispatch_type (const octave_value_list& args,
+                   builtin_type_t& builtin_type)
+{
+  static builtin_type_t (*sup_table)[btyp_num_types] = build_sup_table ();
+  std::string dispatch_type;
 
-                                        file = lp.find_method (*it, nm, dir_name,
-                                                               s_pack);
-                                        if (! file.empty ())
-                                          {
-                                            pack = s_pack;
-                                            break;
-                                          }
-
-                                        it++;
-                                      }
-                                  }
-                              }
-
-                            // Maybe it's an autoload?
-                            if (file.empty ())
-                              {
-                                tree_evaluator& tw = __get_evaluator__ ();
-
-                                file = tw.lookup_autoload (nm);
-                              }
-
-                            if (file.empty ())
-                              {
-                                load_path& lp = __get_load_path__ ();
-                                file = lp.find_fcn (nm, dir_name, pack);
-                              }
-                          }
-
-                        if (! file.empty ())
-                          is_same_file = same_file (file, ff);
-                      }
-                    else
-                      {
-                        is_same_file = true;
-                        file = ff;
-                      }
-
-                    if (file.empty ())
-                      {
-                        // Can't see this function from current
-                        // directory, so we should clear it.
-
-                        function = octave_value ();
+  int n = args.length ();
 
-                        clear_breakpoints = true;
-                      }
-                    else if (is_same_file)
-                      {
-                        // Same file.  If it is out of date, then reload it.
-
-                        sys::time ottp = fcn->time_parsed ();
-                        OCTAVE_TIME_T tp = ottp.unix_time ();
-
-                        fcn->mark_fcn_file_up_to_date (sys::time ());
-
-                        if (! (Vignore_function_time_stamp == 2
-                               || (Vignore_function_time_stamp
-                                   && fcn->is_system_fcn_file ())))
-                          {
-                            sys::file_stat fs (ff);
-
-                            if (fs)
-                              {
-                                if (fs.is_newer (tp))
-                                  {
-                                    retval = load_out_of_date_fcn (ff, dir_name,
-                                                                   function,
-                                                                   dispatch_type,
-                                                                   pack);
-
-                                    clear_breakpoints = true;
-                                  }
-                              }
-                            else
-                              {
-                                function = octave_value ();
-
-                                clear_breakpoints = true;
-                              }
-                          }
-                      }
-                    else
-                      {
-                        // Not the same file, so load the new file in
-                        // place of the old.
-
-                        retval = load_out_of_date_fcn (file, dir_name, function,
-                                                       dispatch_type, pack);
-
-                        clear_breakpoints = true;
-                      }
-
-                    // If the function has been replaced then clear any
-                    // breakpoints associated with it
-                    if (clear_breakpoints)
-                      {
-                        bp_table& bptab = __get_bp_table__ ();
-
-                        bptab.remove_all_breakpoints_from_function (canonical_nm,
-                                                                    true);
-                      }
-                  }
-              }
-          }
-      }
-
-    return retval;
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::find_scoped_function (const symbol_scope& search_scope)
-  {
-    if (search_scope)
-      {
-        // Subfunction.
-
-        octave_value fcn = search_scope.find_subfunction (name);
-
-        if (fcn.is_defined ())
-          return fcn;
+  if (n > 0)
+    {
+      int i = 0;
+      builtin_type = args(0).builtin_type ();
+      if (builtin_type != btyp_unknown)
+        {
+          for (i = 1; i < n; i++)
+            {
+              builtin_type_t bti = args(i).builtin_type ();
+              if (bti != btyp_unknown)
+                builtin_type = sup_table[builtin_type][bti];
+              else
+                {
+                  builtin_type = btyp_unknown;
+                  break;
+                }
+            }
+        }
 
-        // Local function.
-
-        std::string fcn_file = search_scope.fcn_file_name ();
-
-        // For anonymous functions we look at the parent scope so that if
-        // they were defined within class methods and use local functions
-        // (helper functions) we can still use those anonymous functions
-
-        if (! fcn_file.empty ())
-          {
-            auto r = local_functions.find (fcn_file);
-
-            if (r != local_functions.end ())
-              {
-                // We shouldn't need an out-of-date check here since
-                // local functions may ultimately be called only from
-                // a primary function or method defined in the same
-                // file.
+      if (builtin_type == btyp_unknown)
+        {
+          // There's a non-builtin class in the argument list.
+          dispatch_type = args(i).class_name ();
 
-                return r->second;
-              }
-          }
-
-        // Private function.
-
-        return find_private_function (search_scope.dir_name ());
-      }
-
-    return octave_value ();
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::find_private_function (const std::string& dir_name)
-  {
-    if (! dir_name.empty ())
-      {
-        auto q = private_functions.find (dir_name);
+          symbol_table& symtab = __get_symbol_table__ ();
 
-        if (q == private_functions.end ())
-          {
-            octave_value val = load_private_function (dir_name);
-
-            if (val.is_defined ())
-              return val;
-          }
-        else
-          {
-            octave_value& fval = q->second;
-
-            if (fval.is_defined ())
-              out_of_date_check (fval, "", false);
+          for (int j = i+1; j < n; j++)
+            {
+              octave_value arg = args(j);
 
-            if (fval.is_defined ())
-              return fval;
-            else
-              {
-                octave_value val = load_private_function (dir_name);
-
-                if (val.is_defined ())
-                  return val;
-              }
-          }
-      }
-
-    return octave_value ();
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::find_method (const octave_value_list& args)
-  {
-    if (! args.empty ())
-      {
-        std::string dispatch_type = get_dispatch_type (args);
-
-        return find_method (dispatch_type);
-      }
+              if (arg.builtin_type () == btyp_unknown)
+                {
+                  std::string cname = arg.class_name ();
 
-    return octave_value ();
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::xfind (const symbol_scope& search_scope,
-                                 const octave_value_list& args)
-  {
-    // Subfunction, local function, or private function.
-
-    octave_value fcn;
-
-    fcn = find_scoped_function (search_scope);
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Class methods.
-
-    fcn = find_method (args);
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Class constructors.  The class name and function name are the same.
-
-    auto q = class_constructors.find (name);
-
-    if (q == class_constructors.end ())
-      {
-        octave_value val = load_class_constructor ();
-
-        if (val.is_defined ())
-          return val;
-      }
-    else
-      {
-        octave_value& fval = q->second;
-
-        if (fval.is_defined ())
-          out_of_date_check (fval, name);
-
-        if (fval.is_defined ())
-          return fval;
-        else
-          {
-            octave_value val = load_class_constructor ();
-
-            if (val.is_defined ())
-              return val;
-          }
-      }
-
-    // Command-line function.
-
-    if (cmdline_function.is_defined ())
-      return cmdline_function;
-
-    // Autoload?
-
-    fcn = find_autoload ();
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Function on the path.
-
-    fcn = find_user_function ();
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Package
+                  // Only switch to type of ARG if it is marked superior
+                  // to the current DISPATCH_TYPE.
+                  if (! symtab.is_superiorto (dispatch_type, cname)
+                      && symtab.is_superiorto (cname, dispatch_type))
+                    dispatch_type = cname;
+                }
+            }
+        }
+      else
+        dispatch_type = btyp_class_name[builtin_type];
+    }
+  else
+    builtin_type = btyp_unknown;
 
-    fcn = find_package ();
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Built-in function (might be undefined).
-
-    return built_in_function;
-  }
-
-  // Find the definition of NAME according to the following precedence
-  // list:
-  //
-  //   built-in function
-  //   function on the path
-  //   autoload function
-  //   command-line function
-  //   private function
-  //   subfunction
-
-  // This function is used to implement the "builtin" function, which
-  // searches for "built-in" functions.  In Matlab, "builtin" only
-  // returns functions that are actually built-in to the interpreter.
-  // But since the list of built-in functions is different in Octave and
-  // Matlab, we also search up the precedence list until we find
-  // something that matches.  Note that we are only searching by name,
-  // so class methods and constructors are skipped.
-
-  octave_value
-  fcn_info::fcn_info_rep::builtin_find (const symbol_scope& scope)
-  {
-    symbol_scope search_scope
-      = (scope
-         ? scope : __get_current_scope__ ());
-
-    octave_value retval = x_builtin_find (search_scope);
+  return dispatch_type;
+}
 
-    if (! retval.is_defined ())
-      {
-        // It is possible that the user created a file on the fly since
-        // the last prompt or chdir, so try updating the load path and
-        // searching again.
-
-        load_path& lp = __get_load_path__ ();
-
-        lp.update ();
-
-        retval = x_builtin_find (search_scope);
-      }
-
-    return retval;
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::x_builtin_find (const symbol_scope& search_scope)
-  {
-    // Built-in function.
-    if (built_in_function.is_defined ())
-      return built_in_function;
-
-    // Function on the path.
-
-    octave_value fcn = find_user_function ();
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Autoload?
-
-    fcn = find_autoload ();
-
-    if (fcn.is_defined ())
-      return fcn;
-
-    // Command-line function.
+std::string
+get_dispatch_type (const octave_value_list& args)
+{
+  builtin_type_t builtin_type;
+  return get_dispatch_type (args, builtin_type);
+}
 
-    if (cmdline_function.is_defined ())
-      return cmdline_function;
-
-    // Private function, local function, or subfunction.
-
-    if (search_scope)
-      {
-        // Private function.
-
-        std::string dir_name = search_scope.dir_name ();
-
-        if (! dir_name.empty ())
-          {
-            auto q = private_functions.find (dir_name);
-
-            if (q == private_functions.end ())
-              {
-                octave_value val = load_private_function (dir_name);
-
-                if (val.is_defined ())
-                  return val;
-              }
-            else
-              {
-                octave_value& fval = q->second;
-
-                if (fval.is_defined ())
-                  out_of_date_check (fval);
-
-                if (fval.is_defined ())
-                  return fval;
-                else
-                  {
-                    octave_value val = load_private_function (dir_name);
-
-                    if (val.is_defined ())
-                      return val;
-                  }
-              }
-          }
-
-        // Local function.
-
-        std::string fcn_file = search_scope.fcn_file_name ();
-
-        if (! fcn_file.empty ())
-          {
-            auto r = local_functions.find (fcn_file);
-
-            if (r != local_functions.end ())
-              {
-                // We shouldn't need an out-of-date check here since local
-                // functions may ultimately be called only from a primary
-                // function or method defined in the same file.
-
-                return r->second;
-              }
-          }
-
-        // Subfunction.  I think it only makes sense to check for
-        // subfunctions if we are currently executing a function defined
-        // from a .m file.
-
-        octave_value val = search_scope.find_subfunction (name);
-
-        if (val.is_defined ())
-          return val;
-      }
-
-    return octave_value ();
-  }
+// Find function definition according to the following precedence list:
+//
+//   nested functions (and subfunctions)
+//   local functions in the current file
+//   private function
+//   class method
+//   class constructor
+//   command-line function
+//   autoload function
+//   functions on the load_path (current directory is always first)
+//   package (FIXME: does this belong here?)
+//   built-in function
 
-  octave_value
-  fcn_info::fcn_info_rep::find_method (const std::string& dispatch_type)
-  {
-    octave_value retval;
-
-    auto q = class_methods.find (dispatch_type);
-
-    if (q == class_methods.end ())
-      {
-        octave_value val = load_class_method (dispatch_type);
-
-        if (val.is_defined ())
-          return val;
-      }
-    else
-      {
-        octave_value& fval = q->second;
+octave_value
+fcn_info::fcn_info_rep::find (const symbol_scope& scope,
+                              const octave_value_list& args)
+{
+  symbol_scope search_scope
+    = (scope
+       ? scope : __get_current_scope__ ());
 
-        if (fval.is_defined ())
-          out_of_date_check (fval, dispatch_type);
-
-        if (fval.is_defined ())
-          return fval;
-        else
-          {
-            octave_value val = load_class_method (dispatch_type);
-
-            if (val.is_defined ())
-              return val;
-          }
-      }
-
-    return retval;
-  }
-
-  octave_value
-  fcn_info::fcn_info_rep::find_autoload (void)
-  {
-    // Autoloaded function.
+  octave_value retval = xfind (search_scope, args);
 
-    if (autoload_function.is_defined ())
-      out_of_date_check (autoload_function);
-
-    if (! autoload_function.is_defined ())
-      {
-        tree_evaluator& tw = __get_evaluator__ ();
-
-        std::string file_name = tw.lookup_autoload (name);
+  if (retval.is_undefined ())
+    {
+      // It is possible that the user created a file on the fly since
+      // the last prompt or chdir, so try updating the load path and
+      // searching again.
 
-        if (! file_name.empty ())
-          {
-            std::size_t pos = file_name.find_last_of (sys::file_ops::dir_sep_chars ());
-
-            std::string dir_name = file_name.substr (0, pos);
-
-            octave_value ov_fcn
-              = load_fcn_from_file (file_name, dir_name, "", "", name, true);
+      load_path& lp = __get_load_path__ ();
 
-            if (ov_fcn.is_defined ())
-              autoload_function = octave_value (ov_fcn);
-          }
-      }
-
-    return autoload_function;
-  }
+      lp.update ();
 
-  octave_value
-  fcn_info::fcn_info_rep::find_user_function (void)
-  {
-    // Function on the path.
+      retval = xfind (search_scope, args);
+    }
 
-    if (function_on_path.is_defined ())
-      out_of_date_check (function_on_path);
-
-    if (function_on_path.is_undefined ())
-      {
-        std::string dir_name;
-
-        load_path& lp = __get_load_path__ ();
+  return retval;
+}
 
 
-        std::string file_name = lp.find_fcn (name, dir_name, package_name);
+static void
+split_name_with_package (const std::string& name, std::string& fname,
+                         std::string& pname)
+{
+  std::size_t pos = name.rfind ('.');
+
+  fname.clear ();
+  pname.clear ();
+
+  if (pos != std::string::npos)
+    {
+      fname = name.substr (pos + 1);
+      pname = name.substr (0, pos);
+    }
+  else
+    fname = name;
+}
+
+// Check the load path to see if file that defined this is still
+// visible.  If the file is no longer visible, then erase the
+// definition and move on.  If the file is visible, then we also
+// need to check to see whether the file has changed since the
+// function was loaded/parsed.  However, this check should only
+// happen once per prompt (for files found from relative path
+// elements, we also check if the working directory has changed
+// since the last time the function was loaded/parsed).
+//
+// FIXME: perhaps this should be done for all loaded functions when
+// the prompt is printed or the directory has changed, and then we
+// would not check for it when finding symbol definitions.
+
+static inline bool
+load_out_of_date_fcn (const std::string& file_name,
+                      const std::string& dir_name_arg,
+                      octave_value& function,
+                      const std::string& dispatch_type = "",
+                      const std::string& package_name = "")
+{
+  bool retval = false;
+
+  std::string dir_name = dir_name_arg;
+
+  if (dir_name.empty ())
+    {
+      std::size_t pos = file_name.find_last_of (sys::file_ops::dir_sep_chars ());
 
-        if (! file_name.empty ())
-          {
-            octave_value ov_fcn
-              = load_fcn_from_file (file_name, dir_name, "", package_name);
+      dir_name = file_name.substr (0, pos);
+    }
+
+  // FIXME: do the following job of determining private status and
+  // class membership in a separate function?
+
+  std::size_t pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
+
+  bool is_private_fcn
+    = pos != std::string::npos && dir_name.substr (pos+1) == "private";
+
+  if (is_private_fcn)
+    dir_name = dir_name.substr (0, pos);
+
+  std::string class_name;
+
+  pos = dir_name.find_last_of (sys::file_ops::dir_sep_chars ());
+
+  if (pos != std::string::npos)
+    {
+      std::string tmp = dir_name.substr (pos+1);
+
+      if (tmp[0] == '@')
+        class_name = tmp.substr (1);
+    }
+
+  octave_value ov_fcn
+    = load_fcn_from_file (file_name, dir_name, dispatch_type,
+                          package_name);
+
+  if (ov_fcn.is_defined ())
+    {
+      retval = true;
+
+      octave_function *fcn = ov_fcn.function_value ();
+
+      if (is_private_fcn)
+        fcn->mark_as_private_function (class_name);
+
+      function = ov_fcn;
+    }
+  else
+    function = octave_value ();
+
+  return retval;
+}
 
-            if (ov_fcn.is_defined ())
-              function_on_path = ov_fcn;
-          }
-      }
+static bool
+out_of_date_check (octave_value& function,
+                   const std::string& dispatch_type = "",
+                   bool check_relative = true)
+{
+  bool retval = false;
+
+  octave_function *fcn = function.function_value (true);
+
+  if (fcn)
+    {
+      // FIXME: we need to handle subfunctions properly here.
+
+      if (! (fcn->is_subfunction () || fcn->is_anonymous_function ()))
+        {
+          std::string ff = fcn->fcn_file_name ();
+
+          if (! ff.empty ())
+            {
+              sys::time tc = fcn->time_checked ();
+
+              bool relative = check_relative && fcn->is_relative ();
+
+              if (tc <= Vlast_prompt_time
+                  || (relative && tc < Vlast_chdir_time))
+                {
+                  bool clear_breakpoints = false;
+                  std::string nm = fcn->name ();
+                  std::string pack = fcn->package_name ();
+                  std::string canonical_nm = fcn->canonical_name ();
+
+                  bool is_same_file = false;
+
+                  std::string file;
+                  std::string dir_name;
+
+                  if (check_relative)
+                    {
+                      int nm_len = nm.length ();
 
-    return function_on_path;
-  }
+                      if (sys::env::absolute_pathname (nm)
+                          && ((nm_len > 4
+                               && (nm.substr (nm_len-4) == ".oct"
+                                   || nm.substr (nm_len-4) == ".mex"))
+                              || (nm_len > 2
+                                  && nm.substr (nm_len-2) == ".m")))
+                        file = nm;
+                      else
+                        {
+                          // We don't want to make this an absolute name,
+                          // because load_fcn_file looks at the name to
+                          // decide whether it came from a relative lookup.
+
+                          if (! dispatch_type.empty ())
+                            {
+                              load_path& lp = __get_load_path__ ();
+
+                              file = lp.find_method (dispatch_type, nm,
+                                                     dir_name, pack);
+
+                              if (file.empty ())
+                                {
+                                  std::string s_name;
+                                  std::string s_pack;
+
+                                  symbol_table& symtab = __get_symbol_table__ ();
+
+                                  const std::list<std::string>& plist
+                                    = symtab.parent_classes (dispatch_type);
+
+                                  std::list<std::string>::const_iterator it
+                                    = plist.begin ();
+
+                                  while (it != plist.end ())
+                                    {
+                                      split_name_with_package (*it, s_name,
+                                                               s_pack);
+
+                                      file = lp.find_method (*it, nm, dir_name,
+                                                             s_pack);
+                                      if (! file.empty ())
+                                        {
+                                          pack = s_pack;
+                                          break;
+                                        }
+
+                                      it++;
+                                    }
+                                }
+                            }
+
+                          // Maybe it's an autoload?
+                          if (file.empty ())
+                            {
+                              tree_evaluator& tw = __get_evaluator__ ();
 
-  octave_value
-  fcn_info::fcn_info_rep::find_package (void)
-  {
-    // FIXME: implement correct way to check out of date package
-    //if (package.is_defined ())
-    //  out_of_date_check (package);
+                              file = tw.lookup_autoload (nm);
+                            }
+
+                          if (file.empty ())
+                            {
+                              load_path& lp = __get_load_path__ ();
+                              file = lp.find_fcn (nm, dir_name, pack);
+                            }
+                        }
+
+                      if (! file.empty ())
+                        is_same_file = same_file (file, ff);
+                    }
+                  else
+                    {
+                      is_same_file = true;
+                      file = ff;
+                    }
+
+                  if (file.empty ())
+                    {
+                      // Can't see this function from current
+                      // directory, so we should clear it.
+
+                      function = octave_value ();
+
+                      clear_breakpoints = true;
+                    }
+                  else if (is_same_file)
+                    {
+                      // Same file.  If it is out of date, then reload it.
+
+                      sys::time ottp = fcn->time_parsed ();
+                      OCTAVE_TIME_T tp = ottp.unix_time ();
+
+                      fcn->mark_fcn_file_up_to_date (sys::time ());
+
+                      if (! (Vignore_function_time_stamp == 2
+                             || (Vignore_function_time_stamp
+                                 && fcn->is_system_fcn_file ())))
+                        {
+                          sys::file_stat fs (ff);
 
-    if (package.is_undefined ())
-      {
-        cdef_manager& cdm = __get_cdef_manager__ ();
+                          if (fs)
+                            {
+                              if (fs.is_newer (tp))
+                                {
+                                  retval = load_out_of_date_fcn (ff, dir_name,
+                                                                 function,
+                                                                 dispatch_type,
+                                                                 pack);
+
+                                  clear_breakpoints = true;
+                                }
+                            }
+                          else
+                            {
+                              function = octave_value ();
+
+                              clear_breakpoints = true;
+                            }
+                        }
+                    }
+                  else
+                    {
+                      // Not the same file, so load the new file in
+                      // place of the old.
+
+                      retval = load_out_of_date_fcn (file, dir_name, function,
+                                                     dispatch_type, pack);
+
+                      clear_breakpoints = true;
+                    }
+
+                  // If the function has been replaced then clear any
+                  // breakpoints associated with it
+                  if (clear_breakpoints)
+                    {
+                      bp_table& bptab = __get_bp_table__ ();
+
+                      bptab.remove_all_breakpoints_from_function (canonical_nm,
+                          true);
+                    }
+                }
+            }
+        }
+    }
+
+  return retval;
+}
 
-        package = cdm.find_package_symbol (full_name ());
-      }
+octave_value
+fcn_info::fcn_info_rep::find_scoped_function (const symbol_scope& search_scope)
+{
+  if (search_scope)
+    {
+      // Subfunction.
+
+      octave_value fcn = search_scope.find_subfunction (name);
+
+      if (fcn.is_defined ())
+        return fcn;
+
+      // Local function.
+
+      std::string fcn_file = search_scope.fcn_file_name ();
+
+      // For anonymous functions we look at the parent scope so that if
+      // they were defined within class methods and use local functions
+      // (helper functions) we can still use those anonymous functions
+
+      if (! fcn_file.empty ())
+        {
+          auto r = local_functions.find (fcn_file);
 
-    return package;
-  }
+          if (r != local_functions.end ())
+            {
+              // We shouldn't need an out-of-date check here since
+              // local functions may ultimately be called only from
+              // a primary function or method defined in the same
+              // file.
+
+              return r->second;
+            }
+        }
+
+      // Private function.
+
+      return find_private_function (search_scope.dir_name ());
+    }
+
+  return octave_value ();
+}
+
+octave_value
+fcn_info::fcn_info_rep::find_private_function (const std::string& dir_name)
+{
+  if (! dir_name.empty ())
+    {
+      auto q = private_functions.find (dir_name);
 
-  void
-  fcn_info::fcn_info_rep::install_built_in_dispatch (const std::string& klass)
-  {
-    if (built_in_function.is_defined ())
-      {
-        octave_function *fcn = built_in_function.function_value ();
+      if (q == private_functions.end ())
+        {
+          octave_value val = load_private_function (dir_name);
+
+          if (val.is_defined ())
+            return val;
+        }
+      else
+        {
+          octave_value& fval = q->second;
+
+          if (fval.is_defined ())
+            out_of_date_check (fval, "", false);
+
+          if (fval.is_defined ())
+            return fval;
+          else
+            {
+              octave_value val = load_private_function (dir_name);
+
+              if (val.is_defined ())
+                return val;
+            }
+        }
+    }
+
+  return octave_value ();
+}
+
+octave_value
+fcn_info::fcn_info_rep::find_method (const octave_value_list& args)
+{
+  if (! args.empty ())
+    {
+      std::string dispatch_type = get_dispatch_type (args);
+
+      return find_method (dispatch_type);
+    }
+
+  return octave_value ();
+}
+
+octave_value
+fcn_info::fcn_info_rep::xfind (const symbol_scope& search_scope,
+                               const octave_value_list& args)
+{
+  // Subfunction, local function, or private function.
+
+  octave_value fcn;
 
-        if (fcn)
-          {
-            if (fcn->handles_dispatch_class (klass))
-              warning ("install_built_in_dispatch: '%s' already defined for class '%s'",
-                       name.c_str (), klass.c_str ());
-            else
-              fcn->push_dispatch_class (klass);
-          }
-      }
-    else
-      error ("install_built_in_dispatch: '%s' is not a built-in function",
-             name.c_str ());
-  }
+  fcn = find_scoped_function (search_scope);
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Class methods.
+
+  fcn = find_method (args);
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Class constructors.  The class name and function name are the same.
+
+  auto q = class_constructors.find (name);
+
+  if (q == class_constructors.end ())
+    {
+      octave_value val = load_class_constructor ();
+
+      if (val.is_defined ())
+        return val;
+    }
+  else
+    {
+      octave_value& fval = q->second;
+
+      if (fval.is_defined ())
+        out_of_date_check (fval, name);
+
+      if (fval.is_defined ())
+        return fval;
+      else
+        {
+          octave_value val = load_class_constructor ();
+
+          if (val.is_defined ())
+            return val;
+        }
+    }
+
+  // Command-line function.
+
+  if (cmdline_function.is_defined ())
+    return cmdline_function;
+
+  // Autoload?
+
+  fcn = find_autoload ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Function on the path.
+
+  fcn = find_user_function ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Package
+
+  fcn = find_package ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Built-in function (might be undefined).
+
+  return built_in_function;
+}
+
+// Find the definition of NAME according to the following precedence
+// list:
+//
+//   built-in function
+//   function on the path
+//   autoload function
+//   command-line function
+//   private function
+//   subfunction
+
+// This function is used to implement the "builtin" function, which
+// searches for "built-in" functions.  In Matlab, "builtin" only
+// returns functions that are actually built-in to the interpreter.
+// But since the list of built-in functions is different in Octave and
+// Matlab, we also search up the precedence list until we find
+// something that matches.  Note that we are only searching by name,
+// so class methods and constructors are skipped.
+
+octave_value
+fcn_info::fcn_info_rep::builtin_find (const symbol_scope& scope)
+{
+  symbol_scope search_scope
+    = (scope
+       ? scope : __get_current_scope__ ());
+
+  octave_value retval = x_builtin_find (search_scope);
+
+  if (! retval.is_defined ())
+    {
+      // It is possible that the user created a file on the fly since
+      // the last prompt or chdir, so try updating the load path and
+      // searching again.
+
+      load_path& lp = __get_load_path__ ();
+
+      lp.update ();
+
+      retval = x_builtin_find (search_scope);
+    }
+
+  return retval;
+}
+
+octave_value
+fcn_info::fcn_info_rep::x_builtin_find (const symbol_scope& search_scope)
+{
+  // Built-in function.
+  if (built_in_function.is_defined ())
+    return built_in_function;
+
+  // Function on the path.
+
+  octave_value fcn = find_user_function ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Autoload?
+
+  fcn = find_autoload ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
+  // Command-line function.
+
+  if (cmdline_function.is_defined ())
+    return cmdline_function;
+
+  // Private function, local function, or subfunction.
+
+  if (search_scope)
+    {
+      // Private function.
+
+      std::string dir_name = search_scope.dir_name ();
+
+      if (! dir_name.empty ())
+        {
+          auto q = private_functions.find (dir_name);
+
+          if (q == private_functions.end ())
+            {
+              octave_value val = load_private_function (dir_name);
+
+              if (val.is_defined ())
+                return val;
+            }
+          else
+            {
+              octave_value& fval = q->second;
+
+              if (fval.is_defined ())
+                out_of_date_check (fval);
+
+              if (fval.is_defined ())
+                return fval;
+              else
+                {
+                  octave_value val = load_private_function (dir_name);
+
+                  if (val.is_defined ())
+                    return val;
+                }
+            }
+        }
+
+      // Local function.
+
+      std::string fcn_file = search_scope.fcn_file_name ();
+
+      if (! fcn_file.empty ())
+        {
+          auto r = local_functions.find (fcn_file);
 
-  octave_value
-  fcn_info::fcn_info_rep::dump (void) const
-  {
-    std::map<std::string, octave_value> m
-      = {{ "name", full_name () },
-         { "package", package.dump () },
-         { "local_functions", dump_function_map (local_functions) },
-         { "private_functions", dump_function_map (private_functions) },
-         { "class_methods", dump_function_map (class_methods) },
-         { "class_constructors", dump_function_map (class_constructors) },
-         { "cmdline_function", cmdline_function.dump () },
-         { "autoload_function", autoload_function.dump () },
-         { "function_on_path", function_on_path.dump () },
-         { "built_in_function", built_in_function.dump () }};
+          if (r != local_functions.end ())
+            {
+              // We shouldn't need an out-of-date check here since local
+              // functions may ultimately be called only from a primary
+              // function or method defined in the same file.
+
+              return r->second;
+            }
+        }
+
+      // Subfunction.  I think it only makes sense to check for
+      // subfunctions if we are currently executing a function defined
+      // from a .m file.
+
+      octave_value val = search_scope.find_subfunction (name);
+
+      if (val.is_defined ())
+        return val;
+    }
+
+  return octave_value ();
+}
+
+octave_value
+fcn_info::fcn_info_rep::find_method (const std::string& dispatch_type)
+{
+  octave_value retval;
+
+  auto q = class_methods.find (dispatch_type);
+
+  if (q == class_methods.end ())
+    {
+      octave_value val = load_class_method (dispatch_type);
+
+      if (val.is_defined ())
+        return val;
+    }
+  else
+    {
+      octave_value& fval = q->second;
+
+      if (fval.is_defined ())
+        out_of_date_check (fval, dispatch_type);
 
-    return octave_value (m);
-  }
+      if (fval.is_defined ())
+        return fval;
+      else
+        {
+          octave_value val = load_class_method (dispatch_type);
+
+          if (val.is_defined ())
+            return val;
+        }
+    }
+
+  return retval;
+}
+
+octave_value
+fcn_info::fcn_info_rep::find_autoload (void)
+{
+  // Autoloaded function.
+
+  if (autoload_function.is_defined ())
+    out_of_date_check (autoload_function);
+
+  if (! autoload_function.is_defined ())
+    {
+      tree_evaluator& tw = __get_evaluator__ ();
+
+      std::string file_name = tw.lookup_autoload (name);
+
+      if (! file_name.empty ())
+        {
+          std::size_t pos = file_name.find_last_of (sys::file_ops::dir_sep_chars ());
+
+          std::string dir_name = file_name.substr (0, pos);
+
+          octave_value ov_fcn
+            = load_fcn_from_file (file_name, dir_name, "", "", name, true);
+
+          if (ov_fcn.is_defined ())
+            autoload_function = octave_value (ov_fcn);
+        }
+    }
+
+  return autoload_function;
+}
+
+octave_value
+fcn_info::fcn_info_rep::find_user_function (void)
+{
+  // Function on the path.
+
+  if (function_on_path.is_defined ())
+    out_of_date_check (function_on_path);
 
-  octave_value
-  dump_function_map (const std::map<std::string, octave_value>& fcn_map)
-  {
-    if (fcn_map.empty ())
-      return octave_value (Matrix ());
+  if (function_on_path.is_undefined ())
+    {
+      std::string dir_name;
+
+      load_path& lp = __get_load_path__ ();
+
+
+      std::string file_name = lp.find_fcn (name, dir_name, package_name);
+
+      if (! file_name.empty ())
+        {
+          octave_value ov_fcn
+            = load_fcn_from_file (file_name, dir_name, "", package_name);
+
+          if (ov_fcn.is_defined ())
+            function_on_path = ov_fcn;
+        }
+    }
+
+  return function_on_path;
+}
 
-    std::map<std::string, octave_value> info_map;
+octave_value
+fcn_info::fcn_info_rep::find_package (void)
+{
+  // FIXME: implement correct way to check out of date package
+  //if (package.is_defined ())
+  //  out_of_date_check (package);
+
+  if (package.is_undefined ())
+    {
+      cdef_manager& cdm = __get_cdef_manager__ ();
+
+      package = cdm.find_package_symbol (full_name ());
+    }
+
+  return package;
+}
+
+void
+fcn_info::fcn_info_rep::install_built_in_dispatch (const std::string& klass)
+{
+  if (built_in_function.is_defined ())
+    {
+      octave_function *fcn = built_in_function.function_value ();
 
-    for (const auto& nm_fcn : fcn_map)
-      {
-        std::string nm = nm_fcn.first;
-        const octave_value& fcn = nm_fcn.second;
-        info_map[nm] = fcn.dump ();
-      }
+      if (fcn)
+        {
+          if (fcn->handles_dispatch_class (klass))
+            warning ("install_built_in_dispatch: '%s' already defined for class '%s'",
+                     name.c_str (), klass.c_str ());
+          else
+            fcn->push_dispatch_class (klass);
+        }
+    }
+  else
+    error ("install_built_in_dispatch: '%s' is not a built-in function",
+           name.c_str ());
+}
 
-    return octave_value (info_map);
-  }
+octave_value
+fcn_info::fcn_info_rep::dump (void) const
+{
+  std::map<std::string, octave_value> m
+  = {{ "name", full_name () },
+    { "package", package.dump () },
+    { "local_functions", dump_function_map (local_functions) },
+    { "private_functions", dump_function_map (private_functions) },
+    { "class_methods", dump_function_map (class_methods) },
+    { "class_constructors", dump_function_map (class_constructors) },
+    { "cmdline_function", cmdline_function.dump () },
+    { "autoload_function", autoload_function.dump () },
+    { "function_on_path", function_on_path.dump () },
+    { "built_in_function", built_in_function.dump () }
+  };
+
+  return octave_value (m);
+}
+
+octave_value
+dump_function_map (const std::map<std::string, octave_value>& fcn_map)
+{
+  if (fcn_map.empty ())
+    return octave_value (Matrix ());
+
+  std::map<std::string, octave_value> info_map;
+
+  for (const auto& nm_fcn : fcn_map)
+    {
+      std::string nm = nm_fcn.first;
+      const octave_value& fcn = nm_fcn.second;
+      info_map[nm] = fcn.dump ();
+    }
+
+  return octave_value (info_map);
+}
 
 DEFUN (ignore_function_time_stamp, args, nargout,
        doc: /* -*- texinfo -*-
@@ -1182,7 +1183,8 @@
 
   if (nargin == 1)
     {
-      std::string sval = args(0).xstring_value ("ignore_function_time_stamp: first argument must be a string");
+      std::string sval = args(
+                           0).xstring_value ("ignore_function_time_stamp: first argument must be a string");
 
       if (sval == "all")
         Vignore_function_time_stamp = 2;