PEIdent::elaborate_{expr,lval}(): Use new symbol_search()

The PEIdent elaborate_expr() and elaborate_lval() are sort of open-coding
the path traversal implemented by the new symbol_search() using the old
symbol_search().

Switch them over to use the new symbol search as it is better at handling
the corner cases and is also less code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-12-24 07:56:33 -08:00
parent cc2ba4f8cb
commit 862b118098
2 changed files with 29 additions and 57 deletions

View File

@ -4322,12 +4322,6 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
{ {
bool need_const = NEED_CONST & flags; bool need_const = NEED_CONST & flags;
NetNet* net = 0;
ivl_type_t cls_val = 0;
const NetExpr*par = 0;
ivl_type_t par_type = 0;
NetEvent* eve = 0;
NetScope*use_scope = scope; NetScope*use_scope = scope;
if (package_) { if (package_) {
use_scope = des->find_package(package_->pscope_name()); use_scope = des->find_package(package_->pscope_name());
@ -4338,50 +4332,44 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
return tmp; return tmp;
} }
symbol_search(this, des, use_scope, path_, net, par, eve, par_type, cls_val); symbol_search_results sr;
symbol_search(this, des, use_scope, path_, &sr);
if (net == 0 && gn_system_verilog() && path_.size() >= 2) { if (!sr.net) {
// NOTE: this is assuming the member_path is only one cerr << get_fileline() << ": error: Unable to bind variable `"
// component long, and that the use_path will wind up << path_ << "' in `" << scope_path(use_scope) << "'" << endl;
// being the path to the variable. This is not des->errors++;
// necessarily true. Should fix this. return nullptr;
pform_name_t use_path = path_; }
name_component_t member_comp = use_path.back();
use_path.pop_back();
ivl_assert(*this, net == 0); NetNet *net = sr.net;
symbol_search(this, des, use_scope, use_path, net, par, eve,
par_type, cls_val);
if (net == 0) { if (!sr.path_tail.empty()) {
// Nope, no struct/class with member. if (net->struct_type()) {
return check_for_struct_members(this, des, use_scope, net,
sr.path_head.back().index,
sr.path_tail);
} else if (net->class_type()) {
const name_component_t member_comp = sr.path_tail.front();
} else if (net->struct_type() != 0) {
pform_name_t member_path;
member_path.push_back( member_comp );
return check_for_struct_members(this, des, use_scope,
net, use_path.back().index,
member_path);
} else if (net->class_type()!=0) {
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: " cerr << get_fileline() << ": PEIdent::elaborate_expr: "
<< "Ident " << use_path << "Ident " << sr.path_head
<< " look for property " << member_comp << endl; << " look for property " << member_comp << endl;
} }
if (sr.path_tail.size() > 1) {
cerr << get_fileline() << ": sorry: "
<< "Nested member path not yet supported in this context."
<< endl;
return nullptr;
}
return elaborate_expr_class_field_(des, scope, net, return elaborate_expr_class_field_(des, scope, net,
member_comp, 0, flags); member_comp, 0, flags);
} }
} }
if (net == 0) {
cerr << get_fileline() << ": error: Unable to bind variable `"
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
des->errors += 1;
return 0;
}
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: " cerr << get_fileline() << ": PEIdent::elaborate_expr: "
<< "Found net " << net->name() << " for expr " << *this << endl; << "Found net " << net->name() << " for expr " << *this << endl;

View File

@ -159,9 +159,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
bool is_cassign, bool is_cassign,
bool is_force) const bool is_force) const
{ {
NetNet* reg = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
if (debug_elaborate) { if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval: " cerr << get_fileline() << ": PEIdent::elaborate_lval: "
@ -182,25 +179,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
ivl_assert(*this, use_scope); ivl_assert(*this, use_scope);
} }
/* Try to find the base part of the path that names the symbol_search_results sr;
variable. The remainer is the member path. For example, if symbol_search(this, des, use_scope, path_, &sr);
the path is a.b.c.d, and a.b is the path to a variable,
then a.b becomes the base_path and c.d becomes the
member_path. If we cannot find the variable with any
prefix, then the base_path will be empty after this loop
and reg will remain nil. */
pform_name_t base_path = path_;
pform_name_t member_path;
while (reg == 0 && !base_path.empty()) {
symbol_search(this, des, use_scope, base_path, reg, par, eve);
// Found it!
if (reg != 0) break;
// Not found. Try to pop another name off the base_path
// and push it to the front of the member_path.
member_path.push_front( base_path.back() );
base_path.pop_back();
}
NetNet *reg = sr.net;
pform_name_t &base_path = sr.path_head;
pform_name_t &member_path = sr.path_tail;
/* The l-value must be a variable. If not, then give up and /* The l-value must be a variable. If not, then give up and
print a useful error message. */ print a useful error message. */