gdb/
authorYao Qi <yao@codesourcery.com>
Thu, 17 Oct 2013 13:28:37 +0000 (13:28 +0000)
committerYao Qi <yao@codesourcery.com>
Thu, 17 Oct 2013 13:28:37 +0000 (13:28 +0000)
* Makefile.in (SFILES): Add c-varobj.c and jv-varobj.c.
(COMMON_OBS): Add c-varobj.o and jv-varobj.o.
* ada-varobj.c: Include "varobj.h".
(ada_number_of_children): New.  Moved from varobj.c.
(ada_name_of_variable, ada_name_of_child): Likewise.
(ada_path_expr_of_child, ada_value_of_child): Likewise.
(ada_type_of_child, ada_value_of_variable): Likewise.
(ada_value_is_changeable_p, ada_value_has_mutated): Likewise.
(ada_varobj_ops): New.
* c-varobj.c, jv-varobj.c: New file.  Moved from varobj.c.
* gdbtypes.c (get_target_type): New.  Moved from varobj.c.
* gdbtypes.h (get_target_type): Declare.
* varobj.c: Remove the inclusion of "ada-varobj.h" and
"ada-lang.h".
(ANONYMOUS_STRUCT_NAME): Move it to c-varobj.c.
(ANONYMOUS_UNION_NAME): Likewise.
(get_type, get_value_type, get_target_type): Remove declarations.
(value_get_print_value, varobj_value_get_print_value): Likewise.
(c_number_of_children, c_name_of_variable): Likewise.
(c_name_of_child, c_path_expr_of_child): Likewise.
(c_value_of_child, c_type_of_child): Likewise.
(c_value_of_variable, cplus_number_of_children): Likewise.
(cplus_class_num_children, cplus_name_of_variable): Likewise.
(cplus_name_of_child, cplus_path_expr_of_child): Likewise.
(cplus_value_of_child, cplus_type_of_child): Likewise.
(cplus_value_of_variable, java_number_of_children): Likewise.
(java_name_of_variable, java_name_of_child): Likewise.
(java_path_expr_of_child, java_value_of_child): Likewise.
(java_type_of_child, java_value_of_variable): Likewise.
(ada_number_of_children, ada_name_of_variable): Likewise.
(ada_name_of_child, ada_path_expr_of_child): Likewise.
(ada_value_of_child, ada_type_of_child): Likewise.
(ada_value_of_variable, ada_value_is_changeable_p): Likewise.
(ada_value_has_mutated): Likewise.
(struct language_specific): Move it to varobj.h.
(CPLUS_FAKE_CHILD): Move it to varobj.h.
(restrict_range): Rename it varobj_restrict_range.  Make it extern.
Callers update.
(get_path_expr_parent): Rename it to varobj_get_path_expr_parent.
Make it extern.
(is_anonymous_child): Move it to c-varobj.c and rename to
varobj_is_anonymous_child.  Caller update.
(get_type): Move it to c-varobj.c.
(get_value_type): Rename it varobj_get_value_type.  Make it
extern.
(get_target_type): Move it gdbtypes.c.
(varobj_formatted_print_options): New function.
(value_get_print_value): Rename it to
varobj_value_get_print_value and make it extern.
(varobj_value_is_changeable_p): Make it extern.
(adjust_value_for_child_access): Move it to c-varobj.c.
(default_value_is_changeable_p): Rename it to
varobj_default_value_is_changeable_p.  Make it extern.
(c_number_of_children, c_name_of_variable): Move it to c-varobj.c
(c_name_of_child, c_path_expr_of_child): Likewise.
(c_value_of_child, c_type_of_child): Likewise.
(c_value_of_variable, cplus_number_of_children): Likewise.
(cplus_class_num_children, cplus_name_of_variable): Likewise.
(cplus_name_of_child, cplus_path_expr_of_child): Likewise.
(cplus_value_of_child, cplus_type_of_child): Likewise.
(cplus_value_of_variable): Likewise.
(java_number_of_children, java_name_of_variable): Move it to jv-varobj.c.
(java_name_of_child, java_path_expr_of_child): Likewise.
(java_value_of_child, java_type_of_child): Likewise.
(java_value_of_variable): Likewise.
(ada_number_of_children, ada_name_of_variable): Move it to ada-varobj.c.
(ada_name_of_child, ada_path_expr_of_child): Likewise.
(ada_value_of_child, ada_type_of_child): Likewise.
(ada_value_of_variable, ada_value_is_changeable_p): Likewise.
(ada_value_has_mutated): Likewise.
* varobj.h (CPLUS_FAKE_CHILD): New macro, moved from varobj.c.
(struct lang_varobj_ops): New.  Renamed by 'struct language_specific'.
(c_varobj_ops, cplus_varobj_ops): Declare.
(java_varobj_ops, ada_varobj_ops): Declare.
(varobj_default_value_is_changeable_p): Declare.
(varobj_value_is_changeable_p): Declare.
(varobj_get_value_type, varobj_is_anonymous_child): Declare.
(varobj_get_path_expr_parent): Declare.
(varobj_value_get_print_value): Declare.
(varobj_formatted_print_options): Declare.
(varobj_restrict_range): Declare.

gdb/ChangeLog
gdb/Makefile.in
gdb/ada-varobj.c
gdb/c-varobj.c [new file with mode: 0644]
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/jv-varobj.c [new file with mode: 0644]
gdb/varobj.c
gdb/varobj.h

index 1d346e95d0ec0005be17bfd2e7b270bf4ebd4148..db0982a665a03875bb34b8db8866adbf4328f0ca 100644 (file)
@@ -1,3 +1,87 @@
+2013-10-17  Yao Qi  <yao@codesourcery.com>
+
+       * Makefile.in (SFILES): Add c-varobj.c and jv-varobj.c.
+       (COMMON_OBS): Add c-varobj.o and jv-varobj.o.
+       * ada-varobj.c: Include "varobj.h".
+       (ada_number_of_children): New.  Moved from varobj.c.
+       (ada_name_of_variable, ada_name_of_child): Likewise.
+       (ada_path_expr_of_child, ada_value_of_child): Likewise.
+       (ada_type_of_child, ada_value_of_variable): Likewise.
+       (ada_value_is_changeable_p, ada_value_has_mutated): Likewise.
+       (ada_varobj_ops): New.
+       * c-varobj.c, jv-varobj.c: New file.  Moved from varobj.c.
+       * gdbtypes.c (get_target_type): New.  Moved from varobj.c.
+       * gdbtypes.h (get_target_type): Declare.
+       * varobj.c: Remove the inclusion of "ada-varobj.h" and
+       "ada-lang.h".
+       (ANONYMOUS_STRUCT_NAME): Move it to c-varobj.c.
+       (ANONYMOUS_UNION_NAME): Likewise.
+       (get_type, get_value_type, get_target_type): Remove declarations.
+       (value_get_print_value, varobj_value_get_print_value): Likewise.
+       (c_number_of_children, c_name_of_variable): Likewise.
+       (c_name_of_child, c_path_expr_of_child): Likewise.
+       (c_value_of_child, c_type_of_child): Likewise.
+       (c_value_of_variable, cplus_number_of_children): Likewise.
+       (cplus_class_num_children, cplus_name_of_variable): Likewise.
+       (cplus_name_of_child, cplus_path_expr_of_child): Likewise.
+       (cplus_value_of_child, cplus_type_of_child): Likewise.
+       (cplus_value_of_variable, java_number_of_children): Likewise.
+       (java_name_of_variable, java_name_of_child): Likewise.
+       (java_path_expr_of_child, java_value_of_child): Likewise.
+       (java_type_of_child, java_value_of_variable): Likewise.
+       (ada_number_of_children, ada_name_of_variable): Likewise.
+       (ada_name_of_child, ada_path_expr_of_child): Likewise.
+       (ada_value_of_child, ada_type_of_child): Likewise.
+       (ada_value_of_variable, ada_value_is_changeable_p): Likewise.
+       (ada_value_has_mutated): Likewise.
+       (struct language_specific): Move it to varobj.h.
+       (CPLUS_FAKE_CHILD): Move it to varobj.h.
+       (restrict_range): Rename it varobj_restrict_range.  Make it extern.
+       Callers update.
+       (get_path_expr_parent): Rename it to varobj_get_path_expr_parent.
+       Make it extern.
+       (is_anonymous_child): Move it to c-varobj.c and rename to
+       varobj_is_anonymous_child.  Caller update.
+       (get_type): Move it to c-varobj.c.
+       (get_value_type): Rename it varobj_get_value_type.  Make it
+       extern.
+       (get_target_type): Move it gdbtypes.c.
+       (varobj_formatted_print_options): New function.
+       (value_get_print_value): Rename it to
+       varobj_value_get_print_value and make it extern.
+       (varobj_value_is_changeable_p): Make it extern.
+       (adjust_value_for_child_access): Move it to c-varobj.c.
+       (default_value_is_changeable_p): Rename it to
+       varobj_default_value_is_changeable_p.  Make it extern.
+       (c_number_of_children, c_name_of_variable): Move it to c-varobj.c
+       (c_name_of_child, c_path_expr_of_child): Likewise.
+       (c_value_of_child, c_type_of_child): Likewise.
+       (c_value_of_variable, cplus_number_of_children): Likewise.
+       (cplus_class_num_children, cplus_name_of_variable): Likewise.
+       (cplus_name_of_child, cplus_path_expr_of_child): Likewise.
+       (cplus_value_of_child, cplus_type_of_child): Likewise.
+       (cplus_value_of_variable): Likewise.
+       (java_number_of_children, java_name_of_variable): Move it to jv-varobj.c.
+       (java_name_of_child, java_path_expr_of_child): Likewise.
+       (java_value_of_child, java_type_of_child): Likewise.
+       (java_value_of_variable): Likewise.
+       (ada_number_of_children, ada_name_of_variable): Move it to ada-varobj.c.
+       (ada_name_of_child, ada_path_expr_of_child): Likewise.
+       (ada_value_of_child, ada_type_of_child): Likewise.
+       (ada_value_of_variable, ada_value_is_changeable_p): Likewise.
+       (ada_value_has_mutated): Likewise.
+       * varobj.h (CPLUS_FAKE_CHILD): New macro, moved from varobj.c.
+       (struct lang_varobj_ops): New.  Renamed by 'struct language_specific'.
+       (c_varobj_ops, cplus_varobj_ops): Declare.
+       (java_varobj_ops, ada_varobj_ops): Declare.
+       (varobj_default_value_is_changeable_p): Declare.
+       (varobj_value_is_changeable_p): Declare.
+       (varobj_get_value_type, varobj_is_anonymous_child): Declare.
+       (varobj_get_path_expr_parent): Declare.
+       (varobj_value_get_print_value): Declare.
+       (varobj_formatted_print_options): Declare.
+       (varobj_restrict_range): Declare.
+
 2013-10-17  Luis Machado  <lgustavo@codesourcery.com>
 
        * target/waitstatus.h (target_waitkind): Remove spurious
index f13e5c656f813f37e3ecc7a283e4a8b03d2b41c2..f8abb353cf412540b59c864ae3855b380afc2b08 100644 (file)
@@ -721,7 +721,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        block.c blockframe.c \
        breakpoint.c break-catch-sig.c break-catch-throw.c \
        build-id.c buildsym.c \
-       c-exp.y c-lang.c c-typeprint.c c-valprint.c \
+       c-exp.y c-lang.c c-typeprint.c c-valprint.c c-varobj.c \
        charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \
        complaints.c completer.c continuations.c corefile.c corelow.c \
        cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \
@@ -742,7 +742,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        infcmd.c inflow.c infrun.c \
        inline-frame.c \
        interps.c \
