From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 03/47] Move struct value to value.h
Date: Thu, 09 Feb 2023 14:38:24 -0700 [thread overview]
Message-ID: <20230209-submit-value-fixups-2023-v1-3-55dc2794dbb9@tromey.com> (raw)
In-Reply-To: <20230209-submit-value-fixups-2023-v1-0-55dc2794dbb9@tromey.com>
This moves struct value to value.h. For now, all members remain
public, but this is a temporary state -- by the end of the series
we'll add 'private'.
---
gdb/value.c | 213 -----------------------------------------------------------
gdb/value.h | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 211 insertions(+), 218 deletions(-)
diff --git a/gdb/value.c b/gdb/value.c
index b5e5a46573d..7ba46e20e7b 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -66,33 +66,6 @@ struct internal_function
void *cookie;
};
-/* Defines an [OFFSET, OFFSET + LENGTH) range. */
-
-struct range
-{
- /* Lowest offset in the range. */
- LONGEST offset;
-
- /* Length of the range. */
- LONGEST length;
-
- /* Returns true if THIS is strictly less than OTHER, useful for
- searching. We keep ranges sorted by offset and coalesce
- overlapping and contiguous ranges, so this just compares the
- starting offset. */
-
- bool operator< (const range &other) const
- {
- return offset < other.offset;
- }
-
- /* Returns true if THIS is equal to OTHER. */
- bool operator== (const range &other) const
- {
- return offset == other.offset && length == other.length;
- }
-};
-
/* Returns true if the ranges defined by [offset1, offset1+len1) and
[offset2, offset2+len2) overlap. */
@@ -174,192 +147,6 @@ ranges_contain (const std::vector<range> &ranges, LONGEST offset,
static struct cmd_list_element *functionlist;
-/* Note that the fields in this structure are arranged to save a bit
- of memory. */
-
-struct value
-{
- explicit value (struct type *type_)
- : m_modifiable (1),
- m_lazy (1),
- m_initialized (1),
- m_stack (0),
- m_is_zero (false),
- m_type (type_),
- m_enclosing_type (type_)
- {
- }
-
- ~value ();
-
- DISABLE_COPY_AND_ASSIGN (value);
-
- /* Type of value; either not an lval, or one of the various
- different possible kinds of lval. */
- enum lval_type m_lval = not_lval;
-
- /* Is it modifiable? Only relevant if lval != not_lval. */
- unsigned int m_modifiable : 1;
-
- /* If zero, contents of this value are in the contents field. If
- nonzero, contents are in inferior. If the lval field is lval_memory,
- the contents are in inferior memory at location.address plus offset.
- The lval field may also be lval_register.
-
- WARNING: This field is used by the code which handles watchpoints
- (see breakpoint.c) to decide whether a particular value can be
- watched by hardware watchpoints. If the lazy flag is set for
- some member of a value chain, it is assumed that this member of
- the chain doesn't need to be watched as part of watching the
- value itself. This is how GDB avoids watching the entire struct
- or array when the user wants to watch a single struct member or
- array element. If you ever change the way lazy flag is set and
- reset, be sure to consider this use as well! */
- unsigned int m_lazy : 1;
-
- /* If value is a variable, is it initialized or not. */
- unsigned int m_initialized : 1;
-
- /* If value is from the stack. If this is set, read_stack will be
- used instead of read_memory to enable extra caching. */
- unsigned int m_stack : 1;
-
- /* True if this is a zero value, created by 'value_zero'; false
- otherwise. */
- bool m_is_zero : 1;
-
- /* Location of value (if lval). */
- union
- {
- /* If lval == lval_memory, this is the address in the inferior */
- CORE_ADDR address;
-
- /*If lval == lval_register, the value is from a register. */
- struct
- {
- /* Register number. */
- int regnum;
- /* Frame ID of "next" frame to which a register value is relative.
- If the register value is found relative to frame F, then the
- frame id of F->next will be stored in next_frame_id. */
- struct frame_id next_frame_id;
- } reg;
-
- /* Pointer to internal variable. */
- struct internalvar *internalvar;
-
- /* Pointer to xmethod worker. */
- struct xmethod_worker *xm_worker;
-
- /* If lval == lval_computed, this is a set of function pointers
- to use to access and describe the value, and a closure pointer
- for them to use. */
- struct
- {
- /* Functions to call. */
- const struct lval_funcs *funcs;
-
- /* Closure for those functions to use. */
- void *closure;
- } computed;
- } m_location {};
-
- /* Describes offset of a value within lval of a structure in target
- addressable memory units. Note also the member embedded_offset
- below. */
- LONGEST m_offset = 0;
-
- /* Only used for bitfields; number of bits contained in them. */
- LONGEST m_bitsize = 0;
-
- /* Only used for bitfields; position of start of field. For
- little-endian targets, it is the position of the LSB. For
- big-endian targets, it is the position of the MSB. */
- LONGEST m_bitpos = 0;
-
- /* The number of references to this value. When a value is created,
- the value chain holds a reference, so REFERENCE_COUNT is 1. If
- release_value is called, this value is removed from the chain but
- the caller of release_value now has a reference to this value.
- The caller must arrange for a call to value_free later. */
- int m_reference_count = 1;
-
- /* Only used for bitfields; the containing value. This allows a
- single read from the target when displaying multiple
- bitfields. */
- value_ref_ptr m_parent;
-
- /* Type of the value. */
- struct type *m_type;
-
- /* If a value represents a C++ object, then the `type' field gives
- the object's compile-time type. If the object actually belongs
- to some class derived from `type', perhaps with other base
- classes and additional members, then `type' is just a subobject
- of the real thing, and the full object is probably larger than
- `type' would suggest.
-
- If `type' is a dynamic class (i.e. one with a vtable), then GDB
- can actually determine the object's run-time type by looking at
- the run-time type information in the vtable. When this
- information is available, we may elect to read in the entire
- object, for several reasons:
-
- - When printing the value, the user would probably rather see the
- full object, not just the limited portion apparent from the
- compile-time type.
-
- - If `type' has virtual base classes, then even printing `type'
- alone may require reaching outside the `type' portion of the
- object to wherever the virtual base class has been stored.
-
- When we store the entire object, `enclosing_type' is the run-time
- type -- the complete object -- and `embedded_offset' is the
- offset of `type' within that larger type, in target addressable memory
- units. The value_contents() macro takes `embedded_offset' into account,
- so most GDB code continues to see the `type' portion of the value, just
- as the inferior would.
-
- If `type' is a pointer to an object, then `enclosing_type' is a
- pointer to the object's run-time type, and `pointed_to_offset' is
- the offset in target addressable memory units from the full object
- to the pointed-to object -- that is, the value `embedded_offset' would
- have if we followed the pointer and fetched the complete object.
- (I don't really see the point. Why not just determine the
- run-time type when you indirect, and avoid the special case? The
- contents don't matter until you indirect anyway.)
-
- If we're not doing anything fancy, `enclosing_type' is equal to
- `type', and `embedded_offset' is zero, so everything works
- normally. */
- struct type *m_enclosing_type;
- LONGEST m_embedded_offset = 0;
- LONGEST m_pointed_to_offset = 0;
-
- /* Actual contents of the value. Target byte-order.
-
- May be nullptr if the value is lazy or is entirely optimized out.
- Guaranteed to be non-nullptr otherwise. */
- gdb::unique_xmalloc_ptr<gdb_byte> m_contents;
-
- /* Unavailable ranges in CONTENTS. We mark unavailable ranges,
- rather than available, since the common and default case is for a
- value to be available. This is filled in at value read time.
- The unavailable ranges are tracked in bits. Note that a contents
- bit that has been optimized out doesn't really exist in the
- program, so it can't be marked unavailable either. */
- std::vector<range> m_unavailable;
-
- /* Likewise, but for optimized out contents (a chunk of the value of
- a variable that does not actually exist in the program). If LVAL
- is lval_register, this is a register ($pc, $sp, etc., never a
- program variable) that has not been saved in the frame. Not
- saved registers and optimized-out program variables values are
- treated pretty much the same, except not-saved registers have a
- different string representation and related error strings. */
- std::vector<range> m_optimized_out;
-};
-
value::~value ()
{
if (VALUE_LVAL (this) == lval_computed)
diff --git a/gdb/value.h b/gdb/value.h
index f022510ded1..ea549a8cb81 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -84,12 +84,32 @@ struct value_print_options;
extern bool overload_resolution;
-/* The structure which defines the type of a value. It should never
- be possible for a program lval value to survive over a call to the
- inferior (i.e. to be put into the history list or an internal
- variable). */
+/* Defines an [OFFSET, OFFSET + LENGTH) range. */
-struct value;
+struct range
+{
+ /* Lowest offset in the range. */
+ LONGEST offset;
+
+ /* Length of the range. */
+ LONGEST length;
+
+ /* Returns true if THIS is strictly less than OTHER, useful for
+ searching. We keep ranges sorted by offset and coalesce
+ overlapping and contiguous ranges, so this just compares the
+ starting offset. */
+
+ bool operator< (const range &other) const
+ {
+ return offset < other.offset;
+ }
+
+ /* Returns true if THIS is equal to OTHER. */
+ bool operator== (const range &other) const
+ {
+ return offset == other.offset && length == other.length;
+ }
+};
/* Increase VAL's reference count. */
@@ -119,6 +139,192 @@ struct value_ref_policy
typedef gdb::ref_ptr<struct value, value_ref_policy> value_ref_ptr;
+/* Note that the fields in this structure are arranged to save a bit
+ of memory. */
+
+struct value
+{
+ explicit value (struct type *type_)
+ : m_modifiable (1),
+ m_lazy (1),
+ m_initialized (1),
+ m_stack (0),
+ m_is_zero (false),
+ m_type (type_),
+ m_enclosing_type (type_)
+ {
+ }
+
+ ~value ();
+
+ DISABLE_COPY_AND_ASSIGN (value);
+
+ /* Type of value; either not an lval, or one of the various
+ different possible kinds of lval. */
+ enum lval_type m_lval = not_lval;
+
+ /* Is it modifiable? Only relevant if lval != not_lval. */
+ unsigned int m_modifiable : 1;
+
+ /* If zero, contents of this value are in the contents field. If
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
+
+ WARNING: This field is used by the code which handles watchpoints
+ (see breakpoint.c) to decide whether a particular value can be
+ watched by hardware watchpoints. If the lazy flag is set for
+ some member of a value chain, it is assumed that this member of
+ the chain doesn't need to be watched as part of watching the
+ value itself. This is how GDB avoids watching the entire struct
+ or array when the user wants to watch a single struct member or
+ array element. If you ever change the way lazy flag is set and
+ reset, be sure to consider this use as well! */
+ unsigned int m_lazy : 1;
+
+ /* If value is a variable, is it initialized or not. */
+ unsigned int m_initialized : 1;
+
+ /* If value is from the stack. If this is set, read_stack will be
+ used instead of read_memory to enable extra caching. */
+ unsigned int m_stack : 1;
+
+ /* True if this is a zero value, created by 'value_zero'; false
+ otherwise. */
+ bool m_is_zero : 1;
+
+ /* Location of value (if lval). */
+ union
+ {
+ /* If lval == lval_memory, this is the address in the inferior */
+ CORE_ADDR address;
+
+ /*If lval == lval_register, the value is from a register. */
+ struct
+ {
+ /* Register number. */
+ int regnum;
+ /* Frame ID of "next" frame to which a register value is relative.
+ If the register value is found relative to frame F, then the
+ frame id of F->next will be stored in next_frame_id. */
+ struct frame_id next_frame_id;
+ } reg;
+
+ /* Pointer to internal variable. */
+ struct internalvar *internalvar;
+
+ /* Pointer to xmethod worker. */
+ struct xmethod_worker *xm_worker;
+
+ /* If lval == lval_computed, this is a set of function pointers
+ to use to access and describe the value, and a closure pointer
+ for them to use. */
+ struct
+ {
+ /* Functions to call. */
+ const struct lval_funcs *funcs;
+
+ /* Closure for those functions to use. */
+ void *closure;
+ } computed;
+ } m_location {};
+
+ /* Describes offset of a value within lval of a structure in target
+ addressable memory units. Note also the member embedded_offset
+ below. */
+ LONGEST m_offset = 0;
+
+ /* Only used for bitfields; number of bits contained in them. */
+ LONGEST m_bitsize = 0;
+
+ /* Only used for bitfields; position of start of field. For
+ little-endian targets, it is the position of the LSB. For
+ big-endian targets, it is the position of the MSB. */
+ LONGEST m_bitpos = 0;
+
+ /* The number of references to this value. When a value is created,
+ the value chain holds a reference, so REFERENCE_COUNT is 1. If
+ release_value is called, this value is removed from the chain but
+ the caller of release_value now has a reference to this value.
+ The caller must arrange for a call to value_free later. */
+ int m_reference_count = 1;
+
+ /* Only used for bitfields; the containing value. This allows a
+ single read from the target when displaying multiple
+ bitfields. */
+ value_ref_ptr m_parent;
+
+ /* Type of the value. */
+ struct type *m_type;
+
+ /* If a value represents a C++ object, then the `type' field gives
+ the object's compile-time type. If the object actually belongs
+ to some class derived from `type', perhaps with other base
+ classes and additional members, then `type' is just a subobject
+ of the real thing, and the full object is probably larger than
+ `type' would suggest.
+
+ If `type' is a dynamic class (i.e. one with a vtable), then GDB
+ can actually determine the object's run-time type by looking at
+ the run-time type information in the vtable. When this
+ information is available, we may elect to read in the entire
+ object, for several reasons:
+
+ - When printing the value, the user would probably rather see the
+ full object, not just the limited portion apparent from the
+ compile-time type.
+
+ - If `type' has virtual base classes, then even printing `type'
+ alone may require reaching outside the `type' portion of the
+ object to wherever the virtual base class has been stored.
+
+ When we store the entire object, `enclosing_type' is the run-time
+ type -- the complete object -- and `embedded_offset' is the
+ offset of `type' within that larger type, in target addressable memory
+ units. The value_contents() macro takes `embedded_offset' into account,
+ so most GDB code continues to see the `type' portion of the value, just
+ as the inferior would.
+
+ If `type' is a pointer to an object, then `enclosing_type' is a
+ pointer to the object's run-time type, and `pointed_to_offset' is
+ the offset in target addressable memory units from the full object
+ to the pointed-to object -- that is, the value `embedded_offset' would
+ have if we followed the pointer and fetched the complete object.
+ (I don't really see the point. Why not just determine the
+ run-time type when you indirect, and avoid the special case? The
+ contents don't matter until you indirect anyway.)
+
+ If we're not doing anything fancy, `enclosing_type' is equal to
+ `type', and `embedded_offset' is zero, so everything works
+ normally. */
+ struct type *m_enclosing_type;
+ LONGEST m_embedded_offset = 0;
+ LONGEST m_pointed_to_offset = 0;
+
+ /* Actual contents of the value. Target byte-order.
+
+ May be nullptr if the value is lazy or is entirely optimized out.
+ Guaranteed to be non-nullptr otherwise. */
+ gdb::unique_xmalloc_ptr<gdb_byte> m_contents;
+
+ /* Unavailable ranges in CONTENTS. We mark unavailable ranges,
+ rather than available, since the common and default case is for a
+ value to be available. This is filled in at value read time.
+ The unavailable ranges are tracked in bits. Note that a contents
+ bit that has been optimized out doesn't really exist in the
+ program, so it can't be marked unavailable either. */
+ std::vector<range> m_unavailable;
+
+ /* Likewise, but for optimized out contents (a chunk of the value of
+ a variable that does not actually exist in the program). If LVAL
+ is lval_register, this is a register ($pc, $sp, etc., never a
+ program variable) that has not been saved in the frame. Not
+ saved registers and optimized-out program variables values are
+ treated pretty much the same, except not-saved registers have a
+ different string representation and related error strings. */
+ std::vector<range> m_optimized_out;
+};
+
/* Type of the value. */
extern struct type *value_type (const struct value *);
--
2.39.1
next prev parent reply other threads:[~2023-02-09 21:39 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-09 21:38 [PATCH 00/47] Use methods for struct value Tom Tromey
2023-02-09 21:38 ` [PATCH 01/47] Rename all fields of " Tom Tromey
2023-02-10 21:05 ` Tom Tromey
2023-02-09 21:38 ` [PATCH 02/47] Move ~value body out-of-line Tom Tromey
2023-02-09 21:38 ` Tom Tromey [this message]
2023-02-09 21:38 ` [PATCH 04/47] Turn value_type into method Tom Tromey
2023-02-09 21:38 ` [PATCH 05/47] Turn deprecated_set_value_type into a method Tom Tromey
2023-02-09 21:38 ` [PATCH 06/47] Turn value_arch into method Tom Tromey
2023-02-10 2:08 ` Simon Marchi
2023-02-10 16:36 ` Tom Tromey
2023-02-09 21:38 ` [PATCH 07/47] Turn value_bitsize " Tom Tromey
2023-02-09 21:38 ` [PATCH 08/47] Turn value_bitpos " Tom Tromey
2023-02-09 21:38 ` [PATCH 09/47] Turn value_parent " Tom Tromey
2023-02-09 21:38 ` [PATCH 10/47] Turn value_offset " Tom Tromey
2023-02-09 21:38 ` [PATCH 11/47] Turn deprecated_value_modifiable " Tom Tromey
2023-02-09 21:38 ` [PATCH 12/47] Turn value_enclosing_type " Tom Tromey
2023-02-09 21:38 ` [PATCH 13/47] Turn some value offset functions " Tom Tromey
2023-02-09 21:38 ` [PATCH 14/47] Turn value_lazy and set_value_lazy functions into methods Tom Tromey
2023-02-09 21:38 ` [PATCH 15/47] Turn value_stack and set_value_stack " Tom Tromey
2023-02-09 21:38 ` [PATCH 16/47] Turn value_computed_closure and value_computed_funcs " Tom Tromey
2023-02-09 21:38 ` [PATCH 17/47] Convert value_lval_const and deprecated_lval_hack to methods Tom Tromey
2023-02-09 21:38 ` [PATCH 18/47] Turn value_initialized and set_value_initialized functions into methods Tom Tromey
2023-02-09 21:38 ` [PATCH 19/47] Turn value_address and set_value_address " Tom Tromey
2023-02-09 21:38 ` [PATCH 20/47] Turn more deprecated_* " Tom Tromey
2023-02-09 21:38 ` [PATCH 21/47] Turn allocate_value_lazy into a static "constructor" Tom Tromey
2023-02-09 21:38 ` [PATCH 22/47] Turn allocate_value " Tom Tromey
2023-02-09 21:38 ` [PATCH 23/47] Turn allocate_computed_value into " Tom Tromey
2023-02-09 21:38 ` [PATCH 24/47] Turn allocate_optimized_out_value " Tom Tromey
2023-02-09 21:38 ` [PATCH 25/47] Turn value_zero " Tom Tromey
2023-02-09 21:38 ` [PATCH 26/47] Turn some value_contents functions into methods Tom Tromey
2023-02-09 21:38 ` [PATCH 27/47] Turn value_fetch_lazy into a method Tom Tromey
2023-02-09 21:38 ` [PATCH 28/47] Turn allocate_value_contents " Tom Tromey
2023-02-09 21:38 ` [PATCH 29/47] Turn value_contents_eq " Tom Tromey
2023-02-10 2:18 ` Simon Marchi
2023-02-10 17:46 ` Tom Tromey
2023-02-09 21:38 ` [PATCH 30/47] Turn value_bits_synthetic_pointer " Tom Tromey
2023-02-09 21:38 ` [PATCH 31/47] Move value_ref_policy methods out-of-line Tom Tromey
2023-02-09 21:38 ` [PATCH 32/47] Turn value_incref and value_decref into methods Tom Tromey
2023-02-09 21:38 ` [PATCH 33/47] Turn remaining value_contents functions " Tom Tromey
2023-02-10 2:24 ` Simon Marchi
2023-02-10 17:46 ` Tom Tromey
2023-02-09 21:38 ` [PATCH 34/47] Fully qualify calls to copy in value.c Tom Tromey
2023-02-09 21:38 ` [PATCH 35/47] Turn value_copy into a method Tom Tromey
2023-02-10 2:42 ` Simon Marchi
2023-02-10 18:03 ` Tom Tromey
2023-02-09 21:38 ` [PATCH 36/47] Turn many optimized-out value functions into methods Tom Tromey
2023-02-09 21:38 ` [PATCH 37/47] Turn value_non_lval and value_force_lval " Tom Tromey
2023-02-09 21:38 ` [PATCH 38/47] Turn set_value_component_location into method Tom Tromey
2023-02-09 21:39 ` [PATCH 39/47] Change some code to use value methods Tom Tromey
2023-02-09 21:39 ` [PATCH 40/47] Turn some xmethod functions into methods Tom Tromey
2023-02-09 21:39 ` [PATCH 41/47] Turn preserve_one_value into method Tom Tromey
2023-02-09 21:39 ` [PATCH 42/47] Turn various value copying-related functions into methods Tom Tromey
2023-02-10 20:20 ` Tom Tromey
2023-02-09 21:39 ` [PATCH 43/47] Add value::set_modifiable Tom Tromey
2023-02-09 21:39 ` [PATCH 44/47] Make struct value data members private Tom Tromey
2023-02-09 21:39 ` [PATCH 45/47] Make ~value private Tom Tromey
2023-02-09 21:39 ` [PATCH 46/47] Introduce set_lval method on value Tom Tromey
2023-02-09 21:39 ` [PATCH 47/47] Remove deprecated_lval_hack Tom Tromey
2023-02-10 2:54 ` [PATCH 00/47] Use methods for struct value Simon Marchi
2023-02-10 18:08 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230209-submit-value-fixups-2023-v1-3-55dc2794dbb9@tromey.com \
--to=tom@tromey.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).