Skip to content

Commit 0aa666e

Browse files
committed
Store has-local-scope information in symbolt
None of the existing flags (nor any combination thereof) would enable us to distinguish procedure-local type declarations from translation-unit wide ones.
1 parent 617dd98 commit 0aa666e

14 files changed

+51
-42
lines changed

src/ansi-c/ansi_c_declaration.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ void ansi_c_declarationt::to_symbol(
139139
symbol.is_macro=get_is_typedef() || get_is_enum_constant();
140140
symbol.is_parameter=get_is_parameter();
141141
symbol.is_weak=get_is_weak();
142+
symbol.has_local_scope = !get_is_global();
142143

143144
// is it a function?
144145

src/ansi-c/type2name.cpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,27 @@ static std::string type2name_tag(
3838
if(ns.lookup(identifier, symbol))
3939
return "SYM#"+id2string(identifier)+"#";
4040

41+
std::string result;
42+
43+
// this isn't really a qualifier, but the linker needs to
44+
// distinguish these - should likely be fixed in the linker instead
45+
if(symbol->has_local_scope)
46+
result += 'l';
47+
4148
assert(symbol && symbol->is_type);
4249

4350
if(symbol->type.id()!=ID_struct &&
4451
symbol->type.id()!=ID_union)
45-
return type2name(symbol->type, ns, symbol_number);
52+
return result + type2name(symbol->type, ns, symbol_number);
4653

4754
// assign each symbol a number when seen for the first time
4855
std::pair<symbol_numbert::iterator, bool> entry=
4956
symbol_number.insert(std::make_pair(
5057
identifier,
5158
std::make_pair(symbol_number.size(), true)));
5259

53-
std::string result = "SYM" +
54-
id2string(to_struct_union_type(symbol->type).get_tag()) +
55-
'#' + std::to_string(entry.first->second.first);
60+
result += "SYM" + id2string(to_struct_union_type(symbol->type).get_tag()) +
61+
'#' + std::to_string(entry.first->second.first);
5662

5763
// new entry, add definition
5864
if(entry.second)
@@ -99,11 +105,6 @@ static std::string type2name(
99105
if(type.get_bool(ID_C_noreturn))
100106
result+='n';
101107

102-
// this isn't really a qualifier, but the linker needs to
103-
// distinguish these - should likely be fixed in the linker instead
104-
if(!type.source_location().get_function().empty())
105-
result+='l';
106-
107108
if(type.id().empty())
108109
throw "empty type encountered";
109110
else if(type.id()==ID_empty)

src/cpp/cpp_declarator_converter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ symbolt &cpp_declarator_convertert::convert_new_symbol(
426426
symbol.is_type=is_typedef;
427427
symbol.is_macro=is_typedef && !is_template_parameter;
428428
symbol.pretty_name=pretty_name;
429+
symbol.has_local_scope =
430+
!cpp_typecheck.cpp_scopes.current_scope().is_global_scope();
429431

430432
// Constant? These are propagated.
431433
if(symbol.type.get_bool(ID_C_constant) &&

src/cpp/cpp_typecheck_compound_type.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ void cpp_typecheckt::typecheck_compound_type(
233233
cpp_scopes.current_scope().suffix;
234234
symbol.type.set(
235235
ID_tag, cpp_scopes.current_scope().prefix+id2string(symbol.base_name));
236+
symbol.has_local_scope = !cpp_scopes.current_scope().is_global_scope();
236237

237238
// move early, must be visible before doing body
238239
symbolt *new_symbol;

src/cpp/cpp_typecheck_enum_type.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ void cpp_typecheckt::typecheck_enum_type(typet &type)
178178
symbol.is_type=true;
179179
symbol.is_macro=false;
180180
symbol.pretty_name=pretty_name;
181+
symbol.has_local_scope = !cpp_scopes.current_scope().is_global_scope();
181182

182183
// move early, must be visible before doing body
183184
symbolt *new_symbol;

src/cpp/cpp_typecheck_template.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ void cpp_typecheckt::typecheck_class_template(
178178

179179
symbol.pretty_name=
180180
cpp_scopes.current_scope().prefix+id2string(symbol.base_name);
181+
symbol.has_local_scope = !cpp_scopes.current_scope().is_global_scope();
181182

182183
symbolt *new_symbol;
183184
if(symbol_table.move(symbol, new_symbol))

src/goto-instrument/dump_c.cpp

+11-14
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,9 @@ void dump_ct::operator()(std::ostream &os)
168168
const symbolt &symbol=ns.lookup(*it);
169169
const irep_idt &type_id=symbol.type.id();
170170

171-
if(symbol.is_type &&
172-
symbol.location.get_function().empty() &&
173-
(type_id==ID_struct ||
174-
type_id==ID_union ||
175-
type_id==ID_c_enum))
171+
if(
172+
symbol.is_type && !symbol.has_local_scope &&
173+
(type_id == ID_struct || type_id == ID_union || type_id == ID_c_enum))
176174
{
177175
if(!system_symbols.is_symbol_internal_symbol(symbol, system_headers))
178176
{
@@ -293,7 +291,7 @@ void dump_ct::convert_compound_declaration(
293291
const symbolt &symbol,
294292
std::ostream &os_body)
295293
{
296-
if(!symbol.location.get_function().empty())
294+
if(symbol.has_local_scope)
297295
return;
298296

299297
// do compound type body
@@ -737,8 +735,7 @@ void dump_ct::gather_global_typedefs()
737735
{
738736
const symbolt &symbol=symbol_entry.second;
739737

740-
if(symbol.is_macro && symbol.is_type &&
741-
symbol.location.get_function().empty())
738+
if(symbol.is_macro && symbol.is_type && !symbol.has_local_scope)
742739
{
743740
const irep_idt &typedef_str=symbol.type.get(ID_C_typedef);
744741
PRECONDITION(!typedef_str.empty());
@@ -843,9 +840,10 @@ void dump_ct::convert_global_variable(
843840
std::ostream &os,
844841
local_static_declst &local_static_decls)
845842
{
846-
const irep_idt &func=symbol.location.get_function();
847-
if((func.empty() || symbol.is_extern || symbol.value.is_not_nil()) &&
848-
!converted_global.insert(symbol.name).second)
843+
const bool global = !symbol.has_local_scope;
844+
if(
845+
(global || symbol.is_extern || symbol.value.is_not_nil()) &&
846+
!converted_global.insert(symbol.name).second)
849847
return;
850848

851849
code_declt d(symbol.symbol_expr());
@@ -856,8 +854,7 @@ void dump_ct::convert_global_variable(
856854

857855
// add a tentative declaration to cater for symbols in the initializer
858856
// relying on it this symbol
859-
if((func.empty() || symbol.is_extern) &&
860-
(symbol.value.is_nil() || !syms.empty()))
857+
if((global || symbol.is_extern) && (symbol.value.is_nil() || !syms.empty()))
861858
{
862859
os << "// " << symbol.name << '\n';
863860
os << "// " << symbol.location << '\n';
@@ -889,7 +886,7 @@ void dump_ct::convert_global_variable(
889886
d.copy_to_operands(symbol.value);
890887
}
891888

892-
if(!func.empty() && !symbol.is_extern)
889+
if(!global && !symbol.is_extern)
893890
{
894891
local_static_decls.emplace(symbol.name, d);
895892
}

src/goto-instrument/goto_program2code.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -1416,8 +1416,7 @@ void goto_program2codet::add_local_types(const typet &type)
14161416
const irep_idt &identifier=to_symbol_type(type).get_identifier();
14171417
const symbolt &symbol=ns.lookup(identifier);
14181418

1419-
if(symbol.location.get_function().empty() ||
1420-
!type_names_set.insert(identifier).second)
1419+
if(!symbol.has_local_scope || !type_names_set.insert(identifier).second)
14211420
return;
14221421

14231422
for(const auto &c : to_struct_union_type(full_type).components())
@@ -1432,8 +1431,7 @@ void goto_program2codet::add_local_types(const typet &type)
14321431
const irep_idt &identifier=to_c_enum_tag_type(type).get_identifier();
14331432
const symbolt &symbol=ns.lookup(identifier);
14341433

1435-
if(symbol.location.get_function().empty() ||
1436-
!type_names_set.insert(identifier).second)
1434+
if(!symbol.has_local_scope || !type_names_set.insert(identifier).second)
14371435
return;
14381436

14391437
assert(!identifier.empty());
@@ -1979,11 +1977,10 @@ void goto_program2codet::cleanup_expr(exprt &expr, bool no_typecast)
19791977
const irep_idt &identifier=to_symbol_expr(expr).get_identifier();
19801978
const symbolt &symbol=ns.lookup(identifier);
19811979

1982-
if(symbol.is_static_lifetime &&
1983-
symbol.type.id()!=ID_code &&
1984-
!symbol.is_extern &&
1985-
!symbol.location.get_function().empty() &&
1986-
local_static_set.insert(identifier).second)
1980+
if(
1981+
symbol.is_static_lifetime && symbol.type.id() != ID_code &&
1982+
!symbol.is_extern && symbol.has_local_scope &&
1983+
local_static_set.insert(identifier).second)
19871984
{
19881985
if(symbol.value.is_not_nil())
19891986
{

src/goto-programs/read_bin_goto_object.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static bool read_bin_goto_object_v5(
6060
sym.is_state_var = (flags &(1 << 9))!=0;
6161
sym.is_parameter = (flags &(1 << 8))!=0;
6262
sym.is_auxiliary = (flags &(1 << 7))!=0;
63-
// sym.binding = (flags &(1 << 6))!=0;
63+
sym.has_local_scope = (flags & (1 << 6)) != 0;
6464
sym.is_lvalue = (flags &(1 << 5))!=0;
6565
sym.is_static_lifetime = (flags &(1 << 4))!=0;
6666
sym.is_thread_local = (flags &(1 << 3))!=0;

src/goto-programs/show_symbol_table.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ static void show_symbol_table_json_ui(
223223
{"isVolatile", jsont::json_boolean(symbol.is_volatile)},
224224
{"isParameter", jsont::json_boolean(symbol.is_parameter)},
225225
{"isAuxiliary", jsont::json_boolean(symbol.is_auxiliary)},
226-
{"isWeak", jsont::json_boolean(symbol.is_weak)}};
226+
{"isWeak", jsont::json_boolean(symbol.is_weak)},
227+
{"hasLocalScope", jsont::json_boolean(symbol.has_local_scope)}};
227228

228229
result.push_back(id2string(symbol.name), std::move(symbol_json));
229230
}

src/goto-programs/write_goto_binary.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ bool write_goto_binary_v5(
6262
flags = (flags << 1) | static_cast<int>(sym.is_state_var);
6363
flags = (flags << 1) | static_cast<int>(sym.is_parameter);
6464
flags = (flags << 1) | static_cast<int>(sym.is_auxiliary);
65-
flags = (flags << 1) | static_cast<int>(false); // sym.binding;
65+
flags = (flags << 1) | static_cast<int>(sym.has_local_scope);
6666
flags = (flags << 1) | static_cast<int>(sym.is_lvalue);
6767
flags = (flags << 1) | static_cast<int>(sym.is_static_lifetime);
6868
flags = (flags << 1) | static_cast<int>(sym.is_thread_local);

src/json-symtab-language/json_symbol.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ symbolt symbol_from_json(const jsont &in)
107107
result.is_auxiliary = try_get_bool(kv.second, "isAuxiliary");
108108
else if(kv.first == "isWeak")
109109
result.is_weak = try_get_bool(kv.second, "isWeak");
110+
else if(kv.first == "hasLocalScope")
111+
result.has_local_scope = try_get_bool(kv.second, "hasLocalScope");
110112
else if(kv.first == "prettyType")
111113
{
112114
} // ignore

src/util/symbol.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ void symbolt::show(std::ostream &out) const
4848
out << " auxiliary";
4949
if(is_weak)
5050
out << " weak";
51+
if(has_local_scope)
52+
out << " local_scope";
5153
if(is_property)
5254
out << " property";
5355
if(is_state_var)
@@ -108,6 +110,7 @@ void symbolt::swap(symbolt &b)
108110
SYM_SWAP2(is_parameter);
109111
SYM_SWAP2(is_auxiliary);
110112
SYM_SWAP2(is_weak);
113+
SYM_SWAP2(has_local_scope);
111114
SYM_SWAP2(is_lvalue);
112115
SYM_SWAP2(is_static_lifetime);
113116
SYM_SWAP2(is_thread_local);
@@ -220,6 +223,7 @@ bool symbolt::operator==(const symbolt &other) const
220223
is_parameter == other.is_parameter &&
221224
is_auxiliary == other.is_auxiliary &&
222225
is_weak == other.is_weak &&
226+
has_local_scope == other.has_local_scope &&
223227
is_lvalue == other.is_lvalue &&
224228
is_static_lifetime == other.is_static_lifetime &&
225229
is_thread_local == other.is_thread_local &&

src/util/symbol.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ class symbolt
6363

6464
// ANSI-C
6565
bool is_static_lifetime, is_thread_local;
66-
bool is_lvalue, is_file_local, is_extern, is_volatile,
67-
is_parameter, is_auxiliary, is_weak;
66+
bool is_lvalue, is_file_local, is_extern, is_volatile, is_parameter,
67+
is_auxiliary, is_weak, has_local_scope;
6868

6969
symbolt()
7070
{
@@ -80,11 +80,10 @@ class symbolt
8080

8181
name=module=base_name=mode=pretty_name=irep_idt();
8282

83-
is_type=is_macro=is_exported=
84-
is_input=is_output=is_state_var=is_property=
85-
is_static_lifetime=is_thread_local=
86-
is_lvalue=is_file_local=is_extern=is_volatile=
87-
is_parameter=is_auxiliary=is_weak=false;
83+
is_type = is_macro = is_exported = is_input = is_output = is_state_var =
84+
is_property = is_static_lifetime = is_thread_local = is_lvalue =
85+
is_file_local = is_extern = is_volatile = is_parameter = is_auxiliary =
86+
is_weak = has_local_scope = false;
8887
}
8988

9089
void swap(symbolt &b);
@@ -153,6 +152,7 @@ class auxiliary_symbolt:public symbolt
153152
is_thread_local=true;
154153
is_file_local=true;
155154
is_auxiliary=true;
155+
has_local_scope = true;
156156
}
157157

158158
auxiliary_symbolt(const irep_idt &name, const typet &type):
@@ -177,6 +177,7 @@ class parameter_symbolt:public symbolt
177177
is_thread_local=true;
178178
is_file_local=true;
179179
is_parameter=true;
180+
has_local_scope = true;
180181
}
181182
};
182183

0 commit comments

Comments
 (0)