Skip to content

Commit 3809a49

Browse files
committed
Make find_symbols implementations uniform
Each function used a different approach, with different potential omissions of symbols. Instead, try to use the most efficient and complete approaches, and re-use code by making some functions just thin wrappers.
1 parent 9a4e3e6 commit 3809a49

File tree

2 files changed

+100
-62
lines changed

2 files changed

+100
-62
lines changed

src/util/find_symbols.cpp

Lines changed: 88 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -50,67 +50,93 @@ bool has_symbol(
5050
return has_symbol(src, symbols, true, true);
5151
}
5252

53+
static void find_symbols(const typet &src, std::set<symbol_exprt> &dest)
54+
{
55+
if(src.has_subtype())
56+
find_symbols(to_type_with_subtype(src).subtype(), dest);
57+
58+
for(const typet &subtype : to_type_with_subtypes(src).subtypes())
59+
find_symbols(subtype, dest);
60+
61+
if(src.id() == ID_struct || src.id() == ID_union)
62+
{
63+
const struct_union_typet &struct_union_type = to_struct_union_type(src);
64+
65+
for(const auto &c : struct_union_type.components())
66+
find_symbols(c, dest);
67+
}
68+
else if(src.id() == ID_code)
69+
{
70+
const code_typet &code_type = to_code_type(src);
71+
find_symbols(code_type.return_type(), dest);
72+
73+
for(const auto &p : code_type.parameters())
74+
{
75+
find_symbols(p, dest);
76+
}
77+
}
78+
else if(src.id() == ID_array)
79+
{
80+
// do the size -- the subtype is already done
81+
find_symbols(to_array_type(src).size(), dest);
82+
}
83+
}
84+
5385
void find_symbols(
5486
const exprt &src,
5587
std::set<symbol_exprt> &dest)
5688
{
5789
src.visit_pre([&dest](const exprt &e) {
90+
find_symbols(e.type(), dest);
91+
5892
if(e.id() == ID_symbol)
5993
dest.insert(to_symbol_expr(e));
60-
});
61-
}
6294

63-
std::set<symbol_exprt> find_symbols(const exprt &src)
64-
{
65-
return make_range(src.depth_begin(), src.depth_end())
66-
.filter([](const exprt &e) { return e.id() == ID_symbol; })
67-
.map([](const exprt &e) { return to_symbol_expr(e); });
68-
}
95+
const irept &c_sizeof_type = e.find(ID_C_c_sizeof_type);
6996

70-
std::unordered_set<irep_idt> find_symbol_identifiers(const exprt &src)
71-
{
72-
std::unordered_set<irep_idt> result;
73-
src.visit_pre([&](const exprt &e) {
74-
if(e.id() == ID_symbol)
75-
result.insert(to_symbol_expr(e).get_identifier());
97+
if(c_sizeof_type.is_not_nil())
98+
find_symbols(static_cast<const typet &>(c_sizeof_type), dest);
99+
100+
const irept &va_arg_type = e.find(ID_C_va_arg_type);
101+
102+
if(va_arg_type.is_not_nil())
103+
find_symbols(static_cast<const typet &>(va_arg_type), dest);
76104
});
77-
return result;
78105
}
79106

80107
void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest);
81108

82109
void find_symbols(kindt kind, const exprt &src, find_symbols_sett &dest)
83110
{
84-
forall_operands(it, src)
85-
find_symbols(kind, *it, dest);
86-
87-
find_symbols(kind, src.type(), dest);
111+
src.visit_pre([&dest, kind](const exprt &e) {
112+
find_symbols(kind, e.type(), dest);
88113

89-
if(
90-
kind == kindt::F_ALL || kind == kindt::F_EXPR_CURRENT ||
91-
kind == kindt::F_EXPR_BOTH)
92-
{
93-
if(src.id() == ID_symbol)
94-
dest.insert(to_symbol_expr(src).get_identifier());
95-
}
114+
if(
115+
kind == kindt::F_ALL || kind == kindt::F_EXPR_CURRENT ||
116+
kind == kindt::F_EXPR_BOTH)
117+
{
118+
if(e.id() == ID_symbol)
119+
dest.insert(to_symbol_expr(e).get_identifier());
120+
}
96121

97-
if(
98-
kind == kindt::F_ALL || kind == kindt::F_EXPR_NEXT ||
99-
kind == kindt::F_EXPR_BOTH)
100-
{
101-
if(src.id() == ID_next_symbol)
102-
dest.insert(src.get(ID_identifier));
103-
}
122+
if(
123+
kind == kindt::F_ALL || kind == kindt::F_EXPR_NEXT ||
124+
kind == kindt::F_EXPR_BOTH)
125+
{
126+
if(e.id() == ID_next_symbol)
127+
dest.insert(e.get(ID_identifier));
128+
}
104129

105-
const irept &c_sizeof_type=src.find(ID_C_c_sizeof_type);
130+
const irept &c_sizeof_type = e.find(ID_C_c_sizeof_type);
106131

107-
if(c_sizeof_type.is_not_nil())
108-
find_symbols(kind, static_cast<const typet &>(c_sizeof_type), dest);
132+
if(c_sizeof_type.is_not_nil())
133+
find_symbols(kind, static_cast<const typet &>(c_sizeof_type), dest);
109134

110-
const irept &va_arg_type=src.find(ID_C_va_arg_type);
135+
const irept &va_arg_type = e.find(ID_C_va_arg_type);
111136

112-
if(va_arg_type.is_not_nil())
113-
find_symbols(kind, static_cast<const typet &>(va_arg_type), dest);
137+
if(va_arg_type.is_not_nil())
138+
find_symbols(kind, static_cast<const typet &>(va_arg_type), dest);
139+
});
114140
}
115141

