/* Implementation of the GDB variable objects API.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1999-2012 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
#include "expression.h"
#include "frame.h"
#include "language.h"
-#include "wrapper.h"
#include "gdbcmd.h"
#include "block.h"
#include "valprint.h"
typedef int PyObject;
#endif
+/* The names of varobjs representing anonymous structs or unions. */
+#define ANONYMOUS_STRUCT_NAME _("<anonymous struct>")
+#define ANONYMOUS_UNION_NAME _("<anonymous union>")
+
/* Non-zero if we want to see trace of varobj level stuff. */
int varobjdebug = 0;
fprintf_filtered (file, _("Varobj debugging is %s.\n"), value);
}
-/* String representations of gdb's format codes */
+/* String representations of gdb's format codes. */
char *varobj_format_string[] =
{ "natural", "binary", "decimal", "hexadecimal", "octal" };
-/* String representations of gdb's known languages */
+/* 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. */
/* Data structures */
/* Every root variable has one of these structures saved in its
- varobj. Members which must be free'd are noted. */
+ varobj. Members which must be free'd are noted. */
struct varobj_root
{
- /* Alloc'd expression for this parent. */
+ /* Alloc'd expression for this parent. */
struct expression *exp;
- /* Block for which this expression is valid */
+ /* Block for which this expression is valid. */
struct block *valid_block;
/* The frame for this expression. This field is set iff valid_block is
struct frame_id frame;
/* The thread ID that this varobj_root belong to. This field
- is only valid if valid_block is not NULL.
+ is only valid if valid_block is not NULL.
When not 0, indicates which thread 'frame' belongs to.
When 0, indicates that the thread list was empty when the varobj_root
was created. */
/* If 1, the -var-update always recomputes the value in the
current thread and frame. Otherwise, variable object is
- always updated in the specific scope/thread/frame */
+ always updated in the specific scope/thread/frame. */
int floating;
/* Flag that indicates validity: set to 0 when this varobj_root refers
to symbols that do not exist anymore. */
int is_valid;
- /* Language info for this variable and its children */
+ /* Language info for this variable and its children. */
struct language_specific *lang;
- /* The varobj for this root node. */
+ /* The varobj for this root node. */
struct varobj *rootvar;
/* Next root variable */
};
/* 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. */
+ 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
+ /* 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" */
+ (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. */
+ /* 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 */
+ /* Index of this variable in its parent or -1. */
int index;
/* The type of this variable. This can be NULL
the value is either NULL, or not lazy. */
struct value *value;
- /* The number of (immediate) children this variable has */
+ /* The number of (immediate) children this variable has. */
int num_children;
- /* If this object is a child, this points to its immediate parent. */
+ /* If this object is a child, this points to its immediate parent. */
struct varobj *parent;
/* Children of this object. */
can avoid that. */
int children_requested;
- /* Description of the root variable. Points to root variable for children. */
+ /* Description of the root variable. Points to root variable for
+ children. */
struct varobj_root *root;
- /* The format of the output for this object */
+ /* The format of the output for this object. */
enum varobj_display_formats format;
- /* Was this variable updated via a varobj_set_value operation */
+ /* Was this variable updated via a varobj_set_value operation. */
int updated;
/* Last print value. */
/* Private function prototypes */
-/* Helper functions for the above subcommands. */
+/* Helper functions for the above subcommands. */
static int delete_variable (struct cpstack **, struct varobj *, int);
static int install_new_value (struct varobj *var, struct value *value,
int initial);
-/* Language-specific routines. */
+/* Language-specific routines. */
static enum varobj_languages variable_language (struct varobj *var);
#if HAVE_PYTHON
-static struct varobj *
-varobj_add_child (struct varobj *var, const char *name, struct value *value);
+static struct varobj *varobj_add_child (struct varobj *var,
+ const char *name,
+ struct value *value);
#endif /* HAVE_PYTHON */
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);
+
/* The language specific vector */
struct language_specific
{
- /* The language of this variable */
+ /* The language of this variable. */
enum varobj_languages language;
- /* The number of children of PARENT. */
+ /* The number of children of PARENT. */
int (*number_of_children) (struct varobj * parent);
- /* The name (expression) of a root varobj. */
+ /* The name (expression) of a root varobj. */
char *(*name_of_variable) (struct varobj * parent);
- /* The name of the INDEX'th child of 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. */
+ /* 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. */
+ /* 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. */
+ /* The type of the INDEX'th child of PARENT. */
struct type *(*type_of_child) (struct varobj * parent, int index);
- /* The current value of VAR. */
+ /* The current value of VAR. */
char *(*value_of_variable) (struct varobj * var,
enum varobj_display_formats format);
};
-/* Array of known source language routines. */
+/* Array of known source language routines. */
static struct language_specific languages[vlang_end] = {
- /* Unknown (try treating as C */
+ /* Unknown (try treating as C). */
{
vlang_unknown,
c_number_of_children,
java_value_of_root,
java_value_of_child,
java_type_of_child,
- java_value_of_variable}
+ java_value_of_variable},
+ /* 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}
};
-/* A little convenience enum for dealing with C++/Java */
+/* 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 */
+/* Mappings of varobj_display_formats enums to gdb's format codes. */
static int format_code[] = { 0, 't', 'd', 'x', 'o' };
-/* Header of the list of root variable objects */
+/* Header of the list of root variable objects. */
static struct varobj_root *rootlist;
-/* Prime number indicating the number of buckets in the hash table */
-/* A prime large enough to avoid too many colisions */
+/* Prime number indicating the number of buckets in the hash table. */
+/* A prime large enough to avoid too many colisions. */
#define VAROBJ_TABLE_SIZE 227
-/* Pointer to the varobj hash table (built at run time) */
+/* Pointer to the varobj hash table (built at run time). */
static struct vlist **varobj_table;
-/* Is the variable X one of our "fake" children? */
+/* Is the variable X one of our "fake" children? */
#define CPLUS_FAKE_CHILD(x) \
((x) != NULL && (x)->type == NULL && (x)->value == NULL)
\f
}
#endif
-/* Creates a varobj (not its children) */
+/* Creates a varobj (not its children). */
/* Return the full FRAME which corresponds to the given CORE_ADDR
or NULL if no FRAME on the chain corresponds to CORE_ADDR. */
struct varobj *var;
struct cleanup *old_chain;
- /* Fill out a varobj structure for the (root) variable being constructed. */
+ /* Fill out a varobj structure for the (root) variable being constructed. */
var = new_root_variable ();
old_chain = make_cleanup_free_variable (var);
char *p;
enum varobj_languages lang;
struct value *value = NULL;
+ volatile struct gdb_exception except;
/* Parse and evaluate the expression, filling in as much of the
variable's data as possible. */
if (has_stack_frames ())
{
- /* Allow creator to specify context of variable */
+ /* Allow creator to specify context of variable. */
if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME))
fi = get_selected_frame (NULL);
else
else
fi = NULL;
- /* frame = -2 means always use selected frame */
+ /* frame = -2 means always use selected frame. */
if (type == USE_SELECTED_FRAME)
var->root->floating = 1;
p = expression;
innermost_block = NULL;
/* Wrap the call to parse expression, so we can
- return a sensible error. */
- if (!gdb_parse_exp_1 (&p, block, 0, &var->root->exp))
+ return a sensible error. */
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
+ var->root->exp = parse_exp_1 (&p, block, 0);
+ }
+
+ if (except.reason < 0)
+ {
+ do_cleanups (old_chain);
return NULL;
}
- /* Don't allow variables to be created for types. */
+ /* Don't allow variables to be created for types. */
if (var->root->exp->elts[0].opcode == OP_TYPE)
{
do_cleanups (old_chain);
/* When the frame is different from the current frame,
we must select the appropriate frame before parsing
the expression, otherwise the value will not be current.
- Since select_frame is so benign, just call it for all cases. */
+ Since select_frame is so benign, just call it for all cases. */
if (innermost_block)
{
/* User could specify explicit FRAME-ADDR which was not found but
/* We definitely need to catch errors here.
If evaluate_expression succeeds we got the value we wanted.
- But if it fails, we still go on with a call to evaluate_type() */
- if (!gdb_evaluate_expression (var->root->exp, &value))
+ But if it fails, we still go on with a call to evaluate_type(). */
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value = evaluate_expression (var->root->exp);
+ }
+
+ if (except.reason < 0)
{
/* Error getting the value. Try to at least get the
right type. */
lang = variable_language (var);
var->root->lang = &languages[lang];
- /* Set ourselves as our root */
+ /* Set ourselves as our root. */
var->root->rootvar = var;
- /* Reset the selected frame */
+ /* Reset the selected frame. */
if (frame_id_p (old_id))
select_frame (frame_find_by_id (old_id));
}
/* If the variable object name is null, that means this
- is a temporary variable, so don't install it. */
+ is a temporary variable, so don't install it. */
if ((var != NULL) && (objname != NULL))
{
var->obj_name = xstrdup (objname);
/* If a varobj name is duplicated, the install will fail so
- we must clenup */
+ we must cleanup. */
if (!install_variable (var))
{
do_cleanups (old_chain);
return var;
}
-/* Generates an unique name that can be used for a varobj */
+/* Generates an unique name that can be used for a varobj. */
char *
varobj_gen_name (void)
static int id = 0;
char *obj_name;
- /* generate a name for this object */
+ /* Generate a name for this object. */
id++;
obj_name = xstrprintf ("var%d", id);
return cv->var;
}
-/* Given the handle, return the name of the object */
+/* Given the handle, return the name of the object. */
char *
varobj_get_objname (struct varobj *var)
return var->obj_name;
}
-/* Given the handle, return the expression represented by the object */
+/* Given the handle, return the expression represented by the object. */
char *
varobj_get_expression (struct varobj *var)
/* Deletes a varobj and all its children if only_children == 0,
otherwise deletes only the children; returns a malloc'ed list of
all the (malloc'ed) names of the variables that have been deleted
- (NULL terminated) */
+ (NULL terminated). */
int
varobj_delete (struct varobj *var, char ***dellist, int only_children)
struct cpstack *result = NULL;
char **cp;
- /* Initialize a stack for temporary results */
+ /* Initialize a stack for temporary results. */
cppush (&result, NULL);
if (only_children)
- /* Delete only the variable children */
+ /* Delete only the variable children. */
delcount = delete_variable (&result, var, 1 /* only the children */ );
else
- /* Delete the variable and all its children */
+ /* Delete the variable and all its children. */
delcount = delete_variable (&result, var, 0 /* parent+children */ );
- /* We may have been asked to return a list of what has been deleted */
+ /* We may have been asked to return a list of what has been deleted. */
if (dellist != NULL)
{
*dellist = xmalloc ((delcount + 1) * sizeof (char *));
printer = PyObject_CallFunctionObjArgs (constructor, val_obj, NULL);
Py_DECREF (val_obj);
return printer;
- return NULL;
}
#endif
-/* Set/Get variable object display format */
+/* Set/Get variable object display format. */
enum varobj_display_formats
varobj_set_display_format (struct varobj *var,
/* If the variable object is bound to a specific thread, that
is its evaluation can always be done in context of a frame
inside that thread, returns GDB id of the thread -- which
- is always positive. Otherwise, returns -1. */
+ is always positive. Otherwise, returns -1. */
int
varobj_get_thread_id (struct varobj *var)
{
for (; to < 0 || i < to + 1; ++i)
{
PyObject *item;
+ int force_done = 0;
/* See if there was a leftover from last time. */
if (var->saved_item)
item = PyIter_Next (var->child_iter);
if (!item)
- break;
+ {
+ /* Normal end of iteration. */
+ if (!PyErr_Occurred ())
+ break;
+
+ /* If we got a memory error, just use the text as the
+ item. */
+ if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
+ {
+ PyObject *type, *value, *trace;
+ char *name_str, *value_str;
+
+ PyErr_Fetch (&type, &value, &trace);
+ value_str = gdbpy_exception_to_string (type, value);
+ Py_XDECREF (type);
+ Py_XDECREF (value);
+ Py_XDECREF (trace);
+ if (!value_str)
+ {
+ gdbpy_print_stack ();
+ break;
+ }
+
+ name_str = xstrprintf ("<error at %d>", i);
+ item = Py_BuildValue ("(ss)", name_str, value_str);
+ xfree (name_str);
+ xfree (value_str);
+ if (!item)
+ {
+ gdbpy_print_stack ();
+ break;
+ }
+
+ force_done = 1;
+ }
+ else
+ {
+ /* Any other kind of error. */
+ gdbpy_print_stack ();
+ break;
+ }
+ }
/* We don't want to push the extra child on any report list. */
if (to < 0 || i < to)
{
PyObject *py_v;
- char *name;
+ const char *name;
struct value *v;
struct cleanup *inner;
int can_mention = from < 0 || i >= from;
inner = make_cleanup_py_decref (item);
if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- error (_("Invalid item from the child list"));
+ {
+ gdbpy_print_stack ();
+ error (_("Invalid item from the child list"));
+ }
v = convert_value_from_python (py_v);
if (v == NULL)
element. */
break;
}
+
+ if (force_done)
+ break;
}
if (i < VEC_length (varobj_p, var->children))
}
/* Creates a list of the immediate children of a variable object;
- the return code is the number of such children or -1 on error */
+ the return code is the number of such children or -1 on error. */
VEC (varobj_p)*
varobj_list_children (struct varobj *var, int *from, int *to)
#endif /* HAVE_PYTHON */
/* Obtain the type of an object Variable as a string similar to the one gdb
- prints on the console */
+ prints on the console. */
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. (It's type is
NULL, too.)
Do not return a type for invalid variables as well. */
if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
return var->type;
}
+/* Is VAR a path expression parent, i.e., can it be used to construct
+ a valid path expression? */
+
+static int
+is_path_expr_parent (struct varobj *var)
+{
+ struct type *type;
+
+ /* "Fake" children are not path_expr parents. */
+ if (CPLUS_FAKE_CHILD (var))
+ return 0;
+
+ type = get_value_type (var);
+
+ /* Anonymous unions and structs are also not path_expr parents. */
+ return !((TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ && TYPE_NAME (type) == NULL);
+}
+
+/* Return the path expression parent for VAR. */
+
+static struct varobj *
+get_path_expr_parent (struct varobj *var)
+{
+ struct varobj *parent = var;
+
+ while (!is_root_p (parent) && !is_path_expr_parent (parent))
+ parent = parent->parent;
+
+ return parent;
+}
+
/* Return a pointer to the full rooted expression of varobj VAR.
If it has not been computed yet, compute it. */
char *
int attributes = 0;
if (varobj_editable_p (var))
- /* FIXME: define masks for attributes */
+ /* FIXME: define masks for attributes. */
attributes |= 0x00000001; /* Editable */
return attributes;
}
/* Set the value of an object variable (if it is editable) to the
- value of the given expression */
-/* Note: Invokes functions that can call error() */
+ value of the given expression. */
+/* Note: Invokes functions that can call error(). */
int
varobj_set_value (struct varobj *var, char *expression)
{
- struct value *val;
-
+ struct value *val = NULL; /* Initialize to keep gcc happy. */
/* The argument "expression" contains the variable's new value.
- We need to first construct a legal expression for this -- ugh! */
- /* Does this cover all the bases? */
+ We need to first construct a legal expression for this -- ugh! */
+ /* Does this cover all the bases? */
struct expression *exp;
- struct value *value;
+ struct value *value = NULL; /* Initialize to keep gcc happy. */
int saved_input_radix = input_radix;
char *s = expression;
+ volatile struct gdb_exception except;
gdb_assert (varobj_editable_p (var));
- input_radix = 10; /* ALWAYS reset to decimal temporarily */
+ input_radix = 10; /* ALWAYS reset to decimal temporarily. */
exp = parse_exp_1 (&s, 0, 0);
- if (!gdb_evaluate_expression (exp, &value))
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value = evaluate_expression (exp);
+ }
+
+ if (except.reason < 0)
{
- /* We cannot proceed without a valid expression. */
+ /* We cannot proceed without a valid expression. */
xfree (exp);
return 0;
}
after assignment, and the first thing value_assign
does is coerce the input.
For example, if we are assigning an array to a pointer variable we
- should compare the pointer with the the array's address, not with the
+ should compare the pointer with the array's address, not with the
array's content. */
value = coerce_array (value);
- /* The new value may be lazy. gdb_value_assign, or
- rather value_contents, will take care of this.
- If fetching of the new value will fail, gdb_value_assign
- with catch the exception. */
- if (!gdb_value_assign (var->value, value, &val))
+ /* The new value may be lazy. value_assign, or
+ rather value_contents, will take care of this. */
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ val = value_assign (var->value, value);
+ }
+
+ if (except.reason < 0)
return 0;
-
+
/* If the value has changed, record it, so that next -var-update can
report this change. If a variable had a value of '1', we've set it
to '333' and then set again to '1', when -var-update will report this
variable as changed -- because the first assignment has set the
'updated' flag. There's no need to optimize that, because return value
of -var-update should be considered an approximation. */
- var->updated = install_new_value (var, val, 0 /* Compare values. */);
+ var->updated = install_new_value (var, val, 0 /* Compare values. */);
input_radix = saved_input_radix;
return 1;
}
static void
install_default_visualizer (struct varobj *var)
{
+ /* Do not install a visualizer on a CPLUS_FAKE_CHILD. */
+ if (CPLUS_FAKE_CHILD (var))
+ return;
+
if (pretty_printing)
{
PyObject *pretty_printer = NULL;
{
PyObject *pretty_printer;
+ /* Do not install a visualizer on a CPLUS_FAKE_CHILD. */
+ if (CPLUS_FAKE_CHILD (var))
+ return;
+
Py_INCREF (constructor);
if (constructor == Py_None)
pretty_printer = NULL;
this is the first assignement after the variable object was just
created, or changed type. In that case, just assign the value
and return 0.
- Otherwise, assign the new value, and return 1 if the value is different
- from the current one, 0 otherwise. The comparison is done on textual
- representation of value. Therefore, some types need not be compared. E.g.
- for structures the reported value is always "{...}", so no comparison is
- necessary here. If the old value was NULL and new one is not, or vice versa,
- we always return 1.
+ Otherwise, assign the new value, and return 1 if the value is
+ different from the current one, 0 otherwise. The comparison is
+ done on textual representation of value. Therefore, some types
+ need not be compared. E.g. for structures the reported value is
+ always "{...}", so no comparison is necessary here. If the old
+ value was NULL and new one is not, or vice versa, we always return 1.
The VALUE parameter should not be released -- the function will
take care of releasing it when needed. */
/* We need to know the varobj's type to decide if the value should
be fetched or not. C++ fake children (public/protected/private)
- don't have a type. */
+ don't have a type. */
gdb_assert (var->type || CPLUS_FAKE_CHILD (var));
changeable = varobj_value_is_changeable_p (var);
/* If the type has custom visualizer, we consider it to be always
- changeable. FIXME: need to make sure this behaviour will not
+ changeable. FIXME: need to make sure this behaviour will not
mess up read-sensitive values. */
if (var->pretty_printer)
changeable = 1;
explicitly asked to compare the new value with the old one. */
intentionally_not_fetched = 1;
}
- else if (!gdb_value_fetch_lazy (value))
+ else
{
- /* Set the value to NULL, so that for the next -var-update,
- we don't try to compare the new value with this value,
- that we couldn't even read. */
- value = NULL;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value_fetch_lazy (value);
+ }
+
+ if (except.reason < 0)
+ {
+ /* Set the value to NULL, so that for the next -var-update,
+ we don't try to compare the new value with this value,
+ that we couldn't even read. */
+ value = NULL;
+ }
}
}
+ /* Get a reference now, before possibly passing it to any Python
+ code that might release it. */
+ if (value != NULL)
+ value_incref (value);
/* Below, we'll be comparing string rendering of old and new
values. Don't get string rendering if the value is
/* If the value of the varobj was changed by -var-set-value,
then the value in the varobj and in the target is the same.
However, that value is different from the value that the
- varobj had after the previous -var-update. So need to the
+ varobj had after the previous -var-update. So need to the
varobj as changed. */
if (var->updated)
{
changed = 1;
}
else if (var->value == NULL && value == NULL)
- /* Equal. */
+ /* Equal. */
;
else if (var->value == NULL || value == NULL)
{
if (var->value != NULL && var->value != value)
value_free (var->value);
var->value = value;
- if (value != NULL)
- value_incref (value);
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = 1;
else
The EXPLICIT parameter specifies if this call is result
of MI request to update this specific variable, or
- result of implicit -var-update *. For implicit request, we don't
+ result of implicit -var-update *. For implicit request, we don't
update frozen variables.
- NOTE: This function may delete the caller's varobj. If it
+ NOTE: This function may delete the caller's varobj. If it
returns TYPE_CHANGED, then it has done this and VARP will be modified
to point to the new varobj. */
-VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
+VEC(varobj_update_result) *
+varobj_update (struct varobj **varp, int explicit)
{
int changed = 0;
int type_changed = 0;
r.varobj = *varp;
r.status = VAROBJ_IN_SCOPE;
- /* Update the root variable. value_of_root can return NULL
+ /* Update the root variable. value_of_root can return NULL
if the variable is no longer around, i.e. we stepped out of
- the frame in which a local existed. We are letting the
+ the frame in which a local existed. We are letting the
value_of_root variable dispose of the varobj if the type
has changed. */
new = value_of_root (varp, &type_changed);
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
- invoked. */
+ invoked. */
if (v->pretty_printer)
{
VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
return delcount;
}
-/* Delete the variable object VAR and its children */
+/* Delete the variable object VAR and its children. */
/* IMPORTANT NOTE: If we delete a variable which is a child
and the parent is not removed we dump core. It must be always
- initially called with remove_from_parent_p set */
+ initially called with remove_from_parent_p set. */
static void
delete_variable_1 (struct cpstack **resultp, int *delcountp,
struct varobj *var, int only_children_p,
{
int i;
- /* Delete any children of this variable, too. */
+ /* Delete any children of this variable, too. */
for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
{
varobj_p child = VEC_index (varobj_p, var->children, i);
}
VEC_free (varobj_p, var->children);
- /* if we were called to delete only the children we are done here */
+ /* if we were called to delete only the children we are done here. */
if (only_children_p)
return;
- /* Otherwise, add it to the list of deleted ones and proceed to do so */
+ /* Otherwise, add it to the list of deleted ones and proceed to do so. */
/* If the name is null, this is a temporary variable, that has not
- yet been installed, don't report it, it belongs to the caller... */
+ yet been installed, don't report it, it belongs to the caller... */
if (var->obj_name != NULL)
{
cppush (resultp, xstrdup (var->obj_name));
*delcountp = *delcountp + 1;
}
- /* If this variable has a parent, remove it from its parent's list */
+ /* If this variable has a parent, remove it from its parent's list. */
/* OPTIMIZATION: if the parent of this variable is also being deleted,
(as indicated by remove_from_parent_p) we don't bother doing an
expensive list search to find the element to remove when we are
- discarding the list afterwards */
+ discarding the list afterwards. */
if ((remove_from_parent_p) && (var->parent != NULL))
{
VEC_replace (varobj_p, var->parent->children, var->index, NULL);
if (var->obj_name != NULL)
uninstall_variable (var);
- /* Free memory associated with this variable */
+ /* Free memory associated with this variable. */
free_variable (var);
}
-/* Install the given variable VAR with the object name VAR->OBJ_NAME. */
+/* Install the given variable VAR with the object name VAR->OBJ_NAME. */
static int
install_variable (struct varobj *var)
{
if (cv != NULL)
error (_("Duplicate variable object name"));
- /* Add varobj to hash table */
+ /* Add varobj to hash table. */
newvl = xmalloc (sizeof (struct vlist));
newvl->next = *(varobj_table + index);
newvl->var = var;
*(varobj_table + index) = newvl;
- /* If root, add varobj to root list */
+ /* If root, add varobj to root list. */
if (is_root_p (var))
{
- /* Add to list of root variables */
+ /* Add to list of root variables. */
if (rootlist == NULL)
var->root->next = NULL;
else
return 1; /* OK */
}
-/* Unistall the object VAR. */
+/* Unistall the object VAR. */
static void
uninstall_variable (struct varobj *var)
{
unsigned int index = 0;
unsigned int i = 1;
- /* Remove varobj from hash table */
+ /* Remove varobj from hash table. */
for (chp = var->obj_name; *chp; chp++)
{
index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
xfree (cv);
- /* If root, remove varobj from root list */
+ /* If root, remove varobj from root list. */
if (is_root_p (var))
{
- /* Remove from list of root variables */
+ /* Remove from list of root variables. */
if (rootlist == var->root)
rootlist = var->root->next;
else
}
if (cr == NULL)
{
- warning ("Assertion failed: Could not find "
- "varobj \"%s\" in root list",
+ warning (_("Assertion failed: Could not find "
+ "varobj \"%s\" in root list"),
var->obj_name);
return;
}
}
-/* Create and install a child of the parent of the given name */
+/* Create and install a child of the parent of the given name. */
static struct varobj *
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,
struct value *value)
child = new_variable ();
- /* name is allocated by name_of_child */
+ /* Name is allocated by name_of_child. */
/* FIXME: xstrdup should not be here. */
child->name = xstrdup (name);
child->index = index;
child->parent = parent;
child->root = parent->root;
- childs_name = xstrprintf ("%s.%s", parent->obj_name, name);
+
+ if (is_anonymous_child (child))
+ childs_name = xstrprintf ("%s.%d_anonymous", parent->obj_name, index);
+ else
+ childs_name = xstrprintf ("%s.%s", parent->obj_name, name);
child->obj_name = childs_name;
+
install_variable (child);
/* Compute the type of the child. Must do this before
calling install_new_value. */
if (value != NULL)
/* If the child had no evaluation errors, var->value
- will be non-NULL and contain a valid type. */
+ will be non-NULL and contain a valid type. */
child->type = value_type (value);
else
- /* Otherwise, we must compute the type. */
+ /* Otherwise, we must compute the type. */
child->type = (*child->root->lang->type_of_child) (child->parent,
child->index);
install_new_value (child, value, 1);
* Miscellaneous utility functions.
*/
-/* Allocate memory and initialize a new variable */
+/* Allocate memory and initialize a new variable. */
static struct varobj *
new_variable (void)
{
return var;
}
-/* Allocate memory and initialize a new root variable */
+/* Allocate memory and initialize a new root variable. */
static struct varobj *
new_root_variable (void)
{
return var;
}
-/* Free any allocated memory associated with VAR. */
+/* Free any allocated memory associated with VAR. */
static void
free_variable (struct varobj *var)
{
value_free (var->value);
- /* Free the expression if this is a root variable. */
+ /* Free the expression if this is a root variable. */
if (is_root_p (var))
{
xfree (var->root->exp);
return make_cleanup (do_free_variable_cleanup, var);
}
-/* This returns the type of the variable. It also skips past typedefs
+/* 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. */
+ except within get_target_type and get_type. */
static struct type *
get_type (struct varobj *var)
{
/* Return the type of the value that's stored in VAR,
or that would have being stored there if the
- value were accessible.
+ value were accessible.
This differs from VAR->type in that VAR->type is always
the true type of the expession in the source language.
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. */
+ except within get_target_type and get_type. */
static struct type *
get_target_type (struct type *type)
{
}
/* What is the default display for this variable? We assume that
- everything is "natural". Any exceptions? */
+ everything is "natural". Any exceptions? */
static enum varobj_display_formats
variable_default_display (struct varobj *var)
{
return FORMAT_NATURAL;
}
-/* FIXME: The following should be generic for any pointer */
+/* FIXME: The following should be generic for any pointer. */
static void
cppush (struct cpstack **pstack, char *name)
{
*pstack = s;
}
-/* FIXME: The following should be generic for any pointer */
+/* FIXME: The following should be generic for any pointer. */
static char *
cppop (struct cpstack **pstack)
{
/* Common entry points */
-/* Get the language of variable VAR. */
+/* Get the language of variable VAR. */
static enum varobj_languages
variable_language (struct varobj *var)
{
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
+ implementation. The number of children returned by this function
is the number of children that the user will see in the variable
- display. */
+ display. */
static int
number_of_children (struct varobj *var)
{
- return (*var->root->lang->number_of_children) (var);;
+ return (*var->root->lang->number_of_children) (var);
}
/* What is the expression for the root varobj VAR? Returns a malloc'd
- string. */
+ string. */
static char *
name_of_variable (struct varobj *var)
{
}
/* What is the name of the INDEX'th child of VAR? Returns a malloc'd
- string. */
+ string. */
static char *
name_of_child (struct varobj *var, int index)
{
var = *var_handle;
/* This should really be an exception, since this should
- only get called with a root variable. */
+ only get called with a root variable. */
if (!is_root_p (var))
return NULL;
return (*var->root->lang->value_of_root) (var_handle);
}
-/* What is the ``struct value *'' for the INDEX'th child of PARENT? */
+/* What is the ``struct value *'' for the INDEX'th child of PARENT? */
static struct value *
value_of_child (struct varobj *parent, int index)
{
return value;
}
-/* GDB already has a command called "value_of_variable". Sigh. */
+/* GDB already has a command called "value_of_variable". Sigh. */
static char *
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
{
- char *hint;
struct value *replacement;
PyObject *output = NULL;
- hint = gdbpy_get_display_hint (value_formatter);
- if (hint)
- {
- if (!strcmp (hint, "string"))
- string_print = 1;
- xfree (hint);
- }
-
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,
}
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);
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;
}
get_formatted_print_options (&opts, format_code[(int) format]);
opts.deref_ref = 0;
opts.raw = 1;
+
+ /* If the THEVALUE has contents, it is a regular string. */
if (thevalue)
LA_PRINT_STRING (stb, type, 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. */
val_print_string (type, encoding, str_addr, len, stb, &opts);
else
+ /* All other cases. */
common_val_print (value, stb, 0, &opts, current_language);
+
thevalue = ui_file_xstrdup (stb, NULL);
do_cleanups (old_chain);
for getting children of the variable object.
This includes dereferencing top-level references
to all types and dereferencing pointers to
- structures.
+ structures.
- Both TYPE and *TYPE should be non-null. VALUE
+ 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.
+ value is not known.
If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1
depending on whether pointer was dereferenced
{
if (value && *value)
{
- int success = gdb_value_ind (*value, value);
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ *value = value_ind (*value);
+ }
- if (!success)
+ if (except.reason < 0)
*value = NULL;
}
*type = target_type;
break;
case TYPE_CODE_PTR:
- /* The type here is a pointer to non-struct. Typically, pointers
+ /* 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" */
+ TYPE_NAME == "char". */
if (TYPE_CODE (target) == TYPE_CODE_FUNC
|| TYPE_CODE (target) == TYPE_CODE_VOID)
children = 0;
break;
default:
- /* Other types have no children */
+ /* Other types have no children. */
break;
}
/* 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.
+ or union, or a typedef to struct/union.
Returns NULL if getting the value fails. Never throws. */
static struct value *
}
/* Obtain the information about child INDEX of the variable
- object PARENT.
+ 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.
struct type *type = get_value_type (parent);
char *parent_expression = NULL;
int was_ptr;
+ volatile struct gdb_exception except;
if (cname)
*cname = NULL;
if (cfull_expression)
{
*cfull_expression = NULL;
- parent_expression = varobj_get_path_expr (parent);
+ parent_expression = varobj_get_path_expr (get_path_expr_parent (parent));
}
adjust_value_for_child_access (&value, &type, &was_ptr);
{
int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
- gdb_value_subscript (value, real_index, cvalue);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ *cvalue = value_subscript (value, real_index);
+ }
}
if (ctype)
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
- if (cname)
- *cname = xstrdup (TYPE_FIELD_NAME (type, index));
+ {
+ const char *field_name;
- if (cvalue && value)
- {
- /* For C, varobj index is the same as type index. */
- *cvalue = value_struct_element_index (value, index);
- }
+ /* 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 (ctype)
- *ctype = TYPE_FIELD_TYPE (type, index);
+ if (cfull_expression)
+ *cfull_expression = xstrdup ("");
+ }
+ else
+ {
+ if (cname)
+ *cname = xstrdup (field_name);
- if (cfull_expression)
- {
- char *join = was_ptr ? "->" : ".";
+ if (cfull_expression)
+ {
+ char *join = was_ptr ? "->" : ".";
- *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join,
- TYPE_FIELD_NAME (type, index));
- }
+ *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 (cvalue && value)
{
- int success = gdb_value_ind (value, cvalue);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ *cvalue = value_ind (value);
+ }
- if (!success)
+ if (except.reason < 0)
*cvalue = NULL;
}
break;
default:
- /* This should not happen */
+ /* 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. */
+ /* Don't set value and type, we don't know then. */
}
}
int within_scope = 0;
struct cleanup *back_to;
- /* Only root variables can be updated... */
+ /* Only root variables can be updated... */
if (!is_root_p (var))
- /* Not a root var */
+ /* Not a root var. */
return NULL;
back_to = make_cleanup_restore_current_thread ();
- /* Determine whether the variable is still around. */
+ /* 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)
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. */
- gdb_evaluate_expression (var->root->exp, &new_val);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ new_val = evaluate_expression (var->root->exp);
+ }
+
return new_val;
}
if (var->pretty_printer && var->print_value)
return xstrdup (var->print_value);
- /* Strip top-level references. */
+ /* Strip top-level references. */
while (TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
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. */
+ member when the parent is an invalid pointer. This is an
+ error condition, so we should tell the caller. */
return NULL;
}
else
gdb_assert (!value_lazy (var->value));
/* If the specified format is the current one,
- we can reuse print_value */
+ we can reuse print_value. */
if (format == var->format)
return xstrdup (var->print_value);
else
if (kids[v_protected] != 0)
children++;
- /* Add any baseclasses */
+ /* Add any baseclasses. */
children += TYPE_N_BASECLASSES (type);
dont_know = 0;
- /* FIXME: save children in var */
+ /* FIXME: save children in var. */
}
}
else
/* 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. */
+ how many are there, too. */
static void
cplus_class_num_children (struct type *type, int children[3])
{
value = parent->parent->value;
type = get_value_type (parent->parent);
if (cfull_expression)
- parent_expression = varobj_get_path_expr (parent->parent);
+ parent_expression
+ = varobj_get_path_expr (get_path_expr_parent (parent->parent));
}
else
{
value = parent->value;
type = get_value_type (parent);
if (cfull_expression)
- parent_expression = varobj_get_path_expr (parent);
+ parent_expression
+ = varobj_get_path_expr (get_path_expr_parent (parent));
}
adjust_value_for_child_access (&value, &type, &was_ptr);
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. */
+ 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)
}
--type_index;
- if (cname)
- *cname = xstrdup (TYPE_FIELD_NAME (type, 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);
-
- if (cfull_expression)
- *cfull_expression
- = xstrprintf ("((%s)%s%s)", parent_expression,
- join,
- TYPE_FIELD_NAME (type, type_index));
}
else if (index < TYPE_N_BASECLASSES (type))
{
{
char *ptr = was_ptr ? "*" : "";
- /* Cast the parent to the base' type. Note that in gdb,
+ /* 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. */
- *cfull_expression = xstrprintf ("(%s(%s%s) %s)",
+ 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,
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". */
+ this order. So if INDEX == 2, it MUST be "protected". */
index -= TYPE_N_BASECLASSES (type);
switch (index)
{
access = "protected";
break;
case 2:
- /* Must be protected */
+ /* Must be protected. */
access = "protected";
break;
default:
- /* error! */
+ /* error! */
break;
}
{
/* If we have one of our special types, don't print out
- any value. */
+ any value. */
if (CPLUS_FAKE_CHILD (var))
return xstrdup ("");
name = cplus_name_of_variable (parent);
/* If the name has "-" in it, it is because we
- needed to escape periods in the name... */
+ needed to escape periods in the name... */
p = name;
while (*p != '\000')
char *name, *p;
name = cplus_name_of_child (parent, index);
- /* Escape any periods in the name... */
+ /* Escape any periods in the name... */
p = name;
while (*p != '\000')
return cplus_value_of_variable (var, format);
}
+/* Ada specific callbacks for VAROBJs. */
+
+static int
+ada_number_of_children (struct varobj *var)
+{
+ return c_number_of_children (var);
+}
+
+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 c_name_of_child (parent, index);
+}
+
+static char*
+ada_path_expr_of_child (struct varobj *child)
+{
+ return c_path_expr_of_child (child);
+}
+
+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 c_value_of_child (parent, index);
+}
+
+static struct type *
+ada_type_of_child (struct varobj *parent, int index)
+{
+ return c_type_of_child (parent, index);
+}
+
+static char *
+ada_value_of_variable (struct varobj *var, enum varobj_display_formats format)
+{
+ return c_value_of_variable (var, format);
+}
+
/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
with an arbitrary caller supplied DATA pointer. */