Skip to content

Commit 11a4d3d

Browse files
committed
Factor struct member offset routine to enable iterating over members with offsets.
1 parent a1b6623 commit 11a4d3d

File tree

2 files changed

+51
-21
lines changed

2 files changed

+51
-21
lines changed

src/util/pointer_offset_size.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,39 @@ Author: Daniel Kroening, [email protected]
2121

2222
#include "pointer_offset_size.h"
2323

24+
member_offset_iterator::member_offset_iterator(const struct_typet _type,
25+
const namespacet _ns) :
26+
type(_type),
27+
ns(_ns),
28+
bit_field_bits(0),
29+
current({0,0})
30+
{
31+
}
32+
33+
member_offset_iterator& member_offset_iterator::operator++()
34+
{
35+
if(current.second!=-1) // Already failed?
36+
{
37+
const auto& comp=type.components()[current.first];
38+
if(comp.type().id()==ID_c_bit_field)
39+
{
40+
// take the extra bytes needed
41+
std::size_t w=to_c_bit_field_type(comp.type()).get_width();
42+
for(; w>bit_field_bits; ++current.second, bit_field_bits+=8);
43+
bit_field_bits-=w;
44+
}
45+
else
46+
{
47+
const typet &subtype=comp.type();
48+
mp_integer sub_size=pointer_offset_size(subtype, ns);
49+
if(sub_size==-1) current.second=-1; // give up
50+
else current.second+=sub_size;
51+
}
52+
}
53+
++current.first;
54+
return *this;
55+
}
56+
2457
/*******************************************************************\
2558
2659
Function: member_offset
@@ -39,35 +72,18 @@ mp_integer member_offset(
3972
const namespacet &ns)
4073
{
4174
const struct_typet::componentst &components=type.components();
42-
43-
mp_integer result=0;
44-
std::size_t bit_field_bits=0;
75+
member_offset_iterator offsets(type,ns);
4576

4677
for(struct_typet::componentst::const_iterator
4778
it=components.begin();
48-
it!=components.end();
49-
it++)
79+
it!=components.end() && offsets->second!=-1;
80+
++it, ++offsets)
5081
{
5182
if(it->get_name()==member)
5283
break;
53-
54-
if(it->type().id()==ID_c_bit_field)
55-
{
56-
// take the extra bytes needed
57-
std::size_t w=to_c_bit_field_type(it->type()).get_width();
58-
for(; w>bit_field_bits; ++result, bit_field_bits+=8);
59-
bit_field_bits-=w;
60-
}
61-
else
62-
{
63-
const typet &subtype=it->type();
64-
mp_integer sub_size=pointer_offset_size(subtype, ns);
65-
if(sub_size==-1) return -1; // give up
66-
result+=sub_size;
67-
}
6884
}
6985

70-
return result;
86+
return offsets->second;
7187
}
7288

7389
/*******************************************************************\

src/util/pointer_offset_size.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ class constant_exprt;
2121

2222
// these return -1 on failure
2323

24+
class member_offset_iterator {
25+
typedef std::pair<size_t,mp_integer> refst;
26+
refst current;
27+
const struct_typet &type;
28+
const namespacet &ns;
29+
size_t bit_field_bits;
30+
public:
31+
member_offset_iterator(const struct_typet _type,
32+
const namespacet _ns);
33+
member_offset_iterator& operator++();
34+
const refst& operator*() const { return current; }
35+
const refst* operator->() const { return &current; }
36+
};
37+
2438
mp_integer member_offset(
2539
const struct_typet &type,
2640
const irep_idt &member,

0 commit comments

Comments
 (0)