116142
void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest)
@@ -124,9 +150,14 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest)
124150
for(const typet &subtype : to_type_with_subtypes(src).subtypes())
125151
find_symbols(kind, subtype, dest);
126152

127-
const irep_idt &typedef_name=src.get(ID_C_typedef);
128-
if(!typedef_name.empty())
129-
dest.insert(typedef_name);
153+
if(
154+
kind == kindt::F_TYPE || kind == kindt::F_TYPE_NON_PTR ||
155+
kind == kindt::F_ALL)
156+
{
157+
const irep_idt &typedef_name = src.get(ID_C_typedef);
158+
if(!typedef_name.empty())
159+
dest.insert(typedef_name);
160+
}
130161
}
131162

132163
if(src.id()==ID_struct ||
@@ -152,17 +183,22 @@ void find_symbols(kindt kind, const typet &src, find_symbols_sett &dest)
152183
// do the size -- the subtype is already done
153184
find_symbols(kind, to_array_type(src).size(), dest);
154185
}
155-
else if(src.id()==ID_c_enum_tag)
156-
{
157-
dest.insert(to_c_enum_tag_type(src).get_identifier());
158-
}
159-
else if(src.id()==ID_struct_tag)
160-
{
161-
dest.insert(to_struct_tag_type(src).get_identifier());
162-
}
163-
else if(src.id()==ID_union_tag)
186+
else if(
187+
kind == kindt::F_TYPE || kind == kindt::F_TYPE_NON_PTR ||
188+
kind == kindt::F_ALL)
164189
{
165-
dest.insert(to_union_tag_type(src).get_identifier());
190+
if(src.id() == ID_c_enum_tag)
191+
{
192+
dest.insert(to_c_enum_tag_type(src).get_identifier());
193+
}
194+
else if(src.id() == ID_struct_tag)
195+
{
196+
dest.insert(to_struct_tag_type(src).get_identifier());
197+
}
198+
else if(src.id() == ID_union_tag)
199+
{
200+
dest.insert(to_union_tag_type(src).get_identifier());
201+
}
166202
}
167203
}
168204

src/util/find_symbols.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,26 @@ find_symbols_sett find_symbols_or_nexts(iteratort begin, iteratort end)
5050
return result;
5151
}
5252

53-
/// Add to the set \p dest the sub-expressions of \p src with id ID_symbol if
54-
/// \p current is true, and ID_next_symbol if \p next is true
55-
void find_symbols(
56-
const exprt &src,
57-
find_symbols_sett &dest,
58-
bool current,
59-
bool next);
60-
6153
/// Find sub expressions with id ID_symbol
6254
void find_symbols(
6355
const exprt &src,
6456
std::set<symbol_exprt> &dest);
6557

6658
/// Find sub expressions with id ID_symbol
67-
std::set<symbol_exprt> find_symbols(const exprt &src);
59+
inline std::set<symbol_exprt> find_symbols(const exprt &src)
60+
{
61+
std::set<symbol_exprt> syms;
62+
find_symbols(src, syms);
63+
return syms;
64+
}
6865

6966
/// Find identifiers of the sub expressions with id ID_symbol
70-
std::unordered_set<irep_idt> find_symbol_identifiers(const exprt &src);
67+
inline find_symbols_sett find_symbol_identifiers(const exprt &src)
68+
{
69+
find_symbols_sett identifiers;
70+
find_symbols(src, identifiers, true, false);
71+
return identifiers;
72+
}
7173

7274
DEPRECATED(SINCE(2022, 3, 14, "pick a specific implementation of find_symbols"))
7375
/// \return true if one of the symbols in \p src is present in \p symbols

0 commit comments

Comments
 (0)