diff --git a/HName.cc b/HName.cc index c783d57bb..6b40eafcd 100644 --- a/HName.cc +++ b/HName.cc @@ -40,7 +40,7 @@ hname_t::hname_t(perm_string text, int num) number_[0] = num; } -hname_t::hname_t(perm_string text, vector&nums) +hname_t::hname_t(perm_string text, const vector&nums) : name_(text), number_(nums) { } diff --git a/HName.h b/HName.h index 90f0d7942..b278aae55 100644 --- a/HName.h +++ b/HName.h @@ -42,7 +42,7 @@ class hname_t { hname_t (); explicit hname_t (perm_string text); explicit hname_t (perm_string text, int num); - explicit hname_t (perm_string text, std::vector&nums); + explicit hname_t (perm_string text, const std::vector&nums); hname_t (const hname_t&that); ~hname_t(); @@ -56,12 +56,12 @@ class hname_t { size_t has_numbers() const; int peek_number(size_t idx) const; + const std::vector&peek_numbers() const; private: perm_string name_; - // If the number is anything other than INT_MIN, then this is - // the numeric part of the name. Otherwise, it is not part of - // the name at all. + // If this vector has size, then the numbers all together make + // up part of the hierarchical name. std::vector number_; private: // not implemented @@ -82,6 +82,11 @@ inline int hname_t::peek_number(size_t idx) const return number_[idx]; } +inline const std::vector& hname_t::peek_numbers(void) const +{ + return number_; +} + inline size_t hname_t::has_numbers() const { return number_.size(); diff --git a/elaborate.cc b/elaborate.cc index c4024bedd..376c099d1 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5728,6 +5728,9 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const "generate " << scheme_type << " elaborating in scope " << scope_path(container) << "." << endl; + cerr << get_fileline() << ": PGenerate::elaborate: " + "generate scope_name=" << scope_name + << ", id_number=" << id_number << endl; } // Handle the special case that this is a CASE scheme. In this @@ -5762,6 +5765,7 @@ bool PGenerate::elaborate(Design*des, NetScope*container) const // scheme defined in the Verilog-2005 standard. const char*name = scope_name.str(); if (name[0] == '$') { + if (!scope->auto_name("genblk", '0', name + 4)) { cerr << get_fileline() << ": warning: Couldn't build" << " unique name for unnamed generate block" diff --git a/net_scope.cc b/net_scope.cc index 5ebd657d6..688266aff 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -264,19 +264,20 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix) assert(self != up_->children_.end()); assert(self->second == this); - char tmp[32]; - int pad_pos = strlen(prefix); - int max_pos = sizeof(tmp) - strlen(suffix) - 1; - strncpy(tmp, prefix, sizeof(tmp)); - tmp[31] = 0; + // This is to keep the pad attempts from being stuck in some + // sort of infinite loop. This should not be a practical + // limit, but an extreme one. + const size_t max_pad_attempts = 32 + strlen(prefix); + + string use_prefix = prefix; // Try a variety of potential new names. Make sure the new // name is not in the parent scope. Keep looking until we are // sure we have a unique name, or we run out of names to try. - while (pad_pos <= max_pos) { + while (use_prefix.size() <= max_pad_attempts) { // Try this name... - strcat(tmp + pad_pos, suffix); - hname_t new_name(lex_strings.make(tmp)); + string tmp = use_prefix + suffix; + hname_t new_name(lex_strings.make(tmp.c_str()), name_.peek_numbers()); if (!up_->child(new_name)) { // Ah, this name is unique. Rename myself, and // change my name in the parent scope. @@ -285,7 +286,9 @@ bool NetScope::auto_name(const char*prefix, char pad, const char* suffix) up_->children_[name_] = this; return true; } - tmp[pad_pos++] = pad; + + // Name collides, so try a different name. + use_prefix = use_prefix + pad; } return false; }