Track whether a parameter is overridable
Parameters declared in certain scopes behave like local parameters and can not be overridden. Rather than making those parameters a localparam track whether a parameter can be overridden. This allows to generate better error messages when trying to override the parameter. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
1207e908b1
commit
9f5ad34e35
4
PScope.h
4
PScope.h
|
|
@ -101,7 +101,7 @@ class LexicalScope {
|
||||||
this map. */
|
this map. */
|
||||||
struct param_expr_t : public PNamedItem {
|
struct param_expr_t : public PNamedItem {
|
||||||
inline param_expr_t() : data_type(0), expr(0), range(0),
|
inline param_expr_t() : data_type(0), expr(0), range(0),
|
||||||
local_flag(false) { }
|
local_flag(false), overridable(true) { }
|
||||||
// Type information.
|
// Type information.
|
||||||
data_type_t*data_type;
|
data_type_t*data_type;
|
||||||
// Value expression
|
// Value expression
|
||||||
|
|
@ -110,6 +110,8 @@ class LexicalScope {
|
||||||
range_t*range;
|
range_t*range;
|
||||||
// Whether it is a local parameter
|
// Whether it is a local parameter
|
||||||
bool local_flag;
|
bool local_flag;
|
||||||
|
// Whether the parameter can be overridden
|
||||||
|
bool overridable;
|
||||||
|
|
||||||
SymbolType symbol_type() const;
|
SymbolType symbol_type() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ static void collect_parm_item(Design*des, NetScope*scope, perm_string name,
|
||||||
// don't try to elaborate it here, because there may be references to
|
// don't try to elaborate it here, because there may be references to
|
||||||
// other parameters still being located during scope elaboration.
|
// other parameters still being located during scope elaboration.
|
||||||
scope->set_parameter(name, is_annotatable, cur.expr, cur.data_type,
|
scope->set_parameter(name, is_annotatable, cur.expr, cur.data_type,
|
||||||
cur.local_flag, range_list, cur);
|
cur.local_flag, cur.overridable, range_list, cur);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
net_scope.cc
12
net_scope.cc
|
|
@ -305,7 +305,7 @@ const netenum_t*NetScope::find_enumeration_for_name(const Design*des, perm_strin
|
||||||
*/
|
*/
|
||||||
void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
||||||
PExpr*val, data_type_t*val_type,
|
PExpr*val, data_type_t*val_type,
|
||||||
bool local_flag,
|
bool local_flag, bool overridable,
|
||||||
NetScope::range_t*range_list,
|
NetScope::range_t*range_list,
|
||||||
const LineInfo&file_line)
|
const LineInfo&file_line)
|
||||||
{
|
{
|
||||||
|
|
@ -315,6 +315,7 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable,
|
||||||
ref.val_type = val_type;
|
ref.val_type = val_type;
|
||||||
ref.val_scope = this;
|
ref.val_scope = this;
|
||||||
ref.local_flag = local_flag;
|
ref.local_flag = local_flag;
|
||||||
|
ref.overridable = overridable;
|
||||||
ivl_assert(file_line, ref.range == 0);
|
ivl_assert(file_line, ref.range == 0);
|
||||||
ref.range = range_list;
|
ref.range = range_list;
|
||||||
ref.val = 0;
|
ref.val = 0;
|
||||||
|
|
@ -400,6 +401,15 @@ void NetScope::replace_parameter(Design *des, perm_string key, PExpr*val, NetSco
|
||||||
des->errors++;
|
des->errors++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!ref.overridable) {
|
||||||
|
cerr << val->get_fileline() << ": error: "
|
||||||
|
<< "Cannot override parameter `" << key << "` in `"
|
||||||
|
<< scope_path(this) << "`. Parameter cannot be overriden "
|
||||||
|
<< "in the scope it has been declared in."
|
||||||
|
<< endl;
|
||||||
|
des->errors++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ref.val_expr = val;
|
ref.val_expr = val;
|
||||||
ref.val_scope = scope;
|
ref.val_scope = scope;
|
||||||
|
|
|
||||||
|
|
@ -968,7 +968,7 @@ class NetScope : public Definitions, public Attrib {
|
||||||
struct range_t;
|
struct range_t;
|
||||||
void set_parameter(perm_string name, bool is_annotatable,
|
void set_parameter(perm_string name, bool is_annotatable,
|
||||||
PExpr*val, data_type_t*data_type,
|
PExpr*val, data_type_t*data_type,
|
||||||
bool local_flag,
|
bool local_flag, bool overridable,
|
||||||
NetScope::range_t*range_list,
|
NetScope::range_t*range_list,
|
||||||
const LineInfo&file_line);
|
const LineInfo&file_line);
|
||||||
void set_parameter(perm_string name, NetExpr*val,
|
void set_parameter(perm_string name, NetExpr*val,
|
||||||
|
|
@ -1227,6 +1227,8 @@ class NetScope : public Definitions, public Attrib {
|
||||||
bool is_annotatable;
|
bool is_annotatable;
|
||||||
// Is this a localparam?
|
// Is this a localparam?
|
||||||
bool local_flag;
|
bool local_flag;
|
||||||
|
// Can it be overriden?
|
||||||
|
bool overridable;
|
||||||
// range constraints
|
// range constraints
|
||||||
struct range_t*range;
|
struct range_t*range;
|
||||||
// Expression value and type (elaborated versoins of val_expr/val_type)
|
// Expression value and type (elaborated versoins of val_expr/val_type)
|
||||||
|
|
|
||||||
6
pform.cc
6
pform.cc
|
|
@ -3232,6 +3232,9 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
is_local ? "localparam" : "parameter");
|
is_local ? "localparam" : "parameter");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool overridable = !is_local;
|
||||||
|
|
||||||
if (scope == pform_cur_generate && !is_local) {
|
if (scope == pform_cur_generate && !is_local) {
|
||||||
VLerror("parameter declarations are not permitted in generate blocks");
|
VLerror("parameter declarations are not permitted in generate blocks");
|
||||||
return;
|
return;
|
||||||
|
|
@ -3247,11 +3250,12 @@ void pform_set_parameter(const struct vlltype&loc,
|
||||||
parm->data_type = data_type;
|
parm->data_type = data_type;
|
||||||
parm->range = value_range;
|
parm->range = value_range;
|
||||||
parm->local_flag = is_local;
|
parm->local_flag = is_local;
|
||||||
|
parm->overridable = overridable;
|
||||||
|
|
||||||
scope->parameters[name] = parm;
|
scope->parameters[name] = parm;
|
||||||
|
|
||||||
// Only a module keeps the position of the parameter.
|
// Only a module keeps the position of the parameter.
|
||||||
if (!is_local &&
|
if (overridable &&
|
||||||
(dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front()))
|
(dynamic_cast<Module*>(scope)) && (scope == pform_cur_module.front()))
|
||||||
pform_cur_module.front()->param_names.push_back(name);
|
pform_cur_module.front()->param_names.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue