diff --git a/elab_scope.cc b/elab_scope.cc index 9f640de5a..f9bb9bde7 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -355,7 +355,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, } rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value); - rc_flag &= scope->add_enumeration_name(use_enum, cur->name); + rc_flag &= scope->add_enumeration_name(use_enum, cur->name, *cur); if (! rc_flag) { cerr << use_enum->get_fileline() diff --git a/net_scope.cc b/net_scope.cc index ef8ee794a..607c51a8d 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -52,15 +52,17 @@ void Definitions::add_enumeration_set(const enum_type_t*key, netenum_t*enum_set) tmp = enum_set; } -bool Definitions::add_enumeration_name(const netenum_t*enum_set, perm_string name) +bool Definitions::add_enumeration_name(const netenum_t *enum_set, + perm_string name, + const LineInfo &location) { - netenum_t::iterator enum_val = enum_set->find_name(name); + auto enum_val = enum_set->find_name(name); assert(enum_val != enum_set->end_name()); - NetEConstEnum*val = new NetEConstEnum(name, enum_set, enum_val->second); + auto val = new NetEConstEnum(name, enum_set, enum_val->second); + val->set_line(location); - pair::iterator, bool> cur; - cur = enum_names_.insert(make_pair(name,val)); + auto cur = enum_names_.insert(make_pair(name, val)); // Return TRUE if the name is added (i.e. is NOT a duplicate.) return cur.second; @@ -466,23 +468,37 @@ LineInfo NetScope::get_parameter_line_info(perm_string key) const return LineInfo(); } -unsigned NetScope::get_parameter_lexical_pos(perm_string key) const +unsigned int NetScope::get_constant_lexical_pos(perm_string key, + bool &is_enum_name) const { map::const_iterator idx; idx = parameters.find(key); - if (idx != parameters.end()) return idx->second.lexical_pos; + if (idx != parameters.end()) { + is_enum_name = false; + return idx->second.lexical_pos; + } - // If we get here, assume an enumeration value. - return 0; + auto enum_idx = enum_names_.find(key); + assert(enum_idx != enum_names_.end()); + is_enum_name = true; + return enum_idx->second->lexical_pos(); } -void NetScope::set_parameter_lexical_pos(perm_string key, unsigned lexical_pos) +void NetScope::set_constant_lexical_pos(perm_string key, + unsigned int lexical_pos) { map::iterator idx; idx = parameters.find(key); - if (idx != parameters.end()) idx->second.lexical_pos = lexical_pos; + if (idx != parameters.end()) { + idx->second.lexical_pos = lexical_pos; + return; + } + + auto enum_idx = enum_names_.find(key); + assert(enum_idx != enum_names_.end()); + enum_idx->second->lexical_pos(lexical_pos); } void NetScope::print_type(ostream&stream) const diff --git a/netlist.h b/netlist.h index ba1d3936a..f64a97246 100644 --- a/netlist.h +++ b/netlist.h @@ -945,7 +945,9 @@ class Definitions { // up this enumeration based on the pform type. void add_enumeration_set(const enum_type_t*key, netenum_t*enum_set); - bool add_enumeration_name(const netenum_t*enum_set, perm_string enum_name); + bool add_enumeration_name(const netenum_t *enum_set, + perm_string enum_name, + const LineInfo &location); // Look up the enumeration set that was added with the given // key. This is used by enum_type_t::elaborate_type to locate @@ -1335,8 +1337,10 @@ class NetScope : public Definitions, public Attrib { LineInfo get_parameter_line_info(perm_string name) const; - unsigned get_parameter_lexical_pos(perm_string name) const; - void set_parameter_lexical_pos(perm_string name, unsigned lexical_pos); + unsigned int get_constant_lexical_pos(perm_string name, + bool &is_enum_name) const; + void set_constant_lexical_pos(perm_string name, + unsigned int lexical_pos); /* Module instance arrays are collected here for access during the multiple elaboration passes. */ diff --git a/symbol_search.cc b/symbol_search.cc index fc82cea9b..3baf8d118 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -237,22 +237,30 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, } } - if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->type)) { + if (const NetExpr *par = scope->get_parameter(des, path_tail.name, res->type)) { + bool is_enum_name; + unsigned int declaration_pos = + scope->get_constant_lexical_pos(path_tail.name, + is_enum_name); bool decl_after_use = !scope_is_bound - && !(scope->get_parameter_lexical_pos(path_tail.name) <= lexical_pos); + && !(declaration_pos <= lexical_pos); if (!gn_strict_parameter_declaration || !decl_after_use) { path.push_back(path_tail); res->scope = scope; res->par_val = par; res->path_head = path; if (warn_decl_after_use && decl_after_use) { + const char *kind = is_enum_name + ? "enum named constant" : "parameter"; cerr << li->get_fileline() - << ": warning: parameter `" << path_tail.name + << ": warning: " << kind << " `" + << path_tail.name << "` used before declaration." << endl; cerr << par->get_fileline() - << ": : the parameter is declared here." << endl; - // suppress further warnings for this parameter - scope->set_parameter_lexical_pos(path_tail.name, lexical_pos); + << ": : the " << kind + << " is declared here." << endl; + // suppress further warnings for this constant + scope->set_constant_lexical_pos(path_tail.name, lexical_pos); } return true; } else if (!res->decl_after_use) {