From 76a9d38d87fcc039f58d6eabcdc657e1b9186649 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 19 Feb 2024 11:48:00 +0000 Subject: [PATCH] Add check for parameters used before they are declared. --- PScope.h | 4 +++- net_scope.cc | 15 +++++++++++++-- netlist.h | 4 ++++ pform.cc | 1 + symbol_search.cc | 12 +++++++----- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/PScope.h b/PScope.h index 9fd41a461..03bc4f2e3 100644 --- a/PScope.h +++ b/PScope.h @@ -1,7 +1,7 @@ #ifndef 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 * and/or modify it in source code form under the terms of the GNU @@ -121,6 +121,8 @@ class LexicalScope { bool overridable; // Whether the parameter is a type parameter bool type_flag = false; + // The lexical position of the declaration + unsigned lexical_pos = 0; SymbolType symbol_type() const; }; diff --git a/net_scope.cc b/net_scope.cc index 9fac014e8..76d29c601 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -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) * * 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.overridable = param.overridable; ref.type_flag = param.type_flag; + ref.lexical_pos = param.lexical_pos; ivl_assert(param, !ref.range); ref.range = range_list; ref.val = 0; @@ -449,6 +450,17 @@ LineInfo NetScope::get_parameter_line_info(perm_string key) const return LineInfo(); } +unsigned NetScope::get_parameter_lexical_pos(perm_string key) const +{ + map::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 { switch (type_) { @@ -879,4 +891,3 @@ void NetScope::add_tie_lo(Design*des) connect(sig->pin(0), tie_lo_->pin(0)); } } - diff --git a/netlist.h b/netlist.h index 79e158baa..d2a039e44 100644 --- a/netlist.h +++ b/netlist.h @@ -1243,6 +1243,8 @@ class NetScope : public Definitions, public Attrib { bool overridable = false; // Is it a type parameter bool type_flag = false; + // The lexical position of the declaration + unsigned lexical_pos = 0; // range constraints struct range_t*range; @@ -1261,6 +1263,8 @@ class NetScope : public Definitions, public Attrib { 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 the multiple elaboration passes. */ typedef std::vector scope_vec_t; diff --git a/pform.cc b/pform.cc index d57d0ed01..99714f3af 100644 --- a/pform.cc +++ b/pform.cc @@ -2953,6 +2953,7 @@ void pform_set_parameter(const struct vlltype&loc, parm->local_flag = is_local; parm->overridable = overridable; parm->type_flag = is_type; + parm->lexical_pos = loc.lexical_pos; scope->parameters[name] = parm; diff --git a/symbol_search.cc b/symbol_search.cc index 704a03d8e..5db3405a6 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -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)) { - path.push_back(path_tail); - res->scope = scope; - res->par_val = par; - res->path_head = path; - return true; + if (prefix_scope || (scope->get_parameter_lexical_pos(path_tail.name) <= lexical_pos)) { + path.push_back(path_tail); + res->scope = scope; + res->par_val = par; + res->path_head = path; + return true; + } } // Static items are just normal signals and are found above.