-       jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
+       jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c jv-varobj.c \
        language.c linespec.c minidebug.c \
        m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c \
        macrotab.c macroexp.c macrocmd.c macroscope.c main.c maint.c \
@@ -926,11 +926,11 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
        dwarf2read.o mipsread.o stabsread.o corefile.o \
        dwarf2expr.o dwarf2loc.o dwarf2-frame.o dwarf2-frame-tailcall.o \
        ada-lang.o c-lang.o d-lang.o f-lang.o objc-lang.o \
-       ada-tasks.o ada-varobj.o \
+       ada-tasks.o ada-varobj.o c-varobj.o \
        ui-out.o cli-out.o \
        varobj.o vec.o \
        go-lang.o go-valprint.o go-typeprint.o \
-       jv-lang.o jv-valprint.o jv-typeprint.o \
+       jv-lang.o jv-valprint.o jv-typeprint.o jv-varobj.o \
        m2-lang.o opencl-lang.o p-lang.o p-typeprint.o p-valprint.o \
        sentinel-frame.o \
        complaints.o typeprint.o \
index 53d8a9c6b45cd66a3859c97cbd1b7bd0df219a0b..52c76875296b002e0f0d7cb721475da2d64f0479 100644 (file)
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "ada-varobj.h"
 #include "ada-lang.h"
+#include "varobj.h"
 #include "language.h"
 #include "valprint.h"
 
@@ -885,4 +886,140 @@ ada_varobj_get_value_of_variable (struct value *value,
   return result;
 }
 
+/* Ada specific callbacks for VAROBJs.  */
 
