/* Implementation of the GDB variable objects API.
- Copyright (C) 1999-2017 Free Software Foundation, Inc.
+ Copyright (C) 1999-2018 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 "gdbthread.h"
#include "inferior.h"
#include "varobj-iter.h"
+#include "parser-defs.h"
#if HAVE_PYTHON
#include "python/python.h"
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. */
- bool children_requested_ = false;
+ bool children_requested = false;
/* The pretty-printer constructor. If NULL, then the default
pretty-printer will be looked up. If None, then no
else
fi = NULL;
- /* frame = -2 means always use selected frame. */
if (type == USE_SELECTED_FRAME)
var->root->floating = true;
}
p = expression;
- innermost_block = NULL;
+ innermost_block.reset (INNERMOST_BLOCK_FOR_SYMBOLS
+ | INNERMOST_BLOCK_FOR_REGISTERS);
/* Wrap the call to parse expression, so we can
return a sensible error. */
TRY
}
var->format = variable_default_display (var.get ());
- var->root->valid_block = innermost_block;
+ var->root->valid_block =
+ var->root->floating ? NULL : innermost_block.block ();
var->name = expression;
/* For a root var, the name and the expr are the same. */
var->path_expr = expression;
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. */
- if (innermost_block)
+ if (var->root->valid_block)
{
/* User could specify explicit FRAME-ADDR which was not found but
EXPRESSION is frame specific and we would not be able to evaluate
error (_("Failed to find the specified frame"));
var->root->frame = get_frame_id (fi);
- var->root->thread_id = ptid_to_global_thread_id (inferior_ptid);
+ var->root->thread_id = inferior_thread ()->global_num;
old_id = get_frame_id (get_selected_frame (NULL));
select_frame (fi);
}
}
if (varobj_value_is_changeable_p (var)
- && var->value && !value_lazy (var->value))
+ && var->value != nullptr && !value_lazy (var->value.get ()))
{
- var->print_value = varobj_value_get_print_value (var->value,
+ var->print_value = varobj_value_get_print_value (var->value.get (),
var->format, var);
}
{
if (var->saved_item != NULL)
{
- value_free (var->saved_item->value);
+ value_decref (var->saved_item->value);
delete var->saved_item;
var->saved_item = NULL;
}
/* Release vitem->value so its lifetime is not bound to the
execution of a command. */
if (item != NULL && item->value != NULL)
- release_value_or_incref (item->value);
+ release_value (item->value).release ();
}
if (item == NULL)
const std::vector<varobj *> &
varobj_list_children (struct varobj *var, int *from, int *to)
{
- var->dynamic->children_requested_ = true;
+ var->dynamic->children_requested = true;
if (varobj_is_dynamic_p (var))
{
while (!is_root_p (parent) && !is_path_expr_parent (parent))
parent = parent->parent;
+ /* Computation of full rooted expression for children of dynamic
+ varobjs is not supported. */
+ if (varobj_is_dynamic_p (parent))
+ error (_("Invalid variable object (child of a dynamic varobj)"));
+
return parent;
}
gdb_assert (varobj_value_is_changeable_p (var));
/* The value of a changeable variable object must not be lazy. */
- gdb_assert (!value_lazy (var->value));
+ gdb_assert (!value_lazy (var->value.get ()));
/* Need to coerce the input. We want to check if the
value of the variable object will be different
rather value_contents, will take care of this. */
TRY
{
- val = value_assign (var->value, value);
+ val = value_assign (var->value.get (), value);
}
CATCH (except, RETURN_MASK_ERROR)
{
PyObject *pretty_printer = NULL;
- if (var->value)
+ if (var->value != nullptr)
{
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->value.get ());
if (! pretty_printer)
{
gdbpy_print_stack ();
pretty_printer = NULL;
else
{
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ pretty_printer = instantiate_pretty_printer (constructor,
+ var->value.get ());
if (! pretty_printer)
{
gdbpy_print_stack ();
/* Get a reference now, before possibly passing it to any Python
code that might release it. */
+ value_ref_ptr value_holder;
if (value != NULL)
- value_incref (value);
+ value_holder = value_ref_ptr::new_reference (value);
/* Below, we'll be comparing string rendering of old and new
values. Don't get string rendering if the value is
{
/* Try to compare the values. That requires that both
values are non-lazy. */
- if (var->not_fetched && value_lazy (var->value))
+ if (var->not_fetched && value_lazy (var->value.get ()))
{
/* This is a frozen varobj and the value was never read.
Presumably, UI shows some "never read" indicator.
}
else
{
- gdb_assert (!value_lazy (var->value));
+ gdb_assert (!value_lazy (var->value.get ()));
gdb_assert (!value_lazy (value));
gdb_assert (!var->print_value.empty () && !print_value.empty ());
}
/* We must always keep the new value, since children depend on it. */
- if (var->value != NULL && var->value != value)
- value_free (var->value);
- var->value = value;
+ var->value = value_holder;
if (value && value_lazy (value) && intentionally_not_fetched)
var->not_fetched = true;
else
to see if the variable changed. */
if (var->dynamic->pretty_printer != NULL)
{
- print_value = varobj_value_get_print_value (var->value, var->format,
- var);
+ print_value = varobj_value_get_print_value (var->value.get (),
+ var->format, var);
if ((var->print_value.empty () && !print_value.empty ())
|| (!var->print_value.empty () && print_value.empty ())
|| (!var->print_value.empty () && !print_value.empty ()
}
var->print_value = print_value;
- gdb_assert (!var->value || value_type (var->value));
+ gdb_assert (var->value == nullptr || value_type (var->value.get ()));
return changed;
}
gdbpy_enter_varobj enter_py (var);
mainmod = PyImport_AddModule ("__main__");
- gdbpy_ref<> globals (PyModule_GetDict (mainmod));
- Py_INCREF (globals.get ());
-
+ gdbpy_ref<> globals
+ = gdbpy_ref<>::new_reference (PyModule_GetDict (mainmod));
gdbpy_ref<> constructor (PyRun_String (visualizer, Py_eval_input,
globals.get (), globals.get ()));
if (v->frozen)
continue;
- if (!v->dynamic->children_requested_)
+ if (!v->dynamic->children_requested)
{
bool dummy;
varobj_iter_delete (var->dynamic->child_iter);
varobj_clear_saved_item (var->dynamic);
- value_free (var->value);
if (is_root_p (var))
delete var->root;
{
struct type *type;
- if (var->value)
- type = value_type (var->value);
+ if (var->value != nullptr)
+ type = value_type (var->value.get ());
else
type = var->type;
}
else
{
- ptid_t ptid = global_thread_id_to_ptid (var->root->thread_id);
+ thread_info *thread = find_thread_global_id (var->root->thread_id);
- if (!ptid_equal (minus_one_ptid, ptid))
+ if (thread != NULL)
{
- switch_to_thread (ptid);
+ switch_to_thread (thread);
within_scope = check_scope (var);
}
}
if (var->root->is_valid)
{
if (var->dynamic->pretty_printer != NULL)
- return varobj_value_get_print_value (var->value, var->format, var);
+ return varobj_value_get_print_value (var->value.get (), var->format,
+ var);
return (*var->root->lang_ops->value_of_variable) (var, format);
}
else
{
get_formatted_print_options (opts, format_code[(int) format]);
opts->deref_ref = 0;
- opts->raw = 1;
+ opts->raw = !pretty_printing;
}
std::string
{
struct value *replacement;
- gdbpy_ref<> output (apply_varobj_pretty_printer (value_formatter,
- &replacement,
- &stb));
+ gdbpy_ref<> output = apply_varobj_pretty_printer (value_formatter,
+ &replacement,
+ &stb);
/* If we have string like output ... */
if (output != NULL)
{
struct type *type;
- if (!(var->root->is_valid && var->value && VALUE_LVAL (var->value)))
+ if (!(var->root->is_valid && var->value != nullptr
+ && VALUE_LVAL (var->value.get ())))
return false;
type = varobj_get_value_type (var);