Merge pull request #829 from larsclausen/class-super

Add support for handling `super` keyword
This commit is contained in:
Stephen Williams 2022-12-26 08:33:56 -08:00 committed by GitHub
commit 5347ba19cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 254 additions and 160 deletions

View File

@ -417,6 +417,7 @@ class PEIdent : public PExpr {
index_component_t::ctype_t,
bool need_const_idx) const;
NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
const netclass_t *class_type,
NetNet*,
pform_name_t) const;
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
@ -511,8 +512,7 @@ class PEIdent : public PExpr {
unsigned flags) const;
NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope,
NetNet*net,
const name_component_t&comp,
const symbol_search_results &sr,
unsigned expr_wid,
unsigned flags) const;

View File

@ -1480,8 +1480,7 @@ unsigned PECallFunction::test_width_method_(Design*, NetScope*,
// and the scope is the scope where the instance lives. The class method
// in turn defines it's own scope. Use that to find the return value.
if (search_results.net && search_results.net->data_type()==IVL_VT_CLASS) {
NetNet*net = search_results.net;
const netclass_t*class_type = net->class_type();
const netclass_t *class_type = dynamic_cast<const netclass_t*>(search_results.type);
ivl_assert(*this, class_type);
NetScope*method = class_type->method_from_name(method_name);
@ -2536,12 +2535,26 @@ static NetExpr* class_static_property_expression(const LineInfo*li,
}
NetExpr* PEIdent::elaborate_expr_class_field_(Design*des, NetScope*scope,
NetNet*net,
const name_component_t&comp,
const symbol_search_results &sr,
unsigned expr_wid,
unsigned flags) const
{
const netclass_t*class_type = net->class_type();
const netclass_t *class_type = dynamic_cast<const netclass_t*>(sr.type);
const name_component_t comp = sr.path_tail.front();
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
<< "Ident " << sr.path_head
<< " look for property " << comp << endl;
}
if (sr.path_tail.size() > 1) {
cerr << get_fileline() << ": sorry: "
<< "Nested member path not yet supported for class properties."
<< endl;
return nullptr;
}
ivl_type_t par_type;
const NetExpr *par_val = class_type->get_parameter(des, comp.name, par_type);
@ -2562,7 +2575,7 @@ NetExpr* PEIdent::elaborate_expr_class_field_(Design*des, NetScope*scope,
if (debug_elaborate) {
cerr << get_fileline() << ": check_for_class_property: "
<< "Property " << comp.name
<< " of net " << net->name()
<< " of net " << sr.net->name()
<< ", context scope=" << scope_path(scope)
<< endl;
}
@ -2582,7 +2595,7 @@ NetExpr* PEIdent::elaborate_expr_class_field_(Design*des, NetScope*scope,
prop_name);
}
NetEProperty*tmp = new NetEProperty(net, comp.name);
NetEProperty*tmp = new NetEProperty(sr.net, pidx);
tmp->set_line(*this);
return tmp;
}
@ -2751,6 +2764,7 @@ NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope,
use_search_results.path_tail.push_back(search_results.path_head.back());
use_search_results.path_head.push_back(name_component_t(perm_string::literal(THIS_TOKEN)));
use_search_results.net = scope->find_signal(perm_string::literal(THIS_TOKEN));
use_search_results.type = use_search_results.net->net_type();
ivl_assert(*this, use_search_results.net);
return elaborate_expr_method_(des, scope, use_search_results);
@ -3026,12 +3040,12 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
if (search_results.par_val)
cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: "
<< "search_results.par_val: " << *search_results.par_val << endl;
if (search_results.par_type)
if (search_results.type)
cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: "
<< "search_results.par_type: " << *search_results.par_type << endl;
<< "search_results.type: " << *search_results.type << endl;
}
if (search_results.par_val && search_results.par_type) {
if (search_results.par_val && search_results.type) {
return elaborate_expr_method_par_(des, scope, search_results);
}
@ -3177,7 +3191,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
perm_string method_name = search_results.path_tail.back().name;
NetNet*net = search_results.net;
const netclass_t*class_type = net->class_type();
const netclass_t*class_type = dynamic_cast<const netclass_t*>(search_results.type);
ivl_assert(*this, class_type);
NetScope*method = class_type->method_from_name(method_name);
@ -3285,10 +3299,10 @@ NetExpr* PECallFunction::elaborate_expr_method_par_(Design*des, NetScope*scope,
const
{
ivl_assert(*this, search_results.par_val);
ivl_assert(*this, search_results.par_type);
ivl_assert(*this, search_results.type);
const NetExpr*par_val = search_results.par_val;
ivl_type_t par_type = search_results.par_type;
ivl_type_t par_type = search_results.type;
perm_string method_name = search_results.path_tail.back().name;
// If the parameter is of type string, then look for the standard string
@ -4230,8 +4244,8 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
// Similarly, if this net is an object, the path tail may
// be a class property.
if (sr.net->class_type() != 0 && !sr.path_tail.empty()) {
const netclass_t*class_type = sr.net->class_type();
const netclass_t *class_type = dynamic_cast<const netclass_t*>(sr.type);
if (class_type && !sr.path_tail.empty()) {
perm_string pname = peek_tail_name(sr.path_tail);
ivl_type_t par_type;
const NetExpr *par = class_type->get_parameter(des, pname, par_type);
@ -4322,12 +4336,6 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
{
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;
if (package_) {
use_scope = des->find_package(package_->pscope_name());
@ -4338,48 +4346,26 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
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) {
// NOTE: this is assuming the member_path is only one
// component long, and that the use_path will wind up
// being the path to the variable. This is not
// necessarily true. Should fix this.
pform_name_t use_path = path_;
name_component_t member_comp = use_path.back();
use_path.pop_back();
ivl_assert(*this, net == 0);
symbol_search(this, des, use_scope, use_path, net, par, eve,
par_type, cls_val);
if (net == 0) {
// Nope, no struct/class with member.
} 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) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
<< "Ident " << use_path
<< " look for property " << member_comp << endl;
}
return elaborate_expr_class_field_(des, scope, net,
member_comp, 0, flags);
}
}
if (net == 0) {
if (!sr.net) {
cerr << get_fileline() << ": error: Unable to bind variable `"
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
des->errors += 1;
return 0;
des->errors++;
return nullptr;
}
NetNet *net = sr.net;
if (!sr.path_tail.empty()) {
if (net->struct_type()) {
return check_for_struct_members(this, des, use_scope, net,
sr.path_head.back().index,
sr.path_tail);
} else if (dynamic_cast<const netclass_t*>(sr.type)) {
return elaborate_expr_class_field_(des, scope, sr, 0, flags);
}
}
if (debug_elaborate) {
@ -4582,7 +4568,7 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
<< " canonical index: " << *canon_index << endl;
}
NetEProperty*tmp = new NetEProperty(this_net, member_name, canon_index);
NetEProperty*tmp = new NetEProperty(this_net, pidx, canon_index);
tmp->set_line(*this);
return tmp;
}
@ -4679,7 +4665,7 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope,
}
return elaborate_expr_param_or_specparam_(des, scope, sr.par_val,
sr.scope, sr.par_type,
sr.scope, sr.type,
expr_wid, flags);
}
@ -4894,18 +4880,8 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope,
return 0;
}
if (sr.net->class_type() && !sr.path_tail.empty()) {
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
"Ident " << sr.path_head
<< " look for class property " << sr.path_tail
<< endl;
}
ivl_assert(*this, sr.path_tail.size() == 1);
const name_component_t member_comp = sr.path_tail.front();
return elaborate_expr_class_field_(des, use_scope,
sr.net, member_comp,
if (dynamic_cast<const netclass_t*>(sr.type) && !sr.path_tail.empty()) {
return elaborate_expr_class_field_(des, use_scope, sr,
expr_wid, flags);
}

View File

@ -159,9 +159,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
bool is_cassign,
bool is_force) const
{
NetNet* reg = 0;
const NetExpr*par = 0;
NetEvent* eve = 0;
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval: "
@ -182,25 +179,12 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
ivl_assert(*this, use_scope);
}
/* Try to find the base part of the path that names the
variable. The remainer is the member path. For example, if
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();
}
symbol_search_results sr;
symbol_search(this, des, use_scope, path_, &sr);
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
print a useful error message. */
@ -301,8 +285,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
// If the variable is a class object, then handle it with the
// net_class_member_ method.
if (reg->class_type() && !member_path.empty() && gn_system_verilog()) {
NetAssign_*lv = elaborate_lval_net_class_member_(des, use_scope, reg, member_path);
const netclass_t *class_type = dynamic_cast<const netclass_t *>(sr.type);
if (class_type && !member_path.empty() && gn_system_verilog()) {
NetAssign_*lv = elaborate_lval_net_class_member_(des, use_scope, class_type, reg, member_path);
return lv;
}
@ -491,7 +476,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
}
NetAssign_*this_lval = new NetAssign_(this_net);
this_lval->set_property(member_name);
this_lval->set_property(member_name, pidx);
if (canon_index) this_lval->set_word(canon_index);
return this_lval;
@ -1094,7 +1079,8 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
* obj, and member_path=base.x.
*/
NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
NetNet*sig, pform_name_t member_path) const
const netclass_t *class_type, NetNet*sig,
pform_name_t member_path) const
{
if (debug_elaborate) {
cerr << get_fileline() << ": PEIdent::elaborate_lval_net_class_member_: "
@ -1102,7 +1088,6 @@ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope
<< " of " << sig->name() << "." << endl;
}
const netclass_t*class_type = sig->class_type();
ivl_assert(*this, class_type);
// Iterate over the member_path. This handles nested class
@ -1165,7 +1150,7 @@ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope
}
lv = lv? new NetAssign_(lv) : new NetAssign_(sig);
lv->set_property(method_name);
lv->set_property(method_name, pidx);
// Now get the type of the property.
ivl_type_t ptype = class_type->get_prop_type(pidx);