+static int
+ada_number_of_children (struct varobj *var)
+{
+  return ada_varobj_get_number_of_children (var->value, var->type);
+}
+
+static char *
+ada_name_of_variable (struct varobj *parent)
+{
+  return c_varobj_ops.name_of_variable (parent);
+}
+
+static char *
+ada_name_of_child (struct varobj *parent, int index)
+{
+  return ada_varobj_get_name_of_child (parent->value, parent->type,
+                                      parent->name, index);
+}
+
+static char*
+ada_path_expr_of_child (struct varobj *child)
+{
+  struct varobj *parent = child->parent;
+  const char *parent_path_expr = varobj_get_path_expr (parent);
+
+  return ada_varobj_get_path_expr_of_child (parent->value,
+                                           parent->type,
+                                           parent->name,
+                                           parent_path_expr,
+                                           child->index);
+}
+
+static struct value *
+ada_value_of_child (struct varobj *parent, int index)
+{
+  return ada_varobj_get_value_of_child (parent->value, parent->type,
+                                       parent->name, index);
+}
+
+static struct type *
+ada_type_of_child (struct varobj *parent, int index)
+{
+  return ada_varobj_get_type_of_child (parent->value, parent->type,
+                                      index);
+}
+
+static char *
+ada_value_of_variable (struct varobj *var, enum varobj_display_formats format)
+{
+  struct value_print_options opts;
+
+  varobj_formatted_print_options (&opts, format);
+
+  return ada_varobj_get_value_of_variable (var->value, var->type, &opts);
+}
+
+/* Implement the "value_is_changeable_p" routine for Ada.  */
+
+static int
+ada_value_is_changeable_p (struct varobj *var)
+{
+  struct type *type = var->value ? value_type (var->value) : var->type;
+
+  if (ada_is_array_descriptor_type (type)
+      && TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    {
+      /* This is in reality a pointer to an unconstrained array.
+        its value is changeable.  */
+      return 1;
+    }
+
+  if (ada_is_string_type (type))
+    {
+      /* We display the contents of the string in the array's
+        "value" field.  The contents can change, so consider
+        that the array is changeable.  */
+      return 1;
+    }
+
+  return varobj_default_value_is_changeable_p (var);
+}
+
+/* Implement the "value_has_mutated" routine for Ada.  */
+
+static int
+ada_value_has_mutated (struct varobj *var, struct value *new_val,
+                      struct type *new_type)
+{
+  int i;
+  int from = -1;
+  int to = -1;
+
+  /* If the number of fields have changed, then for sure the type
+     has mutated.  */
+  if (ada_varobj_get_number_of_children (new_val, new_type)
+      != var->num_children)
+    return 1;
+
+  /* If the number of fields have remained the same, then we need
+     to check the name of each field.  If they remain the same,
+     then chances are the type hasn't mutated.  This is technically
+     an incomplete test, as the child's type might have changed
+     despite the fact that the name remains the same.  But we'll
+     handle this situation by saying that the child has mutated,
+     not this value.
+
+     If only part (or none!) of the children have been fetched,
+     then only check the ones we fetched.  It does not matter
+     to the frontend whether a child that it has not fetched yet
+     has mutated or not. So just assume it hasn't.  */
+
+  varobj_restrict_range (var->children, &from, &to);
+  for (i = from; i < to; i++)
+    if (strcmp (ada_varobj_get_name_of_child (new_val, new_type,
+                                             var->name, i),
+               VEC_index (varobj_p, var->children, i)->name) != 0)
+      return 1;
+
+  return 0;
+}
+
+/* varobj operations for ada.  */
+
+const struct lang_varobj_ops ada_varobj_ops =
+{
+  ada_number_of_children,
+  ada_name_of_variable,
+  ada_name_of_child,
+  ada_path_expr_of_child,
+  ada_value_of_child,
+  ada_type_of_child,
+  ada_value_of_variable,
+  ada_value_is_changeable_p,
+  ada_value_has_mutated
+};
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
new file mode 100644 (file)
index 0000000..73e785c
--- /dev/null
@@ -0,0 +1,910 @@
+/* varobj support for C and C++.
+
+   Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "value.h"
+#include "varobj.h"
+#include "gdbthread.h"
+#include "valprint.h"
+
+static void cplus_class_num_children (struct type *type, int children[3]);
+
+/* The names of varobjs representing anonymous structs or unions.  */
+#define ANONYMOUS_STRUCT_NAME _("<anonymous struct>")
+#define ANONYMOUS_UNION_NAME _("<anonymous union>")
+
+/* Does CHILD represent a child with no name?  This happens when
+   the child is an anonmous struct or union and it has no field name
+   in its parent variable.
+
+   This has already been determined by *_describe_child. The easiest
+   thing to do is to compare the child's name with ANONYMOUS_*_NAME.  */
+
+int
+varobj_is_anonymous_child (struct varobj *child)
+{
+  return (strcmp (child->name, ANONYMOUS_STRUCT_NAME) == 0
+         || strcmp (child->name, ANONYMOUS_UNION_NAME) == 0);
+}
+
+/* Given the value and the type of a variable object,
+   adjust the value and type to those necessary
+   for getting children of the variable object.
+   This includes dereferencing top-level references
+   to all types and dereferencing pointers to
+   structures.
+
+   If LOOKUP_ACTUAL_TYPE is set the enclosing type of the
+   value will be fetched and if it differs from static type
+   the value will be casted to it.
+
+   Both TYPE and *TYPE should be non-null.  VALUE
+   can be null if we want to only translate type.
+   *VALUE can be null as well -- if the parent
+   value is not known.
+
+   If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1
+   depending on whether pointer was dereferenced
+   in this function.  */
+
+static void
+adjust_value_for_child_access (struct value **value,
+                                 struct type **type,
+                                 int *was_ptr,
+                                 int lookup_actual_type)
+{
+  gdb_assert (type && *type);
+
+  if (was_ptr)
+    *was_ptr = 0;
+
+  *type = check_typedef (*type);
+  
+  /* The type of value stored in varobj, that is passed
+     to us, is already supposed to be
+     reference-stripped.  */
+
+  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+
+  /* Pointers to structures are treated just like
+     structures when accessing children.  Don't
+     dererences pointers to other types.  */
+  if (TYPE_CODE (*type) == TYPE_CODE_PTR)
+    {
+      struct type *target_type = get_target_type (*type);
+      if (TYPE_CODE (target_type) == TYPE_CODE_STRUCT
+         || TYPE_CODE (target_type) == TYPE_CODE_UNION)
+       {
+         if (value && *value)
+           {
+             volatile struct gdb_exception except;
+
+             TRY_CATCH (except, RETURN_MASK_ERROR)
+               {
+                 *value = value_ind (*value);
+               }
+
+             if (except.reason < 0)
+               *value = NULL;
+           }
+         *type = target_type;
+         if (was_ptr)
+           *was_ptr = 1;
+       }
+    }
+
+  /* The 'get_target_type' function calls check_typedef on
+     result, so we can immediately check type code.  No
+     need to call check_typedef here.  */
+
+  /* Access a real type of the value (if necessary and possible).  */
+  if (value && *value && lookup_actual_type)
+    {
+      struct type *enclosing_type;
+      int real_type_found = 0;
+
+      enclosing_type = value_actual_type (*value, 1, &real_type_found);
+      if (real_type_found)
+        {
+          *type = enclosing_type;
+          *value = value_cast (enclosing_type, *value);
+        }
+    }
+}
+
+/* C */
+
+static int
+c_number_of_children (struct varobj *var)
+{
+  struct type *type = varobj_get_value_type (var);
+  int children = 0;
+  struct type *target;
+
+  adjust_value_for_child_access (NULL, &type, NULL, 0);
+  target = get_target_type (type);
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0
+         && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
+       children = TYPE_LENGTH (type) / TYPE_LENGTH (target);
+      else
+       /* If we don't know how many elements there are, don't display
+          any.  */
+       children = 0;
+      break;
+
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      children = TYPE_NFIELDS (type);
+      break;
+
+    case TYPE_CODE_PTR:
+      /* The type here is a pointer to non-struct.  Typically, pointers
+        have one child, except for function ptrs, which have no children,
+        and except for void*, as we don't know what to show.
+
+         We can show char* so we allow it to be dereferenced.  If you decide
+         to test for it, please mind that a little magic is necessary to
+         properly identify it: char* has TYPE_CODE == TYPE_CODE_INT and 
+         TYPE_NAME == "char".  */
+      if (TYPE_CODE (target) == TYPE_CODE_FUNC
+         || TYPE_CODE (target) == TYPE_CODE_VOID)
+       children = 0;
+      else
+       children = 1;
+      break;
+
+    default:
+      /* Other types have no children.  */
+      break;
+    }
+
+  return children;
+}
+
+static char *
+c_name_of_variable (struct varobj *parent)
+{
+  return xstrdup (parent->name);
+}
+
+/* Return the value of element TYPE_INDEX of a structure
+   value VALUE.  VALUE's type should be a structure,
+   or union, or a typedef to struct/union.
+
+   Returns NULL if getting the value fails.  Never throws.  */
+
+static struct value *
+value_struct_element_index (struct value *value, int type_index)
+{
+  struct value *result = NULL;
+  volatile struct gdb_exception e;
+  struct type *type = value_type (value);
+
+  type = check_typedef (type);
+
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+             || TYPE_CODE (type) == TYPE_CODE_UNION);
+
+  TRY_CATCH (e, RETURN_MASK_ERROR)
+    {
+      if (field_is_static (&TYPE_FIELD (type, type_index)))
+       result = value_static_field (type, type_index);
+      else
+       result = value_primitive_field (value, 0, type_index, type);
+    }
+  if (e.reason < 0)
+    {
+      return NULL;
+    }
+  else
+    {
+      return result;
+    }
+}
+
+/* Obtain the information about child INDEX of the variable
+   object PARENT.
+   If CNAME is not null, sets *CNAME to the name of the child relative
+   to the parent.
+   If CVALUE is not null, sets *CVALUE to the value of the child.
+   If CTYPE is not null, sets *CTYPE to the type of the child.
+
+   If any of CNAME, CVALUE, or CTYPE is not null, but the corresponding
+   information cannot be determined, set *CNAME, *CVALUE, or *CTYPE
+   to NULL.  */
+
+static void 
+c_describe_child (struct varobj *parent, int index,
+                 char **cname, struct value **cvalue, struct type **ctype,
+                 char **cfull_expression)
+{
+  struct value *value = parent->value;
+  struct type *type = varobj_get_value_type (parent);
+  char *parent_expression = NULL;
+  int was_ptr;
+  volatile struct gdb_exception except;
+
+  if (cname)
+    *cname = NULL;
+  if (cvalue)
+    *cvalue = NULL;
+  if (ctype)
+    *ctype = NULL;
+  if (cfull_expression)
+    {
+      *cfull_expression = NULL;
+      parent_expression
+       = varobj_get_path_expr (varobj_get_path_expr_parent (parent));
+    }
+  adjust_value_for_child_access (&value, &type, &was_ptr, 0);
+      
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      if (cname)
+       *cname
+         = xstrdup (int_string (index 
+                                + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
+                                10, 1, 0, 0));
+
+      if (cvalue && value)
+       {
+         int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
+
+         TRY_CATCH (except, RETURN_MASK_ERROR)
+           {
+             *cvalue = value_subscript (value, real_index);
+           }
+       }
+
+      if (ctype)
+       *ctype = get_target_type (type);
+
+      if (cfull_expression)
+       *cfull_expression = 
+         xstrprintf ("(%s)[%s]", parent_expression, 
+                     int_string (index
+                                 + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
+                                 10, 1, 0, 0));
+
+
+      break;
+
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      {
+       const char *field_name;
+
+       /* If the type is anonymous and the field has no name,
+          set an appropriate name.  */
+       field_name = TYPE_FIELD_NAME (type, index);
+       if (field_name == NULL || *field_name == '\0')
+         {
+           if (cname)
+             {
+               if (TYPE_CODE (TYPE_FIELD_TYPE (type, index))
+                   == TYPE_CODE_STRUCT)
+                 *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
+               else
+                 *cname = xstrdup (ANONYMOUS_UNION_NAME);
+             }
+
+           if (cfull_expression)
+             *cfull_expression = xstrdup ("");
+         }
+       else
+         {
+           if (cname)
+             *cname = xstrdup (field_name);
+
+           if (cfull_expression)
+             {
+               char *join = was_ptr ? "->" : ".";
+
+               *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression,
+                                               join, field_name);
+             }
+         }
+
+       if (cvalue && value)
+         {
+           /* For C, varobj index is the same as type index.  */
+           *cvalue = value_struct_element_index (value, index);
+         }
+
+       if (ctype)
+         *ctype = TYPE_FIELD_TYPE (type, index);
+      }
+      break;
+
+    case TYPE_CODE_PTR:
+      if (cname)
+       *cname = xstrprintf ("*%s", parent->name);
+
+      if (cvalue && value)
+       {
+         TRY_CATCH (except, RETURN_MASK_ERROR)
+           {
+             *cvalue = value_ind (value);
+           }
+
+         if (except.reason < 0)
+           *cvalue = NULL;
+       }
+
+      /* Don't use get_target_type because it calls
+        check_typedef and here, we want to show the true
+        declared type of the variable.  */
+      if (ctype)
+       *ctype = TYPE_TARGET_TYPE (type);
+
+      if (cfull_expression)
+       *cfull_expression = xstrprintf ("*(%s)", parent_expression);
+      
+      break;
+
+    default:
+      /* This should not happen.  */
+      if (cname)
+       *cname = xstrdup ("???");
+      if (cfull_expression)
+       *cfull_expression = xstrdup ("???");
+      /* Don't set value and type, we don't know then.  */
+    }
+}
+
+static char *
+c_name_of_child (struct varobj *parent, int index)
+{
+  char *name;
+
+  c_describe_child (parent, index, &name, NULL, NULL, NULL);
+  return name;
+}
+
+static char *
+c_path_expr_of_child (struct varobj *child)
+{
+  c_describe_child (child->parent, child->index, NULL, NULL, NULL, 
+                   &child->path_expr);
+  return child->path_expr;
+}
+
+static struct value *
+c_value_of_child (struct varobj *parent, int index)
+{
+  struct value *value = NULL;
+
+  c_describe_child (parent, index, NULL, &value, NULL, NULL);
+  return value;
+}
+
+static struct type *
+c_type_of_child (struct varobj *parent, int index)
+{
+  struct type *type = NULL;
+
+  c_describe_child (parent, index, NULL, NULL, &type, NULL);
+  return type;
+}
+
+/* This returns the type of the variable.  It also skips past typedefs
+   to return the real type of the variable.  */
+
+static struct type *
+get_type (struct varobj *var)
+{
+  struct type *type;
+
+  type = var->type;
+  if (type != NULL)
+    type = check_typedef (type);
+
+  return type;
+}
+
+static char *
+c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
+{
+  /* BOGUS: if val_print sees a struct/class, or a reference to one,
+     it will print out its children instead of "{...}".  So we need to
+     catch that case explicitly.  */
+  struct type *type = get_type (var);
+
+  /* Strip top-level references.  */
+  while (TYPE_CODE (type) == TYPE_CODE_REF)
+    type = check_typedef (TYPE_TARGET_TYPE (type));
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      return xstrdup ("{...}");
+      /* break; */
+
+    case TYPE_CODE_ARRAY:
+      {
+       char *number;
+
+       number = xstrprintf ("[%d]", var->num_children);
+       return (number);
+      }
+      /* break; */
+
+    default:
+      {
+       if (var->value == NULL)
+         {
+           /* This can happen if we attempt to get the value of a struct
+              member when the parent is an invalid pointer.  This is an
+              error condition, so we should tell the caller.  */
+           return NULL;
+         }
+       else
+         {
+           if (var->not_fetched && value_lazy (var->value))
+             /* Frozen variable and no value yet.  We don't
+                implicitly fetch the value.  MI response will
+                use empty string for the value, which is OK.  */
+             return NULL;
+
+           gdb_assert (varobj_value_is_changeable_p (var));
+           gdb_assert (!value_lazy (var->value));
+           
+           /* If the specified format is the current one,
+              we can reuse print_value.  */
+           if (format == var->format)
+             return xstrdup (var->print_value);
+           else
+             return varobj_value_get_print_value (var->value, format, var);
+         }
+      }
+    }
+}
+\f
+
+/* varobj operations for c.  */
+
+const struct lang_varobj_ops c_varobj_ops =
+{
+   c_number_of_children,
+   c_name_of_variable,
+   c_name_of_child,
+   c_path_expr_of_child,
+   c_value_of_child,
+   c_type_of_child,
+   c_value_of_variable,
+   varobj_default_value_is_changeable_p,
+   NULL /* value_has_mutated */
+};
+
+/* A little convenience enum for dealing with C++/Java.  */
+enum vsections
+{
+  v_public = 0, v_private, v_protected
+};
+
+/* C++ */
+
+static int
+cplus_number_of_children (struct varobj *var)
+{
+  struct value *value = NULL;
+  struct type *type;
+  int children, dont_know;
+  int lookup_actual_type = 0;
+  struct value_print_options opts;
+
+  dont_know = 1;
+  children = 0;
+
+  get_user_print_options (&opts);
+
+  if (!CPLUS_FAKE_CHILD (var))
+    {
+      type = varobj_get_value_type (var);
+
+      /* It is necessary to access a real type (via RTTI).  */
+      if (opts.objectprint)
+        {
+          value = var->value;
+          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+                               || TYPE_CODE (var->type) == TYPE_CODE_PTR);
+        }
+      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
+
+      if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
+         ((TYPE_CODE (type)) == TYPE_CODE_UNION))
+       {
+         int kids[3];
+
+         cplus_class_num_children (type, kids);
+         if (kids[v_public] != 0)
+           children++;
+         if (kids[v_private] != 0)
+           children++;
+         if (kids[v_protected] != 0)
+           children++;
+
+         /* Add any baseclasses.  */
+         children += TYPE_N_BASECLASSES (type);
+         dont_know = 0;
+
+         /* FIXME: save children in var.  */
+       }
+    }
+  else
+    {
+      int kids[3];
+
+      type = varobj_get_value_type (var->parent);
+
+      /* It is necessary to access a real type (via RTTI).  */
+      if (opts.objectprint)
+        {
+         struct varobj *parent = var->parent;
+
+         value = parent->value;
+         lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+                               || TYPE_CODE (parent->type) == TYPE_CODE_PTR);
+        }
+      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
+
+      cplus_class_num_children (type, kids);
+      if (strcmp (var->name, "public") == 0)
+       children = kids[v_public];
+      else if (strcmp (var->name, "private") == 0)
+       children = kids[v_private];
+      else
+       children = kids[v_protected];
+      dont_know = 0;
+    }
+
+  if (dont_know)
+    children = c_number_of_children (var);
+
+  return children;
+}
+
+/* Compute # of public, private, and protected variables in this class.
+   That means we need to descend into all baseclasses and find out
+   how many are there, too.  */
+
+static void
+cplus_class_num_children (struct type *type, int children[3])
+{
+  int i, vptr_fieldno;
+  struct type *basetype = NULL;
+
+  children[v_public] = 0;
+  children[v_private] = 0;
+  children[v_protected] = 0;
+
+  vptr_fieldno = get_vptr_fieldno (type, &basetype);
+  for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
+    {
+      /* If we have a virtual table pointer, omit it.  Even if virtual
+        table pointers are not specifically marked in the debug info,
+        they should be artificial.  */
+      if ((type == basetype && i == vptr_fieldno)
+         || TYPE_FIELD_ARTIFICIAL (type, i))
+       continue;
+
+      if (TYPE_FIELD_PROTECTED (type, i))
+       children[v_protected]++;
+      else if (TYPE_FIELD_PRIVATE (type, i))
+       children[v_private]++;
+      else
+       children[v_public]++;
+    }
+}
+
+static char *
+cplus_name_of_variable (struct varobj *parent)
+{
+  return c_name_of_variable (parent);
+}
+
+enum accessibility { private_field, protected_field, public_field };
+
+/* Check if field INDEX of TYPE has the specified accessibility.
+   Return 0 if so and 1 otherwise.  */
+
+static int 
+match_accessibility (struct type *type, int index, enum accessibility acc)
+{
+  if (acc == private_field && TYPE_FIELD_PRIVATE (type, index))
+    return 1;
+  else if (acc == protected_field && TYPE_FIELD_PROTECTED (type, index))
+    return 1;
+  else if (acc == public_field && !TYPE_FIELD_PRIVATE (type, index)
+          && !TYPE_FIELD_PROTECTED (type, index))
+    return 1;
+  else
+    return 0;
+}
+
+static void
+cplus_describe_child (struct varobj *parent, int index,
+                     char **cname, struct value **cvalue, struct type **ctype,
+                     char **cfull_expression)
+{
+  struct value *value;
+  struct type *type;
+  int was_ptr;
+  int lookup_actual_type = 0;
+  char *parent_expression = NULL;
+  struct varobj *var;
+  struct value_print_options opts;
+
+  if (cname)
+    *cname = NULL;
+  if (cvalue)
+    *cvalue = NULL;
+  if (ctype)
+    *ctype = NULL;
+  if (cfull_expression)
+    *cfull_expression = NULL;
+
+  get_user_print_options (&opts);
+
+  var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
+  if (opts.objectprint)
+    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+                         || TYPE_CODE (var->type) == TYPE_CODE_PTR);
+  value = var->value;
+  type = varobj_get_value_type (var);
+  if (cfull_expression)
+    parent_expression
+      = varobj_get_path_expr (varobj_get_path_expr_parent (var));
+
+  adjust_value_for_child_access (&value, &type, &was_ptr, lookup_actual_type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+      || TYPE_CODE (type) == TYPE_CODE_UNION)
+    {
+      char *join = was_ptr ? "->" : ".";
+
+      if (CPLUS_FAKE_CHILD (parent))
+       {
+         /* The fields of the class type are ordered as they
+            appear in the class.  We are given an index for a
+            particular access control type ("public","protected",
+            or "private").  We must skip over fields that don't
+            have the access control we are looking for to properly
+            find the indexed field.  */
+         int type_index = TYPE_N_BASECLASSES (type);
+         enum accessibility acc = public_field;
+         int vptr_fieldno;
+         struct type *basetype = NULL;
+         const char *field_name;
+
+         vptr_fieldno = get_vptr_fieldno (type, &basetype);
+         if (strcmp (parent->name, "private") == 0)
+           acc = private_field;
+         else if (strcmp (parent->name, "protected") == 0)
+           acc = protected_field;
+
+         while (index >= 0)
+           {
+             if ((type == basetype && type_index == vptr_fieldno)
+                 || TYPE_FIELD_ARTIFICIAL (type, type_index))
+               ; /* ignore vptr */
+             else if (match_accessibility (type, type_index, acc))
+                   --index;
+                 ++type_index;
+           }
+         --type_index;
+
+         /* If the type is anonymous and the field has no name,
+            set an appopriate name.  */
+         field_name = TYPE_FIELD_NAME (type, type_index);
+         if (field_name == NULL || *field_name == '\0')
+           {
+             if (cname)
+               {
+                 if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
+                     == TYPE_CODE_STRUCT)
+                   *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
+                 else if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
+                          == TYPE_CODE_UNION)
+                   *cname = xstrdup (ANONYMOUS_UNION_NAME);
+               }
+
+             if (cfull_expression)
+               *cfull_expression = xstrdup ("");
+           }
+         else
+           {
+             if (cname)
+               *cname = xstrdup (TYPE_FIELD_NAME (type, type_index));
+
+             if (cfull_expression)
+               *cfull_expression
+                 = xstrprintf ("((%s)%s%s)", parent_expression, join,
+                               field_name);
+           }
+
+         if (cvalue && value)
+           *cvalue = value_struct_element_index (value, type_index);
+
+         if (ctype)
+           *ctype = TYPE_FIELD_TYPE (type, type_index);
+       }
+      else if (index < TYPE_N_BASECLASSES (type))
+       {
+         /* This is a baseclass.  */
+         if (cname)
+           *cname = xstrdup (TYPE_FIELD_NAME (type, index));
+
+         if (cvalue && value)
+           *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+
+         if (ctype)
+           {
+             *ctype = TYPE_FIELD_TYPE (type, index);
+           }
+
+         if (cfull_expression)
+           {
+             char *ptr = was_ptr ? "*" : "";
+
+             /* Cast the parent to the base' type.  Note that in gdb,
+                expression like 
+                        (Base1)d
+                will create an lvalue, for all appearences, so we don't
+                need to use more fancy:
+                        *(Base1*)(&d)
+                construct.
+
+                When we are in the scope of the base class or of one
+                of its children, the type field name will be interpreted
+                as a constructor, if it exists.  Therefore, we must
+                indicate that the name is a class name by using the
+                'class' keyword.  See PR mi/11912  */
+             *cfull_expression = xstrprintf ("(%s(class %s%s) %s)", 
+                                             ptr, 
+                                             TYPE_FIELD_NAME (type, index),
+                                             ptr,
+                                             parent_expression);
+           }
+       }
+      else
+       {
+         char *access = NULL;
+         int children[3];
+
+         cplus_class_num_children (type, children);
+
+         /* Everything beyond the baseclasses can
+            only be "public", "private", or "protected"
+
+            The special "fake" children are always output by varobj in
+            this order.  So if INDEX == 2, it MUST be "protected".  */
+         index -= TYPE_N_BASECLASSES (type);
+         switch (index)
+           {
+           case 0:
+             if (children[v_public] > 0)
+               access = "public";
+             else if (children[v_private] > 0)
+               access = "private";
+             else 
+               access = "protected";
+             break;
+           case 1:
+             if (children[v_public] > 0)
+               {
+                 if (children[v_private] > 0)
+                   access = "private";
+                 else
+                   access = "protected";
+               }
+             else if (children[v_private] > 0)
+               access = "protected";
+             break;
+           case 2:
+             /* Must be protected.  */
+             access = "protected";
+             break;
+           default:
+             /* error!  */
+             break;
+           }
+
+         gdb_assert (access);
+         if (cname)
+           *cname = xstrdup (access);
+
+         /* Value and type and full expression are null here.  */
+       }
+    }
+  else
+    {
+      c_describe_child (parent, index, cname, cvalue, ctype, cfull_expression);
+    }  
+}
+
+static char *
+cplus_name_of_child (struct varobj *parent, int index)
+{
+  char *name = NULL;
+
+  cplus_describe_child (parent, index, &name, NULL, NULL, NULL);
+  return name;
+}
+
+static char *
+cplus_path_expr_of_child (struct varobj *child)
+{
+  cplus_describe_child (child->parent, child->index, NULL, NULL, NULL, 
+                       &child->path_expr);
+  return child->path_expr;
+}
+
+static struct value *
+cplus_value_of_child (struct varobj *parent, int index)
+{
+  struct value *value = NULL;
+
+  cplus_describe_child (parent, index, NULL, &value, NULL, NULL);
+  return value;
+}
+
+static struct type *
+cplus_type_of_child (struct varobj *parent, int index)
+{
+  struct type *type = NULL;
+
+  cplus_describe_child (parent, index, NULL, NULL, &type, NULL);
+  return type;
+}
+
+static char *
+cplus_value_of_variable (struct varobj *var, 
+                        enum varobj_display_formats format)
+{
+
+  /* If we have one of our special types, don't print out
+     any value.  */
+  if (CPLUS_FAKE_CHILD (var))
+    return xstrdup ("");
+
+  return c_value_of_variable (var, format);
+}
+\f
+
+/* varobj operations for c++.  */
+
+const struct lang_varobj_ops cplus_varobj_ops =
+{
+   cplus_number_of_children,
+   cplus_name_of_variable,
+   cplus_name_of_child,
+   cplus_path_expr_of_child,
+   cplus_value_of_child,
+   cplus_type_of_child,
+   cplus_value_of_variable,
+   varobj_default_value_is_changeable_p,
+   NULL /* value_has_mutated */
+};
+
+\f
index 6c809a401a3511583a365e2acfa565ad7ceb3717..9069a1122e768e0e629a41d7de3973e14a60a58d 100644 (file)
@@ -239,6 +239,21 @@ get_type_arch (const struct type *type)
     return TYPE_OWNER (type).gdbarch;
 }
 
