From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23962 invoked by alias); 18 Nov 2017 21:46:16 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 23814 invoked by uid 89); 18 Nov 2017 21:46:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KB_WAM_FROM_NAME_SINGLEWORD,RCVD_IN_DNSWL_NONE,SPF_SOFTFAIL autolearn=ham version=3.3.2 spammy=H*r:sk:barracu, varobj, type_name X-HELO: barracuda.ebox.ca Received: from barracuda.ebox.ca (HELO barracuda.ebox.ca) (96.127.255.19) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 18 Nov 2017 21:46:12 +0000 X-ASG-Debug-ID: 1511041570-0c856e65d53bf3e90001-fS2M51 Received: from smtp.electronicbox.net (smtp.electronicbox.net [96.127.255.82]) by barracuda.ebox.ca with ESMTP id T0rIngNjchlK3DPY (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 18 Nov 2017 16:46:10 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.lan (192-222-251-162.qc.cable.ebox.net [192.222.251.162]) by smtp.electronicbox.net (Postfix) with ESMTP id 5CE87441D83; Sat, 18 Nov 2017 16:46:10 -0500 (EST) From: Simon Marchi X-Barracuda-Effective-Source-IP: 192-222-251-162.qc.cable.ebox.net[192.222.251.162] X-Barracuda-Apparent-Source-IP: 192.222.251.162 X-Barracuda-RBL-IP: 192.222.251.162 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 3/4] Replace VEC (varobj_update_result) with std::vector Date: Sat, 18 Nov 2017 21:46:00 -0000 X-ASG-Orig-Subj: [PATCH 3/4] Replace VEC (varobj_update_result) with std::vector Message-Id: <20171118214606.24468-4-simon.marchi@polymtl.ca> In-Reply-To: <20171118214606.24468-1-simon.marchi@polymtl.ca> References: <20171118214606.24468-1-simon.marchi@polymtl.ca> X-Barracuda-Connect: smtp.electronicbox.net[96.127.255.82] X-Barracuda-Start-Time: 1511041570 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-Scan-Msg-Size: 15871 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.44999 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-IsSubscribed: yes X-SW-Source: 2017-11/txt/msg00380.txt.bz2 This patch replaces makes varobj_update return an std::vector, and updates the fallouts. To make that easier, the varobj_update_result is c++ified a bit. I added a constructor and initialized its fields in-class. The newobj vector is also made an std::vector, so that it's automatically freed when varobj_update_result is destroyed and handled correctly by the default move constructor. I disabled copy constructor and assignment for that structure, because normally it never needs to be copied, only moved. As a result, the newobj parameter of update_dynamic_varobj_children must be changed to an std::vector. The patch converts the other vector parameters of update_dynamic_varobj_children to std::vector. It's not strictly necessary to do it in the same patch, but I think it makes sense to do it. gdb/ChangeLog: * varobj.h (struct varobj_update_result): Add constructor, add move constructor, disable copy and assign, initialize fields. : Change type to std::vector. (varobj_update): Return std::vector. * varobj.c (install_dynamic_child): Change VEC parameters to std::vector and adjust. (update_dynamic_varobj_children): Likewise. (varobj_update): Return std::vector and adjust. * mi/mi-cmd-var.c (varobj_update_one): Adjust to vector changes. --- gdb/mi/mi-cmd-var.c | 49 +++++++----------- gdb/varobj.c | 146 ++++++++++++++++++++-------------------------------- gdb/varobj.h | 29 +++++++---- 3 files changed, 95 insertions(+), 129 deletions(-) diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c index 084cc38d28..d051874ab2 100644 --- a/gdb/mi/mi-cmd-var.c +++ b/gdb/mi/mi-cmd-var.c @@ -685,27 +685,24 @@ varobj_update_one (struct varobj *var, enum print_values print_values, int is_explicit) { struct ui_out *uiout = current_uiout; - VEC (varobj_update_result) *changes; - varobj_update_result *r; - int i; - - changes = varobj_update (&var, is_explicit); + + std::vector changes = varobj_update (&var, is_explicit); - for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i) + for (const varobj_update_result &r : changes) { int from, to; gdb::optional tuple_emitter; if (mi_version (uiout) > 1) tuple_emitter.emplace (uiout, nullptr); - uiout->field_string ("name", varobj_get_objname (r->varobj)); + uiout->field_string ("name", varobj_get_objname (r.varobj)); - switch (r->status) + switch (r.status) { case VAROBJ_IN_SCOPE: - if (mi_print_value_p (r->varobj, print_values)) + if (mi_print_value_p (r.varobj, print_values)) { - std::string val = varobj_get_value (r->varobj); + std::string val = varobj_get_value (r.varobj); uiout->field_string ("value", val.c_str ()); } @@ -719,53 +716,47 @@ varobj_update_one (struct varobj *var, enum print_values print_values, break; } - if (r->status != VAROBJ_INVALID) + if (r.status != VAROBJ_INVALID) { - if (r->type_changed) + if (r.type_changed) uiout->field_string ("type_changed", "true"); else uiout->field_string ("type_changed", "false"); } - if (r->type_changed) + if (r.type_changed) { - std::string type_name = varobj_get_type (r->varobj); + std::string type_name = varobj_get_type (r.varobj); uiout->field_string ("new_type", type_name.c_str ()); } - if (r->type_changed || r->children_changed) + if (r.type_changed || r.children_changed) uiout->field_int ("new_num_children", - varobj_get_num_children (r->varobj)); + varobj_get_num_children (r.varobj)); gdb::unique_xmalloc_ptr display_hint - = varobj_get_display_hint (r->varobj); + = varobj_get_display_hint (r.varobj); if (display_hint) uiout->field_string ("displayhint", display_hint.get ()); - if (varobj_is_dynamic_p (r->varobj)) + if (varobj_is_dynamic_p (r.varobj)) uiout->field_int ("dynamic", 1); - varobj_get_child_range (r->varobj, &from, &to); - uiout->field_int ("has_more", varobj_has_more (r->varobj, to)); + varobj_get_child_range (r.varobj, &from, &to); + uiout->field_int ("has_more", varobj_has_more (r.varobj, to)); - if (r->newobj) + if (!r.newobj.empty ()) { - int j; - varobj_p child; - ui_out_emit_list list_emitter (uiout, "new_children"); - for (j = 0; VEC_iterate (varobj_p, r->newobj, j, child); ++j) + + for (varobj *child : r.newobj) { ui_out_emit_tuple tuple_emitter (uiout, NULL); print_varobj (child, print_values, 1 /* print_expression */); } - - VEC_free (varobj_p, r->newobj); - r->newobj = NULL; /* Paranoia. */ } } - VEC_free (varobj_update_result, changes); } void diff --git a/gdb/varobj.c b/gdb/varobj.c index 363ebec570..29c338dd77 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -629,10 +629,10 @@ varobj_restrict_range (const std::vector &children, static void install_dynamic_child (struct varobj *var, - VEC (varobj_p) **changed, - VEC (varobj_p) **type_changed, - VEC (varobj_p) **newobj, - VEC (varobj_p) **unchanged, + std::vector *changed, + std::vector *type_changed, + std::vector *newobj, + std::vector *unchanged, int *cchanged, int index, struct varobj_item *item) @@ -642,9 +642,9 @@ install_dynamic_child (struct varobj *var, /* There's no child yet. */ struct varobj *child = varobj_add_child (var, item); - if (newobj) + if (newobj != NULL) { - VEC_safe_push (varobj_p, *newobj, child); + newobj->push_back (child); *cchanged = 1; } } @@ -655,16 +655,16 @@ install_dynamic_child (struct varobj *var, if (type_updated) { - if (type_changed) - VEC_safe_push (varobj_p, *type_changed, existing); + if (type_changed != NULL) + type_changed->push_back (existing); } if (install_new_value (existing, item->value, 0)) { - if (!type_updated && changed) - VEC_safe_push (varobj_p, *changed, existing); + if (!type_updated && changed != NULL) + changed->push_back (existing); } - else if (!type_updated && unchanged) - VEC_safe_push (varobj_p, *unchanged, existing); + else if (!type_updated && unchanged != NULL) + unchanged->push_back (existing); } } @@ -713,10 +713,10 @@ varobj_clear_saved_item (struct varobj_dynamic *var) static int update_dynamic_varobj_children (struct varobj *var, - VEC (varobj_p) **changed, - VEC (varobj_p) **type_changed, - VEC (varobj_p) **newobj, - VEC (varobj_p) **unchanged, + std::vector *changed, + std::vector *type_changed, + std::vector *newobj, + std::vector *unchanged, int *cchanged, int update_children, int from, @@ -1525,14 +1525,13 @@ varobj_value_has_mutated (const struct varobj *var, struct value *new_value, returns TYPE_CHANGED, then it has done this and VARP will be modified to point to the new varobj. */ -VEC(varobj_update_result) * +std::vector varobj_update (struct varobj **varp, int is_explicit) { int type_changed = 0; - int i; struct value *newobj; - VEC (varobj_update_result) *stack = NULL; - VEC (varobj_update_result) *result = NULL; + std::vector stack; + std::vector result; /* Frozen means frozen -- we don't check for any change in this varobj, including its going out of scope, or @@ -1544,20 +1543,13 @@ varobj_update (struct varobj **varp, int is_explicit) if (!(*varp)->root->is_valid) { - varobj_update_result r = {0}; - - r.varobj = *varp; - r.status = VAROBJ_INVALID; - VEC_safe_push (varobj_update_result, result, &r); + result.emplace_back (*varp, VAROBJ_INVALID); return result; } if ((*varp)->root->rootvar == *varp) { - varobj_update_result r = {0}; - - r.varobj = *varp; - r.status = VAROBJ_IN_SCOPE; + 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 @@ -1579,28 +1571,23 @@ varobj_update (struct varobj **varp, int is_explicit) if (r.status == VAROBJ_NOT_IN_SCOPE) { if (r.type_changed || r.changed) - VEC_safe_push (varobj_update_result, result, &r); + result.push_back (std::move (r)); + return result; } - - VEC_safe_push (varobj_update_result, stack, &r); - } - else - { - varobj_update_result r = {0}; - r.varobj = *varp; - VEC_safe_push (varobj_update_result, stack, &r); + stack.push_back (std::move (r)); } + else + stack.emplace_back (*varp); /* Walk through the children, reconstructing them all. */ - while (!VEC_empty (varobj_update_result, stack)) + while (!stack.empty ()) { - varobj_update_result r = *(VEC_last (varobj_update_result, stack)); + varobj_update_result r = std::move (stack.back ()); + stack.pop_back (); struct varobj *v = r.varobj; - VEC_pop (varobj_update_result, stack); - /* Update this variable, unless it's a root, which is already updated. */ if (!r.value_installed) @@ -1638,9 +1625,8 @@ varobj_update (struct varobj **varp, int is_explicit) for which -var-list-children was never invoked. */ if (varobj_is_dynamic_p (v)) { - VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0; - VEC (varobj_p) *newobj = 0; - int i, children_changed = 0; + std::vector changed, type_changed, unchanged, newobj; + int children_changed = 0; if (v->frozen) continue; @@ -1664,7 +1650,7 @@ varobj_update (struct varobj **varp, int is_explicit) } if (r.changed) - VEC_safe_push (varobj_update_result, result, &r); + result.push_back (std::move (r)); continue; } @@ -1675,58 +1661,48 @@ varobj_update (struct varobj **varp, int is_explicit) &unchanged, &children_changed, 1, v->from, v->to)) { - if (children_changed || newobj) + if (children_changed || !newobj.empty ()) { r.children_changed = 1; - r.newobj = newobj; + r.newobj = std::move (newobj); } /* 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 (i = VEC_length (varobj_p, type_changed) - 1; i >= 0; --i) + for (int i = type_changed.size () - 1; i >= 0; --i) { - varobj_p tmp = VEC_index (varobj_p, type_changed, i); - varobj_update_result r = {0}; + varobj_update_result r (type_changed[i]); /* Type may change only if value was changed. */ - r.varobj = tmp; r.changed = 1; r.type_changed = 1; r.value_installed = 1; - VEC_safe_push (varobj_update_result, stack, &r); + + stack.push_back (std::move (r)); } - for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i) + for (int i = changed.size () - 1; i >= 0; --i) { - varobj_p tmp = VEC_index (varobj_p, changed, i); - varobj_update_result r = {0}; + varobj_update_result r (changed[i]); - r.varobj = tmp; r.changed = 1; r.value_installed = 1; - VEC_safe_push (varobj_update_result, stack, &r); + + stack.push_back (std::move (r)); } - for (i = VEC_length (varobj_p, unchanged) - 1; i >= 0; --i) - { - varobj_p tmp = VEC_index (varobj_p, unchanged, i); - - if (!tmp->frozen) - { - varobj_update_result r = {0}; - - r.varobj = tmp; - r.value_installed = 1; - VEC_safe_push (varobj_update_result, stack, &r); - } - } - if (r.changed || r.children_changed) - VEC_safe_push (varobj_update_result, result, &r); + for (int i = unchanged.size () - 1; i >= 0; --i) + { + if (!unchanged[i]->frozen) + { + varobj_update_result r (unchanged[i]); - /* Free CHANGED, TYPE_CHANGED and UNCHANGED, but not NEW, - because NEW has been put into the result vector. */ - VEC_free (varobj_p, changed); - VEC_free (varobj_p, type_changed); - VEC_free (varobj_p, unchanged); + r.value_installed = 1; + + stack.push_back (std::move (r)); + } + } + if (r.changed || r.children_changed) + result.push_back (std::move (r)); continue; } @@ -1736,29 +1712,21 @@ varobj_update (struct varobj **varp, int is_explicit) child is popped from the work stack first, and so will be added to result first. This does not affect correctness, just "nicer". */ - for (i = v->children.size () - 1; i >= 0; --i) + 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) - { - varobj_update_result r = {0}; - - r.varobj = c; - VEC_safe_push (varobj_update_result, stack, &r); - } + stack.emplace_back (c); } if (r.changed || r.type_changed) - VEC_safe_push (varobj_update_result, result, &r); + result.push_back (std::move (r)); } - VEC_free (varobj_update_result, stack); - return result; } - /* Helper functions */ diff --git a/gdb/varobj.h b/gdb/varobj.h index 8384eb53e5..201fac21ab 100644 --- a/gdb/varobj.h +++ b/gdb/varobj.h @@ -60,26 +60,33 @@ struct varobj; typedef struct varobj *varobj_p; DEF_VEC_P (varobj_p); -typedef struct varobj_update_result_t +struct varobj_update_result { + varobj_update_result (struct varobj *varobj_, + varobj_scope_status status_ = VAROBJ_IN_SCOPE) + : varobj (varobj_), status (status_) + {} + + varobj_update_result (varobj_update_result &&other) = default; + + DISABLE_COPY_AND_ASSIGN (varobj_update_result); + struct varobj *varobj; - int type_changed; - int children_changed; - int changed; + int type_changed = 0; + int children_changed = 0; + int changed = 0; enum varobj_scope_status status; /* This variable is used internally by varobj_update to indicate if the new value of varobj is already computed and installed, or has to be yet installed. Don't use this outside varobj.c. */ - int value_installed; + int value_installed = 0; /* This will be non-NULL when new children were added to the varobj. It lists the new children (which must necessarily come at the end of the child list) added during an update. The caller is responsible for freeing this vector. */ - VEC (varobj_p) *newobj; -} varobj_update_result; - -DEF_VEC_O (varobj_update_result); + std::vector newobj; +}; struct varobj_root; struct varobj_dynamic; @@ -305,8 +312,8 @@ extern int varobj_set_value (struct varobj *var, const char *expression); extern void all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data); -extern VEC(varobj_update_result) *varobj_update (struct varobj **varp, - int is_explicit); +extern std::vector + varobj_update (struct varobj **varp, int is_explicit); extern void varobj_invalidate (void); -- 2.15.0