| Index: gdb/varobj.c
|
| diff --git a/gdb/varobj.c b/gdb/varobj.c
|
| index 6b7ec52c983d1e63fb3b4897f152abba06119409..b78969a89ec3657ad733913d4597ba038f0583f4 100644
|
| --- a/gdb/varobj.c
|
| +++ b/gdb/varobj.c
|
| @@ -1,6 +1,6 @@
|
| /* Implementation of the GDB variable objects API.
|
|
|
| - Copyright (C) 1999-2012 Free Software Foundation, Inc.
|
| + 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
|
| @@ -26,15 +26,13 @@
|
| #include "valprint.h"
|
|
|
| #include "gdb_assert.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "gdb_regex.h"
|
|
|
| #include "varobj.h"
|
| #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,13 +41,9 @@
|
| 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. */
|
|
|
| -int varobjdebug = 0;
|
| +unsigned int varobjdebug = 0;
|
| static void
|
| show_varobjdebug (struct ui_file *file, int from_tty,
|
| struct cmd_list_element *c, const char *value)
|
| @@ -61,9 +55,6 @@ show_varobjdebug (struct ui_file *file, int from_tty,
|
| char *varobj_format_string[] =
|
| { "natural", "binary", "decimal", "hexadecimal", "octal" };
|
|
|
| -/* String representations of gdb's known languages. */
|
| -char *varobj_language_string[] = { "unknown", "C", "C++", "Java" };
|
| -
|
| /* True if we want to allow Python-based pretty-printing. */
|
| static int pretty_printing = 0;
|
|
|
| @@ -84,7 +75,7 @@ struct varobj_root
|
| struct expression *exp;
|
|
|
| /* Block for which this expression is valid. */
|
| - struct block *valid_block;
|
| + const struct block *valid_block;
|
|
|
| /* The frame for this expression. This field is set iff valid_block is
|
| not NULL. */
|
| @@ -106,8 +97,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_ops;
|
|
|
| /* The varobj for this root node. */
|
| struct varobj *rootvar;
|
| @@ -116,84 +108,16 @@ struct varobj_root
|
| struct varobj_root *next;
|
| };
|
|
|
| -/* Every variable in the system has a structure of this type defined
|
| - for it. This structure holds all information necessary to manipulate
|
| - a particular object variable. Members which must be freed are noted. */
|
| -struct varobj
|
| -{
|
| -
|
| - /* Alloc'd name of the variable for this object. If this variable is a
|
| - child, then this name will be the child's source name.
|
| - (bar, not foo.bar). */
|
| - /* NOTE: This is the "expression". */
|
| - char *name;
|
| -
|
| - /* Alloc'd expression for this child. Can be used to create a
|
| - root variable corresponding to this child. */
|
| - char *path_expr;
|
| -
|
| - /* The alloc'd name for this variable's object. This is here for
|
| - convenience when constructing this object's children. */
|
| - char *obj_name;
|
| -
|
| - /* Index of this variable in its parent or -1. */
|
| - int index;
|
| -
|
| - /* The type of this variable. This can be NULL
|
| - for artifial variable objects -- currently, the "accessibility"
|
| - variable objects in C++. */
|
| - struct type *type;
|
| -
|
| - /* The value of this expression or subexpression. A NULL value
|
| - indicates there was an error getting this value.
|
| - Invariant: if varobj_value_is_changeable_p (this) is non-zero,
|
| - the value is either NULL, or not lazy. */
|
| - struct value *value;
|
| -
|
| - /* The number of (immediate) children this variable has. */
|
| - int num_children;
|
| -
|
| - /* If this object is a child, this points to its immediate parent. */
|
| - struct varobj *parent;
|
| -
|
| - /* Children of this object. */
|
| - VEC (varobj_p) *children;
|
| +/* Dynamic part of varobj. */
|
|
|
| +struct varobj_dynamic
|
| +{
|
| /* Whether the children of this varobj were requested. This field is
|
| used to decide if dynamic varobj should recompute their children.
|
| In the event that the frontend never asked for the children, we
|
| can avoid that. */
|
| int children_requested;
|
|
|
| - /* Description of the root variable. Points to root variable for
|
| - children. */
|
| - struct varobj_root *root;
|
| -
|
| - /* The format of the output for this object. */
|
| - enum varobj_display_formats format;
|
| -
|
| - /* Was this variable updated via a varobj_set_value operation. */
|
| - int updated;
|
| -
|
| - /* Last print value. */
|
| - char *print_value;
|
| -
|
| - /* Is this variable frozen. Frozen variables are never implicitly
|
| - updated by -var-update *
|
| - or -var-update <direct-or-indirect-parent>. */
|
| - int frozen;
|
| -
|
| - /* Is the value of this variable intentionally not fetched? It is
|
| - not fetched if either the variable is frozen, or any parents is
|
| - frozen. */
|
| - int not_fetched;
|
| -
|
| - /* Sub-range of children which the MI consumer has requested. If
|
| - FROM < 0 or TO < 0, means that all children have been
|
| - requested. */
|
| - int from;
|
| - int to;
|
| -
|
| /* The pretty-printer constructor. If NULL, then the default
|
| pretty-printer will be looked up. If None, then no
|
| pretty-printer will be installed. */
|
| @@ -245,7 +169,7 @@ static void uninstall_variable (struct varobj *);
|
| static struct varobj *create_child (struct varobj *, int, char *);
|
|
|
| static struct varobj *
|
| -create_child_with_value (struct varobj *parent, int index, const char *name,
|
| +create_child_with_value (struct varobj *parent, int index, char *name,
|
| struct value *value);
|
|
|
| /* Utility routines */
|
| @@ -258,12 +182,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);
|
| @@ -278,8 +196,6 @@ static int install_new_value (struct varobj *var, struct value *value,
|
|
|
| /* Language-specific routines. */
|
|
|
| -static enum varobj_languages variable_language (struct varobj *var);
|
| -
|
| static int number_of_children (struct varobj *);
|
|
|
| static char *name_of_variable (struct varobj *);
|
| @@ -293,245 +209,16 @@ 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
|
|
|
| static struct varobj *varobj_add_child (struct varobj *var,
|
| - const char *name,
|
| + char *name,
|
| struct value *value);
|
|
|
| #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_root (struct varobj **var_handle);
|
| -
|
| -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_root (struct varobj **var_handle);
|
| -
|
| -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_root (struct varobj **var_handle);
|
| -
|
| -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_root (struct varobj **var_handle);
|
| -
|
| -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 language of this variable. */
|
| - enum varobj_languages language;
|
| -
|
| - /* 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 root variable ROOT. */
|
| - struct value *(*value_of_root) (struct varobj ** root_handle);
|
| -
|
| - /* 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] = {
|
| - /* Unknown (try treating as C). */
|
| - {
|
| - vlang_unknown,
|
| - c_number_of_children,
|
| - c_name_of_variable,
|
| - c_name_of_child,
|
| - c_path_expr_of_child,
|
| - c_value_of_root,
|
| - c_value_of_child,
|
| - c_type_of_child,
|
| - c_value_of_variable,
|
| - default_value_is_changeable_p,
|
| - NULL /* value_has_mutated */}
|
| - ,
|
| - /* C */
|
| - {
|
| - vlang_c,
|
| - c_number_of_children,
|
| - c_name_of_variable,
|
| - c_name_of_child,
|
| - c_path_expr_of_child,
|
| - c_value_of_root,
|
| - c_value_of_child,
|
| - c_type_of_child,
|
| - c_value_of_variable,
|
| - default_value_is_changeable_p,
|
| - NULL /* value_has_mutated */}
|
| - ,
|
| - /* C++ */
|
| - {
|
| - vlang_cplus,
|
| - cplus_number_of_children,
|
| - cplus_name_of_variable,
|
| - cplus_name_of_child,
|
| - cplus_path_expr_of_child,
|
| - cplus_value_of_root,
|
| - cplus_value_of_child,
|
| - cplus_type_of_child,
|
| - cplus_value_of_variable,
|
| - default_value_is_changeable_p,
|
| - NULL /* value_has_mutated */}
|
| - ,
|
| - /* Java */
|
| - {
|
| - vlang_java,
|
| - java_number_of_children,
|
| - java_name_of_variable,
|
| - java_name_of_child,
|
| - java_path_expr_of_child,
|
| - java_value_of_root,
|
| - java_value_of_child,
|
| - java_type_of_child,
|
| - java_value_of_variable,
|
| - default_value_is_changeable_p,
|
| - NULL /* value_has_mutated */},
|
| - /* Ada */
|
| - {
|
| - vlang_ada,
|
| - ada_number_of_children,
|
| - ada_name_of_variable,
|
| - ada_name_of_child,
|
| - ada_path_expr_of_child,
|
| - ada_value_of_root,
|
| - 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
|
| -};
|
| -
|
| /* Private data */
|
|
|
| /* Mappings of varobj_display_formats enums to gdb's format codes. */
|
| @@ -547,9 +234,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 */
|
| @@ -620,8 +304,7 @@ varobj_create (char *objname,
|
| struct frame_info *fi;
|
| struct frame_id old_id = null_frame_id;
|
| struct block *block;
|
| - char *p;
|
| - enum varobj_languages lang;
|
| + const char *p;
|
| struct value *value = NULL;
|
| volatile struct gdb_exception except;
|
| CORE_ADDR pc;
|
| @@ -675,7 +358,9 @@ varobj_create (char *objname,
|
| }
|
|
|
| /* Don't allow variables to be created for types. */
|
| - if (var->root->exp->elts[0].opcode == OP_TYPE)
|
| + if (var->root->exp->elts[0].opcode == OP_TYPE
|
| + || var->root->exp->elts[0].opcode == OP_TYPEOF
|
| + || var->root->exp->elts[0].opcode == OP_DECLTYPE)
|
| {
|
| do_cleanups (old_chain);
|
| fprintf_unfiltered (gdb_stderr, "Attempt to use a type name"
|
| @@ -734,8 +419,7 @@ varobj_create (char *objname,
|
| }
|
|
|
| /* Set language info */
|
| - lang = variable_language (var);
|
| - var->root->lang = &languages[lang];
|
| + var->root->lang_ops = var->root->exp->language_defn->la_varobj_ops;
|
|
|
| install_new_value (var, value, 1 /* Initial assignment */);
|
|
|
| @@ -915,7 +599,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;
|
| @@ -933,10 +618,15 @@ varobj_get_display_hint (struct varobj *var)
|
| char *result = NULL;
|
|
|
| #if HAVE_PYTHON
|
| - struct cleanup *back_to = varobj_ensure_python_env (var);
|
| + struct cleanup *back_to;
|
| +
|
| + if (!gdb_python_initialized)
|
| + return NULL;
|
|
|
| - if (var->pretty_printer)
|
| - result = gdbpy_get_display_hint (var->pretty_printer);
|
| + back_to = varobj_ensure_python_env (var);
|
| +
|
| + if (var->dynamic->pretty_printer != NULL)
|
| + result = gdbpy_get_display_hint (var->dynamic->pretty_printer);
|
|
|
| do_cleanups (back_to);
|
| #endif
|
| @@ -952,7 +642,7 @@ varobj_has_more (struct varobj *var, int to)
|
| if (VEC_length (varobj_p, var->children) > to)
|
| return 1;
|
| return ((to == -1 || VEC_length (varobj_p, var->children) == to)
|
| - && var->saved_item != NULL);
|
| + && (var->dynamic->saved_item != NULL));
|
| }
|
|
|
| /* If the variable object is bound to a specific thread, that
|
| @@ -992,8 +682,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)
|
| {
|
| @@ -1024,7 +714,7 @@ install_dynamic_child (struct varobj *var,
|
| VEC (varobj_p) **unchanged,
|
| int *cchanged,
|
| int index,
|
| - const char *name,
|
| + char *name,
|
| struct value *value)
|
| {
|
| if (VEC_length (varobj_p, var->children) < index + 1)
|
| @@ -1038,11 +728,11 @@ install_dynamic_child (struct varobj *var,
|
| *cchanged = 1;
|
| }
|
| }
|
| - else
|
| + else
|
| {
|
| varobj_p existing = VEC_index (varobj_p, var->children, index);
|
| -
|
| int type_updated = update_type_if_necessary (existing, value);
|
| +
|
| if (type_updated)
|
| {
|
| if (type_changed)
|
| @@ -1062,9 +752,12 @@ static int
|
| dynamic_varobj_has_child_method (struct varobj *var)
|
| {
|
| struct cleanup *back_to;
|
| - PyObject *printer = var->pretty_printer;
|
| + PyObject *printer = var->dynamic->pretty_printer;
|
| int result;
|
|
|
| + if (!gdb_python_initialized)
|
| + return 0;
|
| +
|
| back_to = varobj_ensure_python_env (var);
|
| result = PyObject_HasAttr (printer, gdbpy_children_cst);
|
| do_cleanups (back_to);
|
| @@ -1088,7 +781,10 @@ update_dynamic_varobj_children (struct varobj *var,
|
| struct cleanup *back_to;
|
| PyObject *children;
|
| int i;
|
| - PyObject *printer = var->pretty_printer;
|
| + PyObject *printer = var->dynamic->pretty_printer;
|
| +
|
| + if (!gdb_python_initialized)
|
| + return 0;
|
|
|
| back_to = varobj_ensure_python_env (var);
|
|
|
| @@ -1099,7 +795,7 @@ update_dynamic_varobj_children (struct varobj *var,
|
| return 0;
|
| }
|
|
|
| - if (update_children || !var->child_iter)
|
| + if (update_children || var->dynamic->child_iter == NULL)
|
| {
|
| children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
|
| NULL);
|
| @@ -1112,16 +808,16 @@ update_dynamic_varobj_children (struct varobj *var,
|
|
|
| make_cleanup_py_decref (children);
|
|
|
| - Py_XDECREF (var->child_iter);
|
| - var->child_iter = PyObject_GetIter (children);
|
| - if (!var->child_iter)
|
| + Py_XDECREF (var->dynamic->child_iter);
|
| + var->dynamic->child_iter = PyObject_GetIter (children);
|
| + if (var->dynamic->child_iter == NULL)
|
| {
|
| gdbpy_print_stack ();
|
| error (_("Could not get children iterator"));
|
| }
|
|
|
| - Py_XDECREF (var->saved_item);
|
| - var->saved_item = NULL;
|
| + Py_XDECREF (var->dynamic->saved_item);
|
| + var->dynamic->saved_item = NULL;
|
|
|
| i = 0;
|
| }
|
| @@ -1136,13 +832,13 @@ update_dynamic_varobj_children (struct varobj *var,
|
| int force_done = 0;
|
|
|
| /* See if there was a leftover from last time. */
|
| - if (var->saved_item)
|
| + if (var->dynamic->saved_item)
|
| {
|
| - item = var->saved_item;
|
| - var->saved_item = NULL;
|
| + item = var->dynamic->saved_item;
|
| + var->dynamic->saved_item = NULL;
|
| }
|
| else
|
| - item = PyIter_Next (var->child_iter);
|
| + item = PyIter_Next (var->dynamic->child_iter);
|
|
|
| if (!item)
|
| {
|
| @@ -1212,13 +908,14 @@ update_dynamic_varobj_children (struct varobj *var,
|
| can_mention ? type_changed : NULL,
|
| can_mention ? new : NULL,
|
| can_mention ? unchanged : NULL,
|
| - can_mention ? cchanged : NULL, i, name, v);
|
| + can_mention ? cchanged : NULL, i,
|
| + xstrdup (name), v);
|
| do_cleanups (inner);
|
| }
|
| else
|
| {
|
| - Py_XDECREF (var->saved_item);
|
| - var->saved_item = item;
|
| + Py_XDECREF (var->dynamic->saved_item);
|
| + var->dynamic->saved_item = item;
|
|
|
| /* We want to truncate the child list just before this
|
| element. */
|
| @@ -1250,7 +947,7 @@ update_dynamic_varobj_children (struct varobj *var,
|
|
|
| return 1;
|
| #else
|
| - gdb_assert (0 && "should never be called if Python is not enabled");
|
| + gdb_assert_not_reached ("should never be called if Python is not enabled");
|
| #endif
|
| }
|
|
|
| @@ -1259,7 +956,7 @@ varobj_get_num_children (struct varobj *var)
|
| {
|
| if (var->num_children == -1)
|
| {
|
| - if (var->pretty_printer)
|
| + if (var->dynamic->pretty_printer != NULL)
|
| {
|
| int dummy;
|
|
|
| @@ -1284,16 +981,16 @@ varobj_list_children (struct varobj *var, int *from, int *to)
|
| char *name;
|
| int i, children_changed;
|
|
|
| - var->children_requested = 1;
|
| + var->dynamic->children_requested = 1;
|
|
|
| - if (var->pretty_printer)
|
| + if (var->dynamic->pretty_printer != NULL)
|
| {
|
| /* This, in theory, can result in the number of children changing without
|
| frontend noticing. But well, calling -var-list-children on the same
|
| 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;
|
| }
|
|
|
| @@ -1324,14 +1021,14 @@ 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;
|
| }
|
|
|
| #if HAVE_PYTHON
|
|
|
| static struct varobj *
|
| -varobj_add_child (struct varobj *var, const char *name, struct value *value)
|
| +varobj_add_child (struct varobj *var, char *name, struct value *value)
|
| {
|
| varobj_p v = create_child_with_value (var,
|
| VEC_length (varobj_p, var->children),
|
| @@ -1349,7 +1046,7 @@ varobj_add_child (struct varobj *var, const char *name, struct value *value)
|
| char *
|
| varobj_get_type (struct varobj *var)
|
| {
|
| - /* For the "fake" variables, do not return a type. (It's type is
|
| + /* For the "fake" variables, do not return a type. (Its type is
|
| NULL, too.)
|
| Do not return a type for invalid variables as well. */
|
| if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
|
| @@ -1378,7 +1075,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
|
| @@ -1388,8 +1085,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;
|
|
|
| @@ -1412,14 +1109,14 @@ varobj_get_path_expr (struct varobj *var)
|
| when creating varobj, so here it should be
|
| child varobj. */
|
| gdb_assert (!is_root_p (var));
|
| - return (*var->root->lang->path_expr_of_child) (var);
|
| + return (*var->root->lang_ops->path_expr_of_child) (var);
|
| }
|
| }
|
|
|
| -enum varobj_languages
|
| +const struct language_defn *
|
| varobj_get_language (struct varobj *var)
|
| {
|
| - return variable_language (var);
|
| + return var->root->exp->language_defn;
|
| }
|
|
|
| int
|
| @@ -1437,7 +1134,7 @@ varobj_get_attributes (struct varobj *var)
|
| int
|
| varobj_pretty_printed_p (struct varobj *var)
|
| {
|
| - return var->pretty_printer != NULL;
|
| + return var->dynamic->pretty_printer != NULL;
|
| }
|
|
|
| char *
|
| @@ -1467,7 +1164,7 @@ varobj_set_value (struct varobj *var, char *expression)
|
| struct expression *exp;
|
| struct value *value = NULL; /* Initialize to keep gcc happy. */
|
| int saved_input_radix = input_radix;
|
| - char *s = expression;
|
| + const char *s = expression;
|
| volatile struct gdb_exception except;
|
|
|
| gdb_assert (varobj_editable_p (var));
|
| @@ -1525,10 +1222,10 @@ varobj_set_value (struct varobj *var, char *expression)
|
| #if HAVE_PYTHON
|
|
|
| /* A helper function to install a constructor function and visualizer
|
| - in a varobj. */
|
| + in a varobj_dynamic. */
|
|
|
| static void
|
| -install_visualizer (struct varobj *var, PyObject *constructor,
|
| +install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
|
| PyObject *visualizer)
|
| {
|
| Py_XDECREF (var->constructor);
|
| @@ -1570,7 +1267,7 @@ install_default_visualizer (struct varobj *var)
|
| pretty_printer = NULL;
|
| }
|
|
|
| - install_visualizer (var, NULL, pretty_printer);
|
| + install_visualizer (var->dynamic, NULL, pretty_printer);
|
| }
|
| }
|
|
|
| @@ -1607,7 +1304,7 @@ construct_visualizer (struct varobj *var, PyObject *constructor)
|
| }
|
| }
|
|
|
| - install_visualizer (var, constructor, pretty_printer);
|
| + install_visualizer (var->dynamic, constructor, pretty_printer);
|
| }
|
|
|
| #endif /* HAVE_PYTHON */
|
| @@ -1621,16 +1318,19 @@ install_new_value_visualizer (struct varobj *var)
|
| #if HAVE_PYTHON
|
| /* If the constructor is None, then we want the raw value. If VAR
|
| does not have a value, just skip this. */
|
| - if (var->constructor != Py_None && var->value)
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| + if (var->dynamic->constructor != Py_None && var->value != NULL)
|
| {
|
| struct cleanup *cleanup;
|
|
|
| cleanup = varobj_ensure_python_env (var);
|
|
|
| - if (!var->constructor)
|
| + if (var->dynamic->constructor == NULL)
|
| install_default_visualizer (var);
|
| else
|
| - construct_visualizer (var, var->constructor);
|
| + construct_visualizer (var, var->dynamic->constructor);
|
|
|
| do_cleanups (cleanup);
|
| }
|
| @@ -1707,7 +1407,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
|
| /* If the type has custom visualizer, we consider it to be always
|
| changeable. FIXME: need to make sure this behaviour will not
|
| mess up read-sensitive values. */
|
| - if (var->pretty_printer)
|
| + if (var->dynamic->pretty_printer != NULL)
|
| changeable = 1;
|
|
|
| need_to_fetch = changeable;
|
| @@ -1778,8 +1478,9 @@ install_new_value (struct varobj *var, struct value *value, int initial)
|
| values. Don't get string rendering if the value is
|
| lazy -- if it is, the code above has decided that the value
|
| should not be fetched. */
|
| - if (value && !value_lazy (value) && !var->pretty_printer)
|
| - print_value = value_get_print_value (value, var->format, var);
|
| + if (value != NULL && !value_lazy (value)
|
| + && var->dynamic->pretty_printer == NULL)
|
| + 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
|
| @@ -1795,7 +1496,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
|
| {
|
| changed = 1;
|
| }
|
| - else if (! var->pretty_printer)
|
| + else if (var->dynamic->pretty_printer == NULL)
|
| {
|
| /* Try to compare the values. That requires that both
|
| values are non-lazy. */
|
| @@ -1850,10 +1551,11 @@ install_new_value (struct varobj *var, struct value *value, int initial)
|
|
|
| /* If we installed a pretty-printer, re-compare the printed version
|
| to see if the variable changed. */
|
| - if (var->pretty_printer)
|
| + 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
|
| @@ -1897,6 +1599,9 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
|
| PyObject *mainmod, *globals, *constructor;
|
| struct cleanup *back_to;
|
|
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| back_to = varobj_ensure_python_env (var);
|
|
|
| mainmod = PyImport_AddModule ("__main__");
|
| @@ -1943,8 +1648,8 @@ varobj_value_has_mutated (struct varobj *var, struct value *new_value,
|
| if (var->num_children < 0)
|
| return 0;
|
|
|
| - if (var->root->lang->value_has_mutated)
|
| - return var->root->lang->value_has_mutated (var, new_value, new_type);
|
| + if (var->root->lang_ops->value_has_mutated)
|
| + return var->root->lang_ops->value_has_mutated (var, new_value, new_type);
|
| else
|
| return 0;
|
| }
|
| @@ -1967,7 +1672,6 @@ varobj_value_has_mutated (struct varobj *var, struct value *new_value,
|
| VEC(varobj_update_result) *
|
| varobj_update (struct varobj **varp, int explicit)
|
| {
|
| - int changed = 0;
|
| int type_changed = 0;
|
| int i;
|
| struct value *new;
|
| @@ -2053,7 +1757,7 @@ varobj_update (struct varobj **varp, int explicit)
|
| if (new)
|
| new_type = value_type (new);
|
| else
|
| - new_type = v->root->lang->type_of_child (v->parent, v->index);
|
| + new_type = v->root->lang_ops->type_of_child (v->parent, v->index);
|
|
|
| if (varobj_value_has_mutated (v, new, new_type))
|
| {
|
| @@ -2077,7 +1781,7 @@ varobj_update (struct varobj **varp, int explicit)
|
| /* We probably should not get children of a varobj that has a
|
| pretty-printer, but for which -var-list-children was never
|
| invoked. */
|
| - if (v->pretty_printer)
|
| + if (v->dynamic->pretty_printer != NULL)
|
| {
|
| VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
|
| VEC (varobj_p) *new = 0;
|
| @@ -2086,7 +1790,7 @@ varobj_update (struct varobj **varp, int explicit)
|
| if (v->frozen)
|
| continue;
|
|
|
| - if (!v->children_requested)
|
| + if (!v->dynamic->children_requested)
|
| {
|
| int dummy;
|
|
|
| @@ -2398,22 +2102,8 @@ 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, const char *name,
|
| +create_child_with_value (struct varobj *parent, int index, char *name,
|
| struct value *value)
|
| {
|
| struct varobj *child;
|
| @@ -2421,14 +2111,13 @@ create_child_with_value (struct varobj *parent, int index, const char *name,
|
|
|
| child = new_variable ();
|
|
|
| - /* Name is allocated by name_of_child. */
|
| - /* FIXME: xstrdup should not be here. */
|
| - child->name = xstrdup (name);
|
| + /* NAME is allocated by caller. */
|
| + child->name = name;
|
| child->index = index;
|
| 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);
|
| @@ -2444,8 +2133,8 @@ create_child_with_value (struct varobj *parent, int index, const char *name,
|
| child->type = value_actual_type (value, 0, NULL);
|
| else
|
| /* Otherwise, we must compute the type. */
|
| - child->type = (*child->root->lang->type_of_child) (child->parent,
|
| - child->index);
|
| + child->type = (*child->root->lang_ops->type_of_child) (child->parent,
|
| + child->index);
|
| install_new_value (child, value, 1);
|
|
|
| return child;
|
| @@ -2478,13 +2167,15 @@ new_variable (void)
|
| var->print_value = NULL;
|
| var->frozen = 0;
|
| var->not_fetched = 0;
|
| - var->children_requested = 0;
|
| + var->dynamic
|
| + = (struct varobj_dynamic *) xmalloc (sizeof (struct varobj_dynamic));
|
| + var->dynamic->children_requested = 0;
|
| var->from = -1;
|
| var->to = -1;
|
| - var->constructor = 0;
|
| - var->pretty_printer = 0;
|
| - var->child_iter = 0;
|
| - var->saved_item = 0;
|
| + var->dynamic->constructor = 0;
|
| + var->dynamic->pretty_printer = 0;
|
| + var->dynamic->child_iter = 0;
|
| + var->dynamic->saved_item = 0;
|
|
|
| return var;
|
| }
|
| @@ -2496,7 +2187,7 @@ new_root_variable (void)
|
| struct varobj *var = new_variable ();
|
|
|
| var->root = (struct varobj_root *) xmalloc (sizeof (struct varobj_root));
|
| - var->root->lang = NULL;
|
| + var->root->lang_ops = NULL;
|
| var->root->exp = NULL;
|
| var->root->valid_block = NULL;
|
| var->root->frame = null_frame_id;
|
| @@ -2512,13 +2203,14 @@ static void
|
| free_variable (struct varobj *var)
|
| {
|
| #if HAVE_PYTHON
|
| - if (var->pretty_printer)
|
| + if (var->dynamic->pretty_printer != NULL)
|
| {
|
| struct cleanup *cleanup = varobj_ensure_python_env (var);
|
| - Py_XDECREF (var->constructor);
|
| - Py_XDECREF (var->pretty_printer);
|
| - Py_XDECREF (var->child_iter);
|
| - Py_XDECREF (var->saved_item);
|
| +
|
| + Py_XDECREF (var->dynamic->constructor);
|
| + Py_XDECREF (var->dynamic->pretty_printer);
|
| + Py_XDECREF (var->dynamic->child_iter);
|
| + Py_XDECREF (var->dynamic->saved_item);
|
| do_cleanups (cleanup);
|
| }
|
| #endif
|
| @@ -2536,6 +2228,7 @@ free_variable (struct varobj *var)
|
| xfree (var->obj_name);
|
| xfree (var->print_value);
|
| xfree (var->path_expr);
|
| + xfree (var->dynamic);
|
| xfree (var);
|
| }
|
|
|
| @@ -2551,23 +2244,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.
|
| @@ -2579,8 +2255,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;
|
|
|
| @@ -2599,24 +2275,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
|
| @@ -2661,32 +2319,6 @@ cppop (struct cpstack **pstack)
|
|
|
| /* Common entry points */
|
|
|
| -/* Get the language of variable VAR. */
|
| -static enum varobj_languages
|
| -variable_language (struct varobj *var)
|
| -{
|
| - enum varobj_languages lang;
|
| -
|
| - switch (var->root->exp->language_defn->la_language)
|
| - {
|
| - default:
|
| - case language_c:
|
| - lang = vlang_c;
|
| - break;
|
| - case language_cplus:
|
| - lang = vlang_cplus;
|
| - break;
|
| - case language_java:
|
| - lang = vlang_java;
|
| - break;
|
| - case language_ada:
|
| - lang = vlang_ada;
|
| - break;
|
| - }
|
| -
|
| - return lang;
|
| -}
|
| -
|
| /* Return the number of children for a given variable.
|
| The result of this function is defined by the language
|
| implementation. The number of children returned by this function
|
| @@ -2695,7 +2327,7 @@ variable_language (struct varobj *var)
|
| static int
|
| number_of_children (struct varobj *var)
|
| {
|
| - return (*var->root->lang->number_of_children) (var);
|
| + return (*var->root->lang_ops->number_of_children) (var);
|
| }
|
|
|
| /* What is the expression for the root varobj VAR? Returns a malloc'd
|
| @@ -2703,7 +2335,7 @@ number_of_children (struct varobj *var)
|
| static char *
|
| name_of_variable (struct varobj *var)
|
| {
|
| - return (*var->root->lang->name_of_variable) (var);
|
| + return (*var->root->lang_ops->name_of_variable) (var);
|
| }
|
|
|
| /* What is the name of the INDEX'th child of VAR? Returns a malloc'd
|
| @@ -2711,7 +2343,87 @@ name_of_variable (struct varobj *var)
|
| static char *
|
| name_of_child (struct varobj *var, int index)
|
| {
|
| - return (*var->root->lang->name_of_child) (var, index);
|
| + return (*var->root->lang_ops->name_of_child) (var, index);
|
| +}
|
| +
|
| +/* If frame associated with VAR can be found, switch
|
| + to it and return 1. Otherwise, return 0. */
|
| +
|
| +static int
|
| +check_scope (struct varobj *var)
|
| +{
|
| + struct frame_info *fi;
|
| + int scope;
|
| +
|
| + fi = frame_find_by_id (var->root->frame);
|
| + scope = fi != NULL;
|
| +
|
| + if (fi)
|
| + {
|
| + CORE_ADDR pc = get_frame_pc (fi);
|
| +
|
| + if (pc < BLOCK_START (var->root->valid_block) ||
|
| + pc >= BLOCK_END (var->root->valid_block))
|
| + scope = 0;
|
| + else
|
| + select_frame (fi);
|
| + }
|
| + return scope;
|
| +}
|
| +
|
| +/* Helper function to value_of_root. */
|
| +
|
| +static struct value *
|
| +value_of_root_1 (struct varobj **var_handle)
|
| +{
|
| + struct value *new_val = NULL;
|
| + struct varobj *var = *var_handle;
|
| + int within_scope = 0;
|
| + struct cleanup *back_to;
|
| +
|
| + /* Only root variables can be updated... */
|
| + if (!is_root_p (var))
|
| + /* Not a root var. */
|
| + return NULL;
|
| +
|
| + back_to = make_cleanup_restore_current_thread ();
|
| +
|
| + /* Determine whether the variable is still around. */
|
| + if (var->root->valid_block == NULL || var->root->floating)
|
| + within_scope = 1;
|
| + else if (var->root->thread_id == 0)
|
| + {
|
| + /* The program was single-threaded when the variable object was
|
| + created. Technically, it's possible that the program became
|
| + multi-threaded since then, but we don't support such
|
| + scenario yet. */
|
| + within_scope = check_scope (var);
|
| + }
|
| + else
|
| + {
|
| + ptid_t ptid = thread_id_to_pid (var->root->thread_id);
|
| + if (in_thread_list (ptid))
|
| + {
|
| + switch_to_thread (ptid);
|
| + within_scope = check_scope (var);
|
| + }
|
| + }
|
| +
|
| + if (within_scope)
|
| + {
|
| + volatile struct gdb_exception except;
|
| +
|
| + /* We need to catch errors here, because if evaluate
|
| + expression fails we want to just return NULL. */
|
| + TRY_CATCH (except, RETURN_MASK_ERROR)
|
| + {
|
| + new_val = evaluate_expression (var->root->exp);
|
| + }
|
| + }
|
| +
|
| + do_cleanups (back_to);
|
| +
|
| + return new_val;
|
| }
|
|
|
| /* What is the ``struct value *'' of the root variable VAR?
|
| @@ -2791,7 +2503,7 @@ value_of_root (struct varobj **var_handle, int *type_changed)
|
| {
|
| struct value *value;
|
|
|
| - value = (*var->root->lang->value_of_root) (var_handle);
|
| + value = value_of_root_1 (var_handle);
|
| if (var->value == NULL || value == NULL)
|
| {
|
| /* For root varobj-s, a NULL value indicates a scoping issue.
|
| @@ -2818,7 +2530,7 @@ value_of_child (struct varobj *parent, int index)
|
| {
|
| struct value *value;
|
|
|
| - value = (*parent->root->lang->value_of_child) (parent, index);
|
| + value = (*parent->root->lang_ops->value_of_child) (parent, index);
|
|
|
| return value;
|
| }
|
| @@ -2829,21 +2541,31 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
|
| {
|
| if (var->root->is_valid)
|
| {
|
| - if (var->pretty_printer)
|
| - return value_get_print_value (var->value, var->format, var);
|
| - return (*var->root->lang->value_of_variable) (var, format);
|
| + if (var->dynamic->pretty_printer != NULL)
|
| + return varobj_value_get_print_value (var->value, var->format, var);
|
| + return (*var->root->lang_ops->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;
|
| - gdb_byte *thevalue = NULL;
|
| + char *thevalue = NULL;
|
| struct value_print_options opts;
|
| struct type *type = NULL;
|
| long len = 0;
|
| @@ -2861,103 +2583,100 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
|
|
|
| gdbarch = get_type_arch (value_type (value));
|
| #if HAVE_PYTHON
|
| - {
|
| - PyObject *value_formatter = var->pretty_printer;
|
| + if (gdb_python_initialized)
|
| + {
|
| + PyObject *value_formatter = var->dynamic->pretty_printer;
|
|
|
| - varobj_ensure_python_env (var);
|
| + varobj_ensure_python_env (var);
|
|
|
| - if (value_formatter)
|
| - {
|
| - /* First check to see if we have any children at all. If so,
|
| - we simply return {...}. */
|
| - if (dynamic_varobj_has_child_method (var))
|
| - {
|
| - do_cleanups (old_chain);
|
| - return xstrdup ("{...}");
|
| - }
|
| + if (value_formatter)
|
| + {
|
| + /* First check to see if we have any children at all. If so,
|
| + we simply return {...}. */
|
| + if (dynamic_varobj_has_child_method (var))
|
| + {
|
| + do_cleanups (old_chain);
|
| + return xstrdup ("{...}");
|
| + }
|
|
|
| - if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
|
| - {
|
| - struct value *replacement;
|
| - PyObject *output = NULL;
|
| -
|
| - output = apply_varobj_pretty_printer (value_formatter,
|
| - &replacement,
|
| - stb);
|
| -
|
| - /* If we have string like output ... */
|
| - if (output)
|
| - {
|
| - make_cleanup_py_decref (output);
|
| -
|
| - /* If this is a lazy string, extract it. For lazy
|
| - strings we always print as a string, so set
|
| - string_print. */
|
| - if (gdbpy_is_lazy_string (output))
|
| - {
|
| - gdbpy_extract_lazy_string (output, &str_addr, &type,
|
| - &len, &encoding);
|
| - make_cleanup (free_current_contents, &encoding);
|
| - string_print = 1;
|
| - }
|
| - else
|
| - {
|
| - /* If it is a regular (non-lazy) string, extract
|
| - it and copy the contents into THEVALUE. If the
|
| - hint says to print it as a string, set
|
| - string_print. Otherwise just return the extracted
|
| - string as a value. */
|
| -
|
| - PyObject *py_str
|
| - = python_string_to_target_python_string (output);
|
| -
|
| - if (py_str)
|
| - {
|
| - char *s = PyString_AsString (py_str);
|
| - char *hint;
|
| -
|
| - hint = gdbpy_get_display_hint (value_formatter);
|
| - if (hint)
|
| - {
|
| - if (!strcmp (hint, "string"))
|
| - string_print = 1;
|
| - xfree (hint);
|
| - }
|
| -
|
| - len = PyString_Size (py_str);
|
| - thevalue = xmemdup (s, len + 1, len + 1);
|
| - type = builtin_type (gdbarch)->builtin_char;
|
| - Py_DECREF (py_str);
|
| -
|
| - if (!string_print)
|
| - {
|
| - do_cleanups (old_chain);
|
| - return thevalue;
|
| - }
|
| -
|
| - make_cleanup (xfree, thevalue);
|
| - }
|
| - else
|
| - gdbpy_print_stack ();
|
| - }
|
| - }
|
| - /* If the printer returned a replacement value, set VALUE
|
| - to REPLACEMENT. If there is not a replacement value,
|
| - just use the value passed to this function. */
|
| - if (replacement)
|
| - value = replacement;
|
| - }
|
| - }
|
| - }
|
| -#endif
|
| + if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
|
| + {
|
| + struct value *replacement;
|
| + PyObject *output = NULL;
|
|
|
| - get_formatted_print_options (&opts, format_code[(int) format]);
|
| - opts.deref_ref = 0;
|
| - opts.raw = 1;
|
| + output = apply_varobj_pretty_printer (value_formatter,
|
| + &replacement,
|
| + stb);
|
| +
|
| + /* If we have string like output ... */
|
| + if (output)
|
| + {
|
| + make_cleanup_py_decref (output);
|
| +
|
| + /* If this is a lazy string, extract it. For lazy
|
| + strings we always print as a string, so set
|
| + string_print. */
|
| + if (gdbpy_is_lazy_string (output))
|
| + {
|
| + gdbpy_extract_lazy_string (output, &str_addr, &type,
|
| + &len, &encoding);
|
| + make_cleanup (free_current_contents, &encoding);
|
| + string_print = 1;
|
| + }
|
| + else
|
| + {
|
| + /* If it is a regular (non-lazy) string, extract
|
| + it and copy the contents into THEVALUE. If the
|
| + hint says to print it as a string, set
|
| + string_print. Otherwise just return the extracted
|
| + string as a value. */
|
| +
|
| + char *s = python_string_to_target_string (output);
|
| +
|
| + if (s)
|
| + {
|
| + char *hint;
|
| +
|
| + hint = gdbpy_get_display_hint (value_formatter);
|
| + if (hint)
|
| + {
|
| + if (!strcmp (hint, "string"))
|
| + string_print = 1;
|
| + xfree (hint);
|
| + }
|
| +
|
| + len = strlen (s);
|
| + thevalue = xmemdup (s, len + 1, len + 1);
|
| + type = builtin_type (gdbarch)->builtin_char;
|
| + xfree (s);
|
| +
|
| + if (!string_print)
|
| + {
|
| + do_cleanups (old_chain);
|
| + return thevalue;
|
| + }
|
| +
|
| + make_cleanup (xfree, thevalue);
|
| + }
|
| + else
|
| + gdbpy_print_stack ();
|
| + }
|
| + }
|
| + /* If the printer returned a replacement value, set VALUE
|
| + to REPLACEMENT. If there is not a replacement value,
|
| + just use the value passed to this function. */
|
| + if (replacement)
|
| + value = replacement;
|
| + }
|
| + }
|
| + }
|
| +#endif
|
| +
|
| + varobj_formatted_print_options (&opts, format);
|
|
|
| /* If the THEVALUE has contents, it is a regular string. */
|
| if (thevalue)
|
| - LA_PRINT_STRING (stb, type, thevalue, len, encoding, 0, &opts);
|
| + LA_PRINT_STRING (stb, type, (gdb_byte *) thevalue, len, encoding, 0, &opts);
|
| else if (string_print)
|
| /* Otherwise, if string_print is set, and it is not a regular
|
| string, it is a lazy string. */
|
| @@ -2980,7 +2699,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))
|
| {
|
| @@ -3000,10 +2719,10 @@ 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);
|
| + return var->root->lang_ops->value_is_changeable_p (var);
|
| }
|
|
|
| /* Return 1 if that varobj is floating, that is is always evaluated in the
|
| @@ -3015,95 +2734,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;
|
| @@ -3111,7 +2746,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))
|
| {
|
| @@ -3128,1022 +2763,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;
|
| -}
|
| -
|
| -/* If frame associated with VAR can be found, switch
|
| - to it and return 1. Otherwise, return 0. */
|
| -static int
|
| -check_scope (struct varobj *var)
|
| -{
|
| - struct frame_info *fi;
|
| - int scope;
|
| -
|
| - fi = frame_find_by_id (var->root->frame);
|
| - scope = fi != NULL;
|
| -
|
| - if (fi)
|
| - {
|
| - CORE_ADDR pc = get_frame_pc (fi);
|
| -
|
| - if (pc < BLOCK_START (var->root->valid_block) ||
|
| - pc >= BLOCK_END (var->root->valid_block))
|
| - scope = 0;
|
| - else
|
| - select_frame (fi);
|
| - }
|
| - return scope;
|
| -}
|
| -
|
| -static struct value *
|
| -c_value_of_root (struct varobj **var_handle)
|
| -{
|
| - struct value *new_val = NULL;
|
| - struct varobj *var = *var_handle;
|
| - int within_scope = 0;
|
| - struct cleanup *back_to;
|
| -
|
| - /* Only root variables can be updated... */
|
| - if (!is_root_p (var))
|
| - /* Not a root var. */
|
| - return NULL;
|
| -
|
| - back_to = make_cleanup_restore_current_thread ();
|
| -
|
| - /* Determine whether the variable is still around. */
|
| - if (var->root->valid_block == NULL || var->root->floating)
|
| - within_scope = 1;
|
| - else if (var->root->thread_id == 0)
|
| - {
|
| - /* The program was single-threaded when the variable object was
|
| - created. Technically, it's possible that the program became
|
| - multi-threaded since then, but we don't support such
|
| - scenario yet. */
|
| - within_scope = check_scope (var);
|
| - }
|
| - else
|
| - {
|
| - ptid_t ptid = thread_id_to_pid (var->root->thread_id);
|
| - if (in_thread_list (ptid))
|
| - {
|
| - switch_to_thread (ptid);
|
| - within_scope = check_scope (var);
|
| - }
|
| - }
|
| -
|
| - if (within_scope)
|
| - {
|
| - volatile struct gdb_exception except;
|
| -
|
| - /* We need to catch errors here, because if evaluate
|
| - expression fails we want to just return NULL. */
|
| - TRY_CATCH (except, RETURN_MASK_ERROR)
|
| - {
|
| - new_val = evaluate_expression (var->root->exp);
|
| - }
|
| -
|
| - return new_val;
|
| - }
|
| -
|
| - do_cleanups (back_to);
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -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_root (struct varobj **var_handle)
|
| -{
|
| - return c_value_of_root (var_handle);
|
| -}
|
| -
|
| -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_root (struct varobj **var_handle)
|
| -{
|
| - return cplus_value_of_root (var_handle);
|
| -}
|
| -
|
| -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_root (struct varobj **var_handle)
|
| -{
|
| - return c_value_of_root (var_handle);
|
| -}
|
| -
|
| -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. */
|
|
|
| @@ -4171,28 +2790,27 @@ _initialize_varobj (void)
|
| varobj_table = xmalloc (sizeof_table);
|
| memset (varobj_table, 0, sizeof_table);
|
|
|
| - add_setshow_zinteger_cmd ("debugvarobj", class_maintenance,
|
| - &varobjdebug,
|
| - _("Set varobj debugging."),
|
| - _("Show varobj debugging."),
|
| - _("When non-zero, varobj debugging is enabled."),
|
| - NULL, show_varobjdebug,
|
| - &setlist, &showlist);
|
| + add_setshow_zuinteger_cmd ("debugvarobj", class_maintenance,
|
| + &varobjdebug,
|
| + _("Set varobj debugging."),
|
| + _("Show varobj debugging."),
|
| + _("When non-zero, varobj debugging is enabled."),
|
| + NULL, show_varobjdebug,
|
| + &setlist, &showlist);
|
| }
|
|
|
| /* Invalidate varobj VAR if it is tied to locals and re-create it if it is
|
| - defined on globals. It is a helper for varobj_invalidate. */
|
| + defined on globals. It is a helper for varobj_invalidate.
|
| +
|
| + This function is called after changing the symbol file, in this case the
|
| + pointers to "struct type" stored by the varobj are no longer valid. All
|
| + varobj must be either re-evaluated, or marked as invalid here. */
|
|
|
| static void
|
| varobj_invalidate_iter (struct varobj *var, void *unused)
|
| {
|
| - /* Floating varobjs are reparsed on each stop, so we don't care if the
|
| - presently parsed expression refers to something that's gone. */
|
| - if (var->root->floating)
|
| - return;
|
| -
|
| - /* global var must be re-evaluated. */
|
| - if (var->root->valid_block == NULL)
|
| + /* global and floating var must be re-evaluated. */
|
| + if (var->root->floating || var->root->valid_block == NULL)
|
| {
|
| struct varobj *tmp_var;
|
|
|
|
|