+/* See gdbtypes.h.  */
+
+struct type *
+get_target_type (struct type *type)
+{
+  if (type != NULL)
+    {
+      type = TYPE_TARGET_TYPE (type);
+      if (type != NULL)
+       type = check_typedef (type);
+    }
+
+  return type;
+}
+
 /* Alloc a new type instance structure, fill it with some defaults,
    and point it at OLDTYPE.  Allocate the new type instance from the
    same place as OLDTYPE.  */
index 5e8d1e710ae5b50b48f6b785909c427b8c9fb8df..d7fdedfec104c43710d999e2613b4a2c1fe94856 100644 (file)
@@ -1431,6 +1431,10 @@ extern struct type *alloc_type_copy (const struct type *);
    objfile's architecture is returned.  */
 extern struct gdbarch *get_type_arch (const struct type *);
 
+/* This returns the target type (or NULL) of TYPE, also skipping
+   past typedefs.  */
+extern struct type *get_target_type (struct type *type);
+
 /* Helper function to construct objfile-owned types.  */
 extern struct type *init_type (enum type_code, int, int, const char *,
                               struct objfile *);
diff --git a/gdb/jv-varobj.c b/gdb/jv-varobj.c
new file mode 100644 (file)
index 0000000..e70aa28
--- /dev/null
@@ -0,0 +1,105 @@
+/* varobj support for Java.
+
+   Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "varobj.h"
+
+/* Java */
+
+static int
+java_number_of_children (struct varobj *var)
+{
+  return cplus_varobj_ops.number_of_children (var);
+}
+
+static char *
+java_name_of_variable (struct varobj *parent)
+{
+  char *p, *name;
+
+  name = cplus_varobj_ops.name_of_variable (parent);
+  /* If  the name has "-" in it, it is because we
+     needed to escape periods in the name...  */
+  p = name;
+
+  while (*p != '\000')
+    {
+      if (*p == '-')
+       *p = '.';
+      p++;
+    }
+
+  return name;
+}
+
+static char *
+java_name_of_child (struct varobj *parent, int index)
+{
+  char *name, *p;
+
+  name = cplus_varobj_ops.name_of_child (parent, index);
+  /* Escape any periods in the name...  */
+  p = name;
+
+  while (*p != '\000')
+    {
+      if (*p == '.')
+       *p = '-';
+      p++;
+    }
+
+  return name;
+}
+
+static char *
+java_path_expr_of_child (struct varobj *child)
+{
+  return NULL;
+}
+
+static struct value *
+java_value_of_child (struct varobj *parent, int index)
+{
+  return cplus_varobj_ops.value_of_child (parent, index);
+}
+
+static struct type *
+java_type_of_child (struct varobj *parent, int index)
+{
+  return cplus_varobj_ops.type_of_child (parent, index);
+}
+
+static char *
+java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
+{
+  return cplus_varobj_ops.value_of_variable (var, format);
+}
+
+/* varobj operations for java.  */
+
+const struct lang_varobj_ops java_varobj_ops =
+{
+   java_number_of_children,
+   java_name_of_variable,
+   java_name_of_child,
+   java_path_expr_of_child,
+   java_value_of_child,
+   java_type_of_child,
+   java_value_of_variable,
+   varobj_default_value_is_changeable_p,
+   NULL /* value_has_mutated */
+};
index 1967842c78bb1b740f891a4561cacdf219231495..01cf3d2a1d0a48ffcd1fc107e6b46e7ab1d370f8 100644 (file)
@@ -33,8 +33,6 @@
 #include "vec.h"
 #include "gdbthread.h"
 #include "inferior.h"
-#include "ada-varobj.h"
-#include "ada-lang.h"
 
 #if HAVE_PYTHON
 #include "python/python.h"
 typedef int PyObject;
 #endif
 
-/* The names of varobjs representing anonymous structs or unions.  */
-#define ANONYMOUS_STRUCT_NAME _("<anonymous struct>")
-#define ANONYMOUS_UNION_NAME _("<anonymous union>")
-
 /* Non-zero if we want to see trace of varobj level stuff.  */
 
 unsigned int varobjdebug = 0;
@@ -106,8 +100,9 @@ struct varobj_root
      to symbols that do not exist anymore.  */
   int is_valid;
 
-  /* Language info for this variable and its children.  */
-  struct language_specific *lang;
+  /* Language-related operations for this variable and its
+     children.  */
+  const struct lang_varobj_ops *lang;
 
   /* The varobj for this root node.  */
   struct varobj *rootvar;
@@ -190,12 +185,6 @@ static void free_variable (struct varobj *var);
 
 static struct cleanup *make_cleanup_free_variable (struct varobj *var);
 
-static struct type *get_type (struct varobj *var);
-
-static struct type *get_value_type (struct varobj *var);
-
-static struct type *get_target_type (struct type *);
-
 static enum varobj_display_formats variable_default_display (struct varobj *);
 
 static void cppush (struct cpstack **pstack, char *name);
