/* Implementation of the GDB variable objects API.
- Copyright (C) 1999-2018 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 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 "gdb_regex.h"
#include "varobj.h"
-#include "vec.h"
+#include "common/vec.h"
#include "gdbthread.h"
#include "inferior.h"
#include "varobj-iter.h"
#if HAVE_PYTHON
#include "python/python.h"
#include "python/python-internal.h"
-#include "python/py-ref.h"
#else
typedef int PyObject;
#endif
}
p = expression;
- innermost_block.reset (INNERMOST_BLOCK_FOR_SYMBOLS
- | INNERMOST_BLOCK_FOR_REGISTERS);
+
+ innermost_block_tracker tracker (INNERMOST_BLOCK_FOR_SYMBOLS
+ | INNERMOST_BLOCK_FOR_REGISTERS);
/* Wrap the call to parse expression, so we can
return a sensible error. */
- TRY
+ try
{
- var->root->exp = parse_exp_1 (&p, pc, block, 0);
+ var->root->exp = parse_exp_1 (&p, pc, block, 0, &tracker);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
return NULL;
}
- END_CATCH
/* Don't allow variables to be created for types. */
if (var->root->exp->elts[0].opcode == OP_TYPE
var->format = variable_default_display (var.get ());
var->root->valid_block =
- var->root->floating ? NULL : innermost_block.block ();
+ var->root->floating ? NULL : tracker.block ();
var->name = expression;
/* For a root var, the name and the expr are the same. */
var->path_expr = expression;
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);
}
/* 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(). */
- TRY
+ try
{
value = evaluate_expression (var->root->exp.get ());
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
/* Error getting the value. Try to at least get the
right type. */
var->type = value_type (type_only_value);
}
- END_CATCH
if (value != NULL)
{
/* Release vitem->value so its lifetime is not bound to the
execution of a command. */
if (item != NULL && item->value != NULL)
- release_value (item->value).release ();
+ item->value = release_value (item->value).release ();
}
if (item == NULL)
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;
}
input_radix = 10; /* ALWAYS reset to decimal temporarily. */
expression_up exp = parse_exp_1 (&s, 0, 0, 0);
- TRY
+ try
{
value = evaluate_expression (exp.get ());
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
/* We cannot proceed without a valid expression. */
return false;
}
- END_CATCH
/* All types that are editable must also be changeable. */
gdb_assert (varobj_value_is_changeable_p (var));
/* The new value may be lazy. value_assign, or
rather value_contents, will take care of this. */
- TRY
+ try
{
val = value_assign (var->value.get (), value);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
return false;
}
- END_CATCH
/* 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
if (pretty_printing)
{
- PyObject *pretty_printer = NULL;
+ gdbpy_ref<> pretty_printer;
if (var->value != nullptr)
{
pretty_printer = gdbpy_get_varobj_pretty_printer (var->value.get ());
- if (! pretty_printer)
+ if (pretty_printer == nullptr)
{
gdbpy_print_stack ();
error (_("Cannot instantiate printer for default visualizer"));
}
}
-
+
if (pretty_printer == Py_None)
- {
- Py_DECREF (pretty_printer);
- pretty_printer = NULL;
- }
+ pretty_printer.reset (nullptr);
- install_visualizer (var->dynamic, NULL, pretty_printer);
+ install_visualizer (var->dynamic, NULL, pretty_printer.release ());
}
}
else
{
- TRY
+ try
{
value_fetch_lazy (value);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
/* 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;
}
- END_CATCH
}
}
for which -var-list-children was never invoked. */
if (varobj_is_dynamic_p (v))
{
- std::vector<varobj *> changed, type_changed, unchanged, newobj;
+ std::vector<varobj *> changed, type_changed_vec, unchanged, newobj_vec;
bool children_changed = false;
if (v->frozen)
/* If update_dynamic_varobj_children returns false, then we have
a non-conforming pretty-printer, so we skip it. */
- if (update_dynamic_varobj_children (v, &changed, &type_changed, &newobj,
- &unchanged, &children_changed, true,
- v->from, v->to))
+ if (update_dynamic_varobj_children (v, &changed, &type_changed_vec,
+ &newobj_vec,
+ &unchanged, &children_changed,
+ true, v->from, v->to))
{
- if (children_changed || !newobj.empty ())
+ if (children_changed || !newobj_vec.empty ())
{
r.children_changed = true;
- r.newobj = std::move (newobj);
+ r.newobj = std::move (newobj_vec);
}
/* Push in reverse order so that the first child is
popped from the work stack first, and so will be
added to result first. This does not affect
correctness, just "nicer". */
- for (int i = type_changed.size () - 1; i >= 0; --i)
+ for (int i = type_changed_vec.size () - 1; i >= 0; --i)
{
- varobj_update_result r (type_changed[i]);
+ varobj_update_result item (type_changed_vec[i]);
/* Type may change only if value was changed. */
- r.changed = true;
- r.type_changed = true;
- r.value_installed = true;
+ item.changed = true;
+ item.type_changed = true;
+ item.value_installed = true;
- stack.push_back (std::move (r));
+ stack.push_back (std::move (item));
}
for (int i = changed.size () - 1; i >= 0; --i)
{
- varobj_update_result r (changed[i]);
+ varobj_update_result item (changed[i]);
- r.changed = true;
- r.value_installed = true;
+ item.changed = true;
+ item.value_installed = true;
- stack.push_back (std::move (r));
+ stack.push_back (std::move (item));
}
for (int i = unchanged.size () - 1; i >= 0; --i)
{
if (!unchanged[i]->frozen)
{
- varobj_update_result r (unchanged[i]);
+ varobj_update_result item (unchanged[i]);
- r.value_installed = true;
+ item.value_installed = true;
- stack.push_back (std::move (r));
+ stack.push_back (std::move (item));
}
}
if (r.changed || r.children_changed)
}
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);
}
}
/* We need to catch errors here, because if evaluate
expression fails we want to just return NULL. */
- TRY
+ try
{
new_val = evaluate_expression (var->root->exp.get ());
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
}
- END_CATCH
}
return new_val;
{
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)