From: Yao Qi Date: Thu, 17 Oct 2013 13:28:37 +0000 (+0000) Subject: gdb/ X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=99ad94278d293fb7f5a823caf92221ff4419e556;p=deliverable%2Fbinutils-gdb.git gdb/ * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1d346e95d0..db0982a665 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,87 @@ +2013-10-17 Yao Qi + + * 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 * target/waitstatus.h (target_waitkind): Remove spurious diff --git a/gdb/Makefile.in b/gdb/Makefile.in index f13e5c656f..f8abb353cf 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 53d8a9c6b4..52c7687529 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 0000000000..73e785c5e5 --- /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 . */ + +#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 _("") +#define ANONYMOUS_UNION_NAME _("") + +/* 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); + } + } + } +} + + +/* 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); +} + + +/* 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 */ +}; + + diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 6c809a401a..9069a1122e 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 5e8d1e710a..d7fdedfec1 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 0000000000..e70aa28d42 --- /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 . */ + +#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 1967842c78..01cf3d2a1d 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 _("") -#define ANONYMOUS_UNION_NAME _("") - /* 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) /* 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); - } - } - } -} - - -/* 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); -} - -/* 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 4a4dd751c1..e32c6ef1f7 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 */