@@ -225,12 +214,6 @@ static struct value *value_of_child (struct varobj *parent, int index);
 static char *my_value_of_variable (struct varobj *var,
                                   enum varobj_display_formats format);
 
-static char *value_get_print_value (struct value *value,
-                                   enum varobj_display_formats format,
-                                   struct varobj *var);
-
-static int varobj_value_is_changeable_p (struct varobj *var);
-
 static int is_root_p (struct varobj *var);
 
 #if HAVE_PYTHON
@@ -241,190 +224,12 @@ static struct varobj *varobj_add_child (struct varobj *var,
 
 #endif /* HAVE_PYTHON */
 
-static int default_value_is_changeable_p (struct varobj *var);
-
-/* C implementation */
-
-static int c_number_of_children (struct varobj *var);
-
-static char *c_name_of_variable (struct varobj *parent);
-
-static char *c_name_of_child (struct varobj *parent, int index);
-
-static char *c_path_expr_of_child (struct varobj *child);
-
-static struct value *c_value_of_child (struct varobj *parent, int index);
-
-static struct type *c_type_of_child (struct varobj *parent, int index);
-
-static char *c_value_of_variable (struct varobj *var,
-                                 enum varobj_display_formats format);
-
-/* C++ implementation */
-
-static int cplus_number_of_children (struct varobj *var);
-
-static void cplus_class_num_children (struct type *type, int children[3]);
-
-static char *cplus_name_of_variable (struct varobj *parent);
-
-static char *cplus_name_of_child (struct varobj *parent, int index);
-
-static char *cplus_path_expr_of_child (struct varobj *child);
-
-static struct value *cplus_value_of_child (struct varobj *parent, int index);
-
-static struct type *cplus_type_of_child (struct varobj *parent, int index);
-
-static char *cplus_value_of_variable (struct varobj *var,
-                                     enum varobj_display_formats format);
-
-/* Java implementation */
-
-static int java_number_of_children (struct varobj *var);
-
-static char *java_name_of_variable (struct varobj *parent);
-
-static char *java_name_of_child (struct varobj *parent, int index);
-
-static char *java_path_expr_of_child (struct varobj *child);
-
-static struct value *java_value_of_child (struct varobj *parent, int index);
-
-static struct type *java_type_of_child (struct varobj *parent, int index);
-
-static char *java_value_of_variable (struct varobj *var,
-                                    enum varobj_display_formats format);
-
-/* Ada implementation */
-
-static int ada_number_of_children (struct varobj *var);
-
-static char *ada_name_of_variable (struct varobj *parent);
-
-static char *ada_name_of_child (struct varobj *parent, int index);
-
-static char *ada_path_expr_of_child (struct varobj *child);
-
-static struct value *ada_value_of_child (struct varobj *parent, int index);
-
-static struct type *ada_type_of_child (struct varobj *parent, int index);
-
-static char *ada_value_of_variable (struct varobj *var,
-                                   enum varobj_display_formats format);
-
-static int ada_value_is_changeable_p (struct varobj *var);
-
-static int ada_value_has_mutated (struct varobj *var, struct value *new_val,
-                                 struct type *new_type);
-
-/* The language specific vector */
-
-struct language_specific
-{
-  /* The number of children of PARENT.  */
-  int (*number_of_children) (struct varobj * parent);
-
-  /* The name (expression) of a root varobj.  */
-  char *(*name_of_variable) (struct varobj * parent);
-
-  /* The name of the INDEX'th child of PARENT.  */
-  char *(*name_of_child) (struct varobj * parent, int index);
-
-  /* Returns the rooted expression of CHILD, which is a variable
-     obtain that has some parent.  */
-  char *(*path_expr_of_child) (struct varobj * child);
-
-  /* The ``struct value *'' of the INDEX'th child of PARENT.  */
-  struct value *(*value_of_child) (struct varobj * parent, int index);
-
-  /* The type of the INDEX'th child of PARENT.  */
-  struct type *(*type_of_child) (struct varobj * parent, int index);
-
-  /* The current value of VAR.  */
-  char *(*value_of_variable) (struct varobj * var,
-                             enum varobj_display_formats format);
-
-  /* Return non-zero if changes in value of VAR must be detected and
-     reported by -var-update.  Return zero if -var-update should never
-     report changes of such values.  This makes sense for structures
-     (since the changes in children values will be reported separately),
-     or for artifical objects (like 'public' pseudo-field in C++).
-
-     Return value of 0 means that gdb need not call value_fetch_lazy
-     for the value of this variable object.  */
-  int (*value_is_changeable_p) (struct varobj *var);
-
-  /* Return nonzero if the type of VAR has mutated.
-
-     VAR's value is still the varobj's previous value, while NEW_VALUE
-     is VAR's new value and NEW_TYPE is the var's new type.  NEW_VALUE
-     may be NULL indicating that there is no value available (the varobj
-     may be out of scope, of may be the child of a null pointer, for
-     instance).  NEW_TYPE, on the other hand, must never be NULL.
-
-     This function should also be able to assume that var's number of
-     children is set (not < 0).
-
-     Languages where types do not mutate can set this to NULL.  */
-  int (*value_has_mutated) (struct varobj *var, struct value *new_value,
-                           struct type *new_type);
-};
-
 /* Array of known source language routines.  */
-static struct language_specific languages[vlang_end] = {
-  /* C */
-  {
-   c_number_of_children,
-   c_name_of_variable,
-   c_name_of_child,
-   c_path_expr_of_child,
-   c_value_of_child,
-   c_type_of_child,
-   c_value_of_variable,
-   default_value_is_changeable_p,
-   NULL /* value_has_mutated */}
-  ,
-  /* C++ */
-  {
-   cplus_number_of_children,
-   cplus_name_of_variable,
-   cplus_name_of_child,
-   cplus_path_expr_of_child,
-   cplus_value_of_child,
-   cplus_type_of_child,
-   cplus_value_of_variable,
-   default_value_is_changeable_p,
-   NULL /* value_has_mutated */}
-  ,
-  /* Java */
-  {
-   java_number_of_children,
-   java_name_of_variable,
-   java_name_of_child,
-   java_path_expr_of_child,
-   java_value_of_child,
-   java_type_of_child,
-   java_value_of_variable,
-   default_value_is_changeable_p,
-   NULL /* value_has_mutated */},
-  /* Ada */
-  {
-   ada_number_of_children,
-   ada_name_of_variable,
-   ada_name_of_child,
-   ada_path_expr_of_child,
-   ada_value_of_child,
-   ada_type_of_child,
-   ada_value_of_variable,
-   ada_value_is_changeable_p,
-   ada_value_has_mutated}
-};
-
-/* A little convenience enum for dealing with C++/Java.  */
-enum vsections
-{
-  v_public = 0, v_private, v_protected
+static const struct lang_varobj_ops *languages[vlang_end] = {
+  &c_varobj_ops,
+  &cplus_varobj_ops,
+  &java_varobj_ops,
+  &ada_varobj_ops,
 };
 
 /* Private data */
@@ -442,9 +247,6 @@ static struct varobj_root *rootlist;
 /* Pointer to the varobj hash table (built at run time).  */
 static struct vlist **varobj_table;
 
-/* Is the variable X one of our "fake" children?  */
-#define CPLUS_FAKE_CHILD(x) \
-((x) != NULL && (x)->type == NULL && (x)->value == NULL)
 \f
 
 /* API Implementation */
@@ -632,7 +434,7 @@ varobj_create (char *objname,
 
       /* Set language info */
       lang = variable_language (var);
-      var->root->lang = &languages[lang];
+      var->root->lang = languages[lang];
 
       install_new_value (var, value, 1 /* Initial assignment */);
 
@@ -812,7 +614,8 @@ varobj_set_display_format (struct varobj *var,
       && var->value && !value_lazy (var->value))
     {
       xfree (var->print_value);
-      var->print_value = value_get_print_value (var->value, var->format, var);
+      var->print_value = varobj_value_get_print_value (var->value,
+                                                      var->format, var);
     }
 
   return var->format;
@@ -894,8 +697,8 @@ varobj_get_frozen (struct varobj *var)
    of FROM and TO -- if either is negative, the entire range is
    used.  */
 
-static void
-restrict_range (VEC (varobj_p) *children, int *from, int *to)
+void
+varobj_restrict_range (VEC (varobj_p) *children, int *from, int *to)
 {
   if (*from < 0 || *to < 0)
     {
@@ -1202,7 +1005,7 @@ varobj_list_children (struct varobj *var, int *from, int *to)
         varobj twice is not something a sane frontend would do.  */
       update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL,
                                      &children_changed, 0, 0, *to);
-      restrict_range (var->children, from, to);
+      varobj_restrict_range (var->children, from, to);
       return var->children;
     }
 
@@ -1233,7 +1036,7 @@ varobj_list_children (struct varobj *var, int *from, int *to)
        }
     }
 
-  restrict_range (var->children, from, to);
+  varobj_restrict_range (var->children, from, to);
   return var->children;
 }
 
@@ -1287,7 +1090,7 @@ is_path_expr_parent (struct varobj *var)
   if (CPLUS_FAKE_CHILD (var))
     return 0;
 
