Implement -var-info-path-expression.
* mi/mi-cmds.h (mi_cmd_var_info_path_expression): Declare. * mi/mi-cmds.c (mi_cmds): Register var-info-path-expression. * mi/mi-cmd-var.c (mi_cmd_var_info_path_expression): New. * varobj.c (struct varobj): New field 'path_expr'. (c_path_expr_of_child, cplus_path_expr_of_child) (java_path_expr_of_child): New. (struct language_specific): New field path_expr_of_child. (varobj_create): Initialize the path_expr field. (varobj_get_path_expr): New. (new_variable): Initialize the path_expr field. (free_variable): Free the path_expr field. (adjust_value_for_children_access): New parameter WAS_TYPE. (c_number_of_children): Adjust. (c_describe_child): New parameter CFULL_EXPRESSION. Compute full expression. (c_value_of_child, c_type_of_child): Adjust. (cplus_number_of_children): Adjust. (cplus_describe_child): New parameter CFULL_EXPRESSION. Compute full expression. (cplus_name_of_child, cplus_value_of_child) (cplus_type_of_child): Adjust. * varobj.h (varobj_get_path_expr): Declare.
This commit is contained in:
parent
144c41d992
commit
02142340a0
@ -1,3 +1,32 @@
|
||||
2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
Implement -var-info-path-expression.
|
||||
|
||||
* mi/mi-cmds.h (mi_cmd_var_info_path_expression):
|
||||
Declare.
|
||||
* mi/mi-cmds.c (mi_cmds): Register var-info-path-expression.
|
||||
* mi/mi-cmd-var.c (mi_cmd_var_info_path_expression): New.
|
||||
* varobj.c (struct varobj): New field 'path_expr'.
|
||||
(c_path_expr_of_child, cplus_path_expr_of_child)
|
||||
(java_path_expr_of_child): New.
|
||||
(struct language_specific): New field path_expr_of_child.
|
||||
(varobj_create): Initialize the path_expr field.
|
||||
(varobj_get_path_expr): New.
|
||||
(new_variable): Initialize the path_expr field.
|
||||
(free_variable): Free the path_expr field.
|
||||
(adjust_value_for_children_access): New parameter
|
||||
WAS_TYPE.
|
||||
(c_number_of_children): Adjust.
|
||||
(c_describe_child): New parameter CFULL_EXPRESSION.
|
||||
Compute full expression.
|
||||
(c_value_of_child, c_type_of_child): Adjust.
|
||||
(cplus_number_of_children): Adjust.
|
||||
(cplus_describe_child): New parameter CFULL_EXPRESSION.
|
||||
Compute full expression.
|
||||
(cplus_name_of_child, cplus_value_of_child)
|
||||
(cplus_type_of_child): Adjust.
|
||||
* varobj.h (varobj_get_path_expr): Declare.
|
||||
|
||||
2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* mi/mi-cmd-var.c (print_varobj): If a varobj
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (Variable Objects): Adjust docs
|
||||
for -var-info-expression and document
|
||||
-var-info-path-expression.
|
||||
|
||||
2007-08-20 Jim Blandy <jimb@codesourcery.com>
|
||||
|
||||
* gdb.texinfo (Top): Dedicate manual to the memory of Fred Fish.
|
||||
|
@ -19312,7 +19312,9 @@ access this functionality:
|
||||
@item @code{-var-info-type}
|
||||
@tab show the type of this variable object
|
||||
@item @code{-var-info-expression}
|
||||
@tab print what this variable object represents
|
||||
@tab print parent-relative expression that this variable object represents
|
||||
@item @code{-var-info-path-expression}
|
||||
@tab print full expression that this variable object represents
|
||||
@item @code{-var-show-attributes}
|
||||
@tab is this variable editable? does it exist here?
|
||||
@item @code{-var-evaluate-expression}
|
||||
@ -19513,14 +19515,50 @@ returned as a string in the same format as it is output by the
|
||||
-var-info-expression @var{name}
|
||||
@end smallexample
|
||||
|
||||
Returns what is represented by the variable object @var{name}:
|
||||
Returns a string that is suitable for presenting this
|
||||
variable object in user interface. The string is generally
|
||||
not valid expression in the current language, and cannot be evaluated.
|
||||
|
||||
For example, if @code{a} is an array, and variable object
|
||||
@code{A} was created for @code{a}, then we'll get this output:
|
||||
|
||||
@smallexample
|
||||
lang=@var{lang-spec},exp=@var{expression}
|
||||
(gdb) -var-info-expression A.1
|
||||
^done,lang="C",exp="1"
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
where @var{lang-spec} is @code{@{"C" | "C++" | "Java"@}}.
|
||||
Here, the values of @code{lang} can be @code{@{"C" | "C++" | "Java"@}}.
|
||||
|
||||
Note that the output of the @code{-var-list-children} command also
|
||||
includes those expressions, so the @code{-var-info-expression} command
|
||||
is of limited use.
|
||||
|
||||
@subheading The @code{-var-info-path-expression} Command
|
||||
@findex -var-info-path-expression
|
||||
|
||||
@subsubheading Synopsis
|
||||
|
||||
@smallexample
|
||||
-var-info-path-expression @var{name}
|
||||
@end smallexample
|
||||
|
||||
Returns an expression that can be evaluated in the current
|
||||
context and will yield the same value that a variable object has.
|
||||
Compare this with the @code{-var-info-expression} command, which
|
||||
result can be used only for UI presentation. Typical use of
|
||||
the @code{-var-info-path-expression} command is creating a
|
||||
watchpoint from a variable object.
|
||||
|
||||
For example, suppose @code{C} is a C@t{++} class, derived from class
|
||||
@code{Base}, and that the @code{Base} class has a member called
|
||||
@code{m_size}. Assume a variable @code{c} is has the type of
|
||||
@code{C} and a variable object @code{C} was created for variable
|
||||
@code{c}. Then, we'll get this output:
|
||||
@smallexample
|
||||
(gdb) -var-info-path-expression C.Base.public.m_size
|
||||
^done,path_expr=((Base)c).m_size)
|
||||
@end smallexample
|
||||
|
||||
@subheading The @code{-var-show-attributes} Command
|
||||
@findex -var-show-attributes
|
||||
|
@ -412,6 +412,27 @@ mi_cmd_var_info_type (char *command, char **argv, int argc)
|
||||
return MI_CMD_DONE;
|
||||
}
|
||||
|
||||
enum mi_cmd_result
|
||||
mi_cmd_var_info_path_expression (char *command, char **argv, int argc)
|
||||
{
|
||||
struct varobj *var;
|
||||
char *path_expr;
|
||||
|
||||
if (argc != 1)
|
||||
error (_("Usage: NAME."));
|
||||
|
||||
/* Get varobj handle, if a valid var obj name was specified. */
|
||||
var = varobj_get_handle (argv[0]);
|
||||
if (var == NULL)
|
||||
error (_("Variable object not found"));
|
||||
|
||||
path_expr = varobj_get_path_expr (var);
|
||||
|
||||
ui_out_field_string (uiout, "path_expr", path_expr);
|
||||
|
||||
return MI_CMD_DONE;
|
||||
}
|
||||
|
||||
enum mi_cmd_result
|
||||
mi_cmd_var_info_expression (char *command, char **argv, int argc)
|
||||
{
|
||||
|
@ -149,6 +149,8 @@ struct mi_cmd mi_cmds[] =
|
||||
{ "var-create", { NULL, 0 }, 0, mi_cmd_var_create},
|
||||
{ "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete},
|
||||
{ "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression},
|
||||
{ "var-info-path-expression", { NULL, 0 }, 0,
|
||||
mi_cmd_var_info_path_expression},
|
||||
{ "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression},
|
||||
{ "var-info-num-children", { NULL, 0 }, 0, mi_cmd_var_info_num_children},
|
||||
{ "var-info-type", { NULL, 0 }, 0, mi_cmd_var_info_type},
|
||||
|
@ -107,6 +107,7 @@ extern mi_cmd_argv_ftype mi_cmd_var_create;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_delete;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_info_expression;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_info_path_expression;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_info_num_children;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_info_type;
|
||||
extern mi_cmd_argv_ftype mi_cmd_var_list_children;
|
||||
|
@ -1,3 +1,9 @@
|
||||
2007-08-31 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* gdb.mi/mi-var-cp.cc (path_expression): New
|
||||
function.
|
||||
* gdb.mi/mi-var-cp.exp: Run path exression tests.
|
||||
|
||||
2007-08-27 Markus Deuling <deuling@de.ibm.com>
|
||||
|
||||
* gdb.cp/cp-relocate.exp (add-symbol-file): Change addresses
|
||||
|
@ -120,11 +120,97 @@ int reference_to_struct ()
|
||||
/*: END: reference_to_struct :*/
|
||||
}
|
||||
|
||||
struct Base1
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
struct Base2
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
struct Derived : public Base1, public Base2
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
/* Test for the -var-info-path-expression command. Although
|
||||
said command is not specific to C++, it's of more importance
|
||||
to C++ than to C, so we test it in mi-var-cp test. */
|
||||
int path_expression ()
|
||||
{
|
||||
/*: BEGIN: path_expression :*/
|
||||
int i = 10;
|
||||
int *ip = &i;
|
||||
/*: mi_create_varobj IP ip "create varobj for ip"
|
||||
mi_list_varobj_children IP {{IP.\\*ip \\*ip 0 int}} "list children of IP"
|
||||
mi_gdb_test "-var-info-path-expression IP.*ip" \
|
||||
"\\^done,path_expr=\"\\*\\(ip\\)\"" \
|
||||
"-var-info-path-expression IP.*ip"
|
||||
:*/
|
||||
Derived d;
|
||||
Derived *dp = &d;
|
||||
/*: mi_create_varobj DP dp "create varobj for dp"
|
||||
mi_list_varobj_children DP \
|
||||
{{DP.Base1 Base1 1 Base1} \
|
||||
{DP.Base2 Base2 1 Base2} \
|
||||
{DP.public public 1}} "list children of DP"
|
||||
mi_gdb_test "-var-info-path-expression DP.Base1" \
|
||||
"\\^done,path_expr=\"\\(\\*\\(Base1\\*\\) dp\\)\"" \
|
||||
"-var-info-path-expression DP.Base1"
|
||||
mi_list_varobj_children DP.public { \
|
||||
{DP.public.i i 0 int} \
|
||||
} "list children of DP.public"
|
||||
mi_gdb_test "-var-info-path-expression DP.public.i" \
|
||||
"\\^done,path_expr=\"\\(\\(dp\\)->i\\)\"" \
|
||||
"-var-info-path-expression DP.public.i"
|
||||
mi_list_varobj_children DP.Base1 { \
|
||||
{DP.Base1.public public 1} \
|
||||
} "list children of DP.Base1"
|
||||
mi_list_varobj_children DP.Base1.public { \
|
||||
{DP.Base1.public.i i 0 int} \
|
||||
} "list children of DP.Base1.public"
|
||||
mi_gdb_test "-var-info-path-expression DP.Base1.public.i" \
|
||||
"\\^done,path_expr=\"\\(\\(\\(\\*\\(Base1\\*\\) dp\\)\\).i\\)\"" \
|
||||
"-var-info-path-expression DP.Base1.public.i"
|
||||
|
||||
mi_gdb_test "-var-info-path-expression DP.public" \
|
||||
"\\^done,path_expr=\"\"" \
|
||||
"-var-info-path-expression DP.public"
|
||||
|
||||
mi_create_varobj D d "create varobj for d"
|
||||
mi_list_varobj_children D \
|
||||
{{D.Base1 Base1 1 Base1} \
|
||||
{D.Base2 Base2 1 Base2} \
|
||||
{D.public public 1}} "list children of D"
|
||||
mi_gdb_test "-var-info-path-expression D.Base1" \
|
||||
"\\^done,path_expr=\"\\(\\(Base1\\) d\\)\"" \
|
||||
"-var-info-path-expression D.Base1"
|
||||
:*/
|
||||
int array[4] = {1,2,3};
|
||||
array[3] = 10;
|
||||
/*: mi_create_varobj A array "create varobj for array"
|
||||
mi_list_varobj_children A { \
|
||||
{A.0 0 0 int}
|
||||
{A.1 1 0 int}
|
||||
{A.2 2 0 int}
|
||||
{A.3 3 0 int}} "list children of A"
|
||||
mi_gdb_test "-var-info-path-expression A.2" \
|
||||
"\\^done,path_expr=\"\\(array\\)\\\[2\\\]\"" \
|
||||
"-var-info-path-expression A.2"
|
||||
:*/
|
||||
|
||||
return 99;
|
||||
/*: END: path_expression :*/
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
reference_update_tests ();
|
||||
base_in_reference_test_main ();
|
||||
reference_to_pointer ();
|
||||
reference_to_struct ();
|
||||
path_expression ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ mi_run_inline_test reference_update
|
||||
mi_run_inline_test base_in_reference
|
||||
mi_run_inline_test reference_to_pointer
|
||||
mi_run_inline_test reference_to_struct
|
||||
mi_run_inline_test path_expression
|
||||
|
||||
mi_gdb_exit
|
||||
return 0
|
||||
|
170
gdb/varobj.c
170
gdb/varobj.c
@ -99,6 +99,10 @@ struct varobj
|
||||
/* 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;
|
||||
@ -234,6 +238,8 @@ 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);
|
||||
@ -254,6 +260,8 @@ 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);
|
||||
@ -272,6 +280,8 @@ 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);
|
||||
@ -299,6 +309,10 @@ struct language_specific
|
||||
/* 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);
|
||||
|
||||
@ -323,6 +337,7 @@ static struct language_specific languages[vlang_end] = {
|
||||
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,
|
||||
@ -335,6 +350,7 @@ static struct language_specific languages[vlang_end] = {
|
||||
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,
|
||||
@ -347,6 +363,7 @@ static struct language_specific languages[vlang_end] = {
|
||||
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,
|
||||
@ -359,6 +376,7 @@ static struct language_specific languages[vlang_end] = {
|
||||
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,
|
||||
@ -442,6 +460,7 @@ varobj_create (char *objname,
|
||||
char *p;
|
||||
enum varobj_languages lang;
|
||||
struct value *value = NULL;
|
||||
int expr_len;
|
||||
|
||||
/* Parse and evaluate the expression, filling in as much
|
||||
of the variable's data as possible */
|
||||
@ -486,7 +505,10 @@ varobj_create (char *objname,
|
||||
|
||||
var->format = variable_default_display (var);
|
||||
var->root->valid_block = innermost_block;
|
||||
var->name = savestring (expression, strlen (expression));
|
||||
expr_len = strlen (expression);
|
||||
var->name = savestring (expression, expr_len);
|
||||
/* For a root var, the name and the expr are the same. */
|
||||
var->path_expr = savestring (expression, expr_len);
|
||||
|
||||
/* When the frame is different from the current frame,
|
||||
we must select the appropriate frame before parsing
|
||||
@ -804,6 +826,23 @@ varobj_get_gdb_type (struct varobj *var)
|
||||
return var->type;
|
||||
}
|
||||
|
||||
/* Return a pointer to the full rooted expression of varobj VAR.
|
||||
If it has not been computed yet, compute it. */
|
||||
char *
|
||||
varobj_get_path_expr (struct varobj *var)
|
||||
{
|
||||
if (var->path_expr != NULL)
|
||||
return var->path_expr;
|
||||
else
|
||||
{
|
||||
/* For root varobjs, we initialize path_expr
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
enum varobj_languages
|
||||
varobj_get_language (struct varobj *var)
|
||||
{
|
||||
@ -1457,6 +1496,7 @@ new_variable (void)
|
||||
|
||||
var = (struct varobj *) xmalloc (sizeof (struct varobj));
|
||||
var->name = NULL;
|
||||
var->path_expr = NULL;
|
||||
var->obj_name = NULL;
|
||||
var->index = -1;
|
||||
var->type = NULL;
|
||||
@ -1505,6 +1545,7 @@ free_variable (struct varobj *var)
|
||||
xfree (var->name);
|
||||
xfree (var->obj_name);
|
||||
xfree (var->print_value);
|
||||
xfree (var->path_expr);
|
||||
xfree (var);
|
||||
}
|
||||
|
||||
@ -1845,13 +1886,21 @@ varobj_value_is_changeable_p (struct varobj *var)
|
||||
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 deferenced
|
||||
in this function. */
|
||||
static void
|
||||
adjust_value_for_child_access (struct value **value,
|
||||
struct type **type)
|
||||
struct type **type,
|
||||
int *was_ptr)
|
||||
{
|
||||
gdb_assert (type && *type);
|
||||
|
||||
if (was_ptr)
|
||||
*was_ptr = 0;
|
||||
|
||||
*type = check_typedef (*type);
|
||||
|
||||
/* The type of value stored in varobj, that is passed
|
||||
@ -1872,6 +1921,8 @@ adjust_value_for_child_access (struct value **value,
|
||||
if (value && *value)
|
||||
gdb_value_ind (*value, value);
|
||||
*type = target_type;
|
||||
if (was_ptr)
|
||||
*was_ptr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1888,7 +1939,7 @@ c_number_of_children (struct varobj *var)
|
||||
int children = 0;
|
||||
struct type *target;
|
||||
|
||||
adjust_value_for_child_access (NULL, &type);
|
||||
adjust_value_for_child_access (NULL, &type, NULL);
|
||||
target = get_target_type (type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
@ -1984,10 +2035,13 @@ value_struct_element_index (struct value *value, int type_index)
|
||||
to NULL. */
|
||||
static void
|
||||
c_describe_child (struct varobj *parent, int index,
|
||||
char **cname, struct value **cvalue, struct type **ctype)
|
||||
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;
|
||||
|
||||
if (cname)
|
||||
*cname = NULL;
|
||||
@ -1995,8 +2049,12 @@ c_describe_child (struct varobj *parent, int index,
|
||||
*cvalue = NULL;
|
||||
if (ctype)
|
||||
*ctype = NULL;
|
||||
|
||||
adjust_value_for_child_access (&value, &type);
|
||||
if (cfull_expression)
|
||||
{
|
||||
*cfull_expression = NULL;
|
||||
parent_expression = varobj_get_path_expr (parent);
|
||||
}
|
||||
adjust_value_for_child_access (&value, &type, &was_ptr);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
@ -2016,6 +2074,12 @@ c_describe_child (struct varobj *parent, int index,
|
||||
if (ctype)
|
||||
*ctype = get_target_type (type);
|
||||
|
||||
if (cfull_expression)
|
||||
*cfull_expression = xstrprintf ("(%s)[%d]", parent_expression,
|
||||
index
|
||||
+ TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
@ -2035,6 +2099,13 @@ c_describe_child (struct varobj *parent, int index,
|
||||
if (ctype)
|
||||
*ctype = TYPE_FIELD_TYPE (type, index);
|
||||
|
||||
if (cfull_expression)
|
||||
{
|
||||
char *join = was_ptr ? "->" : ".";
|
||||
*cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join,
|
||||
TYPE_FIELD_NAME (type, index));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
@ -2049,6 +2120,9 @@ c_describe_child (struct varobj *parent, int index,
|
||||
declared type of the variable. */
|
||||
if (ctype)
|
||||
*ctype = TYPE_TARGET_TYPE (type);
|
||||
|
||||
if (cfull_expression)
|
||||
*cfull_expression = xstrprintf ("*(%s)", parent_expression);
|
||||
|
||||
break;
|
||||
|
||||
@ -2056,6 +2130,8 @@ c_describe_child (struct varobj *parent, int index,
|
||||
/* 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. */
|
||||
}
|
||||
}
|
||||
@ -2064,10 +2140,18 @@ static char *
|
||||
c_name_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
char *name;
|
||||
c_describe_child (parent, index, &name, NULL, NULL);
|
||||
c_describe_child (parent, index, &name, NULL, NULL, NULL);
|
||||
return name;
|
||||
}
|
||||
|
||||
static char *
|
||||
c_path_expr_of_child (struct varobj *child)
|
||||
{
|
||||
c_describe_child (child->parent, child->index, NULL, NULL, NULL,
|
||||
&child->path_expr);
|
||||
return child->path_expr;
|
||||
}
|
||||
|
||||
static struct value *
|
||||
c_value_of_root (struct varobj **var_handle)
|
||||
{
|
||||
@ -2116,7 +2200,7 @@ static struct value *
|
||||
c_value_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
struct value *value = NULL;
|
||||
c_describe_child (parent, index, NULL, &value, NULL);
|
||||
c_describe_child (parent, index, NULL, &value, NULL, NULL);
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -2125,7 +2209,7 @@ static struct type *
|
||||
c_type_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
struct type *type = NULL;
|
||||
c_describe_child (parent, index, NULL, NULL, &type);
|
||||
c_describe_child (parent, index, NULL, NULL, &type, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -2215,7 +2299,7 @@ cplus_number_of_children (struct varobj *var)
|
||||
if (!CPLUS_FAKE_CHILD (var))
|
||||
{
|
||||
type = get_value_type (var);
|
||||
adjust_value_for_child_access (NULL, &type);
|
||||
adjust_value_for_child_access (NULL, &type, NULL);
|
||||
|
||||
if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
|
||||
((TYPE_CODE (type)) == TYPE_CODE_UNION))
|
||||
@ -2242,7 +2326,7 @@ cplus_number_of_children (struct varobj *var)
|
||||
int kids[3];
|
||||
|
||||
type = get_value_type (var->parent);
|
||||
adjust_value_for_child_access (NULL, &type);
|
||||
adjust_value_for_child_access (NULL, &type, NULL);
|
||||
|
||||
cplus_class_num_children (type, kids);
|
||||
if (strcmp (var->name, "public") == 0)
|
||||
@ -2313,11 +2397,14 @@ match_accessibility (struct type *type, int index, enum accessibility acc)
|
||||
|
||||
static void
|
||||
cplus_describe_child (struct varobj *parent, int index,
|
||||
char **cname, struct value **cvalue, struct type **ctype)
|
||||
char **cname, struct value **cvalue, struct type **ctype,
|
||||
char **cfull_expression)
|
||||
{
|
||||
char *name = NULL;
|
||||
struct value *value;
|
||||
struct type *type;
|
||||
int was_ptr;
|
||||
char *parent_expression = NULL;
|
||||
|
||||
if (cname)
|
||||
*cname = NULL;
|
||||
@ -2325,24 +2412,30 @@ cplus_describe_child (struct varobj *parent, int index,
|
||||
*cvalue = NULL;
|
||||
if (ctype)
|
||||
*ctype = NULL;
|
||||
|
||||
if (cfull_expression)
|
||||
*cfull_expression = NULL;
|
||||
|
||||
if (CPLUS_FAKE_CHILD (parent))
|
||||
{
|
||||
value = parent->parent->value;
|
||||
type = get_value_type (parent->parent);
|
||||
if (cfull_expression)
|
||||
parent_expression = varobj_get_path_expr (parent->parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = parent->value;
|
||||
type = get_value_type (parent);
|
||||
if (cfull_expression)
|
||||
parent_expression = varobj_get_path_expr (parent);
|
||||
}
|
||||
|
||||
adjust_value_for_child_access (&value, &type);
|
||||
adjust_value_for_child_access (&value, &type, &was_ptr);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
||||
{
|
||||
char *join = was_ptr ? "->" : ".";
|
||||
if (CPLUS_FAKE_CHILD (parent))
|
||||
{
|
||||
/* The fields of the class type are ordered as they
|
||||
@ -2377,6 +2470,11 @@ cplus_describe_child (struct varobj *parent, int 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))
|
||||
{
|
||||
@ -2387,12 +2485,30 @@ cplus_describe_child (struct varobj *parent, int index,
|
||||
if (cvalue && value)
|
||||
{
|
||||
*cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
|
||||
release_value (*cvalue);
|
||||
}
|
||||
|
||||
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. */
|
||||
*cfull_expression = xstrprintf ("(%s(%s%s) %s)",
|
||||
ptr,
|
||||
TYPE_FIELD_NAME (type, index),
|
||||
ptr,
|
||||
parent_expression);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2440,12 +2556,12 @@ cplus_describe_child (struct varobj *parent, int index,
|
||||
if (cname)
|
||||
*cname = xstrdup (access);
|
||||
|
||||
/* Value and type are null here. */
|
||||
/* Value and type and full expression are null here. */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c_describe_child (parent, index, cname, cvalue, ctype);
|
||||
c_describe_child (parent, index, cname, cvalue, ctype, cfull_expression);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2453,10 +2569,18 @@ static char *
|
||||
cplus_name_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
char *name = NULL;
|
||||
cplus_describe_child (parent, index, &name, NULL, 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)
|
||||
{
|
||||
@ -2467,7 +2591,7 @@ static struct value *
|
||||
cplus_value_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
struct value *value = NULL;
|
||||
cplus_describe_child (parent, index, NULL, &value, NULL);
|
||||
cplus_describe_child (parent, index, NULL, &value, NULL, NULL);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -2475,7 +2599,7 @@ static struct type *
|
||||
cplus_type_of_child (struct varobj *parent, int index)
|
||||
{
|
||||
struct type *type = NULL;
|
||||
cplus_describe_child (parent, index, NULL, NULL, &type);
|
||||
cplus_describe_child (parent, index, NULL, NULL, &type, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -2547,6 +2671,12 @@ java_name_of_child (struct varobj *parent, int index)
|
||||
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)
|
||||
{
|
||||
|
@ -97,6 +97,8 @@ extern char *varobj_get_type (struct varobj *var);
|
||||
|
||||
extern struct type *varobj_get_gdb_type (struct varobj *var);
|
||||
|
||||
extern char *varobj_get_path_expr (struct varobj *var);
|
||||
|
||||
extern enum varobj_languages varobj_get_language (struct varobj *var);
|
||||
|
||||
extern int varobj_get_attributes (struct varobj *var);
|
||||
|
Loading…
x
Reference in New Issue
Block a user