X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=97a099ddbd3eccb06bbf42b7d7fec1f3e5a6d2c8;hb=a350efd4fb368a35ada608f6bc26ccd3bed0ae6b;hp=d1e2623458aacc651f2085cc06e8bdae72980a65;hpb=42a4f53d2bf8938c2aeda9f52be7a20534b214a9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/value.c b/gdb/value.c index d1e2623458..97a099ddbd 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -1,6 +1,6 @@ /* Low level packing and unpacking of values for GDB, the GNU Debugger. - Copyright (C) 1986-2019 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -41,8 +41,9 @@ #include "user-regs.h" #include #include "completer.h" -#include "selftest.h" -#include "common/array-view.h" +#include "gdbsupport/selftest.h" +#include "gdbsupport/array-view.h" +#include "cli/cli-style.h" /* Definition of a user function. */ struct internal_function @@ -272,8 +273,8 @@ struct value LONGEST bitsize = 0; /* Only used for bitfields; position of start of field. For - gdbarch_bits_big_endian=0 targets, it is the position of the LSB. For - gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */ + little-endian targets, it is the position of the LSB. For + big-endian targets, it is the position of the MSB. */ LONGEST bitpos = 0; /* The number of references to this value. When a value is created, @@ -1000,9 +1001,9 @@ check_type_length_before_alloc (const struct type *type) if (max_value_size > -1 && length > max_value_size) { - if (TYPE_NAME (type) != NULL) + if (type->name () != NULL) error (_("value of type `%s' requires %u bytes, which is more " - "than max-value-size"), TYPE_NAME (type), length); + "than max-value-size"), type->name (), length); else error (_("value requires %u bytes, which is more than " "max-value-size"), length); @@ -1176,9 +1177,9 @@ value_actual_type (struct value *value, int resolve_simple_types, { /* If result's target type is TYPE_CODE_STRUCT, proceed to fetch its rtti type. */ - if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result)) - && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result))) - == TYPE_CODE_STRUCT + if ((result->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result)) + && (check_typedef (TYPE_TARGET_TYPE (result))->code () + == TYPE_CODE_STRUCT) && !value_optimized_out (value)) { struct type *real_type; @@ -1405,15 +1406,14 @@ value_optimized_out (struct value *value) fetch it. */ if (value->optimized_out.empty () && value->lazy) { - TRY + try { value_fetch_lazy (value); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { /* Fall back to checking value->optimized_out. */ } - END_CATCH } return !value->optimized_out.empty (); @@ -1978,7 +1978,7 @@ init_if_undefined_command (const char* args, int from_tty) intvar = expr->elts[2].internalvar; /* Only evaluate the expression if the lvalue is void. - This may still fail if the expresssion is invalid. */ + This may still fail if the expression is invalid. */ if (intvar->kind == INTERNALVAR_VOID) evaluate_expression (expr.get ()); } @@ -2015,11 +2015,7 @@ complete_internalvar (completion_tracker &tracker, const char *name) for (var = internalvars; var; var = var->next) if (strncmp (var->name, name, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (var->name)); - - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (var->name)); } /* Create an internal variable with name NAME and with a void value. @@ -2030,7 +2026,7 @@ create_internalvar (const char *name) { struct internalvar *var = XNEW (struct internalvar); - var->name = concat (name, (char *)NULL); + var->name = xstrdup (name); var->kind = INTERNALVAR_VOID; var->next = internalvars; internalvars = var; @@ -2157,7 +2153,7 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var) on this value go back to affect the original internal variable. Do not do this for INTERNALVAR_MAKE_VALUE variables, as those have - no underlying modifyable state in the internal variable. + no underlying modifiable state in the internal variable. Likewise, if the variable's value is a computed lvalue, we want references to it to produce another computed lvalue, where @@ -2193,7 +2189,7 @@ get_internalvar_integer (struct internalvar *var, LONGEST *result) { struct type *type = check_typedef (value_type (var->u.value)); - if (TYPE_CODE (type) == TYPE_CODE_INT) + if (type->code () == TYPE_CODE_INT) { *result = value_as_long (var->u.value); return 1; @@ -2258,7 +2254,7 @@ set_internalvar (struct internalvar *var, struct value *val) error (_("Cannot overwrite convenience function %s"), var->name); /* Prepare new contents. */ - switch (TYPE_CODE (check_typedef (value_type (val)))) + switch (check_typedef (value_type (val))->code ()) { case TYPE_CODE_VOID: new_kind = INTERNALVAR_VOID; @@ -2274,20 +2270,20 @@ set_internalvar (struct internalvar *var, struct value *val) default: new_kind = INTERNALVAR_VALUE; - new_data.value = value_copy (val); - new_data.value->modifiable = 1; + struct value *copy = value_copy (val); + copy->modifiable = 1; /* Force the value to be fetched from the target now, to avoid problems later when this internalvar is referenced and the target is gone or has changed. */ - if (value_lazy (new_data.value)) - value_fetch_lazy (new_data.value); + if (value_lazy (copy)) + value_fetch_lazy (copy); /* Release the value from the value chain to prevent it from being deleted by free_all_values. From here on this function should not call error () until new_data is installed into the var->u to avoid leaking memory. */ - release_value (new_data.value).release (); + new_data.value = release_value (copy).release (); /* Internal variables which are created from values with a dynamic location don't need the location property of the origin anymore. @@ -2295,7 +2291,7 @@ set_internalvar (struct internalvar *var, struct value *val) when accessing the value. If we keep it, we would still refer to the origin value. Remove the location property in case it exist. */ - remove_dyn_prop (DYN_PROP_DATA_LOCATION, value_type (new_data.value)); + value_type (new_data.value)->remove_dyn_prop (DYN_PROP_DATA_LOCATION); break; } @@ -2425,33 +2421,43 @@ function_command (const char *command, int from_tty) /* Do nothing. */ } -/* Clean up if an internal function's command is destroyed. */ -static void -function_destroyer (struct cmd_list_element *self, void *ignore) +/* Helper function that does the work for add_internal_function. */ + +static struct cmd_list_element * +do_add_internal_function (const char *name, const char *doc, + internal_function_fn handler, void *cookie) { - xfree ((char *) self->name); - xfree ((char *) self->doc); + struct internal_function *ifn; + struct internalvar *var = lookup_internalvar (name); + + ifn = create_internal_function (name, handler, cookie); + set_internalvar_function (var, ifn); + + return add_cmd (name, no_class, function_command, doc, &functionlist); } -/* Add a new internal function. NAME is the name of the function; DOC - is a documentation string describing the function. HANDLER is - called when the function is invoked. COOKIE is an arbitrary - pointer which is passed to HANDLER and is intended for "user - data". */ +/* See value.h. */ + void add_internal_function (const char *name, const char *doc, internal_function_fn handler, void *cookie) { - struct cmd_list_element *cmd; - struct internal_function *ifn; - struct internalvar *var = lookup_internalvar (name); + do_add_internal_function (name, doc, handler, cookie); +} - ifn = create_internal_function (name, handler, cookie); - set_internalvar_function (var, ifn); +/* See value.h. */ - cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc, - &functionlist); - cmd->destroyer = function_destroyer; +void +add_internal_function (gdb::unique_xmalloc_ptr &&name, + gdb::unique_xmalloc_ptr &&doc, + internal_function_fn handler, void *cookie) +{ + struct cmd_list_element *cmd + = do_add_internal_function (name.get (), doc.get (), handler, cookie); + doc.release (); + cmd->doc_allocated = 1; + name.release (); + cmd->name_allocated = 1; } /* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to @@ -2535,18 +2541,18 @@ show_convenience (const char *ignore, int from_tty) } printf_filtered (("$%s = "), var->name); - TRY + try { struct value *val; val = value_of_internalvar (gdbarch, var); value_print (val, gdb_stdout, &opts); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { - fprintf_filtered (gdb_stdout, _(""), ex.message); + fprintf_styled (gdb_stdout, metadata_style.style (), + _(""), ex.what ()); } - END_CATCH printf_filtered (("\n")); } @@ -2585,7 +2591,7 @@ value_from_xmethod (xmethod_worker_up &&worker) struct type * result_type_of_xmethod (struct value *method, gdb::array_view argv) { - gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD + gdb_assert (value_type (method)->code () == TYPE_CODE_XMETHOD && method->lval == lval_xcallable && !argv.empty ()); return method->location.xm_worker->get_result_type (argv[0], argv.slice (1)); @@ -2596,7 +2602,7 @@ result_type_of_xmethod (struct value *method, gdb::array_view argv) struct value * call_xmethod (struct value *method, gdb::array_view argv) { - gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD + gdb_assert (value_type (method)->code () == TYPE_CODE_XMETHOD && method->lval == lval_xcallable && !argv.empty ()); return method->location.xm_worker->invoke (argv[0], argv.slice (1)); @@ -2671,8 +2677,8 @@ value_as_address (struct value *val) The following shortcut avoids this whole mess. If VAL is a function, just return its address directly. */ - if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC - || TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD) + if (value_type (val)->code () == TYPE_CODE_FUNC + || value_type (val)->code () == TYPE_CODE_METHOD) return value_address (val); val = coerce_array (val); @@ -2714,7 +2720,7 @@ value_as_address (struct value *val) converted to pointers; usually, the ABI doesn't either, but ABI-specific code is a more reasonable place to handle it. */ - if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR + if (value_type (val)->code () != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (value_type (val)) && gdbarch_integer_to_address_p (gdbarch)) return gdbarch_integer_to_address (gdbarch, value_type (val), @@ -2741,8 +2747,8 @@ value_as_address (struct value *val) LONGEST unpack_long (struct type *type, const gdb_byte *valaddr) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - enum type_code code = TYPE_CODE (type); + enum bfd_endian byte_order = type_byte_order (type); + enum type_code code = type->code (); int len = TYPE_LENGTH (type); int nosign = TYPE_UNSIGNED (type); @@ -2757,10 +2763,16 @@ unpack_long (struct type *type, const gdb_byte *valaddr) case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_MEMBERPTR: - if (nosign) - return extract_unsigned_integer (valaddr, len, byte_order); - else - return extract_signed_integer (valaddr, len, byte_order); + { + LONGEST result; + if (nosign) + result = extract_unsigned_integer (valaddr, len, byte_order); + else + result = extract_signed_integer (valaddr, len, byte_order); + if (code == TYPE_CODE_RANGE) + result += TYPE_RANGE_DATA (type)->bias; + return result; + } case TYPE_CODE_FLT: case TYPE_CODE_DECFLOAT: @@ -2826,7 +2838,7 @@ value_static_field (struct type *type, int fieldno) switch (TYPE_FIELD_LOC_KIND (type, fieldno)) { case FIELD_LOC_KIND_PHYSADDR: - retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno), + retval = value_at_lazy (type->field (fieldno).type (), TYPE_FIELD_STATIC_PHYSADDR (type, fieldno)); break; case FIELD_LOC_KIND_PHYSNAME: @@ -2841,7 +2853,7 @@ value_static_field (struct type *type, int fieldno) reported as non-debuggable symbols. */ struct bound_minimal_symbol msym = lookup_minimal_symbol (phys_name, NULL, NULL); - struct type *field_type = TYPE_FIELD_TYPE (type, fieldno); + struct type *field_type = type->field (fieldno).type (); if (!msym.minsym) retval = allocate_optimized_out_value (field_type); @@ -2894,7 +2906,7 @@ value_primitive_field (struct value *arg1, LONGEST offset, int unit_size = gdbarch_addressable_memory_unit_size (arch); arg_type = check_typedef (arg_type); - type = TYPE_FIELD_TYPE (arg_type, fieldno); + type = arg_type->field (fieldno).type (); /* Call check_typedef on our type to make sure that, if TYPE is a TYPE_CODE_TYPEDEF, its length is set to the length @@ -3056,7 +3068,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, /* The minimal symbol might point to a function descriptor; resolve it to the actual code address instead. */ struct objfile *objfile = msym.objfile; - struct gdbarch *gdbarch = get_objfile_arch (objfile); + struct gdbarch *gdbarch = objfile->arch (); set_value_address (v, gdbarch_convert_from_func_ptr_addr @@ -3078,27 +3090,13 @@ value_fn_field (struct value **arg1p, struct fn_field *f, -/* Unpack a bitfield of the specified FIELD_TYPE, from the object at - VALADDR, and store the result in *RESULT. - The bitfield starts at BITPOS bits and contains BITSIZE bits; if - BITSIZE is zero, then the length is taken from FIELD_TYPE. - - Extracting bits depends on endianness of the machine. Compute the - number of least significant bits to discard. For big endian machines, - we compute the total number of bits in the anonymous object, subtract - off the bit count from the MSB of the object to the MSB of the - bitfield, then the size of the bitfield, which leaves the LSB discard - count. For little endian machines, the discard count is simply the - number of bits from the LSB of the anonymous object to the LSB of the - bitfield. - - If the field is signed, we also do sign extension. */ +/* See value.h. */ -static LONGEST +LONGEST unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, LONGEST bitpos, LONGEST bitsize) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type)); + enum bfd_endian byte_order = type_byte_order (field_type); ULONGEST val; ULONGEST valmask; int lsbcount; @@ -3123,7 +3121,7 @@ unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, /* Extract bits. See comment above. */ - if (gdbarch_bits_big_endian (get_type_arch (field_type))) + if (byte_order == BFD_ENDIAN_BIG) lsbcount = (bytes_read * 8 - bitpos % 8 - bitsize); else lsbcount = (bitpos % 8); @@ -3160,7 +3158,7 @@ unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr, { int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); - struct type *field_type = TYPE_FIELD_TYPE (type, fieldno); + struct type *field_type = type->field (fieldno).type (); int bit_offset; gdb_assert (val != NULL); @@ -3183,7 +3181,7 @@ unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno) { int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); - struct type *field_type = TYPE_FIELD_TYPE (type, fieldno); + struct type *field_type = type->field (fieldno).type (); return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize); } @@ -3207,7 +3205,7 @@ unpack_value_bitfield (struct value *dest_val, int dst_bit_offset; struct type *field_type = value_type (dest_val); - byte_order = gdbarch_byte_order (get_type_arch (field_type)); + byte_order = type_byte_order (field_type); /* First, unpack and sign extend the bitfield as if it was wholly valid. Optimized out/unavailable bits are read as zero, but @@ -3248,7 +3246,7 @@ value_field_bitfield (struct type *type, int fieldno, { int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); - struct value *res_val = allocate_value (TYPE_FIELD_TYPE (type, fieldno)); + struct value *res_val = allocate_value (type->field (fieldno).type ()); unpack_value_bitfield (res_val, bitpos, bitsize, valaddr, embedded_offset, val); @@ -3267,7 +3265,7 @@ void modify_field (struct type *type, gdb_byte *addr, LONGEST fieldval, LONGEST bitpos, LONGEST bitsize) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (type); ULONGEST oword; ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize); LONGEST bytesize; @@ -3299,7 +3297,7 @@ modify_field (struct type *type, gdb_byte *addr, oword = extract_unsigned_integer (addr, bytesize, byte_order); /* Shifting for bit field depends on endianness of the target machine. */ - if (gdbarch_bits_big_endian (get_type_arch (type))) + if (byte_order == BFD_ENDIAN_BIG) bitpos = bytesize * 8 - bitpos - bitsize; oword &= ~(mask << bitpos); @@ -3313,20 +3311,22 @@ modify_field (struct type *type, gdb_byte *addr, void pack_long (gdb_byte *buf, struct type *type, LONGEST num) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (type); LONGEST len; type = check_typedef (type); len = TYPE_LENGTH (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { + case TYPE_CODE_RANGE: + num -= TYPE_RANGE_DATA (type)->bias; + /* Fall through. */ case TYPE_CODE_INT: case TYPE_CODE_CHAR: case TYPE_CODE_ENUM: case TYPE_CODE_FLAGS: case TYPE_CODE_BOOL: - case TYPE_CODE_RANGE: case TYPE_CODE_MEMBERPTR: store_signed_integer (buf, len, byte_order, num); break; @@ -3344,7 +3344,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) default: error (_("Unexpected type (%d) encountered for integer constant."), - TYPE_CODE (type)); + type->code ()); } } @@ -3359,9 +3359,9 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) type = check_typedef (type); len = TYPE_LENGTH (type); - byte_order = gdbarch_byte_order (get_type_arch (type)); + byte_order = type_byte_order (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_INT: case TYPE_CODE_CHAR: @@ -3387,7 +3387,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) default: error (_("Unexpected type (%d) encountered " "for unsigned integer constant."), - TYPE_CODE (type)); + type->code ()); } } @@ -3430,6 +3430,19 @@ value_from_pointer (struct type *type, CORE_ADDR addr) return val; } +/* Create and return a value object of TYPE containing the value D. The + TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once + it is converted to target format. */ + +struct value * +value_from_host_double (struct type *type, double d) +{ + struct value *value = allocate_value (type); + gdb_assert (type->code () == TYPE_CODE_FLT); + target_float_from_host_double (value_contents_raw (value), + value_type (value), d); + return value; +} /* Create a value of type TYPE whose contents come from VALADDR, if it is non-null, and whose memory address (in the inferior) is @@ -3464,7 +3477,10 @@ value_from_contents_and_address (struct type *type, const gdb_byte *valaddr, CORE_ADDR address) { - struct type *resolved_type = resolve_dynamic_type (type, valaddr, address); + gdb::array_view view; + if (valaddr != nullptr) + view = gdb::make_array_view (valaddr, TYPE_LENGTH (type)); + struct type *resolved_type = resolve_dynamic_type (type, view, address); struct type *resolved_type_no_typedef = check_typedef (resolved_type); struct value *v; @@ -3648,7 +3664,7 @@ coerce_array (struct value *arg) arg = coerce_ref (arg); type = check_typedef (value_type (arg)); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_ARRAY: if (!TYPE_VECTOR (type) && current_language->c_style_arrays) @@ -3669,7 +3685,7 @@ enum return_value_convention struct_return_convention (struct gdbarch *gdbarch, struct value *function, struct type *value_type) { - enum type_code code = TYPE_CODE (value_type); + enum type_code code = value_type->code (); if (code == TYPE_CODE_ERROR) error (_("Function return type unknown.")); @@ -3687,7 +3703,7 @@ int using_struct_return (struct gdbarch *gdbarch, struct value *function, struct type *value_type) { - if (TYPE_CODE (value_type) == TYPE_CODE_VOID) + if (value_type->code () == TYPE_CODE_VOID) /* A void return value is never in memory. See also corresponding code in "print_return_value". */ return 0; @@ -3915,11 +3931,48 @@ isvoid_internal_fn (struct gdbarch *gdbarch, if (argc != 1) error (_("You must provide one argument for $_isvoid.")); - ret = TYPE_CODE (value_type (argv[0])) == TYPE_CODE_VOID; + ret = value_type (argv[0])->code () == TYPE_CODE_VOID; return value_from_longest (builtin_type (gdbarch)->builtin_int, ret); } +/* Implementation of the convenience function $_creal. Extracts the + real part from a complex number. */ + +static struct value * +creal_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_creal.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (ctype->code () != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_real_part (cval); +} + +/* Implementation of the convenience function $_cimag. Extracts the + imaginary part from a complex number. */ + +static struct value * +cimag_internal_fn (struct gdbarch *gdbarch, + const struct language_defn *language, + void *cookie, int argc, + struct value **argv) +{ + if (argc != 1) + error (_("You must provide one argument for $_cimag.")); + + value *cval = argv[0]; + type *ctype = check_typedef (value_type (cval)); + if (ctype->code () != TYPE_CODE_COMPLEX) + error (_("expected a complex number")); + return value_imaginary_part (cval); +} + #if GDB_SELF_TEST namespace selftests { @@ -4062,8 +4115,9 @@ test_insert_into_bit_range_vector () } /* namespace selftests */ #endif /* GDB_SELF_TEST */ +void _initialize_values (); void -_initialize_values (void) +_initialize_values () { add_cmd ("convenience", no_class, show_convenience, _("\ Debugger convenience (\"$foo\") variables and functions.\n\ @@ -4101,6 +4155,20 @@ Usage: $_isvoid (expression)\n\ Return 1 if the expression is void, zero otherwise."), isvoid_internal_fn, NULL); + add_internal_function ("_creal", _("\ +Extract the real part of a complex number.\n\ +Usage: $_creal (expression)\n\ +Return the real part of a complex number, the type depends on the\n\ +type of a complex number."), + creal_internal_fn, NULL); + + add_internal_function ("_cimag", _("\ +Extract the imaginary part of a complex number.\n\ +Usage: $_cimag (expression)\n\ +Return the imaginary part of a complex number, the type depends on the\n\ +type of a complex number."), + cimag_internal_fn, NULL); + add_setshow_zuinteger_unlimited_cmd ("max-value-size", class_support, &max_value_size, _("\ Set maximum sized value gdb will load from the inferior."), _("\ @@ -4119,3 +4187,11 @@ prevents future values, larger than this size, from being allocated."), selftests::test_insert_into_bit_range_vector); #endif } + +/* See value.h. */ + +void +finalize_values () +{ + all_values.clear (); +}