-  type = get_value_type (var);
+  type = varobj_get_value_type (var);
 
   /* Anonymous unions and structs are also not path_expr parents.  */
   return !((TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -1297,8 +1100,8 @@ is_path_expr_parent (struct varobj *var)
 
 /* Return the path expression parent for VAR.  */
 
-static struct varobj *
-get_path_expr_parent (struct varobj *var)
+struct varobj *
+varobj_get_path_expr_parent (struct varobj *var)
 {
   struct varobj *parent = var;
 
@@ -1692,7 +1495,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      should not be fetched.  */
   if (value != NULL && !value_lazy (value)
       && var->dynamic->pretty_printer == NULL)
-    print_value = value_get_print_value (value, var->format, var);
+    print_value = varobj_value_get_print_value (value, var->format, var);
 
   /* If the type is changeable, compare the old and the new values.
      If this is the initial assignment, we don't have any old value
@@ -1766,7 +1569,8 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   if (var->dynamic->pretty_printer != NULL)
     {
       xfree (print_value);
-      print_value = value_get_print_value (var->value, var->format, var);
+      print_value = varobj_value_get_print_value (var->value, var->format,
+                                                 var);
       if ((var->print_value == NULL && print_value != NULL)
          || (var->print_value != NULL && print_value == NULL)
          || (var->print_value != NULL && print_value != NULL
@@ -2313,20 +2117,6 @@ create_child (struct varobj *parent, int index, char *name)
                                  value_of_child (parent, index));
 }
 
-/* Does CHILD represent a child with no name?  This happens when
-   the child is an anonmous struct or union and it has no field name
-   in its parent variable.
-
-   This has already been determined by *_describe_child. The easiest
-   thing to do is to compare the child's name with ANONYMOUS_*_NAME.  */
-
-static int
-is_anonymous_child (struct varobj *child)
-{
-  return (strcmp (child->name, ANONYMOUS_STRUCT_NAME) == 0
-         || strcmp (child->name, ANONYMOUS_UNION_NAME) == 0);
-}
-
 static struct varobj *
 create_child_with_value (struct varobj *parent, int index, char *name,
                         struct value *value)
@@ -2342,7 +2132,7 @@ create_child_with_value (struct varobj *parent, int index, char *name,
   child->parent = parent;
   child->root = parent->root;
 
-  if (is_anonymous_child (child))
+  if (varobj_is_anonymous_child (child))
     childs_name = xstrprintf ("%s.%d_anonymous", parent->obj_name, index);
   else
     childs_name = xstrprintf ("%s.%s", parent->obj_name, name);
@@ -2469,23 +2259,6 @@ make_cleanup_free_variable (struct varobj *var)
   return make_cleanup (do_free_variable_cleanup, var);
 }
 
-/* This returns the type of the variable.  It also skips past typedefs
-   to return the real type of the variable.
-
-   NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file
-   except within get_target_type and get_type.  */
-static struct type *
-get_type (struct varobj *var)
-{
-  struct type *type;
-
-  type = var->type;
-  if (type != NULL)
-    type = check_typedef (type);
-
-  return type;
-}
-
 /* Return the type of the value that's stored in VAR,
    or that would have being stored there if the
    value were accessible.
@@ -2497,8 +2270,8 @@ get_type (struct varobj *var)
    the values and for comparing previous and new values.
 
    For example, top-level references are always stripped.  */
-static struct type *
-get_value_type (struct varobj *var)
+struct type *
+varobj_get_value_type (struct varobj *var)
 {
   struct type *type;
 
@@ -2517,24 +2290,6 @@ get_value_type (struct varobj *var)
   return type;
 }
 
-/* This returns the target type (or NULL) of TYPE, also skipping
-   past typedefs, just like get_type ().
-
-   NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file
-   except within get_target_type and get_type.  */
-static struct type *
-get_target_type (struct type *type)
-{
-  if (type != NULL)
-    {
-      type = TYPE_TARGET_TYPE (type);
-      if (type != NULL)
-       type = check_typedef (type);
-    }
-
-  return type;
-}
-
 /* What is the default display for this variable? We assume that
    everything is "natural".  Any exceptions?  */
 static enum varobj_display_formats
@@ -2828,16 +2583,26 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
   if (var->root->is_valid)
     {
       if (var->dynamic->pretty_printer != NULL)
-       return value_get_print_value (var->value, var->format, var);
+       return varobj_value_get_print_value (var->value, var->format, var);
       return (*var->root->lang->value_of_variable) (var, format);
     }
   else
     return NULL;
 }
 
-static char *
-value_get_print_value (struct value *value, enum varobj_display_formats format,
-                      struct varobj *var)
+void
+varobj_formatted_print_options (struct value_print_options *opts,
+                               enum varobj_display_formats format)
+{
+  get_formatted_print_options (opts, format_code[(int) format]);
+  opts->deref_ref = 0;
+  opts->raw = 1;
+}
+
+char *
+varobj_value_get_print_value (struct value *value,
+                             enum varobj_display_formats format,
+                             struct varobj *var)
 {
   struct ui_file *stb;
   struct cleanup *old_chain;
@@ -2948,9 +2713,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
     }
 #endif
 
-  get_formatted_print_options (&opts, format_code[(int) format]);
-  opts.deref_ref = 0;
-  opts.raw = 1;
+  varobj_formatted_print_options (&opts, format);
 
   /* If the THEVALUE has contents, it is a regular string.  */
   if (thevalue)
@@ -2977,7 +2740,7 @@ varobj_editable_p (struct varobj *var)
   if (!(var->root->is_valid && var->value && VALUE_LVAL (var->value)))
     return 0;
 
-  type = get_value_type (var);
+  type = varobj_get_value_type (var);
 
   switch (TYPE_CODE (type))
     {
@@ -2997,7 +2760,7 @@ varobj_editable_p (struct varobj *var)
 
 /* Call VAR's value_is_changeable_p language-specific callback.  */
 
-static int
+int
 varobj_value_is_changeable_p (struct varobj *var)
 {
   return var->root->lang->value_is_changeable_p (var);
@@ -3012,95 +2775,11 @@ varobj_floating_p (struct varobj *var)
   return var->root->floating;
 }
 
-/* Given the value and the type of a variable object,
-   adjust the value and type to those necessary
-   for getting children of the variable object.
-   This includes dereferencing top-level references
-   to all types and dereferencing pointers to
-   structures.
-
-   If LOOKUP_ACTUAL_TYPE is set the enclosing type of the
-   value will be fetched and if it differs from static type
-   the value will be casted to it.
-
-   Both TYPE and *TYPE should be non-null.  VALUE
-   can be null if we want to only translate type.
-   *VALUE can be null as well -- if the parent
-   value is not known.
-
-   If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1
-   depending on whether pointer was dereferenced
-   in this function.  */
-static void
-adjust_value_for_child_access (struct value **value,
-                                 struct type **type,
-                                 int *was_ptr,
-                                 int lookup_actual_type)
-{
-  gdb_assert (type && *type);
-
-  if (was_ptr)
-    *was_ptr = 0;
-
-  *type = check_typedef (*type);
-  
-  /* The type of value stored in varobj, that is passed
-     to us, is already supposed to be
-     reference-stripped.  */
-
-  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
-
-  /* Pointers to structures are treated just like
-     structures when accessing children.  Don't
-     dererences pointers to other types.  */
-  if (TYPE_CODE (*type) == TYPE_CODE_PTR)
-    {
-      struct type *target_type = get_target_type (*type);
-      if (TYPE_CODE (target_type) == TYPE_CODE_STRUCT
-         || TYPE_CODE (target_type) == TYPE_CODE_UNION)
-       {
-         if (value && *value)
-           {
-             volatile struct gdb_exception except;
-
-             TRY_CATCH (except, RETURN_MASK_ERROR)
-               {
-                 *value = value_ind (*value);
-               }
-
-             if (except.reason < 0)
-               *value = NULL;
-           }
-         *type = target_type;
-         if (was_ptr)
-           *was_ptr = 1;
-       }
-    }
-
-  /* The 'get_target_type' function calls check_typedef on
-     result, so we can immediately check type code.  No
-     need to call check_typedef here.  */
-
-  /* Access a real type of the value (if necessary and possible).  */
-  if (value && *value && lookup_actual_type)
-    {
-      struct type *enclosing_type;
-      int real_type_found = 0;
-
-      enclosing_type = value_actual_type (*value, 1, &real_type_found);
-      if (real_type_found)
-        {
-          *type = enclosing_type;
-          *value = value_cast (enclosing_type, *value);
-        }
-    }
-}
-
 /* Implement the "value_is_changeable_p" varobj callback for most
    languages.  */
 
-static int
-default_value_is_changeable_p (struct varobj *var)
+int
+varobj_default_value_is_changeable_p (struct varobj *var)
 {
   int r;
   struct type *type;
@@ -3108,7 +2787,7 @@ default_value_is_changeable_p (struct varobj *var)
   if (CPLUS_FAKE_CHILD (var))
     return 0;
 
-  type = get_value_type (var);
+  type = varobj_get_value_type (var);
 
   switch (TYPE_CODE (type))
     {
@@ -3125,925 +2804,6 @@ default_value_is_changeable_p (struct varobj *var)
   return r;
 }
 
-/* C */
-
-static int
-c_number_of_children (struct varobj *var)
-{
-  struct type *type = get_value_type (var);
-  int children = 0;
-  struct type *target;
-
-  adjust_value_for_child_access (NULL, &type, NULL, 0);
-  target = get_target_type (type);
-
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_ARRAY:
-      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0
-         && !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
-       children = TYPE_LENGTH (type) / TYPE_LENGTH (target);
-      else
-       /* If we don't know how many elements there are, don't display
-          any.  */
-       children = 0;
-      break;
-
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      children = TYPE_NFIELDS (type);
-      break;
-
-    case TYPE_CODE_PTR:
-      /* The type here is a pointer to non-struct.  Typically, pointers
-        have one child, except for function ptrs, which have no children,
-        and except for void*, as we don't know what to show.
-
-         We can show char* so we allow it to be dereferenced.  If you decide
-         to test for it, please mind that a little magic is necessary to
-         properly identify it: char* has TYPE_CODE == TYPE_CODE_INT and 
-         TYPE_NAME == "char".  */
-      if (TYPE_CODE (target) == TYPE_CODE_FUNC
-         || TYPE_CODE (target) == TYPE_CODE_VOID)
-       children = 0;
-      else
-       children = 1;
-      break;
-
-    default:
-      /* Other types have no children.  */
-      break;
-    }
-
-  return children;
-}
-
-static char *
-c_name_of_variable (struct varobj *parent)
-{
-  return xstrdup (parent->name);
-}
-
-/* Return the value of element TYPE_INDEX of a structure
-   value VALUE.  VALUE's type should be a structure,
-   or union, or a typedef to struct/union.
-
-   Returns NULL if getting the value fails.  Never throws.  */
-static struct value *
-value_struct_element_index (struct value *value, int type_index)
-{
-  struct value *result = NULL;
-  volatile struct gdb_exception e;
-  struct type *type = value_type (value);
-
-  type = check_typedef (type);
-
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
-             || TYPE_CODE (type) == TYPE_CODE_UNION);
-
-  TRY_CATCH (e, RETURN_MASK_ERROR)
-    {
-      if (field_is_static (&TYPE_FIELD (type, type_index)))
-       result = value_static_field (type, type_index);
-      else
-       result = value_primitive_field (value, 0, type_index, type);
-    }
-  if (e.reason < 0)
-    {
-      return NULL;
-    }
-  else
-    {
-      return result;
-    }
-}
-
-/* Obtain the information about child INDEX of the variable
-   object PARENT.
-   If CNAME is not null, sets *CNAME to the name of the child relative
-   to the parent.
-   If CVALUE is not null, sets *CVALUE to the value of the child.
-   If CTYPE is not null, sets *CTYPE to the type of the child.
-
-   If any of CNAME, CVALUE, or CTYPE is not null, but the corresponding
-   information cannot be determined, set *CNAME, *CVALUE, or *CTYPE
-   to NULL.  */
-static void 
-c_describe_child (struct varobj *parent, int index,
-                 char **cname, struct value **cvalue, struct type **ctype,
-                 char **cfull_expression)
-{
-  struct value *value = parent->value;
-  struct type *type = get_value_type (parent);
-  char *parent_expression = NULL;
-  int was_ptr;
-  volatile struct gdb_exception except;
-
-  if (cname)
-    *cname = NULL;
-  if (cvalue)
-    *cvalue = NULL;
-  if (ctype)
-    *ctype = NULL;
-  if (cfull_expression)
-    {
-      *cfull_expression = NULL;
-      parent_expression = varobj_get_path_expr (get_path_expr_parent (parent));
-    }
-  adjust_value_for_child_access (&value, &type, &was_ptr, 0);
-      
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_ARRAY:
-      if (cname)
-       *cname
-         = xstrdup (int_string (index 
-                                + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
-                                10, 1, 0, 0));
-
-      if (cvalue && value)
-       {
-         int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
-
-         TRY_CATCH (except, RETURN_MASK_ERROR)
-           {
-             *cvalue = value_subscript (value, real_index);
-           }
-       }
-
-      if (ctype)
-       *ctype = get_target_type (type);
-
-      if (cfull_expression)
-       *cfull_expression = 
-         xstrprintf ("(%s)[%s]", parent_expression, 
-                     int_string (index
-                                 + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
-                                 10, 1, 0, 0));
-
-
-      break;
-
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      {
-       const char *field_name;
-
-       /* If the type is anonymous and the field has no name,
-          set an appropriate name.  */
-       field_name = TYPE_FIELD_NAME (type, index);
-       if (field_name == NULL || *field_name == '\0')
-         {
-           if (cname)
-             {
-               if (TYPE_CODE (TYPE_FIELD_TYPE (type, index))
-                   == TYPE_CODE_STRUCT)
-                 *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
-               else
-                 *cname = xstrdup (ANONYMOUS_UNION_NAME);
-             }
-
-           if (cfull_expression)
-             *cfull_expression = xstrdup ("");
-         }
-       else
-         {
-           if (cname)
-             *cname = xstrdup (field_name);
-
-           if (cfull_expression)
-             {
-               char *join = was_ptr ? "->" : ".";
-
-               *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression,
-                                               join, field_name);
-             }
-         }
-
-       if (cvalue && value)
-         {
-           /* For C, varobj index is the same as type index.  */
-           *cvalue = value_struct_element_index (value, index);
-         }
-
-       if (ctype)
-         *ctype = TYPE_FIELD_TYPE (type, index);
-      }
-      break;
-
-    case TYPE_CODE_PTR:
-      if (cname)
-       *cname = xstrprintf ("*%s", parent->name);
-
-      if (cvalue && value)
-       {
-         TRY_CATCH (except, RETURN_MASK_ERROR)
-           {
-             *cvalue = value_ind (value);
-           }
-
-         if (except.reason < 0)
-           *cvalue = NULL;
-       }
-
-      /* Don't use get_target_type because it calls
-        check_typedef and here, we want to show the true
-        declared type of the variable.  */
-      if (ctype)
-       *ctype = TYPE_TARGET_TYPE (type);
-
-      if (cfull_expression)
-       *cfull_expression = xstrprintf ("*(%s)", parent_expression);
-      
-      break;
-
-    default:
-      /* This should not happen.  */
-      if (cname)
-       *cname = xstrdup ("???");
-      if (cfull_expression)
-       *cfull_expression = xstrdup ("???");
-      /* Don't set value and type, we don't know then.  */
-    }
-}
-
-static char *
-c_name_of_child (struct varobj *parent, int index)
-{
-  char *name;
-
-  c_describe_child (parent, index, &name, NULL, NULL, NULL);
-  return name;
-}
-
-static char *
-c_path_expr_of_child (struct varobj *child)
-{
-  c_describe_child (child->parent, child->index, NULL, NULL, NULL, 
-                   &child->path_expr);
-  return child->path_expr;
-}
-
-static struct value *
-c_value_of_child (struct varobj *parent, int index)
-{
-  struct value *value = NULL;
-
-  c_describe_child (parent, index, NULL, &value, NULL, NULL);
-  return value;
-}
-
-static struct type *
-c_type_of_child (struct varobj *parent, int index)
-{
-  struct type *type = NULL;
-
-  c_describe_child (parent, index, NULL, NULL, &type, NULL);
-  return type;
-}
-
-static char *
-c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
-{
-  /* BOGUS: if val_print sees a struct/class, or a reference to one,
-     it will print out its children instead of "{...}".  So we need to
-     catch that case explicitly.  */
-  struct type *type = get_type (var);
-
-  /* Strip top-level references.  */
-  while (TYPE_CODE (type) == TYPE_CODE_REF)
-    type = check_typedef (TYPE_TARGET_TYPE (type));
-
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      return xstrdup ("{...}");
-      /* break; */
-
-    case TYPE_CODE_ARRAY:
-      {
-       char *number;
-
-       number = xstrprintf ("[%d]", var->num_children);
-       return (number);
-      }
-      /* break; */
-
-    default:
-      {
-       if (var->value == NULL)
-         {
-           /* This can happen if we attempt to get the value of a struct
-              member when the parent is an invalid pointer.  This is an
-              error condition, so we should tell the caller.  */
-           return NULL;
-         }
-       else
-         {
-           if (var->not_fetched && value_lazy (var->value))
-             /* Frozen variable and no value yet.  We don't
-                implicitly fetch the value.  MI response will
-                use empty string for the value, which is OK.  */
-             return NULL;
-
-           gdb_assert (varobj_value_is_changeable_p (var));
-           gdb_assert (!value_lazy (var->value));
-           
-           /* If the specified format is the current one,
-              we can reuse print_value.  */
-           if (format == var->format)
-             return xstrdup (var->print_value);
-           else
-             return value_get_print_value (var->value, format, var);
-         }
-      }
-    }
-}
-\f
-
-/* C++ */
-
-static int
-cplus_number_of_children (struct varobj *var)
-{
-  struct value *value = NULL;
-  struct type *type;
-  int children, dont_know;
-  int lookup_actual_type = 0;
-  struct value_print_options opts;
-
-  dont_know = 1;
-  children = 0;
-
-  get_user_print_options (&opts);
-
-  if (!CPLUS_FAKE_CHILD (var))
-    {
-      type = get_value_type (var);
-
-      /* It is necessary to access a real type (via RTTI).  */
-      if (opts.objectprint)
-        {
-          value = var->value;
-          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
-                               || TYPE_CODE (var->type) == TYPE_CODE_PTR);
-        }
-      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
-
-      if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
-         ((TYPE_CODE (type)) == TYPE_CODE_UNION))
-       {
-         int kids[3];
-
-         cplus_class_num_children (type, kids);
-         if (kids[v_public] != 0)
-           children++;
-         if (kids[v_private] != 0)
-           children++;
-         if (kids[v_protected] != 0)
-           children++;
-
-         /* Add any baseclasses.  */
-         children += TYPE_N_BASECLASSES (type);
-         dont_know = 0;
-
-         /* FIXME: save children in var.  */
-       }
-    }
-  else
-    {
-      int kids[3];
-
-      type = get_value_type (var->parent);
-
-      /* It is necessary to access a real type (via RTTI).  */
-      if (opts.objectprint)
-        {
-         struct varobj *parent = var->parent;
-
-         value = parent->value;
-         lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
-                               || TYPE_CODE (parent->type) == TYPE_CODE_PTR);
-        }
-      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
-
-      cplus_class_num_children (type, kids);
-      if (strcmp (var->name, "public") == 0)
-       children = kids[v_public];
-      else if (strcmp (var->name, "private") == 0)
-       children = kids[v_private];
-      else
-       children = kids[v_protected];
-      dont_know = 0;
-    }
-
-  if (dont_know)
-    children = c_number_of_children (var);
-
-  return children;
-}
-
-/* Compute # of public, private, and protected variables in this class.
-   That means we need to descend into all baseclasses and find out
-   how many are there, too.  */
-static void
-cplus_class_num_children (struct type *type, int children[3])
-{
-  int i, vptr_fieldno;
-  struct type *basetype = NULL;
-
-  children[v_public] = 0;
-  children[v_private] = 0;
-  children[v_protected] = 0;
-
-  vptr_fieldno = get_vptr_fieldno (type, &basetype);
-  for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++)
-    {
-      /* If we have a virtual table pointer, omit it.  Even if virtual
-        table pointers are not specifically marked in the debug info,
-        they should be artificial.  */
-      if ((type == basetype && i == vptr_fieldno)
-         || TYPE_FIELD_ARTIFICIAL (type, i))
-       continue;
-
-      if (TYPE_FIELD_PROTECTED (type, i))
-       children[v_protected]++;
-      else if (TYPE_FIELD_PRIVATE (type, i))
-       children[v_private]++;
-      else
-       children[v_public]++;
-    }
-}
-
-static char *
-cplus_name_of_variable (struct varobj *parent)
-{
-  return c_name_of_variable (parent);
-}
-
-enum accessibility { private_field, protected_field, public_field };
-
-/* Check if field INDEX of TYPE has the specified accessibility.
-   Return 0 if so and 1 otherwise.  */
-static int 
-match_accessibility (struct type *type, int index, enum accessibility acc)
-{
-  if (acc == private_field && TYPE_FIELD_PRIVATE (type, index))
-    return 1;
-  else if (acc == protected_field && TYPE_FIELD_PROTECTED (type, index))
-    return 1;
-  else if (acc == public_field && !TYPE_FIELD_PRIVATE (type, index)
-          && !TYPE_FIELD_PROTECTED (type, index))
-    return 1;
-  else
-    return 0;
-}
-
-static void
-cplus_describe_child (struct varobj *parent, int index,
-                     char **cname, struct value **cvalue, struct type **ctype,
-                     char **cfull_expression)
-{
-  struct value *value;
-  struct type *type;
-  int was_ptr;
-  int lookup_actual_type = 0;
-  char *parent_expression = NULL;
-  struct varobj *var;
-  struct value_print_options opts;
-
-  if (cname)
-    *cname = NULL;
-  if (cvalue)
-    *cvalue = NULL;
-  if (ctype)
-    *ctype = NULL;
-  if (cfull_expression)
-    *cfull_expression = NULL;
-
-  get_user_print_options (&opts);
-
-  var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
-  if (opts.objectprint)
-    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
-                         || TYPE_CODE (var->type) == TYPE_CODE_PTR);
-  value = var->value;
-  type = get_value_type (var);
-  if (cfull_expression)
-    parent_expression = varobj_get_path_expr (get_path_expr_parent (var));
-
-  adjust_value_for_child_access (&value, &type, &was_ptr, lookup_actual_type);
-
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION)
-    {
-      char *join = was_ptr ? "->" : ".";
-
-      if (CPLUS_FAKE_CHILD (parent))
-       {
-         /* The fields of the class type are ordered as they
-            appear in the class.  We are given an index for a
-            particular access control type ("public","protected",
-            or "private").  We must skip over fields that don't
-            have the access control we are looking for to properly
-            find the indexed field.  */
-         int type_index = TYPE_N_BASECLASSES (type);
-         enum accessibility acc = public_field;
-         int vptr_fieldno;
-         struct type *basetype = NULL;
-         const char *field_name;
-
-         vptr_fieldno = get_vptr_fieldno (type, &basetype);
-         if (strcmp (parent->name, "private") == 0)
-           acc = private_field;
-         else if (strcmp (parent->name, "protected") == 0)
-           acc = protected_field;
-
-         while (index >= 0)
-           {
-             if ((type == basetype && type_index == vptr_fieldno)
-                 || TYPE_FIELD_ARTIFICIAL (type, type_index))
-               ; /* ignore vptr */
-             else if (match_accessibility (type, type_index, acc))
-                   --index;
-                 ++type_index;
-           }
-         --type_index;
-
-         /* If the type is anonymous and the field has no name,
-            set an appopriate name.  */
-         field_name = TYPE_FIELD_NAME (type, type_index);
-         if (field_name == NULL || *field_name == '\0')
-           {
-             if (cname)
-               {
-                 if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
-                     == TYPE_CODE_STRUCT)
-                   *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
-                 else if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
-                          == TYPE_CODE_UNION)
-                   *cname = xstrdup (ANONYMOUS_UNION_NAME);
-               }
-
-             if (cfull_expression)
-               *cfull_expression = xstrdup ("");
-           }
-         else
-           {
-             if (cname)
-               *cname = xstrdup (TYPE_FIELD_NAME (type, type_index));
-
-             if (cfull_expression)
-               *cfull_expression
-                 = xstrprintf ("((%s)%s%s)", parent_expression, join,
-                               field_name);
-           }
-
-         if (cvalue && value)
-           *cvalue = value_struct_element_index (value, type_index);
-
-         if (ctype)
-           *ctype = TYPE_FIELD_TYPE (type, type_index);
-       }
-      else if (index < TYPE_N_BASECLASSES (type))
-       {
-         /* This is a baseclass.  */
-         if (cname)
-           *cname = xstrdup (TYPE_FIELD_NAME (type, index));
-
-         if (cvalue && value)
-           *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
-
-         if (ctype)
-           {
-             *ctype = TYPE_FIELD_TYPE (type, index);
-           }
-
-         if (cfull_expression)
-           {
-             char *ptr = was_ptr ? "*" : "";
-
-             /* Cast the parent to the base' type.  Note that in gdb,
-                expression like 
-                        (Base1)d
-                will create an lvalue, for all appearences, so we don't
-                need to use more fancy:
-                        *(Base1*)(&d)
-                construct.
-
-                When we are in the scope of the base class or of one
-                of its children, the type field name will be interpreted
-                as a constructor, if it exists.  Therefore, we must
-                indicate that the name is a class name by using the
-                'class' keyword.  See PR mi/11912  */
-             *cfull_expression = xstrprintf ("(%s(class %s%s) %s)", 
-                                             ptr, 
-                                             TYPE_FIELD_NAME (type, index),
-                                             ptr,
-                                             parent_expression);
-           }
-       }
-      else
-       {
-         char *access = NULL;
-         int children[3];
-
-         cplus_class_num_children (type, children);
-
-         /* Everything beyond the baseclasses can
-            only be "public", "private", or "protected"
-
-            The special "fake" children are always output by varobj in
-            this order.  So if INDEX == 2, it MUST be "protected".  */
-         index -= TYPE_N_BASECLASSES (type);
-         switch (index)
-           {
-           case 0:
-             if (children[v_public] > 0)
-               access = "public";
-             else if (children[v_private] > 0)
-               access = "private";
-             else 
-               access = "protected";
-             break;
-           case 1:
-             if (children[v_public] > 0)
-               {
-                 if (children[v_private] > 0)
-                   access = "private";
-                 else
-                   access = "protected";
-               }
-             else if (children[v_private] > 0)
-               access = "protected";
-             break;
-           case 2:
-             /* Must be protected.  */
-             access = "protected";
-             break;
-           default:
-             /* error!  */
-             break;
-           }
-
-         gdb_assert (access);
-         if (cname)
-           *cname = xstrdup (access);
-
-         /* Value and type and full expression are null here.  */
-       }
-    }
-  else
-    {
-      c_describe_child (parent, index, cname, cvalue, ctype, cfull_expression);
-    }  
-}
-
-static char *
-cplus_name_of_child (struct varobj *parent, int index)
-{
-  char *name = NULL;
-
-  cplus_describe_child (parent, index, &name, NULL, NULL, NULL);
-  return name;
-}
-
-static char *
-cplus_path_expr_of_child (struct varobj *child)
-{
-  cplus_describe_child (child->parent, child->index, NULL, NULL, NULL, 
-                       &child->path_expr);
-  return child->path_expr;
-}
-
-static struct value *
-cplus_value_of_child (struct varobj *parent, int index)
-{
-  struct value *value = NULL;
-
-  cplus_describe_child (parent, index, NULL, &value, NULL, NULL);
-  return value;
-}
-
-static struct type *
-cplus_type_of_child (struct varobj *parent, int index)
-{
-  struct type *type = NULL;
-
-  cplus_describe_child (parent, index, NULL, NULL, &type, NULL);
-  return type;
-}
-
-static char *
-cplus_value_of_variable (struct varobj *var, 
-                        enum varobj_display_formats format)
-{
-
-  /* If we have one of our special types, don't print out
-     any value.  */
-  if (CPLUS_FAKE_CHILD (var))
-    return xstrdup ("");
-
-  return c_value_of_variable (var, format);
-}
-\f
-/* Java */
-
-static int
-java_number_of_children (struct varobj *var)
-{
-  return cplus_number_of_children (var);
-}
-
-static char *
-java_name_of_variable (struct varobj *parent)
-{
-  char *p, *name;
-
-  name = cplus_name_of_variable (parent);
-  /* If  the name has "-" in it, it is because we
-     needed to escape periods in the name...  */
-  p = name;
-
-  while (*p != '\000')
-    {
-      if (*p == '-')
-       *p = '.';
-      p++;
-    }
-
-  return name;
-}
-
-static char *
-java_name_of_child (struct varobj *parent, int index)
-{
-  char *name, *p;
-
-  name = cplus_name_of_child (parent, index);
-  /* Escape any periods in the name...  */
-  p = name;
-
-  while (*p != '\000')
-    {
-      if (*p == '.')
-       *p = '-';
-      p++;
-    }
-
-  return name;
-}
-
-static char *
-java_path_expr_of_child (struct varobj *child)
-{
-  return NULL;
-}
-
-static struct value *
-java_value_of_child (struct varobj *parent, int index)
-{
-  return cplus_value_of_child (parent, index);
-}
-
-static struct type *
-java_type_of_child (struct varobj *parent, int index)
-{
-  return cplus_type_of_child (parent, index);
-}
-
-static char *
-java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
-{
-  return cplus_value_of_variable (var, format);
-}
-
-/* Ada specific callbacks for VAROBJs.  */
-
-static int
-ada_number_of_children (struct varobj *var)
-{
-  return ada_varobj_get_number_of_children (var->value, var->type);
-}
-
-static char *
-ada_name_of_variable (struct varobj *parent)
-{
-  return c_name_of_variable (parent);
-}
-
-static char *
-ada_name_of_child (struct varobj *parent, int index)
-{
-  return ada_varobj_get_name_of_child (parent->value, parent->type,
-                                      parent->name, index);
-}
-
-static char*
-ada_path_expr_of_child (struct varobj *child)
-{
-  struct varobj *parent = child->parent;
-  const char *parent_path_expr = varobj_get_path_expr (parent);
-
-  return ada_varobj_get_path_expr_of_child (parent->value,
-                                           parent->type,
-                                           parent->name,
-                                           parent_path_expr,
-                                           child->index);
-}
-
-static struct value *
-ada_value_of_child (struct varobj *parent, int index)
-{
-  return ada_varobj_get_value_of_child (parent->value, parent->type,
-                                       parent->name, index);
-}
-
-static struct type *
-ada_type_of_child (struct varobj *parent, int index)
-{
-  return ada_varobj_get_type_of_child (parent->value, parent->type,
-                                      index);
-}
-
-static char *
-ada_value_of_variable (struct varobj *var, enum varobj_display_formats format)
-{
-  struct value_print_options opts;
-
-  get_formatted_print_options (&opts, format_code[(int) format]);
-  opts.deref_ref = 0;
-  opts.raw = 1;
-
-  return ada_varobj_get_value_of_variable (var->value, var->type, &opts);
-}
-
-/* Implement the "value_is_changeable_p" routine for Ada.  */
-
-static int
-ada_value_is_changeable_p (struct varobj *var)
-{
-  struct type *type = var->value ? value_type (var->value) : var->type;
-
-  if (ada_is_array_descriptor_type (type)
-      && TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
-    {
-      /* This is in reality a pointer to an unconstrained array.
-        its value is changeable.  */
-      return 1;
-    }
-
-  if (ada_is_string_type (type))
-    {
-      /* We display the contents of the string in the array's
-        "value" field.  The contents can change, so consider
-        that the array is changeable.  */
-      return 1;
-    }
-
-  return default_value_is_changeable_p (var);
-}
-
-/* Implement the "value_has_mutated" routine for Ada.  */
-
-static int
-ada_value_has_mutated (struct varobj *var, struct value *new_val,
-                      struct type *new_type)
-{
-  int i;
-  int from = -1;
-  int to = -1;
-
-  /* If the number of fields have changed, then for sure the type
-     has mutated.  */
-  if (ada_varobj_get_number_of_children (new_val, new_type)
-      != var->num_children)
-    return 1;
-
-  /* If the number of fields have remained the same, then we need
-     to check the name of each field.  If they remain the same,
-     then chances are the type hasn't mutated.  This is technically
-     an incomplete test, as the child's type might have changed
-     despite the fact that the name remains the same.  But we'll
-     handle this situation by saying that the child has mutated,
-     not this value.
-
-     If only part (or none!) of the children have been fetched,
-     then only check the ones we fetched.  It does not matter
-     to the frontend whether a child that it has not fetched yet
-     has mutated or not. So just assume it hasn't.  */
-
-  restrict_range (var->children, &from, &to);
-  for (i = from; i < to; i++)
-    if (strcmp (ada_varobj_get_name_of_child (new_val, new_type,
-                                             var->name, i),
-               VEC_index (varobj_p, var->children, i)->name) != 0)
-      return 1;
-
-  return 0;
-}
-
 /* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
    with an arbitrary caller supplied DATA pointer.  */
 
index 4a4dd751c1dc537601fd46db08e69f16e6b926f9..e32c6ef1f75d90a75b73a43ef12e7cb79b1170dd 100644 (file)
@@ -168,6 +168,68 @@ struct varobj
   struct varobj_dynamic *dynamic;
 };
 
