Rework PEIdent::elaborate_expr() to use new-style symbol_search().
This commit is contained in:
parent
b9863b4fde
commit
e547a8355d
163
elab_expr.cc
163
elab_expr.cc
|
|
@ -4516,13 +4516,7 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
|
||||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
unsigned expr_wid, unsigned flags) const
|
unsigned expr_wid, unsigned flags) const
|
||||||
{
|
{
|
||||||
assert(scope);
|
ivl_assert(*this, scope);
|
||||||
|
|
||||||
NetNet* net = 0;
|
|
||||||
ivl_type_t cls_val = 0;
|
|
||||||
const NetExpr*par = 0;
|
|
||||||
ivl_type_t par_type = 0;
|
|
||||||
NetEvent* eve = 0;
|
|
||||||
|
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
|
|
@ -4567,53 +4561,27 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, use_scope);
|
ivl_assert(*this, use_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find the net/parameter/event object that this name refers
|
// Find the net/parameter/event object that this name refers
|
||||||
// to. The path_ may be a scoped path, and may include method
|
// to. The path_ may be a scoped path, and may include method
|
||||||
// or member name parts. For example, main.a.b.c may refer to
|
// or member name parts. For example, main.a.b.c may refer to
|
||||||
// a net called "b" in the scope "main.a" and with a member
|
// a net called "b" in the scope "main.a" and with a member
|
||||||
// named "c". This loop tries to figure that out and the
|
// named "c". symbol_search() handles this for us.
|
||||||
// result is the complete path_ split into a base_path (that
|
symbol_search_results sr;
|
||||||
// locates the object) and the member_path that selects parts
|
symbol_search(this, des, use_scope, path_, &sr);
|
||||||
// in the object.
|
|
||||||
pform_name_t base_path = path_;
|
|
||||||
pform_name_t member_path;
|
|
||||||
NetScope*found_in = 0;
|
|
||||||
while (net==0 && par==0 && eve==0 && !base_path.empty()) {
|
|
||||||
found_in = symbol_search(this, des, use_scope, base_path,
|
|
||||||
net, par, eve, par_type, cls_val);
|
|
||||||
if (net) break;
|
|
||||||
if (par) break;
|
|
||||||
if (eve) 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_elaborate) {
|
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
|
||||||
<< "Symbol search found base_path=" << base_path
|
|
||||||
<< ", member_path=" << member_path
|
|
||||||
<< ", par=" << par
|
|
||||||
<< ", net=" << net
|
|
||||||
<< ", eve=" << eve
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the identifier name is a parameter name, then return
|
// If the identifier name is a parameter name, then return
|
||||||
// the parameter value.
|
// the parameter value.
|
||||||
if (par != 0) {
|
if (sr.par_val != 0) {
|
||||||
|
|
||||||
if (!member_path.empty()) {
|
if (!sr.path_tail.empty()) {
|
||||||
cerr << get_fileline() << ": error: Paramater name " << base_path
|
cerr << get_fileline() << ": error: Parameter name "
|
||||||
<< " can't have member names (member_path=" << member_path << ")."
|
<< sr.path_head << " can't have member names ("
|
||||||
<< endl;
|
<< sr.path_tail << ")." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr*tmp = elaborate_expr_param_(des, scope, par, found_in,
|
NetExpr*tmp = elaborate_expr_param_(des, scope, sr.par_val, sr.scope,
|
||||||
par_type, expr_wid, flags);
|
sr.par_type, expr_wid, flags);
|
||||||
|
|
||||||
if (!tmp) return 0;
|
if (!tmp) return 0;
|
||||||
|
|
||||||
|
|
@ -4622,7 +4590,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
// If the identifier names a signal (a variable or a net)
|
// If the identifier names a signal (a variable or a net)
|
||||||
// then create a NetESignal node to handle it.
|
// then create a NetESignal node to handle it.
|
||||||
if (net != 0) {
|
if (sr.net != 0) {
|
||||||
if (NEED_CONST & flags) {
|
if (NEED_CONST & flags) {
|
||||||
cerr << get_fileline() << ": error: A reference to a wire "
|
cerr << get_fileline() << ": error: A reference to a wire "
|
||||||
"or reg (`" << path_ << "') is not allowed in "
|
"or reg (`" << path_ << "') is not allowed in "
|
||||||
|
|
@ -4630,7 +4598,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (net->scope()->type() == NetScope::MODULE) {
|
if (sr.net->scope()->type() == NetScope::MODULE) {
|
||||||
if (scope->need_const_func()) {
|
if (scope->need_const_func()) {
|
||||||
cerr << get_fileline() << ": error: A reference to a "
|
cerr << get_fileline() << ": error: A reference to a "
|
||||||
"non-local wire or reg (`" << path_ << "') is "
|
"non-local wire or reg (`" << path_ << "') is "
|
||||||
|
|
@ -4644,39 +4612,39 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
// If this is a struct, and there are members in the
|
// If this is a struct, and there are members in the
|
||||||
// member_path, then generate an expression that
|
// member_path, then generate an expression that
|
||||||
// reflects the member selection.
|
// reflects the member selection.
|
||||||
if (net->struct_type() && !member_path.empty()) {
|
if (sr.net->struct_type() && !sr.path_tail.empty()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
"Ident " << base_path
|
"Ident " << sr.path_head
|
||||||
<< " look for struct member " << member_path
|
<< " look for struct member " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetExpr*tmp = check_for_struct_members(this, des, use_scope,
|
NetExpr*tmp = check_for_struct_members(this, des, use_scope,
|
||||||
net, base_path.back().index,
|
sr.net, sr.path_head.back().index,
|
||||||
member_path);
|
sr.path_tail);
|
||||||
if (!tmp) return 0;
|
if (!tmp) return 0;
|
||||||
else return pad_to_width(tmp, expr_wid, signed_flag_, *this);
|
else return pad_to_width(tmp, expr_wid, signed_flag_, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an array object, and there are members in
|
// If this is an array object, and there are members in
|
||||||
// the member_path, check for array properties.
|
// the sr.path_tail, check for array properties.
|
||||||
if (net->darray_type() && !member_path.empty()) {
|
if (sr.net->darray_type() && !sr.path_tail.empty()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
"Ident " << base_path
|
"Ident " << sr.path_head
|
||||||
<< " looking for array property " << member_path
|
<< " looking for array property " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, member_path.size() == 1);
|
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||||
const name_component_t member_comp = member_path.front();
|
const name_component_t member_comp = sr.path_tail.front();
|
||||||
if (member_comp.name == "size") {
|
if (member_comp.name == "size") {
|
||||||
NetESFunc*fun = new NetESFunc("$size", IVL_VT_BOOL, 32, 1);
|
NetESFunc*fun = new NetESFunc("$size", IVL_VT_BOOL, 32, 1);
|
||||||
fun->set_line(*this);
|
fun->set_line(*this);
|
||||||
|
|
||||||
NetESignal*arg = new NetESignal(net);
|
NetESignal*arg = new NetESignal(sr.net);
|
||||||
arg->set_line(*net);
|
arg->set_line(*sr.net);
|
||||||
|
|
||||||
fun->parm(0, arg);
|
fun->parm(0, arg);
|
||||||
return fun;
|
return fun;
|
||||||
|
|
@ -4776,18 +4744,18 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a queue object, and there are members in
|
// If this is a queue object, and there are members in
|
||||||
// the member_path, check for array properties.
|
// the sr.path_tail, check for array properties.
|
||||||
if (net->queue_type() && !member_path.empty()) {
|
if (sr.net->queue_type() && !sr.path_tail.empty()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
<< "Ident " << base_path
|
<< "Ident " << sr.path_head
|
||||||
<< " looking for queue property " << member_path
|
<< " looking for queue property " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, member_path.size() == 1);
|
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||||
const name_component_t member_comp = member_path.front();
|
const name_component_t member_comp = sr.path_tail.front();
|
||||||
const netqueue_t*queue = net->queue_type();
|
const netqueue_t*queue = sr.net->queue_type();
|
||||||
ivl_variable_type_t qelem_type = queue->element_base_type();
|
ivl_variable_type_t qelem_type = queue->element_base_type();
|
||||||
unsigned qelem_width = queue->element_width();
|
unsigned qelem_width = queue->element_width();
|
||||||
if (member_comp.name == "pop_back") {
|
if (member_comp.name == "pop_back") {
|
||||||
|
|
@ -4795,8 +4763,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
qelem_type, qelem_width, 1);
|
qelem_type, qelem_width, 1);
|
||||||
fun->set_line(*this);
|
fun->set_line(*this);
|
||||||
|
|
||||||
NetESignal*arg = new NetESignal(net);
|
NetESignal*arg = new NetESignal(sr.net);
|
||||||
arg->set_line(*net);
|
arg->set_line(*sr.net);
|
||||||
|
|
||||||
fun->parm(0, arg);
|
fun->parm(0, arg);
|
||||||
return fun;
|
return fun;
|
||||||
|
|
@ -4807,24 +4775,24 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
qelem_type, qelem_width, 1);
|
qelem_type, qelem_width, 1);
|
||||||
fun->set_line(*this);
|
fun->set_line(*this);
|
||||||
|
|
||||||
NetESignal*arg = new NetESignal(net);
|
NetESignal*arg = new NetESignal(sr.net);
|
||||||
arg->set_line(*net);
|
arg->set_line(*sr.net);
|
||||||
|
|
||||||
fun->parm(0, arg);
|
fun->parm(0, arg);
|
||||||
return fun;
|
return fun;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((net->data_type() == IVL_VT_STRING) && !member_path.empty()) {
|
if ((sr.net->data_type() == IVL_VT_STRING) && !sr.path_tail.empty()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
"Ident " << base_path
|
"Ident " << sr.path_head
|
||||||
<< " looking for string property " << member_path
|
<< " looking for string property " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, member_path.size() == 1);
|
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||||
const name_component_t member_comp = member_path.front();
|
const name_component_t member_comp = sr.path_tail.front();
|
||||||
cerr << get_fileline() << ": sorry: String method '"
|
cerr << get_fileline() << ": sorry: String method '"
|
||||||
<< member_comp.name << "' currently requires ()."
|
<< member_comp.name << "' currently requires ()."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
@ -4832,41 +4800,42 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net->class_type() && !member_path.empty()) {
|
if (sr.net->class_type() && !sr.path_tail.empty()) {
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
"Ident " << base_path
|
"Ident " << sr.path_head
|
||||||
<< " look for class property " << member_path
|
<< " look for class property " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, member_path.size() == 1);
|
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||||
const name_component_t member_comp = member_path.front();
|
const name_component_t member_comp = sr.path_tail.front();
|
||||||
return check_for_class_property(this, des, use_scope,
|
return check_for_class_property(this, des, use_scope,
|
||||||
net, member_comp);
|
sr.net, member_comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net->enumeration() && !member_path.empty()) {
|
if (sr.net->enumeration() && !sr.path_tail.empty()) {
|
||||||
const netenum_t*netenum = net->enumeration();
|
const netenum_t*netenum = sr.net->enumeration();
|
||||||
if (debug_elaborate) {
|
if (debug_elaborate) {
|
||||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||||
"Ident " << base_path
|
"Ident " << sr.path_head
|
||||||
<< " look for enumeration method " << member_path
|
<< " look for enumeration method " << sr.path_tail
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetESignal*expr = new NetESignal(net);
|
NetESignal*expr = new NetESignal(sr.net);
|
||||||
expr->set_line(*this);
|
expr->set_line(*this);
|
||||||
ivl_assert(*this, member_path.size() == 1);
|
ivl_assert(*this, sr.path_tail.size() == 1);
|
||||||
const name_component_t member_comp = member_path.front();
|
const name_component_t member_comp = sr.path_tail.front();
|
||||||
ivl_assert(*this, member_comp.index.empty());
|
ivl_assert(*this, member_comp.index.empty());
|
||||||
return check_for_enum_methods(this, des, use_scope,
|
return check_for_enum_methods(this, des, use_scope,
|
||||||
netenum, base_path, member_comp.name,
|
netenum, sr.path_head,
|
||||||
|
member_comp.name,
|
||||||
expr, expr_wid, NULL, 0);
|
expr, expr_wid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_assert(*this, member_path.empty());
|
ivl_assert(*this, sr.path_tail.empty());
|
||||||
NetExpr*tmp = elaborate_expr_net(des, scope, net, found_in,
|
NetExpr*tmp = elaborate_expr_net(des, scope, sr.net, sr.scope,
|
||||||
expr_wid, flags);
|
expr_wid, flags);
|
||||||
|
|
||||||
if (!tmp) return 0;
|
if (!tmp) return 0;
|
||||||
|
|
@ -4883,7 +4852,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
// If the identifier is a named event
|
// If the identifier is a named event
|
||||||
// then create a NetEEvent node to handle it.
|
// then create a NetEEvent node to handle it.
|
||||||
if (eve != 0) {
|
if (sr.eve != 0) {
|
||||||
if (NEED_CONST & flags) {
|
if (NEED_CONST & flags) {
|
||||||
cerr << get_fileline() << ": error: A reference to a named "
|
cerr << get_fileline() << ": error: A reference to a named "
|
||||||
"event (`" << path_ << "') is not allowed in a "
|
"event (`" << path_ << "') is not allowed in a "
|
||||||
|
|
@ -4891,7 +4860,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (eve->scope() != scope) {
|
if (sr.eve->scope() != scope) {
|
||||||
if (scope->need_const_func()) {
|
if (scope->need_const_func()) {
|
||||||
cerr << get_fileline() << ": error: A reference to a "
|
cerr << get_fileline() << ": error: A reference to a "
|
||||||
"non-local named event (`" << path_ << "') is "
|
"non-local named event (`" << path_ << "') is "
|
||||||
|
|
@ -4902,14 +4871,14 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
scope->is_const_func(false);
|
scope->is_const_func(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!member_path.empty()) {
|
if (!sr.path_tail.empty()) {
|
||||||
cerr << get_fileline() << ": error: Event name " << base_path
|
cerr << get_fileline() << ": error: Event name "
|
||||||
<< " can't have member names (member_path=" << member_path << ")"
|
<< sr.path_head << " can't have member names ("
|
||||||
<< endl;
|
<< sr.path_tail << ")" << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEEvent*tmp = new NetEEvent(eve);
|
NetEEvent*tmp = new NetEEvent(sr.eve);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue