Fix file/line reported for duplicate parameter declarations.

We need to retain the old parameter information until we have reported
the error.
This commit is contained in:
Martin Whitaker 2019-09-27 00:29:46 +01:00
parent d3bced57cc
commit 628f5645bf
5 changed files with 74 additions and 71 deletions

View File

@ -97,7 +97,7 @@ class Module : public PScopeExtra, public PNamedItem {
/* specparams are simpler than other parameters, in that they /* specparams are simpler than other parameters, in that they
can have a range, but not an explicit type. The restrictions can have a range, but not an explicit type. The restrictions
are enforced by the parser. */ are enforced by the parser. */
map<perm_string,param_expr_t>specparams; map<perm_string,param_expr_t*>specparams;
/* The module also has defparam assignments which don't create /* The module also has defparam assignments which don't create
new parameters within the module, but may be used to set new parameters within the module, but may be used to set

View File

@ -105,8 +105,8 @@ class LexicalScope {
SymbolType symbol_type() const; SymbolType symbol_type() const;
}; };
map<perm_string,param_expr_t>parameters; map<perm_string,param_expr_t*>parameters;
map<perm_string,param_expr_t>localparams; map<perm_string,param_expr_t*>localparams;
// Defined types in the scope. // Defined types in the scope.
map<perm_string,data_type_t*>typedefs; map<perm_string,data_type_t*>typedefs;

View File

@ -63,7 +63,7 @@ void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
des->set_precision(pscope->time_precision); des->set_precision(pscope->time_precision);
} }
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t; typedef map<perm_string,LexicalScope::param_expr_t*>::const_iterator mparm_it_t;
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name, static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
const LexicalScope::param_expr_t&cur, const LexicalScope::param_expr_t&cur,
@ -110,59 +110,59 @@ static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
} }
static void collect_scope_parameters_(Design*des, NetScope*scope, static void collect_scope_parameters_(Design*des, NetScope*scope,
const map<perm_string,LexicalScope::param_expr_t>&parameters) const map<perm_string,LexicalScope::param_expr_t*>&parameters)
{ {
for (mparm_it_t cur = parameters.begin() for (mparm_it_t cur = parameters.begin()
; cur != parameters.end() ; ++ cur ) { ; cur != parameters.end() ; ++ cur ) {
// A parameter can not have the same name as a genvar. // A parameter can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) { if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline() cerr << cur->second->get_fileline()
<< ": error: parameter and genvar in '" << ": error: parameter and genvar in '"
<< scope->fullname() << "' have the same name '" << scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl; << (*cur).first << "'." << endl;
des->errors += 1; des->errors += 1;
} }
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, false); collect_parm_item_(des, scope, cur->first, *(cur->second), false, false);
} }
} }
static void collect_scope_localparams_(Design*des, NetScope*scope, static void collect_scope_localparams_(Design*des, NetScope*scope,
const map<perm_string,LexicalScope::param_expr_t>&localparams) const map<perm_string,LexicalScope::param_expr_t*>&localparams)
{ {
for (mparm_it_t cur = localparams.begin() for (mparm_it_t cur = localparams.begin()
; cur != localparams.end() ; ++ cur ) { ; cur != localparams.end() ; ++ cur ) {
// A localparam can not have the same name as a genvar. // A localparam can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) { if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline() cerr << cur->second->get_fileline()
<< ": error: localparam and genvar in '" << ": error: localparam and genvar in '"
<< scope->fullname() << "' have the same name '" << scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl; << (*cur).first << "'." << endl;
des->errors += 1; des->errors += 1;
} }
collect_parm_item_(des, scope, (*cur).first, (*cur).second, false, true); collect_parm_item_(des, scope, cur->first, *(cur->second), false, true);
} }
} }
static void collect_scope_specparams_(Design*des, NetScope*scope, static void collect_scope_specparams_(Design*des, NetScope*scope,
const map<perm_string,LexicalScope::param_expr_t>&specparams) const map<perm_string,LexicalScope::param_expr_t*>&specparams)
{ {
for (mparm_it_t cur = specparams.begin() for (mparm_it_t cur = specparams.begin()
; cur != specparams.end() ; ++ cur ) { ; cur != specparams.end() ; ++ cur ) {
// A specparam can not have the same name as a genvar. // A specparam can not have the same name as a genvar.
if (scope->find_genvar((*cur).first)) { if (scope->find_genvar((*cur).first)) {
cerr << cur->second.get_fileline() cerr << cur->second->get_fileline()
<< ": error: specparam and genvar in '" << ": error: specparam and genvar in '"
<< scope->fullname() << "' have the same name '" << scope->fullname() << "' have the same name '"
<< (*cur).first << "'." << endl; << (*cur).first << "'." << endl;
des->errors += 1; des->errors += 1;
} }
collect_parm_item_(des, scope, (*cur).first, (*cur).second, true, false); collect_parm_item_(des, scope, cur->first, *(cur->second), true, false);
} }
} }

View File

@ -3059,27 +3059,28 @@ void pform_set_parameter(const struct vlltype&loc,
} }
assert(expr); assert(expr);
Module::param_expr_t&parm = scope->parameters[name]; Module::param_expr_t*parm = new Module::param_expr_t();
FILE_NAME(&parm, loc); FILE_NAME(parm, loc);
parm.expr = expr; add_local_symbol(scope, name, parm);
scope->parameters[name] = parm;
parm.type = type; parm->expr = expr;
parm->type = type;
if (range) { if (range) {
assert(range->size() == 1); assert(range->size() == 1);
pform_range_t&rng = range->front(); pform_range_t&rng = range->front();
assert(rng.first); assert(rng.first);
assert(rng.second); assert(rng.second);
parm.msb = rng.first; parm->msb = rng.first;
parm.lsb = rng.second; parm->lsb = rng.second;
} else { } else {
parm.msb = 0; parm->msb = 0;
parm.lsb = 0; parm->lsb = 0;
} }
parm.signed_flag = signed_flag; parm->signed_flag = signed_flag;
parm.range = value_range; parm->range = value_range;
add_local_symbol(scope, name, &parm);
// Only a Module keeps the position of the parameter. // Only a Module keeps the position of the parameter.
if ((dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front())) if ((dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front()))
@ -3097,27 +3098,28 @@ void pform_set_localparam(const struct vlltype&loc,
} }
assert(expr); assert(expr);
Module::param_expr_t&parm = scope->localparams[name]; Module::param_expr_t*parm = new Module::param_expr_t();
FILE_NAME(&parm, loc); FILE_NAME(parm, loc);
parm.expr = expr; add_local_symbol(scope, name, parm);
scope->localparams[name] = parm;
parm.type = type; parm->expr = expr;
parm->type = type;
if (range) { if (range) {
assert(range->size() == 1); assert(range->size() == 1);
pform_range_t&rng = range->front(); pform_range_t&rng = range->front();
assert(rng.first); assert(rng.first);
assert(rng.second); assert(rng.second);
parm.msb = rng.first; parm->msb = rng.first;
parm.lsb = rng.second; parm->lsb = rng.second;
} else { } else {
parm.msb = 0; parm->msb = 0;
parm.lsb = 0; parm->lsb = 0;
} }
parm.signed_flag = signed_flag; parm->signed_flag = signed_flag;
parm.range = 0; parm->range = 0;
add_local_symbol(scope, name, &parm);
} }
void pform_set_specparam(const struct vlltype&loc, perm_string name, void pform_set_specparam(const struct vlltype&loc, perm_string name,
@ -3128,28 +3130,29 @@ void pform_set_specparam(const struct vlltype&loc, perm_string name,
assert(scope == lexical_scope); assert(scope == lexical_scope);
assert(expr); assert(expr);
Module::param_expr_t&parm = pform_cur_module.front()->specparams[name]; Module::param_expr_t*parm = new Module::param_expr_t();
FILE_NAME(&parm, loc); FILE_NAME(parm, loc);
parm.expr = expr; add_local_symbol(scope, name, parm);
pform_cur_module.front()->specparams[name] = parm;
parm->expr = expr;
if (range) { if (range) {
assert(range->size() == 1); assert(range->size() == 1);
pform_range_t&rng = range->front(); pform_range_t&rng = range->front();
assert(rng.first); assert(rng.first);
assert(rng.second); assert(rng.second);
parm.type = IVL_VT_LOGIC; parm->type = IVL_VT_LOGIC;
parm.msb = rng.first; parm->msb = rng.first;
parm.lsb = rng.second; parm->lsb = rng.second;
} else { } else {
parm.type = IVL_VT_NO_TYPE; parm->type = IVL_VT_NO_TYPE;
parm.msb = 0; parm->msb = 0;
parm.lsb = 0; parm->lsb = 0;
} }
parm.signed_flag = false; parm->signed_flag = false;
parm.range = 0; parm->range = 0;
add_local_symbol(scope, name, &parm);
} }
void pform_set_defparam(const pform_name_t&name, PExpr*expr) void pform_set_defparam(const pform_name_t&name, PExpr*expr)

View File

@ -1359,22 +1359,22 @@ void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
{ {
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t; typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
for (parm_iter_t cur = parameters.begin() for (parm_iter_t cur = parameters.begin()
; cur != parameters.end() ; ++ cur ) { ; cur != parameters.end() ; ++ cur ) {
out << setw(indent) << "" << "parameter " out << setw(indent) << "" << "parameter "
<< (*cur).second.type << " "; << (*cur).second->type << " ";
if ((*cur).second.signed_flag) if ((*cur).second->signed_flag)
out << "signed "; out << "signed ";
if ((*cur).second.msb) if ((*cur).second->msb)
out << "[" << *(*cur).second.msb << ":" out << "[" << *(*cur).second->msb << ":"
<< *(*cur).second.lsb << "] "; << *(*cur).second->lsb << "] ";
out << (*cur).first << " = "; out << (*cur).first << " = ";
if ((*cur).second.expr) if ((*cur).second->expr)
out << *(*cur).second.expr; out << *(*cur).second->expr;
else else
out << "/* ERROR */"; out << "/* ERROR */";
for (LexicalScope::range_t*tmp = (*cur).second.range for (LexicalScope::range_t*tmp = (*cur).second->range
; tmp ; tmp = tmp->next) { ; tmp ; tmp = tmp->next) {
if (tmp->exclude_flag) if (tmp->exclude_flag)
out << " exclude "; out << " exclude ";
@ -1408,16 +1408,16 @@ void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const
void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
{ {
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t; typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
for (parm_iter_t cur = localparams.begin() for (parm_iter_t cur = localparams.begin()
; cur != localparams.end() ; ++ cur ) { ; cur != localparams.end() ; ++ cur ) {
out << setw(indent) << "" << "localparam "; out << setw(indent) << "" << "localparam ";
if ((*cur).second.msb) if ((*cur).second->msb)
out << "[" << *(*cur).second.msb << ":" out << "[" << *(*cur).second->msb << ":"
<< *(*cur).second.lsb << "] "; << *(*cur).second->lsb << "] ";
out << (*cur).first << " = "; out << (*cur).first << " = ";
if ((*cur).second.expr) if ((*cur).second->expr)
out << *(*cur).second.expr << ";" << endl; out << *(*cur).second->expr << ";" << endl;
else else
out << "/* ERROR */;" << endl; out << "/* ERROR */;" << endl;
} }
@ -1513,16 +1513,16 @@ void PClass::dump(ostream&out, unsigned indent) const
void Module::dump_specparams_(ostream&out, unsigned indent) const void Module::dump_specparams_(ostream&out, unsigned indent) const
{ {
typedef map<perm_string,param_expr_t>::const_iterator parm_iter_t; typedef map<perm_string,param_expr_t*>::const_iterator parm_iter_t;
for (parm_iter_t cur = specparams.begin() for (parm_iter_t cur = specparams.begin()
; cur != specparams.end() ; ++ cur ) { ; cur != specparams.end() ; ++ cur ) {
out << setw(indent) << "" << "specparam "; out << setw(indent) << "" << "specparam ";
if ((*cur).second.msb) if ((*cur).second->msb)
out << "[" << *(*cur).second.msb << ":" out << "[" << *(*cur).second->msb << ":"
<< *(*cur).second.lsb << "] "; << *(*cur).second->lsb << "] ";
out << (*cur).first << " = "; out << (*cur).first << " = ";
if ((*cur).second.expr) if ((*cur).second->expr)
out << *(*cur).second.expr << ";" << endl; out << *(*cur).second->expr << ";" << endl;
else else
out << "/* ERROR */;" << endl; out << "/* ERROR */;" << endl;
} }