View File

@ -3906,7 +3906,7 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
"$ivl_queue_method$pop_back");
}
if (const netclass_t*class_type = net->class_type()) {
if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(par_type)) {
NetScope*task = class_type->method_from_name(method_name);
if (task == 0) {
// If an implicit this was added it is not an error if we

View File

@ -0,0 +1,39 @@
// Check that `super` keyword can be used to access members of the base class
class B;
int x, y;
task set_y;
y = 2000;
endtask
function bit check_x;
return x === 1000;
endfunction
endclass
class C extends B;
byte x, y;
task set_x;
super.x = 1000;
endtask
function bit check_y;
return super.y === 2000;
endfunction
endclass
module test;
C c;
initial begin
c = new;
c.set_x;
c.set_y;
if (c.check_x() && c.check_y()) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,26 @@
// Check that `super` keyword can be used to call tasks of the base class
class B;
task t;
$display("PASSED");
endtask
endclass
class C extends B;
task t;
$display("FAILED");
endtask
task check;
super.t;
endtask
endclass
module test;
C c;
initial begin
c = new;
c.check;
end
endmodule

View File

@ -0,0 +1,30 @@
// Check that `super` keyword can be used to call functions of the base class
class B;
function int f;
return 1;
endfunction
endclass
class C extends B;
function int f;
return 2;
endfunction
task check;
if (super.f() === 1) begin
$display("PASSED");
end else begin
$display("FAILED");
end
endtask
endclass
module test;
C c;
initial begin
c = new;
c.check;
end
endmodule

View File

@ -0,0 +1,39 @@
// Check that `this.super` is supported
class B;
int x, y;
task set_y;
y = 2000;
endtask
function bit check_x;
return x === 1000;
endfunction
endclass
class C extends B;
byte x, y;
task set_x;
this.super.x = 1000;
endtask
function bit check_y;
return this.super.y === 2000;
endfunction
endclass
module test;
C c;
initial begin
c = new;
c.set_x;
c.set_y;
if (c.check_x() && c.check_y()) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -587,6 +587,10 @@ sv_class_static_prop2 normal,-g2009 ivltests
sv_class_static_prop3 normal,-g2009 ivltests
sv_class_super1 normal,-g2009 ivltests
sv_class_super2 normal,-g2009 ivltests
sv_class_super3 normal,-g2009 ivltests
sv_class_super4 normal,-g2009 ivltests
sv_class_super5 normal,-g2009 ivltests
sv_class_super6 normal,-g2009 ivltests
sv_class_task1 normal,-g2009 ivltests
sv_class_virt_new_fail CE,-g2009 ivltests
sv_darray1 normal,-g2009 ivltests

View File

@ -435,6 +435,10 @@ sv_class_static_prop2 CE,-g2009 ivltests
sv_class_static_prop3 CE,-g2009 ivltests
sv_class_super1 CE,-g2009 ivltests
sv_class_super2 CE,-g2009 ivltests
sv_class_super3 CE,-g2009 ivltests
sv_class_super4 CE,-g2009 ivltests
sv_class_super5 CE,-g2009 ivltests
sv_class_super6 CE,-g2009 ivltests
sv_class_task1 CE,-g2009 ivltests
sv_end_label CE,-g2009 ivltests # Also generate
sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests

View File

@ -158,10 +158,7 @@ const ivl_type_s* NetAssign_::net_type() const
return ntype;
if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(ntype)) {
int pidx = class_type->property_idx_from_name(member_);
ivl_assert(*this, pidx >= 0);
ivl_type_t tmp = class_type->get_prop_type(pidx);
return tmp;
return class_type->get_prop_type(member_idx_);
}
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (ntype)) {
@ -178,10 +175,7 @@ const ivl_type_s* NetAssign_::net_type() const
if (member_.nil())
return sig_->net_type();
int pidx = class_type->property_idx_from_name(member_);
ivl_assert(*sig_, pidx >= 0);
ivl_type_t tmp = class_type->get_prop_type(pidx);
return tmp;
return class_type->get_prop_type(member_idx_);
}
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (sig_->net_type())) {
@ -246,10 +240,10 @@ void NetAssign_::set_part(NetExpr*base, unsigned wid,
sel_type_ = sel_type;
}
void NetAssign_::set_property(const perm_string&mname)
void NetAssign_::set_property(const perm_string&mname, unsigned idx)
{
//ivl_assert(*sig_, sig_->class_type());
member_ = mname;
member_idx_ = idx;
}
/*

View File

@ -382,13 +382,12 @@ NetENull::~NetENull()
{
}
NetEProperty::NetEProperty(NetNet*net, perm_string pnam, NetExpr*idx)
: net_(net), index_(idx)
NetEProperty::NetEProperty(NetNet*net, size_t pidx, NetExpr*idx)
: net_(net), pidx_(pidx), index_(idx)
{
const netclass_t*use_type = dynamic_cast<const netclass_t*>(net->net_type());
assert(use_type);
pidx_ = use_type->property_idx_from_name(pnam);
ivl_type_t prop_type = use_type->get_prop_type(pidx_);
expr_width(prop_type->packed_width());
cast_signed(prop_type->get_signed());

View File

@ -2838,8 +2838,8 @@ class NetAssign_ {
ivl_select_type_t = IVL_SEL_OTHER);
// Set the member or property name if the signal type is a
// class.
void set_property(const perm_string&name);
inline perm_string get_property(void) const { return member_; }
void set_property(const perm_string&name, unsigned int idx);
inline int get_property_idx(void) const { return member_idx_; }
// Determine if the assigned object is signed or unsigned.
// This is used when determining the expression type for
@ -2897,6 +2897,7 @@ class NetAssign_ {
NetExpr*word_;
// member/property if signal is a class.
perm_string member_;
int member_idx_ = -1;
bool signed_;
bool turn_sig_to_wire_on_release_;
@ -4579,7 +4580,7 @@ class NetENull : public NetExpr {
*/
class NetEProperty : public NetExpr {
public:
NetEProperty(NetNet*n, perm_string pname, NetExpr*canon_index =0);
NetEProperty(NetNet*n, size_t pidx_, NetExpr*canon_index =0);
~NetEProperty();
inline const NetNet* get_sig() const { return net_; }

View File

@ -48,7 +48,7 @@ struct symbol_search_results {
net = 0;
cls_val = 0;
par_val = 0;
par_type = 0;
type = 0;
eve = 0;
}
@ -80,7 +80,7 @@ struct symbol_search_results {
// If this was a parameter, the value expression and the
// optional value dimensions.
const NetExpr*par_val;
ivl_type_t par_type;
ivl_type_t type;
// If this is a named event, ...
NetEvent*eve;

20
parse.y
View File

@ -1554,15 +1554,16 @@ import_export /* IEEE1800-2012: A.2.9 */
;
implicit_class_handle /* IEEE1800-2005: A.8.4 */
: K_this { $$ = pform_create_this(); }
| K_super { $$ = pform_create_super(); }
: K_this '.' { $$ = pform_create_this(); }
| K_super '.' { $$ = pform_create_super(); }
| K_this '.' K_super '.' { $$ = pform_create_super(); }
;
/* `this` or `super` followed by an identifier */
class_hierarchy_identifier
: implicit_class_handle '.' hierarchy_identifier
{ $1->splice($1->end(), *$3);
delete $3;
: implicit_class_handle hierarchy_identifier
{ $1->splice($1->end(), *$2);
delete $2;
$$ = $1;
}
;
@ -3793,10 +3794,9 @@ expr_primary
pform_requires_sv(@1, "Empty function argument list");
}
| implicit_class_handle
{ PEIdent*tmp = new PEIdent(*$1);
| K_this
{ PEIdent*tmp = new PEIdent(perm_string::literal(THIS_TOKEN));
FILE_NAME(tmp,@1);
delete $1;
$$ = tmp;
}
@ -6693,8 +6693,8 @@ statement_item /* This is roughly statement_item in the LRM */
beginning of a constructor, but let the elaborator figure that
out. */
| implicit_class_handle '.' K_new argument_list_parens_opt ';'
{ PChainConstructor*tmp = new PChainConstructor(*$4);
| implicit_class_handle K_new argument_list_parens_opt ';'
{ PChainConstructor*tmp = new PChainConstructor(*$3);
FILE_NAME(tmp, @3);
if (peek_head_name(*$1) == THIS_TOKEN) {
yyerror(@1, "error: this.new is invalid syntax. Did you mean super.new?");

View File

@ -87,7 +87,12 @@ ostream& operator<< (ostream&out, const index_component_t&that)
ostream& operator<< (ostream&out, const name_component_t&that)
{
out << that.name.str();
if (that.name == THIS_TOKEN)
out << "this";
else if (that.name == SUPER_TOKEN)
out << "super";
else
out << that.name.str();
typedef std::list<index_component_t>::const_iterator index_it_t;
for (index_it_t idx = that.index.begin()

View File

@ -132,12 +132,6 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
if (scope->genvar_tmp.str() && path_tail.name == scope->genvar_tmp)
return false;
if (path_tail.name == "#") {
cerr << li->get_fileline() << ": sorry: "
<< "Implicit class handle \"super\" not supported." << endl;
return false;
}
// These items cannot be seen outside the bounding module where
// the search starts. But we continue searching up because scope
// names can match. For example:
@ -151,10 +145,26 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
// ... top.not_ok; // Matches.
// endmodule
if (!passed_module_boundary) {
// Special case `super` keyword. Return the `this` object, but
// with the type of the base class.
if (path_tail.name == "#") {
if (NetNet *net = scope->find_signal(perm_string::literal(THIS_TOKEN))) {
const netclass_t *class_type = dynamic_cast<const netclass_t*>(net->net_type());
path.push_back(path_tail);
res->scope = scope;
res->net = net;
res->type = class_type->get_super();
res->path_head = path;
return true;
}
return false;
}
if (NetNet*net = scope->find_signal(path_tail.name)) {
path.push_back(path_tail);
res->scope = scope;
res->net = net;
res->type = net->net_type();
res->path_head = path;
return true;
}
@ -167,7 +177,7 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
return true;
}
if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->par_type)) {
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;
@ -326,7 +336,7 @@ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
net = recurse.net;
cls_val = recurse.cls_val;
par = recurse.par_val;
par_type = recurse.par_type;
par_type = recurse.type;
eve = recurse.eve;
if (! flag) {
return 0;

View File

@ -179,8 +179,6 @@ bool dll_target::make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, con
cur->width_ = asn->lwidth();
ivl_type_t nest_type = 0;
if (asn->sig()) {
cur->type_ = IVL_LVAL_REG;
cur->n.sig = find_signal(des_, asn->sig());
@ -188,7 +186,6 @@ bool dll_target::make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, con
} else {
const NetAssign_*asn_nest = asn->nest();
ivl_assert(*li, asn_nest);
nest_type = asn_nest->net_type();
struct ivl_lval_s*cur_nest = new struct ivl_lval_s;
make_single_lval_(li, cur_nest, asn_nest);
@ -209,22 +206,7 @@ bool dll_target::make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, con
expr_ = 0;
}
cur->property_idx = -1;
perm_string pname = asn->get_property();
if (!pname.nil()) {
const netclass_t*use_type;
switch (cur->type_) {
case IVL_LVAL_LVAL:
assert(nest_type);
use_type = dynamic_cast<const netclass_t*> (nest_type);
break;
default:
use_type = dynamic_cast<const netclass_t*> (cur->n.sig->net_type);
break;
}
assert(use_type);
cur->property_idx = use_type->property_idx_from_name(pname);
}
cur->property_idx = asn->get_property_idx();
return flag;
}