Re: [PATCH 6/7] Move language stuff out of varobj.c

Yao Qi
2013-10-17T13:33:44Z

On 10/17/2013 01:40 PM, Joel Brobecker wrote:
>> +/* This returns the target type (or NULL) of TYPE, also skipping
>> >+ past typedefs. */
>> >+
>> >+struct type *
>> >+get_target_type (struct type *type)
> I noticed you documented this function twice, once in the header,
> and ones in the body. Can you you only document it once? You have
> two options: Remove the documentation in the header entirely, or
> replace the documentation in the body by "See gdbtype.h" or some
> such. I can't remember exactly the style that TomT introduced for
> that - perhaps seem minsyms.h, IIRC.
>

I did the latter.

>> >- /* Language info for this variable and its children. */
>> >- struct language_specific *lang;
>> >+ /* Language-related operations for this variable and its
>> >+ children. */
>> >+ struct lang_varobj_ops *lang;
> Please make that field a "const". That way...
>
>> >@@ -632,7 +434,7 @@ varobj_create (char *objname,
>> >
>> > /* Set language info */
>> > lang = variable_language (var);
>> >- var->root->lang = &languages[lang];
>> >+ var->root->lang = (struct lang_varobj_ops *) languages[lang];
> ... we can get rid of the cast here.
>

Fixed.

> Approved with those changes.

Patch is committed.

--
Yao (é½å°§)

gdb:

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 "lang-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.
* lang-varobj.h (c_varobj_ops, cplus_varobj_ops): Declare.
(java_varobj_ops, ada_varobj_ops): 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'.
(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/Makefile.in | 8 +-
gdb/ada-varobj.c | 137 ++++++
gdb/c-varobj.c | 910 +++++++++++++++++++++++++++++++++++++
gdb/gdbtypes.c | 15 +
gdb/gdbtypes.h | 4 +
gdb/jv-varobj.c | 105 +++++
gdb/varobj.c | 1328 ++----------------------------------------------------
gdb/varobj.h | 80 ++++
8 files changed, 1299 insertions(+), 1288 deletions(-)
create mode 100644 gdb/c-varobj.c
create mode 100644 gdb/jv-varobj.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f13e5c6..f8abb35 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -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 \
diff --git a/gdb/ada-varobj.c b/gdb/ada-varobj.c
index 53d8a9c..52c7687 100644
--- a/gdb/ada-varobj.c
+++ b/gdb/ada-varobj.c
@@ -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
index 0000000..73e785c
--- /dev/null
+++ b/gdb/c-varobj.c
@@ -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
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 6c809a4..9069a11 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -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. */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 5e8d1e7..d7fdedf 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -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
index 0000000..e70aa28
--- /dev/null
+++ b/gdb/jv-varobj.c
@@ -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 */
+};
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 1967842..01cf3d2 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -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"
@@ -43,10 +41,6 @@
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. */

diff --git a/gdb/varobj.h b/gdb/varobj.h
index 4a4dd75..e32c6ef 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -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 */
--
1.7.7.6