Add check for parameters used before they are declared.

This commit is contained in:
Martin Whitaker 2024-02-19 11:48:00 +00:00
parent 1c28948484
commit 76a9d38d87
5 changed files with 28 additions and 8 deletions

View File

@ -1,7 +1,7 @@
#ifndef IVL_PScope_H #ifndef IVL_PScope_H
#define IVL_PScope_H #define IVL_PScope_H
/* /*
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2008-2024 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -121,6 +121,8 @@ class LexicalScope {
bool overridable; bool overridable;
// Whether the parameter is a type parameter // Whether the parameter is a type parameter
bool type_flag = false; bool type_flag = false;
// The lexical position of the declaration
unsigned lexical_pos = 0;
SymbolType symbol_type() const; SymbolType symbol_type() const;
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch) * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
@ -280,6 +280,7 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable,
ref.local_flag = param.local_flag; ref.local_flag = param.local_flag;
ref.overridable = param.overridable; ref.overridable = param.overridable;
ref.type_flag = param.type_flag; ref.type_flag = param.type_flag;
ref.lexical_pos = param.lexical_pos;
ivl_assert(param, !ref.range); ivl_assert(param, !ref.range);
ref.range = range_list; ref.range = range_list;
ref.val = 0; ref.val = 0;
@ -449,6 +450,17 @@ LineInfo NetScope::get_parameter_line_info(perm_string key) const
return LineInfo(); return LineInfo();
} }
unsigned NetScope::get_parameter_lexical_pos(perm_string key) const
{
map<perm_string,param_expr_t>::const_iterator idx;
idx = parameters.find(key);
if (idx != parameters.end()) return idx->second.lexical_pos;
// If we get here, assume an enumeration value.
return 0;
}
void NetScope::print_type(ostream&stream) const void NetScope::print_type(ostream&stream) const
{ {
switch (type_) { switch (type_) {
@ -879,4 +891,3 @@ void NetScope::add_tie_lo(Design*des)
connect(sig->pin(0), tie_lo_->pin(0)); connect(sig->pin(0), tie_lo_->pin(0));
} }
} }

View File

@ -1243,6 +1243,8 @@ class NetScope : public Definitions, public Attrib {
bool overridable = false; bool overridable = false;
// Is it a type parameter // Is it a type parameter
bool type_flag = false; bool type_flag = false;
// The lexical position of the declaration
unsigned lexical_pos = 0;
// range constraints // range constraints
struct range_t*range; struct range_t*range;
@ -1261,6 +1263,8 @@ class NetScope : public Definitions, public Attrib {
LineInfo get_parameter_line_info(perm_string name) const; LineInfo get_parameter_line_info(perm_string name) const;
unsigned get_parameter_lexical_pos(perm_string name) const;
/* Module instance arrays are collected here for access during /* Module instance arrays are collected here for access during
the multiple elaboration passes. */ the multiple elaboration passes. */
typedef std::vector<NetScope*> scope_vec_t; typedef std::vector<NetScope*> scope_vec_t;

View File

@ -2953,6 +2953,7 @@ void pform_set_parameter(const struct vlltype&loc,
parm->local_flag = is_local; parm->local_flag = is_local;
parm->overridable = overridable; parm->overridable = overridable;
parm->type_flag = is_type; parm->type_flag = is_type;
parm->lexical_pos = loc.lexical_pos;
scope->parameters[name] = parm; scope->parameters[name] = parm;

View File

@ -184,11 +184,13 @@ 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)) {
path.push_back(path_tail); if (prefix_scope || (scope->get_parameter_lexical_pos(path_tail.name) <= lexical_pos)) {
res->scope = scope; path.push_back(path_tail);
res->par_val = par; res->scope = scope;
res->path_head = path; res->par_val = par;
return true; res->path_head = path;
return true;
}
} }
// Static items are just normal signals and are found above. // Static items are just normal signals and are found above.