Skip to content

get_max: do not parse every symbol name in the symbol table #2252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 13 additions & 23 deletions src/util/namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,14 @@ Author: Daniel Kroening, [email protected]
#include "string2int.h"
#include "symbol_table.h"

unsigned get_max(
static std::size_t smallest_unused_suffix(
const std::string &prefix,
const symbol_tablet::symbolst &symbols)
{
unsigned max_nr=0;
std::size_t max_nr = 0;

for(const auto &symbol_pair : symbols)
{
if(has_prefix(id2string(symbol_pair.first), prefix))
{
max_nr = std::max(
unsafe_string2unsigned(
id2string(symbol_pair.first).substr(prefix.size())),
max_nr);
}
}
while(symbols.find(prefix + std::to_string(max_nr)) != symbols.end())
++max_nr;

return max_nr;
}
Expand Down Expand Up @@ -122,15 +114,15 @@ void namespace_baset::follow_macros(exprt &expr) const
follow_macros(*it);
}

unsigned namespacet::get_max(const std::string &prefix) const
std::size_t namespacet::smallest_unused_suffix(const std::string &prefix) const
{
unsigned m=0;
std::size_t m = 0;

if(symbol_table1!=nullptr)
m=std::max(m, ::get_max(prefix, symbol_table1->symbols));
m = std::max(m, ::smallest_unused_suffix(prefix, symbol_table1->symbols));

if(symbol_table2!=nullptr)
m=std::max(m, ::get_max(prefix, symbol_table2->symbols));
m = std::max(m, ::smallest_unused_suffix(prefix, symbol_table2->symbols));

return m;
}
Expand Down Expand Up @@ -166,15 +158,13 @@ bool namespacet::lookup(
return true;
}

unsigned multi_namespacet::get_max(const std::string &prefix) const
std::size_t
multi_namespacet::smallest_unused_suffix(const std::string &prefix) const
{
unsigned m=0;
std::size_t m = 0;

for(symbol_table_listt::const_iterator
it=symbol_table_list.begin();
it!=symbol_table_list.end();
it++)
m=std::max(m, ::get_max(prefix, (*it)->symbols));
for(const auto &st : symbol_table_list)
m = std::max(m, ::smallest_unused_suffix(prefix, st->symbols));

return m;
}
Expand Down
18 changes: 9 additions & 9 deletions src/util/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ class namespace_baset
const typet &follow_tag(const struct_tag_typet &) const;
const typet &follow_tag(const c_enum_tag_typet &) const;

/// Returns the maximum integer n such that there is a symbol (in some of the
/// symbol tables) whose name is of the form "AB" where A is \p prefix and B
/// is n. Symbols where B is not a number count as if B was equal to 0.
/// Returns the minimal integer n such that there is no symbol (in any of the
/// symbol tables) whose name is of the form "An" where A is \p prefix.
/// The intended use case is finding the next available symbol name for a
/// sequence of auto-generated symbols.
virtual unsigned get_max(const std::string &prefix) const=0;
virtual std::size_t
smallest_unused_suffix(const std::string &prefix) const = 0;

/// Searches for a symbol named \p name. Iff found, set \p symbol to point to
/// the symbol and return false; else \p symbol is unmodified and `true` is
Expand Down Expand Up @@ -98,10 +98,10 @@ class namespacet:public namespace_baset

/// See namespace_baset::lookup(). Note that \ref namespacet has two symbol
/// tables.
virtual bool lookup(const irep_idt &name, const symbolt *&symbol) const;
bool lookup(const irep_idt &name, const symbolt *&symbol) const override;

/// See documentation for namespace_baset::get_max().
virtual unsigned get_max(const std::string &prefix) const;
/// See documentation for namespace_baset::smallest_unused_suffix().
std::size_t smallest_unused_suffix(const std::string &prefix) const override;

const symbol_tablet &get_symbol_table() const
{
Expand Down Expand Up @@ -129,8 +129,8 @@ class multi_namespacet:public namespacet
// these do the actual lookup
using namespace_baset::lookup;

virtual bool lookup(const irep_idt &name, const symbolt *&symbol) const;
virtual unsigned get_max(const std::string &prefix) const;
bool lookup(const irep_idt &name, const symbolt *&symbol) const override;
std::size_t smallest_unused_suffix(const std::string &prefix) const override;

void add(const symbol_tablet &symbol_table)
{
Expand Down
2 changes: 1 addition & 1 deletion src/util/rename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ void get_new_name(irep_idt &new_name, const namespacet &ns, char delimiter)

std::string prefix = id2string(new_name) + delimiter;

new_name=prefix+std::to_string(ns.get_max(prefix)+1);
new_name = prefix + std::to_string(ns.smallest_unused_suffix(prefix));
}