/* varobj support for C and C++.
- Copyright (C) 1999-2013 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 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
thing to do is to compare the child's name with ANONYMOUS_*_NAME. */
int
-varobj_is_anonymous_child (struct varobj *child)
+varobj_is_anonymous_child (const struct varobj *child)
{
return (strcmp (child->name, ANONYMOUS_STRUCT_NAME) == 0
|| strcmp (child->name, ANONYMOUS_UNION_NAME) == 0);
{
if (value && *value)
{
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
*value = value_ind (*value);
}
- if (except.reason < 0)
- *value = NULL;
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ *value = NULL;
+ }
+ END_CATCH
}
*type = target_type;
if (was_ptr)
}
}
+/* Is VAR a path expression parent, i.e., can it be used to construct
+ a valid path expression? */
+
+static int
+c_is_path_expr_parent (const struct varobj *var)
+{
+ struct type *type;
+
+ /* "Fake" children are not path_expr parents. */
+ if (CPLUS_FAKE_CHILD (var))
+ return 0;
+
+ type = varobj_get_gdb_type (var);
+
+ /* Anonymous unions and structs are also not path_expr parents. */
+ if ((TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ && TYPE_NAME (type) == NULL
+ && TYPE_TAG_NAME (type) == NULL)
+ {
+ const struct varobj *parent = var->parent;
+
+ while (parent != NULL && CPLUS_FAKE_CHILD (parent))
+ parent = parent->parent;
+
+ if (parent != NULL)
+ {
+ struct type *parent_type;
+ int was_ptr;
+
+ parent_type = varobj_get_value_type (parent);
+ adjust_value_for_child_access (NULL, &parent_type, &was_ptr, 0);
+
+ if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (parent_type) == TYPE_CODE_UNION)
+ {
+ const char *field_name;
+
+ gdb_assert (var->index < TYPE_NFIELDS (parent_type));
+ field_name = TYPE_FIELD_NAME (parent_type, var->index);
+ return !(field_name == NULL || *field_name == '\0');
+ }
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
/* C */
static int
-c_number_of_children (struct varobj *var)
+c_number_of_children (const struct varobj *var)
{
struct type *type = varobj_get_value_type (var);
int children = 0;
}
static char *
-c_name_of_variable (struct varobj *parent)
+c_name_of_variable (const struct varobj *parent)
{
return xstrdup (parent->name);
}
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)
+ TRY
{
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)
+ CATCH (e, RETURN_MASK_ERROR)
{
return NULL;
}
- else
- {
- return result;
- }
+ END_CATCH
+
+ return result;
}
/* Obtain the information about child INDEX of the variable
to NULL. */
static void
-c_describe_child (struct varobj *parent, int index,
+c_describe_child (const struct varobj *parent, int index,
char **cname, struct value **cvalue, struct type **ctype,
char **cfull_expression)
{
struct type *type = varobj_get_value_type (parent);
char *parent_expression = NULL;
int was_ptr;
- volatile struct gdb_exception except;
if (cname)
*cname = NULL;
{
int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
*cvalue = value_subscript (value, real_index);
}
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ }
+ END_CATCH
}
if (ctype)
if (cvalue && value)
{
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
*cvalue = value_ind (value);
}
- if (except.reason < 0)
- *cvalue = NULL;
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ *cvalue = NULL;
+ }
+ END_CATCH
}
/* Don't use get_target_type because it calls
}
static char *
-c_name_of_child (struct varobj *parent, int index)
+c_name_of_child (const struct varobj *parent, int index)
{
char *name;
}
static char *
-c_path_expr_of_child (struct varobj *child)
+c_path_expr_of_child (const struct varobj *child)
{
+ char *path_expr;
+
c_describe_child (child->parent, child->index, NULL, NULL, NULL,
- &child->path_expr);
- return child->path_expr;
+ &path_expr);
+ return path_expr;
}
static struct value *
-c_value_of_child (struct varobj *parent, int index)
+c_value_of_child (const struct varobj *parent, int index)
{
struct value *value = NULL;
}
static struct type *
-c_type_of_child (struct varobj *parent, int index)
+c_type_of_child (const struct varobj *parent, int index)
{
struct type *type = NULL;
to return the real type of the variable. */
static struct type *
-get_type (struct varobj *var)
+get_type (const struct varobj *var)
{
struct type *type;
}
static char *
-c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
+c_value_of_variable (const 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
c_type_of_child,
c_value_of_variable,
varobj_default_value_is_changeable_p,
- NULL /* value_has_mutated */
+ NULL, /* value_has_mutated */
+ c_is_path_expr_parent /* is_path_expr_parent */
};
/* A little convenience enum for dealing with C++/Java. */
/* C++ */
static int
-cplus_number_of_children (struct varobj *var)
+cplus_number_of_children (const struct varobj *var)
{
struct value *value = NULL;
struct type *type;
/* It is necessary to access a real type (via RTTI). */
if (opts.objectprint)
{
- struct varobj *parent = var->parent;
+ const struct varobj *parent = var->parent;
value = parent->value;
lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
}
static char *
-cplus_name_of_variable (struct varobj *parent)
+cplus_name_of_variable (const struct varobj *parent)
{
return c_name_of_variable (parent);
}
}
static void
-cplus_describe_child (struct varobj *parent, int index,
+cplus_describe_child (const struct varobj *parent, int index,
char **cname, struct value **cvalue, struct type **ctype,
char **cfull_expression)
{
int was_ptr;
int lookup_actual_type = 0;
char *parent_expression = NULL;
- struct varobj *var;
+ const struct varobj *var;
struct value_print_options opts;
if (cname)
}
static char *
-cplus_name_of_child (struct varobj *parent, int index)
+cplus_name_of_child (const struct varobj *parent, int index)
{
char *name = NULL;
}
static char *
-cplus_path_expr_of_child (struct varobj *child)
+cplus_path_expr_of_child (const struct varobj *child)
{
+ char *path_expr;
+
cplus_describe_child (child->parent, child->index, NULL, NULL, NULL,
- &child->path_expr);
- return child->path_expr;
+ &path_expr);
+ return path_expr;
}
static struct value *
-cplus_value_of_child (struct varobj *parent, int index)
+cplus_value_of_child (const struct varobj *parent, int index)
{
struct value *value = NULL;
}
static struct type *
-cplus_type_of_child (struct varobj *parent, int index)
+cplus_type_of_child (const struct varobj *parent, int index)
{
struct type *type = NULL;
}
static char *
-cplus_value_of_variable (struct varobj *var,
+cplus_value_of_variable (const struct varobj *var,
enum varobj_display_formats format)
{
cplus_type_of_child,
cplus_value_of_variable,
varobj_default_value_is_changeable_p,
- NULL /* value_has_mutated */
+ NULL, /* value_has_mutated */
+ c_is_path_expr_parent /* is_path_expr_parent */
};
\f