diff options
author | Yao Qi <yao@codesourcery.com> | 2013-10-17 13:28:37 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2013-10-17 13:28:37 +0000 |
commit | 99ad94278d293fb7f5a823caf92221ff4419e556 (patch) | |
tree | 13f05185c64b72b3b3f2809c64549463c6c4c676 /gdb/varobj.c | |
parent | c8a62302a53ba460e181f0c7cf03a5facc346d57 (diff) | |
download | gdb-99ad94278d293fb7f5a823caf92221ff4419e556.zip gdb-99ad94278d293fb7f5a823caf92221ff4419e556.tar.gz gdb-99ad94278d293fb7f5a823caf92221ff4419e556.tar.bz2 |
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.
Diffstat (limited to 'gdb/varobj.c')
-rw-r--r-- | gdb/varobj.c | 1328 |
1 files changed, 44 insertions, 1284 deletions
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) /* 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. */ |