aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2expr.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-04-04 20:03:26 +0100
committerPedro Alves <palves@redhat.com>2017-04-04 20:03:26 +0100
commit9c5417255690af00751c7d506172459afe856894 (patch)
tree8d6da311b5442e8add81838cb178eb1aba8ad13d /gdb/dwarf2expr.c
parentecfb656c37b982479d8eb07f240b434772d98fd6 (diff)
downloadgdb-9c5417255690af00751c7d506172459afe856894.zip
gdb-9c5417255690af00751c7d506172459afe856894.tar.gz
gdb-9c5417255690af00751c7d506172459afe856894.tar.bz2
Make sect_offset and cu_offset strong typedefs instead of structs
A while ago, back when GDB was a C program, the sect_offset and cu_offset types were made structs in order to prevent incorrect mixing of those offsets. Now that we require C++11, we can make them integers again, while keeping the safety, by exploiting "enum class". We can add a bit more safety, even, by defining operators that the types _should_ support, helping making the suspicious uses stand out more. Getting at the underlying type is done with the new to_underlying function added by the previous patch, which also helps better spot where do we need to step out of the safety net. Mostly, that's around parsing the DWARF, and when we print the offset for complaint/debug purposes. But there are other occasional uses. Since we have to define the sect_offset/cu_offset types in a header anyway, I went ahead and generalized/library-fied the idea of "offset" types, making it trivial to add more such types if we find a use. See common/offset-type.h and the DEFINE_OFFSET_TYPE macro. I needed a couple generaly-useful preprocessor bits (e.g., yet another CONCAT implementation), so I started a new common/preprocessor.h file. I included units tests covering the "offset" types API. These are mostly compile-time tests, using SFINAE to check that expressions that shouldn't compile (e.g., comparing unrelated offset types) really are invalid and would fail to compile. This same idea appeared in my pending enum-flags revamp from a few months ago (though this version is a bit further modernized compared to what I had posted), and I plan on reusing the "check valid expression" bits added here in that series, so I went ahead and defined the CHECK_VALID_EXPR macro in its own header -- common/valid-expr.h. I think that's nicer regardless. I was borderline between calling the new types "offset" types, or "index" types, BTW. I stuck with "offset" simply because that's what we're already calling them, mostly. gdb/ChangeLog: 2017-04-04 Pedro Alves <palves@redhat.com> * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add unittests/offset-type-selftests.c. (SUBDIR_UNITTESTS_OBS): Add offset-type-selftests.o. * common/offset-type.h: New file. * common/preprocessor.h: New file. * common/traits.h: New file. * common/valid-expr.h: New file. * dwarf2expr.c: Include "common/underlying.h". Adjust to use sect_offset and cu_offset strong typedefs throughout. * dwarf2expr.h: Adjust to use sect_offset and cu_offset strong typedefs throughout. * dwarf2loc.c: Include "common/underlying.h". Adjust to use sect_offset and cu_offset strong typedefs throughout. * dwarf2read.c: Adjust to use sect_offset and cu_offset strong typedefs throughout. * gdbtypes.h: Include "common/offset-type.h". (cu_offset): Now an offset type (strong typedef) instead of a struct. (sect_offset): Likewise. (union call_site_parameter_u): Rename "param_offset" field to "param_cu_off". * unittests/offset-type-selftests.c: New file.
Diffstat (limited to 'gdb/dwarf2expr.c')
-rw-r--r--gdb/dwarf2expr.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index fbbb6c4..a693856 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -27,6 +27,7 @@
#include "dwarf2.h"
#include "dwarf2expr.h"
#include "dwarf2loc.h"
+#include "common/underlying.h"
/* Cookie for gdbarch data. */
@@ -317,7 +318,7 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
}
else if (p->location == DWARF_VALUE_IMPLICIT_POINTER)
{
- p->v.ptr.die.sect_off = this->len;
+ p->v.ptr.die_sect_off = (sect_offset) this->len;
p->v.ptr.offset = value_as_long (fetch (0));
}
else if (p->location == DWARF_VALUE_REGISTER)
@@ -976,11 +977,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (op == DW_OP_deref_type || op == DW_OP_GNU_deref_type)
{
- cu_offset type_die;
-
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
- type_die.cu_off = uoffset;
- type = get_base_type (type_die, 0);
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
+ type = get_base_type (type_die_cu_off, 0);
}
else
type = address_type;
@@ -1283,21 +1282,19 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_call2:
{
- cu_offset offset;
-
- offset.cu_off = extract_unsigned_integer (op_ptr, 2, byte_order);
+ cu_offset cu_off
+ = (cu_offset) extract_unsigned_integer (op_ptr, 2, byte_order);
op_ptr += 2;
- this->dwarf_call (offset);
+ this->dwarf_call (cu_off);
}
goto no_push;
case DW_OP_call4:
{
- cu_offset offset;
-
- offset.cu_off = extract_unsigned_integer (op_ptr, 4, byte_order);
+ cu_offset cu_off
+ = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order);
op_ptr += 4;
- this->dwarf_call (offset);
+ this->dwarf_call (cu_off);
}
goto no_push;
@@ -1344,8 +1341,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
{
union call_site_parameter_u kind_u;
- kind_u.param_offset.cu_off = extract_unsigned_integer (op_ptr, 4,
- byte_order);
+ kind_u.param_cu_off
+ = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order);
op_ptr += 4;
this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_PARAM_OFFSET,
kind_u,
@@ -1356,18 +1353,18 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_const_type:
case DW_OP_GNU_const_type:
{
- cu_offset type_die;
int n;
const gdb_byte *data;
struct type *type;
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
- type_die.cu_off = uoffset;
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
+
n = *op_ptr++;
data = op_ptr;
op_ptr += n;
- type = get_base_type (type_die, n);
+ type = get_base_type (type_die_cu_off, n);
result_val = value_from_contents (type, data);
}
break;
@@ -1375,14 +1372,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_regval_type:
case DW_OP_GNU_regval_type:
{
- cu_offset type_die;
struct type *type;
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
- type_die.cu_off = uoffset;
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
- type = get_base_type (type_die, 0);
+ type = get_base_type (type_die_cu_off, 0);
result_val = this->get_reg_value (type, reg);
}
break;
@@ -1392,16 +1388,15 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_reinterpret:
case DW_OP_GNU_reinterpret:
{
- cu_offset type_die;
struct type *type;
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
- type_die.cu_off = uoffset;
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
- if (type_die.cu_off == 0)
+ if (to_underlying (type_die_cu_off) == 0)
type = address_type;
else
- type = get_base_type (type_die, 0);
+ type = get_base_type (type_die_cu_off, 0);
result_val = fetch (0);
pop ();