+/* Is the variable X one of our "fake" children?  */
+#define CPLUS_FAKE_CHILD(x) \
+((x) != NULL && (x)->type == NULL && (x)->value == NULL)
+
+/* The language specific vector */
+
+struct lang_varobj_ops
+{
+  /* The number of children of PARENT.  */
+  int (*number_of_children) (struct varobj * parent);
+
+  /* The name (expression) of a root varobj.  */
+  char *(*name_of_variable) (struct varobj * parent);
+
+  /* The name of the INDEX'th child of PARENT.  */
+  char *(*name_of_child) (struct varobj * parent, int index);
+
+  /* Returns the rooted expression of CHILD, which is a variable
+     obtain that has some parent.  */
+  char *(*path_expr_of_child) (struct varobj * child);
+
+  /* The ``struct value *'' of the INDEX'th child of PARENT.  */
+  struct value *(*value_of_child) (struct varobj * parent, int index);
+
+  /* The type of the INDEX'th child of PARENT.  */
+  struct type *(*type_of_child) (struct varobj * parent, int index);
+
+  /* The current value of VAR.  */
+  char *(*value_of_variable) (struct varobj * var,
+                             enum varobj_display_formats format);
+
+  /* Return non-zero if changes in value of VAR must be detected and
+     reported by -var-update.  Return zero if -var-update should never
+     report changes of such values.  This makes sense for structures
+     (since the changes in children values will be reported separately),
+     or for artifical objects (like 'public' pseudo-field in C++).
+
+     Return value of 0 means that gdb need not call value_fetch_lazy
+     for the value of this variable object.  */
+  int (*value_is_changeable_p) (struct varobj *var);
+
+  /* Return nonzero if the type of VAR has mutated.
+
+     VAR's value is still the varobj's previous value, while NEW_VALUE
+     is VAR's new value and NEW_TYPE is the var's new type.  NEW_VALUE
+     may be NULL indicating that there is no value available (the varobj
+     may be out of scope, of may be the child of a null pointer, for
+     instance).  NEW_TYPE, on the other hand, must never be NULL.
+
+     This function should also be able to assume that var's number of
+     children is set (not < 0).
+
+     Languages where types do not mutate can set this to NULL.  */
+  int (*value_has_mutated) (struct varobj *var, struct value *new_value,
+                           struct type *new_type);
+};
+
+const struct lang_varobj_ops c_varobj_ops;
+const struct lang_varobj_ops cplus_varobj_ops;
+const struct lang_varobj_ops java_varobj_ops;
+const struct lang_varobj_ops ada_varobj_ops;
+
 /* API functions */
 
 extern struct varobj *varobj_create (char *objname,
@@ -255,4 +317,22 @@ extern int varobj_has_more (struct varobj *var, int to);
 
 extern int varobj_pretty_printed_p (struct varobj *var);
 
+extern int varobj_default_value_is_changeable_p (struct varobj *var);
+extern int varobj_value_is_changeable_p (struct varobj *var);
+
+extern struct type *varobj_get_value_type (struct varobj *var);
+
+extern int varobj_is_anonymous_child (struct varobj *child);
+
+extern struct varobj *varobj_get_path_expr_parent (struct varobj *var);
+
+extern char *varobj_value_get_print_value (struct value *value,
+                                          enum varobj_display_formats format,
+                                          struct varobj *var);
+
+extern void varobj_formatted_print_options (struct value_print_options *opts,
+                                           enum varobj_display_formats format);
+
+extern void varobj_restrict_range (VEC (varobj_p) *children, int *from,
+                                  int *to);
 #endif /* VAROBJ_H */