|  | /* Implementation of the GDB variable objects API. | 
|  |  | 
|  | Copyright (C) 1999-2022 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 | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #include "defs.h" | 
|  | #include "value.h" | 
|  | #include "expression.h" | 
|  | #include "frame.h" | 
|  | #include "language.h" | 
|  | #include "gdbcmd.h" | 
|  | #include "block.h" | 
|  | #include "valprint.h" | 
|  | #include "gdbsupport/gdb_regex.h" | 
|  |  | 
|  | #include "varobj.h" | 
|  | #include "gdbthread.h" | 
|  | #include "inferior.h" | 
|  | #include "varobj-iter.h" | 
|  | #include "parser-defs.h" | 
|  | #include "gdbarch.h" | 
|  | #include <algorithm> | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  | #include "python/python.h" | 
|  | #include "python/python-internal.h" | 
|  | #else | 
|  | typedef int PyObject; | 
|  | #endif | 
|  |  | 
|  | /* See varobj.h.  */ | 
|  |  | 
|  | unsigned int varobjdebug = 0; | 
|  | static void | 
|  | show_varobjdebug (struct ui_file *file, int from_tty, | 
|  | struct cmd_list_element *c, const char *value) | 
|  | { | 
|  | fprintf_filtered (file, _("Varobj debugging is %s.\n"), value); | 
|  | } | 
|  |  | 
|  | /* String representations of gdb's format codes.  */ | 
|  | const char *varobj_format_string[] = | 
|  | { "natural", "binary", "decimal", "hexadecimal", "octal", "zero-hexadecimal" }; | 
|  |  | 
|  | /* True if we want to allow Python-based pretty-printing.  */ | 
|  | static bool pretty_printing = false; | 
|  |  | 
|  | void | 
|  | varobj_enable_pretty_printing (void) | 
|  | { | 
|  | pretty_printing = true; | 
|  | } | 
|  |  | 
|  | /* Data structures */ | 
|  |  | 
|  | /* Every root variable has one of these structures saved in its | 
|  | varobj.  */ | 
|  | struct varobj_root | 
|  | { | 
|  | /* The expression for this parent.  */ | 
|  | expression_up exp; | 
|  |  | 
|  | /* Block for which this expression is valid.  */ | 
|  | const struct block *valid_block = NULL; | 
|  |  | 
|  | /* The frame for this expression.  This field is set iff valid_block is | 
|  | not NULL.  */ | 
|  | struct frame_id frame = null_frame_id; | 
|  |  | 
|  | /* The global thread ID that this varobj_root belongs to.  This field | 
|  | 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.  */ | 
|  | int thread_id = 0; | 
|  |  | 
|  | /* If true, 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.  */ | 
|  | bool floating = false; | 
|  |  | 
|  | /* Flag that indicates validity: set to false when this varobj_root refers | 
|  | to symbols that do not exist anymore.  */ | 
|  | bool is_valid = true; | 
|  |  | 
|  | /* Language-related operations for this variable and its | 
|  | children.  */ | 
|  | const struct lang_varobj_ops *lang_ops = NULL; | 
|  |  | 
|  | /* The varobj for this root node.  */ | 
|  | struct varobj *rootvar = NULL; | 
|  | }; | 
|  |  | 
|  | /* Dynamic part of varobj.  */ | 
|  |  | 
|  | struct varobj_dynamic | 
|  | { | 
|  | /* Whether the children of this varobj were requested.  This field is | 
|  | 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; | 
|  |  | 
|  | /* The pretty-printer constructor.  If NULL, then the default | 
|  | pretty-printer will be looked up.  If None, then no | 
|  | pretty-printer will be installed.  */ | 
|  | PyObject *constructor = NULL; | 
|  |  | 
|  | /* The pretty-printer that has been constructed.  If NULL, then a | 
|  | new printer object is needed, and one will be constructed.  */ | 
|  | PyObject *pretty_printer = NULL; | 
|  |  | 
|  | /* The iterator returned by the printer's 'children' method, or NULL | 
|  | if not available.  */ | 
|  | std::unique_ptr<varobj_iter> child_iter; | 
|  |  | 
|  | /* We request one extra item from the iterator, so that we can | 
|  | report to the caller whether there are more items than we have | 
|  | already reported.  However, we don't want to install this value | 
|  | when we read it, because that will mess up future updates.  So, | 
|  | we stash it here instead.  */ | 
|  | std::unique_ptr<varobj_item> saved_item; | 
|  | }; | 
|  |  | 
|  | /* Private function prototypes */ | 
|  |  | 
|  | /* Helper functions for the above subcommands.  */ | 
|  |  | 
|  | static int delete_variable (struct varobj *, bool); | 
|  |  | 
|  | static void delete_variable_1 (int *, struct varobj *, bool, bool); | 
|  |  | 
|  | static void install_variable (struct varobj *); | 
|  |  | 
|  | static void uninstall_variable (struct varobj *); | 
|  |  | 
|  | static struct varobj *create_child (struct varobj *, int, std::string &); | 
|  |  | 
|  | static struct varobj * | 
|  | create_child_with_value (struct varobj *parent, int index, | 
|  | struct varobj_item *item); | 
|  |  | 
|  | /* Utility routines */ | 
|  |  | 
|  | static enum varobj_display_formats variable_default_display (struct varobj *); | 
|  |  | 
|  | static bool update_type_if_necessary (struct varobj *var, | 
|  | struct value *new_value); | 
|  |  | 
|  | static bool install_new_value (struct varobj *var, struct value *value, | 
|  | bool initial); | 
|  |  | 
|  | /* Language-specific routines.  */ | 
|  |  | 
|  | static int number_of_children (const struct varobj *); | 
|  |  | 
|  | static std::string name_of_variable (const struct varobj *); | 
|  |  | 
|  | static std::string name_of_child (struct varobj *, int); | 
|  |  | 
|  | static struct value *value_of_root (struct varobj **var_handle, bool *); | 
|  |  | 
|  | static struct value *value_of_child (const struct varobj *parent, int index); | 
|  |  | 
|  | static std::string my_value_of_variable (struct varobj *var, | 
|  | enum varobj_display_formats format); | 
|  |  | 
|  | static bool is_root_p (const struct varobj *var); | 
|  |  | 
|  | static struct varobj *varobj_add_child (struct varobj *var, | 
|  | struct varobj_item *item); | 
|  |  | 
|  | /* Private data */ | 
|  |  | 
|  | /* Mappings of varobj_display_formats enums to gdb's format codes.  */ | 
|  | static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' }; | 
|  |  | 
|  | /* List of root variable objects.  */ | 
|  | static std::list<struct varobj_root *> rootlist; | 
|  |  | 
|  | /* Pointer to the varobj hash table (built at run time).  */ | 
|  | static htab_t varobj_table; | 
|  |  | 
|  |  | 
|  |  | 
|  | /* API Implementation */ | 
|  | static bool | 
|  | is_root_p (const struct varobj *var) | 
|  | { | 
|  | return (var->root->rootvar == var); | 
|  | } | 
|  |  | 
|  | #ifdef HAVE_PYTHON | 
|  |  | 
|  | /* See python-internal.h.  */ | 
|  | gdbpy_enter_varobj::gdbpy_enter_varobj (const struct varobj *var) | 
|  | : gdbpy_enter (var->root->exp->gdbarch, var->root->exp->language_defn) | 
|  | { | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | /* Return the full FRAME which corresponds to the given CORE_ADDR | 
|  | or NULL if no FRAME on the chain corresponds to CORE_ADDR.  */ | 
|  |  | 
|  | static struct frame_info * | 
|  | find_frame_addr_in_frame_chain (CORE_ADDR frame_addr) | 
|  | { | 
|  | struct frame_info *frame = NULL; | 
|  |  | 
|  | if (frame_addr == (CORE_ADDR) 0) | 
|  | return NULL; | 
|  |  | 
|  | for (frame = get_current_frame (); | 
|  | frame != NULL; | 
|  | frame = get_prev_frame (frame)) | 
|  | { | 
|  | /* The CORE_ADDR we get as argument was parsed from a string GDB | 
|  | output as $fp.  This output got truncated to gdbarch_addr_bit. | 
|  | Truncate the frame base address in the same manner before | 
|  | comparing it against our argument.  */ | 
|  | CORE_ADDR frame_base = get_frame_base_address (frame); | 
|  | int addr_bit = gdbarch_addr_bit (get_frame_arch (frame)); | 
|  |  | 
|  | if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) | 
|  | frame_base &= ((CORE_ADDR) 1 << addr_bit) - 1; | 
|  |  | 
|  | if (frame_base == frame_addr) | 
|  | return frame; | 
|  | } | 
|  |  | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /* Creates a varobj (not its children).  */ | 
|  |  | 
|  | struct varobj * | 
|  | varobj_create (const char *objname, | 
|  | const char *expression, CORE_ADDR frame, enum varobj_type type) | 
|  | { | 
|  | /* Fill out a varobj structure for the (root) variable being constructed.  */ | 
|  | std::unique_ptr<varobj> var (new varobj (new varobj_root)); | 
|  |  | 
|  | if (expression != NULL) | 
|  | { | 
|  | struct frame_info *fi; | 
|  | struct frame_id old_id = null_frame_id; | 
|  | const struct block *block; | 
|  | const char *p; | 
|  | struct value *value = NULL; | 
|  | CORE_ADDR pc; | 
|  |  | 
|  | /* 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.  */ | 
|  | if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME)) | 
|  | fi = get_selected_frame (NULL); | 
|  | else | 
|  | /* FIXME: cagney/2002-11-23: This code should be doing a | 
|  | lookup using the frame ID and not just the frame's | 
|  | ``address''.  This, of course, means an interface | 
|  | change.  However, with out that interface change ISAs, | 
|  | such as the ia64 with its two stacks, won't work. | 
|  | Similar goes for the case where there is a frameless | 
|  | function.  */ | 
|  | fi = find_frame_addr_in_frame_chain (frame); | 
|  | } | 
|  | else | 
|  | fi = NULL; | 
|  |  | 
|  | if (type == USE_SELECTED_FRAME) | 
|  | var->root->floating = true; | 
|  |  | 
|  | pc = 0; | 
|  | block = NULL; | 
|  | if (fi != NULL) | 
|  | { | 
|  | block = get_frame_block (fi, 0); | 
|  | pc = get_frame_pc (fi); | 
|  | } | 
|  |  | 
|  | p = expression; | 
|  |  | 
|  | 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 | 
|  | { | 
|  | var->root->exp = parse_exp_1 (&p, pc, block, 0, &tracker); | 
|  | } | 
|  |  | 
|  | catch (const gdb_exception_error &except) | 
|  | { | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /* Don't allow variables to be created for types.  */ | 
|  | enum exp_opcode opcode = var->root->exp->first_opcode (); | 
|  | if (opcode == OP_TYPE | 
|  | || opcode == OP_TYPEOF | 
|  | || opcode == OP_DECLTYPE) | 
|  | { | 
|  | fprintf_unfiltered (gdb_stderr, "Attempt to use a type name" | 
|  | " as an expression.\n"); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | var->format = variable_default_display (var.get ()); | 
|  | var->root->valid_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; | 
|  |  | 
|  | /* 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.  */ | 
|  | 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 | 
|  | it correctly next time.  With VALID_BLOCK set we must also set | 
|  | FRAME and THREAD_ID.  */ | 
|  | if (fi == NULL) | 
|  | error (_("Failed to find the specified frame")); | 
|  |  | 
|  | var->root->frame = get_frame_id (fi); | 
|  | 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 | 
|  | { | 
|  | value = evaluate_expression (var->root->exp.get ()); | 
|  | } | 
|  | catch (const gdb_exception_error &except) | 
|  | { | 
|  | /* Error getting the value.  Try to at least get the | 
|  | right type.  */ | 
|  | struct value *type_only_value = evaluate_type (var->root->exp.get ()); | 
|  |  | 
|  | var->type = value_type (type_only_value); | 
|  | } | 
|  |  | 
|  | if (value != NULL) | 
|  | { | 
|  | int real_type_found = 0; | 
|  |  | 
|  | var->type = value_actual_type (value, 0, &real_type_found); | 
|  | if (real_type_found) | 
|  | value = value_cast (var->type, value); | 
|  | } | 
|  |  | 
|  | /* Set language info */ | 
|  | var->root->lang_ops = var->root->exp->language_defn->varobj_ops (); | 
|  |  | 
|  | install_new_value (var.get (), value, 1 /* Initial assignment */); | 
|  |  | 
|  | /* Set ourselves as our root.  */ | 
|  | var->root->rootvar = var.get (); | 
|  |  | 
|  | /* 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.  */ | 
|  |  | 
|  | if ((var != NULL) && (objname != NULL)) | 
|  | { | 
|  | var->obj_name = objname; | 
|  | install_variable (var.get ()); | 
|  | } | 
|  |  | 
|  | return var.release (); | 
|  | } | 
|  |  | 
|  | /* Generates an unique name that can be used for a varobj.  */ | 
|  |  | 
|  | std::string | 
|  | varobj_gen_name (void) | 
|  | { | 
|  | static int id = 0; | 
|  |  | 
|  | /* Generate a name for this object.  */ | 
|  | id++; | 
|  | return string_printf ("var%d", id); | 
|  | } | 
|  |  | 
|  | /* Given an OBJNAME, returns the pointer to the corresponding varobj.  Call | 
|  | error if OBJNAME cannot be found.  */ | 
|  |  | 
|  | struct varobj * | 
|  | varobj_get_handle (const char *objname) | 
|  | { | 
|  | varobj *var = (varobj *) htab_find_with_hash (varobj_table, objname, | 
|  | htab_hash_string (objname)); | 
|  |  | 
|  | if (var == NULL) | 
|  | error (_("Variable object not found")); | 
|  |  | 
|  | return var; | 
|  | } | 
|  |  | 
|  | /* Given the handle, return the name of the object.  */ | 
|  |  | 
|  | const char * | 
|  | varobj_get_objname (const struct varobj *var) | 
|  | { | 
|  | return var->obj_name.c_str (); | 
|  | } | 
|  |  | 
|  | /* Given the handle, return the expression represented by the | 
|  | object.  */ | 
|  |  | 
|  | std::string | 
|  | varobj_get_expression (const struct varobj *var) | 
|  | { | 
|  | return name_of_variable (var); | 
|  | } | 
|  |  | 
|  | /* See varobj.h.  */ | 
|  |  | 
|  | int | 
|  | varobj_delete (struct varobj *var, bool only_children) | 
|  | { | 
|  | return delete_variable (var, only_children); | 
|  | } | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  |  | 
|  | /* Convenience function for varobj_set_visualizer.  Instantiate a | 
|  | pretty-printer for a given value.  */ | 
|  | static PyObject * | 
|  | instantiate_pretty_printer (PyObject *constructor, struct value *value) | 
|  | { | 
|  | gdbpy_ref<> val_obj (value_to_value_object (value)); | 
|  | if (val_obj == nullptr) | 
|  | return NULL; | 
|  |  | 
|  | return PyObject_CallFunctionObjArgs (constructor, val_obj.get (), NULL); | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | /* Set/Get variable object display format.  */ | 
|  |  | 
|  | enum varobj_display_formats | 
|  | varobj_set_display_format (struct varobj *var, | 
|  | enum varobj_display_formats format) | 
|  | { | 
|  | switch (format) | 
|  | { | 
|  | case FORMAT_NATURAL: | 
|  | case FORMAT_BINARY: | 
|  | case FORMAT_DECIMAL: | 
|  | case FORMAT_HEXADECIMAL: | 
|  | case FORMAT_OCTAL: | 
|  | case FORMAT_ZHEXADECIMAL: | 
|  | var->format = format; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | var->format = variable_default_display (var); | 
|  | } | 
|  |  | 
|  | if (varobj_value_is_changeable_p (var) | 
|  | && var->value != nullptr && !value_lazy (var->value.get ())) | 
|  | { | 
|  | var->print_value = varobj_value_get_print_value (var->value.get (), | 
|  | var->format, var); | 
|  | } | 
|  |  | 
|  | return var->format; | 
|  | } | 
|  |  | 
|  | enum varobj_display_formats | 
|  | varobj_get_display_format (const struct varobj *var) | 
|  | { | 
|  | return var->format; | 
|  | } | 
|  |  | 
|  | gdb::unique_xmalloc_ptr<char> | 
|  | varobj_get_display_hint (const struct varobj *var) | 
|  | { | 
|  | gdb::unique_xmalloc_ptr<char> result; | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  | if (!gdb_python_initialized) | 
|  | return NULL; | 
|  |  | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  |  | 
|  | if (var->dynamic->pretty_printer != NULL) | 
|  | result = gdbpy_get_display_hint (var->dynamic->pretty_printer); | 
|  | #endif | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /* Return true if the varobj has items after TO, false otherwise.  */ | 
|  |  | 
|  | bool | 
|  | varobj_has_more (const struct varobj *var, int to) | 
|  | { | 
|  | if (var->children.size () > to) | 
|  | return true; | 
|  |  | 
|  | return ((to == -1 || var->children.size () == to) | 
|  | && (var->dynamic->saved_item != NULL)); | 
|  | } | 
|  |  | 
|  | /* 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.  */ | 
|  | int | 
|  | varobj_get_thread_id (const struct varobj *var) | 
|  | { | 
|  | if (var->root->valid_block && var->root->thread_id > 0) | 
|  | return var->root->thread_id; | 
|  | else | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | void | 
|  | varobj_set_frozen (struct varobj *var, bool frozen) | 
|  | { | 
|  | /* When a variable is unfrozen, we don't fetch its value. | 
|  | The 'not_fetched' flag remains set, so next -var-update | 
|  | won't complain. | 
|  |  | 
|  | We don't fetch the value, because for structures the client | 
|  | should do -var-update anyway.  It would be bad to have different | 
|  | client-size logic for structure and other types.  */ | 
|  | var->frozen = frozen; | 
|  | } | 
|  |  | 
|  | bool | 
|  | varobj_get_frozen (const struct varobj *var) | 
|  | { | 
|  | return var->frozen; | 
|  | } | 
|  |  | 
|  | /* A helper function that updates the contents of FROM and TO based on the | 
|  | size of the vector CHILDREN.  If the contents of either FROM or TO are | 
|  | negative the entire range is used.  */ | 
|  |  | 
|  | void | 
|  | varobj_restrict_range (const std::vector<varobj *> &children, | 
|  | int *from, int *to) | 
|  | { | 
|  | int len = children.size (); | 
|  |  | 
|  | if (*from < 0 || *to < 0) | 
|  | { | 
|  | *from = 0; | 
|  | *to = len; | 
|  | } | 
|  | else | 
|  | { | 
|  | if (*from > len) | 
|  | *from = len; | 
|  | if (*to > len) | 
|  | *to = len; | 
|  | if (*from > *to) | 
|  | *from = *to; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* A helper for update_dynamic_varobj_children that installs a new | 
|  | child when needed.  */ | 
|  |  | 
|  | static void | 
|  | install_dynamic_child (struct varobj *var, | 
|  | std::vector<varobj *> *changed, | 
|  | std::vector<varobj *> *type_changed, | 
|  | std::vector<varobj *> *newobj, | 
|  | std::vector<varobj *> *unchanged, | 
|  | bool *cchanged, | 
|  | int index, | 
|  | struct varobj_item *item) | 
|  | { | 
|  | if (var->children.size () < index + 1) | 
|  | { | 
|  | /* There's no child yet.  */ | 
|  | struct varobj *child = varobj_add_child (var, item); | 
|  |  | 
|  | if (newobj != NULL) | 
|  | { | 
|  | newobj->push_back (child); | 
|  | *cchanged = true; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | varobj *existing = var->children[index]; | 
|  | bool type_updated = update_type_if_necessary (existing, | 
|  | item->value.get ()); | 
|  |  | 
|  | if (type_updated) | 
|  | { | 
|  | if (type_changed != NULL) | 
|  | type_changed->push_back (existing); | 
|  | } | 
|  | if (install_new_value (existing, item->value.get (), 0)) | 
|  | { | 
|  | if (!type_updated && changed != NULL) | 
|  | changed->push_back (existing); | 
|  | } | 
|  | else if (!type_updated && unchanged != NULL) | 
|  | unchanged->push_back (existing); | 
|  | } | 
|  | } | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  |  | 
|  | static bool | 
|  | dynamic_varobj_has_child_method (const struct varobj *var) | 
|  | { | 
|  | PyObject *printer = var->dynamic->pretty_printer; | 
|  |  | 
|  | if (!gdb_python_initialized) | 
|  | return false; | 
|  |  | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  | return PyObject_HasAttr (printer, gdbpy_children_cst); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* A factory for creating dynamic varobj's iterators.  Returns an | 
|  | iterator object suitable for iterating over VAR's children.  */ | 
|  |  | 
|  | static std::unique_ptr<varobj_iter> | 
|  | varobj_get_iterator (struct varobj *var) | 
|  | { | 
|  | #if HAVE_PYTHON | 
|  | if (var->dynamic->pretty_printer) | 
|  | return py_varobj_get_iterator (var, var->dynamic->pretty_printer); | 
|  | #endif | 
|  |  | 
|  | gdb_assert_not_reached ("requested an iterator from a non-dynamic varobj"); | 
|  | } | 
|  |  | 
|  | static bool | 
|  | update_dynamic_varobj_children (struct varobj *var, | 
|  | std::vector<varobj *> *changed, | 
|  | std::vector<varobj *> *type_changed, | 
|  | std::vector<varobj *> *newobj, | 
|  | std::vector<varobj *> *unchanged, | 
|  | bool *cchanged, | 
|  | bool update_children, | 
|  | int from, | 
|  | int to) | 
|  | { | 
|  | int i; | 
|  |  | 
|  | *cchanged = false; | 
|  |  | 
|  | if (update_children || var->dynamic->child_iter == NULL) | 
|  | { | 
|  | var->dynamic->child_iter = varobj_get_iterator (var); | 
|  | var->dynamic->saved_item.reset (nullptr); | 
|  |  | 
|  | i = 0; | 
|  |  | 
|  | if (var->dynamic->child_iter == NULL) | 
|  | return false; | 
|  | } | 
|  | else | 
|  | i = var->children.size (); | 
|  |  | 
|  | /* We ask for one extra child, so that MI can report whether there | 
|  | are more children.  */ | 
|  | for (; to < 0 || i < to + 1; ++i) | 
|  | { | 
|  | std::unique_ptr<varobj_item> item; | 
|  |  | 
|  | /* See if there was a leftover from last time.  */ | 
|  | if (var->dynamic->saved_item != NULL) | 
|  | item = std::move (var->dynamic->saved_item); | 
|  | else | 
|  | item = var->dynamic->child_iter->next (); | 
|  |  | 
|  | if (item == NULL) | 
|  | { | 
|  | /* Iteration is done.  Remove iterator from VAR.  */ | 
|  | var->dynamic->child_iter.reset (nullptr); | 
|  | break; | 
|  | } | 
|  | /* We don't want to push the extra child on any report list.  */ | 
|  | if (to < 0 || i < to) | 
|  | { | 
|  | bool can_mention = from < 0 || i >= from; | 
|  |  | 
|  | install_dynamic_child (var, can_mention ? changed : NULL, | 
|  | can_mention ? type_changed : NULL, | 
|  | can_mention ? newobj : NULL, | 
|  | can_mention ? unchanged : NULL, | 
|  | can_mention ? cchanged : NULL, i, | 
|  | item.get ()); | 
|  | } | 
|  | else | 
|  | { | 
|  | var->dynamic->saved_item = std::move (item); | 
|  |  | 
|  | /* We want to truncate the child list just before this | 
|  | element.  */ | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (i < var->children.size ()) | 
|  | { | 
|  | *cchanged = true; | 
|  | for (int j = i; j < var->children.size (); ++j) | 
|  | varobj_delete (var->children[j], 0); | 
|  |  | 
|  | var->children.resize (i); | 
|  | } | 
|  |  | 
|  | /* If there are fewer children than requested, note that the list of | 
|  | children changed.  */ | 
|  | if (to >= 0 && var->children.size () < to) | 
|  | *cchanged = true; | 
|  |  | 
|  | var->num_children = var->children.size (); | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int | 
|  | varobj_get_num_children (struct varobj *var) | 
|  | { | 
|  | if (var->num_children == -1) | 
|  | { | 
|  | if (varobj_is_dynamic_p (var)) | 
|  | { | 
|  | bool dummy; | 
|  |  | 
|  | /* If we have a dynamic varobj, don't report -1 children. | 
|  | So, try to fetch some children first.  */ | 
|  | update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, &dummy, | 
|  | false, 0, 0); | 
|  | } | 
|  | else | 
|  | var->num_children = number_of_children (var); | 
|  | } | 
|  |  | 
|  | return var->num_children >= 0 ? var->num_children : 0; | 
|  | } | 
|  |  | 
|  | /* Creates a list of the immediate children of a variable object; | 
|  | the return code is the number of such children or -1 on error.  */ | 
|  |  | 
|  | const std::vector<varobj *> & | 
|  | varobj_list_children (struct varobj *var, int *from, int *to) | 
|  | { | 
|  | var->dynamic->children_requested = true; | 
|  |  | 
|  | if (varobj_is_dynamic_p (var)) | 
|  | { | 
|  | bool children_changed; | 
|  |  | 
|  | /* This, in theory, can result in the number of children changing without | 
|  | frontend noticing.  But well, calling -var-list-children on the same | 
|  | varobj twice is not something a sane frontend would do.  */ | 
|  | update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, | 
|  | &children_changed, false, 0, *to); | 
|  | varobj_restrict_range (var->children, from, to); | 
|  | return var->children; | 
|  | } | 
|  |  | 
|  | if (var->num_children == -1) | 
|  | var->num_children = number_of_children (var); | 
|  |  | 
|  | /* If that failed, give up.  */ | 
|  | if (var->num_children == -1) | 
|  | return var->children; | 
|  |  | 
|  | /* If we're called when the list of children is not yet initialized, | 
|  | allocate enough elements in it.  */ | 
|  | while (var->children.size () < var->num_children) | 
|  | var->children.push_back (NULL); | 
|  |  | 
|  | for (int i = 0; i < var->num_children; i++) | 
|  | { | 
|  | if (var->children[i] == NULL) | 
|  | { | 
|  | /* Either it's the first call to varobj_list_children for | 
|  | this variable object, and the child was never created, | 
|  | or it was explicitly deleted by the client.  */ | 
|  | std::string name = name_of_child (var, i); | 
|  | var->children[i] = create_child (var, i, name); | 
|  | } | 
|  | } | 
|  |  | 
|  | varobj_restrict_range (var->children, from, to); | 
|  | return var->children; | 
|  | } | 
|  |  | 
|  | static struct varobj * | 
|  | varobj_add_child (struct varobj *var, struct varobj_item *item) | 
|  | { | 
|  | varobj *v = create_child_with_value (var, var->children.size (), item); | 
|  |  | 
|  | var->children.push_back (v); | 
|  |  | 
|  | return v; | 
|  | } | 
|  |  | 
|  | /* Obtain the type of an object Variable as a string similar to the one gdb | 
|  | prints on the console.  The caller is responsible for freeing the string. | 
|  | */ | 
|  |  | 
|  | std::string | 
|  | varobj_get_type (struct varobj *var) | 
|  | { | 
|  | /* For the "fake" variables, do not return a type.  (Its type is | 
|  | NULL, too.) | 
|  | Do not return a type for invalid variables as well.  */ | 
|  | if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid) | 
|  | return std::string (); | 
|  |  | 
|  | return type_to_string (var->type); | 
|  | } | 
|  |  | 
|  | /* Obtain the type of an object variable.  */ | 
|  |  | 
|  | struct type * | 
|  | varobj_get_gdb_type (const struct varobj *var) | 
|  | { | 
|  | return var->type; | 
|  | } | 
|  |  | 
|  | /* Is VAR a path expression parent, i.e., can it be used to construct | 
|  | a valid path expression?  */ | 
|  |  | 
|  | static bool | 
|  | is_path_expr_parent (const struct varobj *var) | 
|  | { | 
|  | gdb_assert (var->root->lang_ops->is_path_expr_parent != NULL); | 
|  | return var->root->lang_ops->is_path_expr_parent (var); | 
|  | } | 
|  |  | 
|  | /* Is VAR a path expression parent, i.e., can it be used to construct | 
|  | a valid path expression?  By default we assume any VAR can be a path | 
|  | parent.  */ | 
|  |  | 
|  | bool | 
|  | varobj_default_is_path_expr_parent (const struct varobj *var) | 
|  | { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Return the path expression parent for VAR.  */ | 
|  |  | 
|  | const struct varobj * | 
|  | varobj_get_path_expr_parent (const struct varobj *var) | 
|  | { | 
|  | const struct varobj *parent = 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; | 
|  | } | 
|  |  | 
|  | /* Return a pointer to the full rooted expression of varobj VAR. | 
|  | If it has not been computed yet, compute it.  */ | 
|  |  | 
|  | const char * | 
|  | varobj_get_path_expr (const struct varobj *var) | 
|  | { | 
|  | if (var->path_expr.empty ()) | 
|  | { | 
|  | /* For root varobjs, we initialize path_expr | 
|  | when creating varobj, so here it should be | 
|  | child varobj.  */ | 
|  | struct varobj *mutable_var = (struct varobj *) var; | 
|  | gdb_assert (!is_root_p (var)); | 
|  |  | 
|  | mutable_var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var); | 
|  | } | 
|  |  | 
|  | return var->path_expr.c_str (); | 
|  | } | 
|  |  | 
|  | const struct language_defn * | 
|  | varobj_get_language (const struct varobj *var) | 
|  | { | 
|  | return var->root->exp->language_defn; | 
|  | } | 
|  |  | 
|  | int | 
|  | varobj_get_attributes (const struct varobj *var) | 
|  | { | 
|  | int attributes = 0; | 
|  |  | 
|  | if (varobj_editable_p (var)) | 
|  | /* FIXME: define masks for attributes.  */ | 
|  | attributes |= 0x00000001;	/* Editable */ | 
|  |  | 
|  | return attributes; | 
|  | } | 
|  |  | 
|  | /* Return true if VAR is a dynamic varobj.  */ | 
|  |  | 
|  | bool | 
|  | varobj_is_dynamic_p (const struct varobj *var) | 
|  | { | 
|  | return var->dynamic->pretty_printer != NULL; | 
|  | } | 
|  |  | 
|  | std::string | 
|  | varobj_get_formatted_value (struct varobj *var, | 
|  | enum varobj_display_formats format) | 
|  | { | 
|  | return my_value_of_variable (var, format); | 
|  | } | 
|  |  | 
|  | std::string | 
|  | varobj_get_value (struct varobj *var) | 
|  | { | 
|  | return my_value_of_variable (var, var->format); | 
|  | } | 
|  |  | 
|  | /* 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().  */ | 
|  |  | 
|  | bool | 
|  | varobj_set_value (struct varobj *var, const char *expression) | 
|  | { | 
|  | 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?  */ | 
|  | struct value *value = NULL; /* Initialize to keep gcc happy.  */ | 
|  | int saved_input_radix = input_radix; | 
|  | const char *s = expression; | 
|  |  | 
|  | gdb_assert (varobj_editable_p (var)); | 
|  |  | 
|  | input_radix = 10;		/* ALWAYS reset to decimal temporarily.  */ | 
|  | expression_up exp = parse_exp_1 (&s, 0, 0, 0); | 
|  | try | 
|  | { | 
|  | value = evaluate_expression (exp.get ()); | 
|  | } | 
|  |  | 
|  | catch (const gdb_exception_error &except) | 
|  | { | 
|  | /* We cannot proceed without a valid expression.  */ | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* All types that are editable must also be changeable.  */ | 
|  | 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.get ())); | 
|  |  | 
|  | /* Need to coerce the input.  We want to check if the | 
|  | value of the variable object will be different | 
|  | 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 array's address, not with the | 
|  | array's content.  */ | 
|  | value = coerce_array (value); | 
|  |  | 
|  | /* The new value may be lazy.  value_assign, or | 
|  | rather value_contents, will take care of this.  */ | 
|  | try | 
|  | { | 
|  | val = value_assign (var->value.get (), value); | 
|  | } | 
|  |  | 
|  | catch (const gdb_exception_error &except) | 
|  | { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* 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, false /* Compare values.  */); | 
|  | input_radix = saved_input_radix; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  |  | 
|  | /* A helper function to install a constructor function and visualizer | 
|  | in a varobj_dynamic.  */ | 
|  |  | 
|  | static void | 
|  | install_visualizer (struct varobj_dynamic *var, PyObject *constructor, | 
|  | PyObject *visualizer) | 
|  | { | 
|  | Py_XDECREF (var->constructor); | 
|  | var->constructor = constructor; | 
|  |  | 
|  | Py_XDECREF (var->pretty_printer); | 
|  | var->pretty_printer = visualizer; | 
|  |  | 
|  | var->child_iter.reset (nullptr); | 
|  | } | 
|  |  | 
|  | /* Install the default visualizer for VAR.  */ | 
|  |  | 
|  | 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) | 
|  | { | 
|  | gdbpy_ref<> pretty_printer; | 
|  |  | 
|  | if (var->value != nullptr) | 
|  | { | 
|  | pretty_printer = gdbpy_get_varobj_pretty_printer (var->value.get ()); | 
|  | if (pretty_printer == nullptr) | 
|  | { | 
|  | gdbpy_print_stack (); | 
|  | error (_("Cannot instantiate printer for default visualizer")); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (pretty_printer == Py_None) | 
|  | pretty_printer.reset (nullptr); | 
|  |  | 
|  | install_visualizer (var->dynamic, NULL, pretty_printer.release ()); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Instantiate and install a visualizer for VAR using CONSTRUCTOR to | 
|  | make a new object.  */ | 
|  |  | 
|  | static void | 
|  | construct_visualizer (struct varobj *var, PyObject *constructor) | 
|  | { | 
|  | 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; | 
|  | else | 
|  | { | 
|  | pretty_printer = instantiate_pretty_printer (constructor, | 
|  | var->value.get ()); | 
|  | if (! pretty_printer) | 
|  | { | 
|  | gdbpy_print_stack (); | 
|  | Py_DECREF (constructor); | 
|  | constructor = Py_None; | 
|  | Py_INCREF (constructor); | 
|  | } | 
|  |  | 
|  | if (pretty_printer == Py_None) | 
|  | { | 
|  | Py_DECREF (pretty_printer); | 
|  | pretty_printer = NULL; | 
|  | } | 
|  | } | 
|  |  | 
|  | install_visualizer (var->dynamic, constructor, pretty_printer); | 
|  | } | 
|  |  | 
|  | #endif /* HAVE_PYTHON */ | 
|  |  | 
|  | /* A helper function for install_new_value.  This creates and installs | 
|  | a visualizer for VAR, if appropriate.  */ | 
|  |  | 
|  | static void | 
|  | install_new_value_visualizer (struct varobj *var) | 
|  | { | 
|  | #if HAVE_PYTHON | 
|  | /* If the constructor is None, then we want the raw value.  If VAR | 
|  | does not have a value, just skip this.  */ | 
|  | if (!gdb_python_initialized) | 
|  | return; | 
|  |  | 
|  | if (var->dynamic->constructor != Py_None && var->value != NULL) | 
|  | { | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  |  | 
|  | if (var->dynamic->constructor == NULL) | 
|  | install_default_visualizer (var); | 
|  | else | 
|  | construct_visualizer (var, var->dynamic->constructor); | 
|  | } | 
|  | #else | 
|  | /* Do nothing.  */ | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* When using RTTI to determine variable type it may be changed in runtime when | 
|  | the variable value is changed.  This function checks whether type of varobj | 
|  | VAR will change when a new value NEW_VALUE is assigned and if it is so | 
|  | updates the type of VAR.  */ | 
|  |  | 
|  | static bool | 
|  | update_type_if_necessary (struct varobj *var, struct value *new_value) | 
|  | { | 
|  | if (new_value) | 
|  | { | 
|  | struct value_print_options opts; | 
|  |  | 
|  | get_user_print_options (&opts); | 
|  | if (opts.objectprint) | 
|  | { | 
|  | struct type *new_type = value_actual_type (new_value, 0, 0); | 
|  | std::string new_type_str = type_to_string (new_type); | 
|  | std::string curr_type_str = varobj_get_type (var); | 
|  |  | 
|  | /* Did the type name change?  */ | 
|  | if (curr_type_str != new_type_str) | 
|  | { | 
|  | var->type = new_type; | 
|  |  | 
|  | /* This information may be not valid for a new type.  */ | 
|  | varobj_delete (var, 1); | 
|  | var->children.clear (); | 
|  | var->num_children = -1; | 
|  | return true; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* Assign a new value to a variable object.  If INITIAL is true, | 
|  | this is the first assignment after the variable object was just | 
|  | created, or changed type.  In that case, just assign the value | 
|  | and return false. | 
|  | Otherwise, assign the new value, and return true if the value is | 
|  | different from the current one, false 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 true. | 
|  |  | 
|  | The VALUE parameter should not be released -- the function will | 
|  | take care of releasing it when needed.  */ | 
|  | static bool | 
|  | install_new_value (struct varobj *var, struct value *value, bool initial) | 
|  | { | 
|  | bool changeable; | 
|  | bool need_to_fetch; | 
|  | bool changed = false; | 
|  | bool intentionally_not_fetched = false; | 
|  |  | 
|  | /* 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.  */ | 
|  | 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 | 
|  | mess up read-sensitive values.  */ | 
|  | if (var->dynamic->pretty_printer != NULL) | 
|  | changeable = true; | 
|  |  | 
|  | need_to_fetch = changeable; | 
|  |  | 
|  | /* We are not interested in the address of references, and given | 
|  | that in C++ a reference is not rebindable, it cannot | 
|  | meaningfully change.  So, get hold of the real value.  */ | 
|  | if (value) | 
|  | value = coerce_ref (value); | 
|  |  | 
|  | if (var->type && var->type->code () == TYPE_CODE_UNION) | 
|  | /* For unions, we need to fetch the value implicitly because | 
|  | of implementation of union member fetch.  When gdb | 
|  | creates a value for a field and the value of the enclosing | 
|  | structure is not lazy,  it immediately copies the necessary | 
|  | bytes from the enclosing values.  If the enclosing value is | 
|  | lazy, the call to value_fetch_lazy on the field will read | 
|  | the data from memory.  For unions, that means we'll read the | 
|  | same memory more than once, which is not desirable.  So | 
|  | fetch now.  */ | 
|  | need_to_fetch = true; | 
|  |  | 
|  | /* The new value might be lazy.  If the type is changeable, | 
|  | that is we'll be comparing values of this type, fetch the | 
|  | value now.  Otherwise, on the next update the old value | 
|  | will be lazy, which means we've lost that old value.  */ | 
|  | if (need_to_fetch && value && value_lazy (value)) | 
|  | { | 
|  | const struct varobj *parent = var->parent; | 
|  | bool frozen = var->frozen; | 
|  |  | 
|  | for (; !frozen && parent; parent = parent->parent) | 
|  | frozen |= parent->frozen; | 
|  |  | 
|  | if (frozen && initial) | 
|  | { | 
|  | /* For variables that are frozen, or are children of frozen | 
|  | variables, we don't do fetch on initial assignment. | 
|  | For non-initial assignment we do the fetch, since it means we're | 
|  | explicitly asked to compare the new value with the old one.  */ | 
|  | intentionally_not_fetched = true; | 
|  | } | 
|  | else | 
|  | { | 
|  |  | 
|  | try | 
|  | { | 
|  | value_fetch_lazy (value); | 
|  | } | 
|  |  | 
|  | 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; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* 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_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 | 
|  | lazy -- if it is, the code above has decided that the value | 
|  | should not be fetched.  */ | 
|  | std::string print_value; | 
|  | if (value != NULL && !value_lazy (value) | 
|  | && var->dynamic->pretty_printer == NULL) | 
|  | print_value = varobj_value_get_print_value (value, var->format, var); | 
|  |  | 
|  | /* If the type is changeable, compare the old and the new values. | 
|  | If this is the initial assignment, we don't have any old value | 
|  | to compare with.  */ | 
|  | if (!initial && changeable) | 
|  | { | 
|  | /* 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 as changed.  */ | 
|  | if (var->updated) | 
|  | changed = true; | 
|  | else if (var->dynamic->pretty_printer == NULL) | 
|  | { | 
|  | /* Try to compare the values.  That requires that both | 
|  | values are non-lazy.  */ | 
|  | 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. | 
|  | Now that we've fetched the real value, we need to report | 
|  | this varobj as changed so that UI can show the real | 
|  | value.  */ | 
|  | changed = true; | 
|  | } | 
|  | else  if (var->value == NULL && value == NULL) | 
|  | /* Equal.  */ | 
|  | ; | 
|  | else if (var->value == NULL || value == NULL) | 
|  | { | 
|  | changed = true; | 
|  | } | 
|  | else | 
|  | { | 
|  | gdb_assert (!value_lazy (var->value.get ())); | 
|  | gdb_assert (!value_lazy (value)); | 
|  |  | 
|  | gdb_assert (!var->print_value.empty () && !print_value.empty ()); | 
|  | if (var->print_value != print_value) | 
|  | changed = true; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!initial && !changeable) | 
|  | { | 
|  | /* For values that are not changeable, we don't compare the values. | 
|  | However, we want to notice if a value was not NULL and now is NULL, | 
|  | or vise versa, so that we report when top-level varobjs come in scope | 
|  | and leave the scope.  */ | 
|  | changed = (var->value != NULL) != (value != NULL); | 
|  | } | 
|  |  | 
|  | /* We must always keep the new value, since children depend on it.  */ | 
|  | var->value = value_holder; | 
|  | if (value && value_lazy (value) && intentionally_not_fetched) | 
|  | var->not_fetched = true; | 
|  | else | 
|  | var->not_fetched = false; | 
|  | var->updated = false; | 
|  |  | 
|  | install_new_value_visualizer (var); | 
|  |  | 
|  | /* If we installed a pretty-printer, re-compare the printed version | 
|  | to see if the variable changed.  */ | 
|  | if (var->dynamic->pretty_printer != NULL) | 
|  | { | 
|  | 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)) | 
|  | changed = true; | 
|  | } | 
|  | var->print_value = print_value; | 
|  |  | 
|  | gdb_assert (var->value == nullptr || value_type (var->value.get ())); | 
|  |  | 
|  | return changed; | 
|  | } | 
|  |  | 
|  | /* Return the requested range for a varobj.  VAR is the varobj.  FROM | 
|  | and TO are out parameters; *FROM and *TO will be set to the | 
|  | selected sub-range of VAR.  If no range was selected using | 
|  | -var-set-update-range, then both will be -1.  */ | 
|  | void | 
|  | varobj_get_child_range (const struct varobj *var, int *from, int *to) | 
|  | { | 
|  | *from = var->from; | 
|  | *to = var->to; | 
|  | } | 
|  |  | 
|  | /* Set the selected sub-range of children of VAR to start at index | 
|  | FROM and end at index TO.  If either FROM or TO is less than zero, | 
|  | this is interpreted as a request for all children.  */ | 
|  | void | 
|  | varobj_set_child_range (struct varobj *var, int from, int to) | 
|  | { | 
|  | var->from = from; | 
|  | var->to = to; | 
|  | } | 
|  |  | 
|  | void | 
|  | varobj_set_visualizer (struct varobj *var, const char *visualizer) | 
|  | { | 
|  | #if HAVE_PYTHON | 
|  | PyObject *mainmod; | 
|  |  | 
|  | if (!gdb_python_initialized) | 
|  | return; | 
|  |  | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  |  | 
|  | mainmod = PyImport_AddModule ("__main__"); | 
|  | gdbpy_ref<> globals | 
|  | = gdbpy_ref<>::new_reference (PyModule_GetDict (mainmod)); | 
|  | gdbpy_ref<> constructor (PyRun_String (visualizer, Py_eval_input, | 
|  | globals.get (), globals.get ())); | 
|  |  | 
|  | if (constructor == NULL) | 
|  | { | 
|  | gdbpy_print_stack (); | 
|  | error (_("Could not evaluate visualizer expression: %s"), visualizer); | 
|  | } | 
|  |  | 
|  | construct_visualizer (var, constructor.get ()); | 
|  |  | 
|  | /* If there are any children now, wipe them.  */ | 
|  | varobj_delete (var, 1 /* children only */); | 
|  | var->num_children = -1; | 
|  | #else | 
|  | error (_("Python support required")); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* If NEW_VALUE is the new value of the given varobj (var), return | 
|  | true if var has mutated.  In other words, if the type of | 
|  | the new value is different from the type of the varobj's old | 
|  | value. | 
|  |  | 
|  | NEW_VALUE may be NULL, if the varobj is now out of scope.  */ | 
|  |  | 
|  | static bool | 
|  | varobj_value_has_mutated (const struct varobj *var, struct value *new_value, | 
|  | struct type *new_type) | 
|  | { | 
|  | /* If we haven't previously computed the number of children in var, | 
|  | it does not matter from the front-end's perspective whether | 
|  | the type has mutated or not.  For all intents and purposes, | 
|  | it has not mutated.  */ | 
|  | if (var->num_children < 0) | 
|  | return false; | 
|  |  | 
|  | if (var->root->lang_ops->value_has_mutated != NULL) | 
|  | { | 
|  | /* The varobj module, when installing new values, explicitly strips | 
|  | references, saying that we're not interested in those addresses. | 
|  | But detection of mutation happens before installing the new | 
|  | value, so our value may be a reference that we need to strip | 
|  | in order to remain consistent.  */ | 
|  | if (new_value != NULL) | 
|  | new_value = coerce_ref (new_value); | 
|  | return var->root->lang_ops->value_has_mutated (var, new_value, new_type); | 
|  | } | 
|  | else | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /* Update the values for a variable and its children.  This is a | 
|  | two-pronged attack.  First, re-parse the value for the root's | 
|  | expression to see if it's changed.  Then go all the way | 
|  | through its children, reconstructing them and noting if they've | 
|  | changed. | 
|  |  | 
|  | The IS_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 | 
|  | update frozen variables. | 
|  |  | 
|  | 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.  */ | 
|  |  | 
|  | std::vector<varobj_update_result> | 
|  | varobj_update (struct varobj **varp, bool is_explicit) | 
|  | { | 
|  | bool type_changed = false; | 
|  | struct value *newobj; | 
|  | std::vector<varobj_update_result> stack; | 
|  | std::vector<varobj_update_result> result; | 
|  |  | 
|  | /* Frozen means frozen -- we don't check for any change in | 
|  | this varobj, including its going out of scope, or | 
|  | changing type.  One use case for frozen varobjs is | 
|  | retaining previously evaluated expressions, and we don't | 
|  | want them to be reevaluated at all.  */ | 
|  | if (!is_explicit && (*varp)->frozen) | 
|  | return result; | 
|  |  | 
|  | if (!(*varp)->root->is_valid) | 
|  | { | 
|  | result.emplace_back (*varp, VAROBJ_INVALID); | 
|  | return result; | 
|  | } | 
|  |  | 
|  | if ((*varp)->root->rootvar == *varp) | 
|  | { | 
|  | varobj_update_result r (*varp); | 
|  |  | 
|  | /* 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 | 
|  | value_of_root variable dispose of the varobj if the type | 
|  | has changed.  */ | 
|  | newobj = value_of_root (varp, &type_changed); | 
|  | if (update_type_if_necessary (*varp, newobj)) | 
|  | type_changed = true; | 
|  | r.varobj = *varp; | 
|  | r.type_changed = type_changed; | 
|  | if (install_new_value ((*varp), newobj, type_changed)) | 
|  | r.changed = true; | 
|  |  | 
|  | if (newobj == NULL) | 
|  | r.status = VAROBJ_NOT_IN_SCOPE; | 
|  | r.value_installed = true; | 
|  |  | 
|  | if (r.status == VAROBJ_NOT_IN_SCOPE) | 
|  | { | 
|  | if (r.type_changed || r.changed) | 
|  | result.push_back (std::move (r)); | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | stack.push_back (std::move (r)); | 
|  | } | 
|  | else | 
|  | stack.emplace_back (*varp); | 
|  |  | 
|  | /* Walk through the children, reconstructing them all.  */ | 
|  | while (!stack.empty ()) | 
|  | { | 
|  | varobj_update_result r = std::move (stack.back ()); | 
|  | stack.pop_back (); | 
|  | struct varobj *v = r.varobj; | 
|  |  | 
|  | /* Update this variable, unless it's a root, which is already | 
|  | updated.  */ | 
|  | if (!r.value_installed) | 
|  | { | 
|  | struct type *new_type; | 
|  |  | 
|  | newobj = value_of_child (v->parent, v->index); | 
|  | if (update_type_if_necessary (v, newobj)) | 
|  | r.type_changed = true; | 
|  | if (newobj) | 
|  | new_type = value_type (newobj); | 
|  | else | 
|  | new_type = v->root->lang_ops->type_of_child (v->parent, v->index); | 
|  |  | 
|  | if (varobj_value_has_mutated (v, newobj, new_type)) | 
|  | { | 
|  | /* The children are no longer valid; delete them now. | 
|  | Report the fact that its type changed as well.  */ | 
|  | varobj_delete (v, 1 /* only_children */); | 
|  | v->num_children = -1; | 
|  | v->to = -1; | 
|  | v->from = -1; | 
|  | v->type = new_type; | 
|  | r.type_changed = true; | 
|  | } | 
|  |  | 
|  | if (install_new_value (v, newobj, r.type_changed)) | 
|  | { | 
|  | r.changed = true; | 
|  | v->updated = false; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* We probably should not get children of a dynamic varobj, but | 
|  | for which -var-list-children was never invoked.  */ | 
|  | if (varobj_is_dynamic_p (v)) | 
|  | { | 
|  | std::vector<varobj *> changed, type_changed_vec, unchanged, newobj_vec; | 
|  | bool children_changed = false; | 
|  |  | 
|  | if (v->frozen) | 
|  | continue; | 
|  |  | 
|  | if (!v->dynamic->children_requested) | 
|  | { | 
|  | bool dummy; | 
|  |  | 
|  | /* If we initially did not have potential children, but | 
|  | now we do, consider the varobj as changed. | 
|  | Otherwise, if children were never requested, consider | 
|  | it as unchanged -- presumably, such varobj is not yet | 
|  | expanded in the UI, so we need not bother getting | 
|  | it.  */ | 
|  | if (!varobj_has_more (v, 0)) | 
|  | { | 
|  | update_dynamic_varobj_children (v, NULL, NULL, NULL, NULL, | 
|  | &dummy, false, 0, 0); | 
|  | if (varobj_has_more (v, 0)) | 
|  | r.changed = true; | 
|  | } | 
|  |  | 
|  | if (r.changed) | 
|  | result.push_back (std::move (r)); | 
|  |  | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* 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_vec, | 
|  | &newobj_vec, | 
|  | &unchanged, &children_changed, | 
|  | true, v->from, v->to)) | 
|  | { | 
|  | if (children_changed || !newobj_vec.empty ()) | 
|  | { | 
|  | r.children_changed = true; | 
|  | 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_vec.size () - 1; i >= 0; --i) | 
|  | { | 
|  | varobj_update_result item (type_changed_vec[i]); | 
|  |  | 
|  | /* Type may change only if value was changed.  */ | 
|  | item.changed = true; | 
|  | item.type_changed = true; | 
|  | item.value_installed = true; | 
|  |  | 
|  | stack.push_back (std::move (item)); | 
|  | } | 
|  | for (int i = changed.size () - 1; i >= 0; --i) | 
|  | { | 
|  | varobj_update_result item (changed[i]); | 
|  |  | 
|  | item.changed = true; | 
|  | item.value_installed = true; | 
|  |  | 
|  | stack.push_back (std::move (item)); | 
|  | } | 
|  | for (int i = unchanged.size () - 1; i >= 0; --i) | 
|  | { | 
|  | if (!unchanged[i]->frozen) | 
|  | { | 
|  | varobj_update_result item (unchanged[i]); | 
|  |  | 
|  | item.value_installed = true; | 
|  |  | 
|  | stack.push_back (std::move (item)); | 
|  | } | 
|  | } | 
|  | if (r.changed || r.children_changed) | 
|  | result.push_back (std::move (r)); | 
|  |  | 
|  | continue; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Push any children.  Use 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 = v->children.size () - 1; i >= 0; --i) | 
|  | { | 
|  | varobj *c = v->children[i]; | 
|  |  | 
|  | /* Child may be NULL if explicitly deleted by -var-delete.  */ | 
|  | if (c != NULL && !c->frozen) | 
|  | stack.emplace_back (c); | 
|  | } | 
|  |  | 
|  | if (r.changed || r.type_changed) | 
|  | result.push_back (std::move (r)); | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | /* Helper functions */ | 
|  |  | 
|  | /* | 
|  | * Variable object construction/destruction | 
|  | */ | 
|  |  | 
|  | static int | 
|  | delete_variable (struct varobj *var, bool only_children_p) | 
|  | { | 
|  | int delcount = 0; | 
|  |  | 
|  | delete_variable_1 (&delcount, var, only_children_p, | 
|  | true /* remove_from_parent_p */ ); | 
|  |  | 
|  | return delcount; | 
|  | } | 
|  |  | 
|  | /* 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.  */ | 
|  | static void | 
|  | delete_variable_1 (int *delcountp, struct varobj *var, bool only_children_p, | 
|  | bool remove_from_parent_p) | 
|  | { | 
|  | /* Delete any children of this variable, too.  */ | 
|  | for (varobj *child : var->children) | 
|  | { | 
|  | if (!child) | 
|  | continue; | 
|  |  | 
|  | if (!remove_from_parent_p) | 
|  | child->parent = NULL; | 
|  |  | 
|  | delete_variable_1 (delcountp, child, false, only_children_p); | 
|  | } | 
|  | var->children.clear (); | 
|  |  | 
|  | /* 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.  */ | 
|  | /* If the name is empty, this is a temporary variable, that has not | 
|  | yet been installed, don't report it, it belongs to the caller...  */ | 
|  | if (!var->obj_name.empty ()) | 
|  | { | 
|  | *delcountp = *delcountp + 1; | 
|  | } | 
|  |  | 
|  | /* 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.  */ | 
|  | if ((remove_from_parent_p) && (var->parent != NULL)) | 
|  | var->parent->children[var->index] = NULL; | 
|  |  | 
|  | if (!var->obj_name.empty ()) | 
|  | uninstall_variable (var); | 
|  |  | 
|  | /* Free memory associated with this variable.  */ | 
|  | delete var; | 
|  | } | 
|  |  | 
|  | /* Install the given variable VAR with the object name VAR->OBJ_NAME.  */ | 
|  | static void | 
|  | install_variable (struct varobj *var) | 
|  | { | 
|  | hashval_t hash = htab_hash_string (var->obj_name.c_str ()); | 
|  | void **slot = htab_find_slot_with_hash (varobj_table, | 
|  | var->obj_name.c_str (), | 
|  | hash, INSERT); | 
|  | if (*slot != nullptr) | 
|  | error (_("Duplicate variable object name")); | 
|  |  | 
|  | /* Add varobj to hash table.  */ | 
|  | *slot = var; | 
|  |  | 
|  | /* If root, add varobj to root list.  */ | 
|  | if (is_root_p (var)) | 
|  | rootlist.push_front (var->root); | 
|  | } | 
|  |  | 
|  | /* Uninstall the object VAR.  */ | 
|  | static void | 
|  | uninstall_variable (struct varobj *var) | 
|  | { | 
|  | hashval_t hash = htab_hash_string (var->obj_name.c_str ()); | 
|  | htab_remove_elt_with_hash (varobj_table, var->obj_name.c_str (), hash); | 
|  |  | 
|  | if (varobjdebug) | 
|  | fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name.c_str ()); | 
|  |  | 
|  | /* If root, remove varobj from root list.  */ | 
|  | if (is_root_p (var)) | 
|  | { | 
|  | auto iter = std::find (rootlist.begin (), rootlist.end (), var->root); | 
|  | rootlist.erase (iter); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Create and install a child of the parent of the given name. | 
|  |  | 
|  | The created VAROBJ takes ownership of the allocated NAME.  */ | 
|  |  | 
|  | static struct varobj * | 
|  | create_child (struct varobj *parent, int index, std::string &name) | 
|  | { | 
|  | struct varobj_item item; | 
|  |  | 
|  | std::swap (item.name, name); | 
|  | item.value = release_value (value_of_child (parent, index)); | 
|  |  | 
|  | return create_child_with_value (parent, index, &item); | 
|  | } | 
|  |  | 
|  | static struct varobj * | 
|  | create_child_with_value (struct varobj *parent, int index, | 
|  | struct varobj_item *item) | 
|  | { | 
|  | varobj *child = new varobj (parent->root); | 
|  |  | 
|  | /* NAME is allocated by caller.  */ | 
|  | std::swap (child->name, item->name); | 
|  | child->index = index; | 
|  | child->parent = parent; | 
|  |  | 
|  | if (varobj_is_anonymous_child (child)) | 
|  | child->obj_name = string_printf ("%s.%d_anonymous", | 
|  | parent->obj_name.c_str (), index); | 
|  | else | 
|  | child->obj_name = string_printf ("%s.%s", | 
|  | parent->obj_name.c_str (), | 
|  | child->name.c_str ()); | 
|  |  | 
|  | install_variable (child); | 
|  |  | 
|  | /* Compute the type of the child.  Must do this before | 
|  | calling install_new_value.  */ | 
|  | if (item->value != NULL) | 
|  | /* If the child had no evaluation errors, var->value | 
|  | will be non-NULL and contain a valid type.  */ | 
|  | child->type = value_actual_type (item->value.get (), 0, NULL); | 
|  | else | 
|  | /* Otherwise, we must compute the type.  */ | 
|  | child->type = (*child->root->lang_ops->type_of_child) (child->parent, | 
|  | child->index); | 
|  | install_new_value (child, item->value.get (), 1); | 
|  |  | 
|  | return child; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* | 
|  | * Miscellaneous utility functions. | 
|  | */ | 
|  |  | 
|  | /* Allocate memory and initialize a new variable.  */ | 
|  | varobj::varobj (varobj_root *root_) | 
|  | : root (root_), dynamic (new varobj_dynamic) | 
|  | { | 
|  | } | 
|  |  | 
|  | /* Free any allocated memory associated with VAR.  */ | 
|  |  | 
|  | varobj::~varobj () | 
|  | { | 
|  | varobj *var = this; | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  | if (var->dynamic->pretty_printer != NULL) | 
|  | { | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  |  | 
|  | Py_XDECREF (var->dynamic->constructor); | 
|  | Py_XDECREF (var->dynamic->pretty_printer); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* This must be deleted before the root object, because Python-based | 
|  | destructors need access to some components.  */ | 
|  | delete var->dynamic; | 
|  |  | 
|  | if (is_root_p (var)) | 
|  | delete var->root; | 
|  | } | 
|  |  | 
|  | /* Return the type of the value that's stored in VAR, | 
|  | or that would have being stored there if the | 
|  | value were accessible. | 
|  |  | 
|  | This differs from VAR->type in that VAR->type is always | 
|  | the true type of the expression in the source language. | 
|  | The return value of this function is the type we're | 
|  | actually storing in varobj, and using for displaying | 
|  | the values and for comparing previous and new values. | 
|  |  | 
|  | For example, top-level references are always stripped.  */ | 
|  | struct type * | 
|  | varobj_get_value_type (const struct varobj *var) | 
|  | { | 
|  | struct type *type; | 
|  |  | 
|  | if (var->value != nullptr) | 
|  | type = value_type (var->value.get ()); | 
|  | else | 
|  | type = var->type; | 
|  |  | 
|  | type = check_typedef (type); | 
|  |  | 
|  | if (TYPE_IS_REFERENCE (type)) | 
|  | type = get_target_type (type); | 
|  |  | 
|  | type = check_typedef (type); | 
|  |  | 
|  | return type; | 
|  | } | 
|  |  | 
|  | /* What is the default display for this variable? We assume that | 
|  | everything is "natural".  Any exceptions?  */ | 
|  | static enum varobj_display_formats | 
|  | variable_default_display (struct varobj *var) | 
|  | { | 
|  | return FORMAT_NATURAL; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Language-dependencies | 
|  | */ | 
|  |  | 
|  | /* Common entry points */ | 
|  |  | 
|  | /* 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 | 
|  | is the number of children that the user will see in the variable | 
|  | display.  */ | 
|  | static int | 
|  | number_of_children (const struct varobj *var) | 
|  | { | 
|  | return (*var->root->lang_ops->number_of_children) (var); | 
|  | } | 
|  |  | 
|  | /* What is the expression for the root varobj VAR? */ | 
|  |  | 
|  | static std::string | 
|  | name_of_variable (const struct varobj *var) | 
|  | { | 
|  | return (*var->root->lang_ops->name_of_variable) (var); | 
|  | } | 
|  |  | 
|  | /* What is the name of the INDEX'th child of VAR?  */ | 
|  |  | 
|  | static std::string | 
|  | name_of_child (struct varobj *var, int index) | 
|  | { | 
|  | return (*var->root->lang_ops->name_of_child) (var, index); | 
|  | } | 
|  |  | 
|  | /* If frame associated with VAR can be found, switch | 
|  | to it and return true.  Otherwise, return false.  */ | 
|  |  | 
|  | static bool | 
|  | check_scope (const struct varobj *var) | 
|  | { | 
|  | struct frame_info *fi; | 
|  | bool scope; | 
|  |  | 
|  | fi = frame_find_by_id (var->root->frame); | 
|  | scope = fi != NULL; | 
|  |  | 
|  | if (fi) | 
|  | { | 
|  | CORE_ADDR pc = get_frame_pc (fi); | 
|  |  | 
|  | if (pc <  BLOCK_START (var->root->valid_block) || | 
|  | pc >= BLOCK_END (var->root->valid_block)) | 
|  | scope = false; | 
|  | else | 
|  | select_frame (fi); | 
|  | } | 
|  | return scope; | 
|  | } | 
|  |  | 
|  | /* Helper function to value_of_root.  */ | 
|  |  | 
|  | static struct value * | 
|  | value_of_root_1 (struct varobj **var_handle) | 
|  | { | 
|  | struct value *new_val = NULL; | 
|  | struct varobj *var = *var_handle; | 
|  | bool within_scope = false; | 
|  |  | 
|  | /*  Only root variables can be updated...  */ | 
|  | if (!is_root_p (var)) | 
|  | /* Not a root var.  */ | 
|  | return NULL; | 
|  |  | 
|  | scoped_restore_current_thread restore_thread; | 
|  |  | 
|  | /* Determine whether the variable is still around.  */ | 
|  | if (var->root->valid_block == NULL || var->root->floating) | 
|  | within_scope = true; | 
|  | else if (var->root->thread_id == 0) | 
|  | { | 
|  | /* The program was single-threaded when the variable object was | 
|  | created.  Technically, it's possible that the program became | 
|  | multi-threaded since then, but we don't support such | 
|  | scenario yet.  */ | 
|  | within_scope = check_scope (var); | 
|  | } | 
|  | else | 
|  | { | 
|  | thread_info *thread = find_thread_global_id (var->root->thread_id); | 
|  |  | 
|  | if (thread != NULL) | 
|  | { | 
|  | switch_to_thread (thread); | 
|  | within_scope = check_scope (var); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (within_scope) | 
|  | { | 
|  |  | 
|  | /* We need to catch errors here, because if evaluate | 
|  | expression fails we want to just return NULL.  */ | 
|  | try | 
|  | { | 
|  | new_val = evaluate_expression (var->root->exp.get ()); | 
|  | } | 
|  | catch (const gdb_exception_error &except) | 
|  | { | 
|  | } | 
|  | } | 
|  |  | 
|  | return new_val; | 
|  | } | 
|  |  | 
|  | /* What is the ``struct value *'' of the root variable VAR? | 
|  | For floating variable object, evaluation can get us a value | 
|  | of different type from what is stored in varobj already.  In | 
|  | that case: | 
|  | - *type_changed will be set to 1 | 
|  | - old varobj will be freed, and new one will be | 
|  | created, with the same name. | 
|  | - *var_handle will be set to the new varobj | 
|  | Otherwise, *type_changed will be set to 0.  */ | 
|  | static struct value * | 
|  | value_of_root (struct varobj **var_handle, bool *type_changed) | 
|  | { | 
|  | struct varobj *var; | 
|  |  | 
|  | if (var_handle == NULL) | 
|  | return NULL; | 
|  |  | 
|  | var = *var_handle; | 
|  |  | 
|  | /* This should really be an exception, since this should | 
|  | only get called with a root variable.  */ | 
|  |  | 
|  | if (!is_root_p (var)) | 
|  | return NULL; | 
|  |  | 
|  | if (var->root->floating) | 
|  | { | 
|  | struct varobj *tmp_var; | 
|  |  | 
|  | tmp_var = varobj_create (NULL, var->name.c_str (), (CORE_ADDR) 0, | 
|  | USE_SELECTED_FRAME); | 
|  | if (tmp_var == NULL) | 
|  | { | 
|  | return NULL; | 
|  | } | 
|  | std::string old_type = varobj_get_type (var); | 
|  | std::string new_type = varobj_get_type (tmp_var); | 
|  | if (old_type == new_type) | 
|  | { | 
|  | /* The expression presently stored inside var->root->exp | 
|  | remembers the locations of local variables relatively to | 
|  | the frame where the expression was created (in DWARF location | 
|  | button, for example).  Naturally, those locations are not | 
|  | correct in other frames, so update the expression.  */ | 
|  |  | 
|  | std::swap (var->root->exp, tmp_var->root->exp); | 
|  |  | 
|  | varobj_delete (tmp_var, 0); | 
|  | *type_changed = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | tmp_var->obj_name = var->obj_name; | 
|  | tmp_var->from = var->from; | 
|  | tmp_var->to = var->to; | 
|  | varobj_delete (var, 0); | 
|  |  | 
|  | install_variable (tmp_var); | 
|  | *var_handle = tmp_var; | 
|  | var = *var_handle; | 
|  | *type_changed = true; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | *type_changed = 0; | 
|  | } | 
|  |  | 
|  | { | 
|  | struct value *value; | 
|  |  | 
|  | value = value_of_root_1 (var_handle); | 
|  | if (var->value == NULL || value == NULL) | 
|  | { | 
|  | /* For root varobj-s, a NULL value indicates a scoping issue. | 
|  | So, nothing to do in terms of checking for mutations.  */ | 
|  | } | 
|  | else if (varobj_value_has_mutated (var, value, value_type (value))) | 
|  | { | 
|  | /* The type has mutated, so the children are no longer valid. | 
|  | Just delete them, and tell our caller that the type has | 
|  | changed.  */ | 
|  | varobj_delete (var, 1 /* only_children */); | 
|  | var->num_children = -1; | 
|  | var->to = -1; | 
|  | var->from = -1; | 
|  | *type_changed = true; | 
|  | } | 
|  | return value; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* What is the ``struct value *'' for the INDEX'th child of PARENT?  */ | 
|  | static struct value * | 
|  | value_of_child (const struct varobj *parent, int index) | 
|  | { | 
|  | struct value *value; | 
|  |  | 
|  | value = (*parent->root->lang_ops->value_of_child) (parent, index); | 
|  |  | 
|  | return value; | 
|  | } | 
|  |  | 
|  | /* GDB already has a command called "value_of_variable".  Sigh.  */ | 
|  | static std::string | 
|  | my_value_of_variable (struct varobj *var, enum varobj_display_formats format) | 
|  | { | 
|  | if (var->root->is_valid) | 
|  | { | 
|  | if (var->dynamic->pretty_printer != NULL) | 
|  | return varobj_value_get_print_value (var->value.get (), var->format, | 
|  | var); | 
|  | return (*var->root->lang_ops->value_of_variable) (var, format); | 
|  | } | 
|  | else | 
|  | return std::string (); | 
|  | } | 
|  |  | 
|  | void | 
|  | varobj_formatted_print_options (struct value_print_options *opts, | 
|  | enum varobj_display_formats format) | 
|  | { | 
|  | get_formatted_print_options (opts, format_code[(int) format]); | 
|  | opts->deref_ref = 0; | 
|  | opts->raw = !pretty_printing; | 
|  | } | 
|  |  | 
|  | std::string | 
|  | varobj_value_get_print_value (struct value *value, | 
|  | enum varobj_display_formats format, | 
|  | const struct varobj *var) | 
|  | { | 
|  | struct value_print_options opts; | 
|  | struct type *type = NULL; | 
|  | long len = 0; | 
|  | gdb::unique_xmalloc_ptr<char> encoding; | 
|  | /* Initialize it just to avoid a GCC false warning.  */ | 
|  | CORE_ADDR str_addr = 0; | 
|  | bool string_print = false; | 
|  |  | 
|  | if (value == NULL) | 
|  | return std::string (); | 
|  |  | 
|  | string_file stb; | 
|  | std::string thevalue; | 
|  |  | 
|  | #if HAVE_PYTHON | 
|  | if (gdb_python_initialized) | 
|  | { | 
|  | PyObject *value_formatter =  var->dynamic->pretty_printer; | 
|  |  | 
|  | gdbpy_enter_varobj enter_py (var); | 
|  |  | 
|  | if (value_formatter) | 
|  | { | 
|  | /* First check to see if we have any children at all.  If so, | 
|  | we simply return {...}.  */ | 
|  | if (dynamic_varobj_has_child_method (var)) | 
|  | return "{...}"; | 
|  |  | 
|  | if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst)) | 
|  | { | 
|  | struct value *replacement; | 
|  |  | 
|  | gdbpy_ref<> output = apply_varobj_pretty_printer (value_formatter, | 
|  | &replacement, | 
|  | &stb); | 
|  |  | 
|  | /* If we have string like output ...  */ | 
|  | if (output != NULL) | 
|  | { | 
|  | /* 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.get ())) | 
|  | { | 
|  | gdbpy_extract_lazy_string (output.get (), &str_addr, | 
|  | &type, &len, &encoding); | 
|  | string_print = true; | 
|  | } | 
|  | 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.  */ | 
|  |  | 
|  | gdb::unique_xmalloc_ptr<char> s | 
|  | = python_string_to_target_string (output.get ()); | 
|  |  | 
|  | if (s) | 
|  | { | 
|  | struct gdbarch *gdbarch; | 
|  |  | 
|  | gdb::unique_xmalloc_ptr<char> hint | 
|  | = gdbpy_get_display_hint (value_formatter); | 
|  | if (hint) | 
|  | { | 
|  | if (!strcmp (hint.get (), "string")) | 
|  | string_print = true; | 
|  | } | 
|  |  | 
|  | thevalue = std::string (s.get ()); | 
|  | len = thevalue.size (); | 
|  | gdbarch = value_type (value)->arch (); | 
|  | type = builtin_type (gdbarch)->builtin_char; | 
|  |  | 
|  | if (!string_print) | 
|  | return thevalue; | 
|  | } | 
|  | else | 
|  | 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; | 
|  | } | 
|  | } | 
|  | } | 
|  | #endif | 
|  |  | 
|  | varobj_formatted_print_options (&opts, format); | 
|  |  | 
|  | /* If the THEVALUE has contents, it is a regular string.  */ | 
|  | if (!thevalue.empty ()) | 
|  | current_language->printstr (&stb, type, (gdb_byte *) thevalue.c_str (), | 
|  | len, encoding.get (), 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.get (), str_addr, len, &stb, &opts); | 
|  | else | 
|  | /* All other cases.  */ | 
|  | common_val_print (value, &stb, 0, &opts, current_language); | 
|  |  | 
|  | return stb.release (); | 
|  | } | 
|  |  | 
|  | bool | 
|  | varobj_editable_p (const struct varobj *var) | 
|  | { | 
|  | struct type *type; | 
|  |  | 
|  | if (!(var->root->is_valid && var->value != nullptr | 
|  | && VALUE_LVAL (var->value.get ()))) | 
|  | return false; | 
|  |  | 
|  | type = varobj_get_value_type (var); | 
|  |  | 
|  | switch (type->code ()) | 
|  | { | 
|  | case TYPE_CODE_STRUCT: | 
|  | case TYPE_CODE_UNION: | 
|  | case TYPE_CODE_ARRAY: | 
|  | case TYPE_CODE_FUNC: | 
|  | case TYPE_CODE_METHOD: | 
|  | return false; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | return true; | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Call VAR's value_is_changeable_p language-specific callback.  */ | 
|  |  | 
|  | bool | 
|  | varobj_value_is_changeable_p (const struct varobj *var) | 
|  | { | 
|  | return var->root->lang_ops->value_is_changeable_p (var); | 
|  | } | 
|  |  | 
|  | /* Return true if that varobj is floating, that is is always evaluated in the | 
|  | selected frame, and not bound to thread/frame.  Such variable objects | 
|  | are created using '@' as frame specifier to -var-create.  */ | 
|  | bool | 
|  | varobj_floating_p (const struct varobj *var) | 
|  | { | 
|  | return var->root->floating; | 
|  | } | 
|  |  | 
|  | /* Implement the "value_is_changeable_p" varobj callback for most | 
|  | languages.  */ | 
|  |  | 
|  | bool | 
|  | varobj_default_value_is_changeable_p (const struct varobj *var) | 
|  | { | 
|  | bool r; | 
|  | struct type *type; | 
|  |  | 
|  | if (CPLUS_FAKE_CHILD (var)) | 
|  | return false; | 
|  |  | 
|  | type = varobj_get_value_type (var); | 
|  |  | 
|  | switch (type->code ()) | 
|  | { | 
|  | case TYPE_CODE_STRUCT: | 
|  | case TYPE_CODE_UNION: | 
|  | case TYPE_CODE_ARRAY: | 
|  | r = false; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | r = true; | 
|  | } | 
|  |  | 
|  | return r; | 
|  | } | 
|  |  | 
|  | /* Iterate all the existing _root_ VAROBJs and call the FUNC callback | 
|  | for each one.  */ | 
|  |  | 
|  | void | 
|  | all_root_varobjs (gdb::function_view<void (struct varobj *var)> func) | 
|  | { | 
|  | /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */ | 
|  | auto iter = rootlist.begin (); | 
|  | auto end = rootlist.end (); | 
|  | while (iter != end) | 
|  | { | 
|  | auto self = iter++; | 
|  | func ((*self)->rootvar); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Invalidate varobj VAR if it is tied to locals and re-create it if it is | 
|  | defined on globals.  It is a helper for varobj_invalidate. | 
|  |  | 
|  | This function is called after changing the symbol file, in this case the | 
|  | pointers to "struct type" stored by the varobj are no longer valid.  All | 
|  | varobj must be either re-evaluated, or marked as invalid here.  */ | 
|  |  | 
|  | static void | 
|  | varobj_invalidate_iter (struct varobj *var) | 
|  | { | 
|  | /* global and floating var must be re-evaluated.  */ | 
|  | if (var->root->floating || var->root->valid_block == NULL) | 
|  | { | 
|  | struct varobj *tmp_var; | 
|  |  | 
|  | /* Try to create a varobj with same expression.  If we succeed | 
|  | replace the old varobj, otherwise invalidate it.  */ | 
|  | tmp_var = varobj_create (NULL, var->name.c_str (), (CORE_ADDR) 0, | 
|  | USE_CURRENT_FRAME); | 
|  | if (tmp_var != NULL) | 
|  | { | 
|  | tmp_var->obj_name = var->obj_name; | 
|  | varobj_delete (var, 0); | 
|  | install_variable (tmp_var); | 
|  | } | 
|  | else | 
|  | var->root->is_valid = false; | 
|  | } | 
|  | else /* locals must be invalidated.  */ | 
|  | var->root->is_valid = false; | 
|  | } | 
|  |  | 
|  | /* Invalidate the varobjs that are tied to locals and re-create the ones that | 
|  | are defined on globals. | 
|  | Invalidated varobjs will be always printed in_scope="invalid".  */ | 
|  |  | 
|  | void | 
|  | varobj_invalidate (void) | 
|  | { | 
|  | all_root_varobjs (varobj_invalidate_iter); | 
|  | } | 
|  |  | 
|  | /* A hash function for a varobj.  */ | 
|  |  | 
|  | static hashval_t | 
|  | hash_varobj (const void *a) | 
|  | { | 
|  | const varobj *obj = (const varobj *) a; | 
|  | return htab_hash_string (obj->obj_name.c_str ()); | 
|  | } | 
|  |  | 
|  | /* A hash table equality function for varobjs.  */ | 
|  |  | 
|  | static int | 
|  | eq_varobj_and_string (const void *a, const void *b) | 
|  | { | 
|  | const varobj *obj = (const varobj *) a; | 
|  | const char *name = (const char *) b; | 
|  |  | 
|  | return obj->obj_name == name; | 
|  | } | 
|  |  | 
|  | void _initialize_varobj (); | 
|  | void | 
|  | _initialize_varobj () | 
|  | { | 
|  | varobj_table = htab_create_alloc (5, hash_varobj, eq_varobj_and_string, | 
|  | nullptr, xcalloc, xfree); | 
|  |  | 
|  | add_setshow_zuinteger_cmd ("varobj", class_maintenance, | 
|  | &varobjdebug, | 
|  | _("Set varobj debugging."), | 
|  | _("Show varobj debugging."), | 
|  | _("When non-zero, varobj debugging is enabled."), | 
|  | NULL, show_varobjdebug, | 
|  | &setdebuglist, &showdebuglist); | 
|  | } |