Merge pull request #862 from larsclausen/enum-compat-check

Improve enum compatbility checks
This commit is contained in:
Stephen Williams 2023-01-16 19:34:05 -08:00 committed by GitHub
commit 18192fdba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 408 additions and 211 deletions

View File

@ -148,7 +148,7 @@ NetEConst* NetEConst::dup_expr() const
NetEConstEnum* NetEConstEnum::dup_expr() const
{
NetEConstEnum*tmp = new NetEConstEnum(name_, enum_set_, value());
NetEConstEnum*tmp = new NetEConstEnum(name_, enumeration(), value());
ivl_assert(*this, tmp);
tmp->set_line(*this);
return tmp;

View File

@ -116,7 +116,9 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
<< endl;
}
NetExpr *rval;
int context_wid = -1;
bool fallback = true;
switch (lv_type) {
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
@ -124,8 +126,11 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
// For these types, use a different elab_and_eval that
// uses the lv_net_type. We should eventually transition
// all the types to this new form.
if (lv_net_type)
return elab_and_eval(des, scope, expr, lv_net_type, need_const);
if (lv_net_type) {
rval = elab_and_eval(des, scope, expr, lv_net_type, need_const);
fallback = false;
}
break;
case IVL_VT_REAL:
case IVL_VT_STRING:
@ -140,10 +145,28 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
break;
}
return elab_and_eval(des, scope, expr, context_wid, need_const,
if (fallback) {
rval = elab_and_eval(des, scope, expr, context_wid, need_const,
false, lv_type, force_unsigned);
}
const netenum_t *lval_enum = dynamic_cast<const netenum_t*>(lv_net_type);
if (lval_enum) {
const netenum_t *rval_enum = rval->enumeration();
if (!rval_enum) {
cerr << expr->get_fileline() << ": error: "
"This assignment requires an explicit cast." << endl;
des->errors += 1;
} else if (!lval_enum->matches(rval_enum)) {
cerr << expr->get_fileline() << ": error: "
"Enumeration type mismatch in assignment." << endl;
des->errors += 1;
}
}
return rval;
}
/*
* If the mode is UPSIZE, make sure the final expression width is at
* least integer_width, but return the calculated lossless width to

View File

@ -596,10 +596,9 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
cerr << get_fileline() << ": debug: "
<< "Bit select of string becomes character select." << endl;
}
if (mux)
lv->set_part(mux, 8);
else
lv->set_part(new NetEConst(verinum(lsb)), 8);
if (!mux)
mux = new NetEConst(verinum(lsb));
lv->set_part(mux, &netvector_t::atom2s8);
} else if (mux) {
ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE);
@ -1171,6 +1170,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
// increases, and use_width shrinks.
unsigned long off = 0;
unsigned long use_width = struct_type->packed_width();
ivl_type_t member_type;
pform_name_t completed_path;
do {
@ -1242,6 +1242,8 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
return false;
}
member_type = member->net_type;
if (const netvector_t*mem_vec = dynamic_cast<const netvector_t*>(member->net_type)) {
// If the member type is a netvector_t, then it is a
// vector of atom or scaler objects. For example, if the
@ -1311,6 +1313,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
off += loff;
use_width = lwid * tail_wid;
member_type = nullptr;
}
// The netvector_t only has atom elements, to
@ -1475,7 +1478,11 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
}
if (packed_base == 0) {
lv->set_part(new NetEConst(verinum(off)), use_width);
NetExpr *base = new NetEConst(verinum(off));
if (member_type)
lv->set_part(base, member_type);
else
lv->set_part(base, use_width);
return true;
}

View File

@ -150,18 +150,6 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
return;
}
if (lval->enumeration()) {
if (! rval_expr->enumeration()) {
cerr << get_fileline() << ": error: "
"This assignment requires an explicit cast." << endl;
des->errors += 1;
} else if (! lval->enumeration()->matches(rval_expr->enumeration())) {
cerr << get_fileline() << ": error: "
"Enumeration type mismatch in assignment." << endl;
des->errors += 1;
}
}
NetNet*rval = rval_expr->synthesize(des, scope, rval_expr);
if (rval == 0) {
@ -2395,7 +2383,8 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
{
ivl_assert(*this, rval_);
NetExpr*rv = elab_and_eval(des, scope, rval_, net_type, is_constant_);
NetExpr*rv = elaborate_rval_expr(des, scope, net_type, rval_,
is_constant_);
if (!is_constant_ || !rv) return rv;
@ -2416,10 +2405,6 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
{
ivl_assert(*this, rval_);
// Don't have a good value for the lv_net_type argument to
// elaborate_rval_expr, so punt and pass nil. In the future we
// should look into fixing calls to this method to pass a
// net_type instead of the separate lv_width/lv_type values.
NetExpr*rv = elaborate_rval_expr(des, scope, lv_net_type, lv_type, lv_width,
rval(), is_constant_, force_unsigned);
@ -2790,18 +2775,6 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
return bl;
}
if (lv->enumeration()) {
if (! rv->enumeration()) {
cerr << get_fileline() << ": error: "
"This assignment requires an explicit cast." << endl;
des->errors += 1;
} else if (! lv->enumeration()->matches(rv->enumeration())) {
cerr << get_fileline() << ": error: "
"Enumeration type mismatch in assignment." << endl;
des->errors += 1;
}
}
NetAssign*cur = new NetAssign(lv, rv);
cur->set_line(*this);
@ -2851,7 +2824,7 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
<< endl;
}
NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv));
NetExpr*rv = elaborate_rval_(des, scope, lv->net_type(), lv->expr_type(), count_lval_width(lv));
if (rv == 0) return 0;
NetExpr*delay = 0;
@ -4481,11 +4454,7 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
unsigned lwid = count_lval_width(lval);
ivl_variable_type_t ltype = lval->expr_type();
// Need to figure out a better thing to do about the
// lv_net_type argument to elaborate_rval_expr here. This
// would entail getting the NetAssign_ to give us an
// ivl_type_t as needed.
NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_);
NetExpr*rexp = elaborate_rval_expr(des, scope, lval->net_type(), ltype, lwid, expr_);
if (rexp == 0)
return 0;

View File

@ -0,0 +1,23 @@
// Check that assigning to a enum types variable from an enum typed class
// array element works.
module test;
typedef enum reg [31:0] {
A, B
} E;
E e;
E ea[2];
initial begin
ea[0] = B;
e = ea[0];
if (e === B) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,25 @@
// Check that assigning to a enum types variable from an enum typed function
// call works.
module test;
typedef enum reg [31:0] {
A, B
} E;
function E f();
return B;
endfunction
E e;
initial begin
e = f();
if (e === B) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,21 @@
// Check that passing an enum type task argument works.
module test;
typedef enum reg [31:0] {
A, B
} E;
task t(E e);
if (e === B) begin
$display("PASSED");
end else begin
$display("FAILED");
end
endtask
initial begin
t(B);
end
endmodule

View File

@ -0,0 +1,26 @@
// Check that assigning to a enum types variable from an enum typed struct
// member works.
module test;
typedef enum reg [31:0] {
A, B
} E;
struct packed {
E e;
} s;
E e;
initial begin
s.e = B;
e = s.e;
if (e === B) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,28 @@
// Check that assigning to a enum types variable from an enum typed class
// property works.
module test;
typedef enum reg [31:0] {
A, B
} E;
class C;
E e;
endclass
C c;
E e;
initial begin
c = new;
c.e = B;
e = c.e;
if (e === B) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that an error is reported for implicit cast to enum when assigning
// to an array element.
module test;
typedef enum reg [31:0] {
A, B
} E;
E ea[2];
initial begin
ea[0] = 10; // This should fail. Implicit cast to enum.
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,19 @@
// Check that an error is reported for implicit cast to enum when assigning
// from an array element.
module test;
typedef enum reg [31:0] {
A, B
} E;
E e;
int ea[2];
initial begin
ea[0] = B; // This is OK.
e = ea[0]; // This should fail. Implicit cast to enum.
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,21 @@
// Check that an error is reported for implicit cast to enum when assigning
// from a function call.
module test;
typedef enum reg [31:0] {
A, B
} E;
function integer f();
return B;
endfunction
E e;
initial begin
e = f(); // This should fail. Implicit cast to enum type.
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,17 @@
// Check that an error is reported for implicit cast to enum for task arguments.
module test;
typedef enum reg [31:0] {
A, B
} E;
task t(E e);
$display("FAILED");
endtask
initial begin
t(10); // This should fail. Implicit cast to enum.
end
endmodule

View File

@ -0,0 +1,19 @@
// Check that an error is reported for implicit cast to enum when assigning to
// struct members.
module test;
typedef enum reg [31:0] {
A, B
} E;
struct packed {
E e;
} s;
initial begin
s.e = 10; // This should fail. Implicit cast to enum.
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,22 @@
// Check that an error is reported for implicit cast to enum when assigning to
// class properties.
module test;
typedef enum reg [31:0] {
A, B
} E;
class C;
E e;
endclass
C c;
initial begin
c = new;
c.e = 10; // This should fail. Implicit cast to enum.
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,21 @@
// Check that an error is reported for implicit cast to enum in function return
// statements.
module test;
typedef enum reg [31:0] {
A, B
} E;
function E f();
return 10; // This should fail. Implicit cast to enum.
endfunction
E e;
initial begin
e = f();
$display("FAILED");
end
endmodule

View File

@ -278,7 +278,19 @@ enum_base_typename2 normal,-g2005-sv ivltests
enum_compatibility1 normal,-g2005-sv ivltests
enum_compatibility2 normal,-g2005-sv ivltests
enum_compatibility3 normal,-g2005-sv ivltests
enum_compatibility_fail CE,-g2005-sv ivltests
enum_compatibility4 normal,-g2005-sv ivltests
enum_compatibility5 normal,-g2005-sv ivltests
enum_compatibility6 normal,-g2005-sv ivltests
enum_compatibility7 normal,-g2005-sv ivltests
enum_compatibility8 normal,-g2005-sv ivltests
enum_compatibility_fail1 CE,-g2005-sv ivltests
enum_compatibility_fail2 CE,-g2005-sv ivltests
enum_compatibility_fail3 CE,-g2005-sv ivltests
enum_compatibility_fail4 CE,-g2005-sv ivltests
enum_compatibility_fail5 CE,-g2005-sv ivltests
enum_compatibility_fail6 CE,-g2005-sv ivltests
enum_compatibility_fail7 CE,-g2005-sv ivltests
enum_compatibility_fail8 CE,-g2005-sv ivltests
enum_elem_ranges normal,-g2005-sv ivltests
enum_dims_invalid CE,-g2005-sv ivltests
enum_in_struct normal,-g2005-sv ivltests

View File

@ -390,6 +390,7 @@ br_gh391 CE,-g2009 ivltests
br_gh437 CE,-g2009 ivltests
br_gh445 CE,-g2009 ivltests
br_gh461 CE,-g2009 ivltests
enum_compatibility8 CE,-g2005-sv ivltests
enum_in_class CE,-g2005-sv ivltests
enum_in_class_name_coll CE,-g2005-sv ivltests
sv_class1 CE,-g2009 ivltests

View File

@ -22,6 +22,7 @@
# include "netlist.h"
# include "netclass.h"
# include "netdarray.h"
# include "netparray.h"
# include "netenum.h"
# include "ivl_assert.h"
@ -116,105 +117,59 @@ unsigned NetAssign_::lwidth() const
// the type of the member. If this returns nil, then resort to
// the lwid_ value.
ivl_type_t ntype = net_type();
if (ntype == 0)
return lwid_;
// If the type is a darray, and there is a word index, then we
// actually want the width of the elements.
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (ntype)) {
if (word_ == 0)
return 1;
else
return darray->element_width();
}
if (ntype)
return ntype->packed_width();
return lwid_;
}
ivl_variable_type_t NetAssign_::expr_type() const
{
ivl_type_t ntype = net_type();
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*>(ntype)) {
if (word_ == 0)
return IVL_VT_DARRAY;
else
return darray->element_base_type();
}
if (sig_ && sig_->data_type()==IVL_VT_STRING && base_!=0)
return IVL_VT_BOOL;
if (ntype) return ntype->base_type();
if (ntype)
return ntype->base_type();
ivl_assert(*this, sig_);
return sig_->data_type();
}
const ivl_type_s* NetAssign_::net_type() const
ivl_type_t NetAssign_::net_type() const
{
// This is a concatenation, it does not have a type
if (more)
return nullptr;
// Selected sub-vector can have its own data type
if (base_)
return part_data_type_;
ivl_type_t ntype;
if (nest_) {
const ivl_type_s*ntype = nest_->net_type();
if (member_.nil())
return ntype;
if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(ntype)) {
return class_type->get_prop_type(member_idx_);
}
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (ntype)) {
if (word_ == 0)
return ntype;
else
return darray->element_type();
}
return 0;
}
if (const netclass_t*class_type = sig_->class_type()) {
if (member_.nil())
return sig_->net_type();
return class_type->get_prop_type(member_idx_);
}
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (sig_->net_type())) {
if (word_ == 0)
return sig_->net_type();
else
return darray->element_type();
}
return 0;
}
const netenum_t*NetAssign_::enumeration() const
{
const netenum_t*tmp = 0;
ivl_type_t ntype = net_type();
if (ntype == 0) {
ntype = nest_->net_type();
} else {
ivl_assert(*this, sig_);
// If the base signal is not an enumeration, return nil.
if ( (tmp = sig_->enumeration()) == 0 )
return 0;
// We don't have types for array signals yet.
if (sig_->unpacked_dimensions() && !word_)
return nullptr;
} else {
tmp = dynamic_cast<const netenum_t*>(ntype);
if (tmp == 0)
return 0;
ntype = sig_->net_type();
}
// Part select of an enumeration is not an enumeration.
if (base_ != 0)
return 0;
if (!member_.nil()) {
const netclass_t *class_type = dynamic_cast<const netclass_t*>(ntype);
ivl_assert(*this, class_type);
ntype = class_type->get_prop_type(member_idx_);
}
// Concatenation of enumerations is not an enumeration.
if (more != 0)
return 0;
if (word_) {
if (const netdarray_t *darray = dynamic_cast<const netdarray_t*>(ntype))
ntype = darray->element_type();
else if (const netuarray_t *uarray = dynamic_cast<const netuarray_t*>(ntype))
ntype = uarray->element_type();
}
return tmp;
return ntype;
}
perm_string NetAssign_::name() const
@ -240,6 +195,12 @@ void NetAssign_::set_part(NetExpr*base, unsigned wid,
sel_type_ = sel_type;
}
void NetAssign_::set_part(NetExpr*base, ivl_type_t data_type)
{
part_data_type_ = data_type;
set_part(base, part_data_type_->packed_width());
}
void NetAssign_::set_property(const perm_string&mname, unsigned idx)
{
member_ = mname;

View File

@ -38,6 +38,10 @@ NetExpr::NetExpr(unsigned w)
NetExpr::NetExpr(ivl_type_t t)
: net_type_(t), width_(0), signed_flag_(false)
{
if (t) {
width_ = t->packed_width();
signed_flag_ = t->get_signed();
}
}
NetExpr::~NetExpr()
@ -49,6 +53,15 @@ ivl_type_t NetExpr::net_type() const
return net_type_;
}
void NetExpr::set_net_type(ivl_type_t type)
{
net_type_ = type;
if (type) {
width_ = type->packed_width();
signed_flag_ = type->get_signed();
}
}
void NetExpr::cast_signed(bool flag)
{
cast_signed_base_(flag);
@ -72,7 +85,7 @@ ivl_variable_type_t NetExpr::expr_type() const
const netenum_t*NetExpr::enumeration() const
{
return 0;
return dynamic_cast<const netenum_t*>(net_type_);
}
NetEArrayPattern::NetEArrayPattern(ivl_type_t lv_type, vector<NetExpr*>&items)
@ -258,8 +271,9 @@ void NetEConcat::set(unsigned idx, NetExpr*e)
expr_width( expr_width() + repeat_ * e->expr_width() );
}
NetEConstEnum::NetEConstEnum(perm_string n, const netenum_t*eset, const verinum&v)
: NetEConst(v), enum_set_(eset), name_(n)
NetEConstEnum::NetEConstEnum(perm_string n, const netenum_t *enum_set,
const verinum &val)
: NetEConst(enum_set, val), name_(n)
{
assert(has_width());
}
@ -268,11 +282,6 @@ NetEConstEnum::~NetEConstEnum()
{
}
const netenum_t*NetEConstEnum::enumeration() const
{
return enum_set_;
}
NetECReal::NetECReal(const verireal&val)
: value_(val)
{
@ -356,12 +365,12 @@ const netenum_t* NetENetenum::netenum() const
}
NetENew::NetENew(ivl_type_t t)
: obj_type_(t), size_(0), init_val_(0)
: NetExpr(t), size_(0), init_val_(0)
{
}
NetENew::NetENew(ivl_type_t t, NetExpr*size, NetExpr*init_val)
: obj_type_(t), size_(size), init_val_(init_val)
: NetExpr(t), size_(size), init_val_(init_val)
{
}
@ -389,33 +398,23 @@ NetEProperty::NetEProperty(NetNet*net, size_t pidx, NetExpr*idx)
assert(use_type);
ivl_type_t prop_type = use_type->get_prop_type(pidx_);
expr_width(prop_type->packed_width());
cast_signed(prop_type->get_signed());
set_net_type(prop_type);
}
NetEProperty::~NetEProperty()
{
}
ivl_variable_type_t NetEProperty::expr_type() const
{
const netclass_t*use_type = dynamic_cast<const netclass_t*>(net_->net_type());
assert(use_type);
ivl_type_t prop_type = use_type->get_prop_type(pidx_);
return prop_type->base_type();
}
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
ivl_select_type_t sel_type)
: expr_(exp), base_(base), use_type_(0), sel_type_(sel_type)
: expr_(exp), base_(base), sel_type_(sel_type)
{
expr_width(wid);
}
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
ivl_type_t use_type)
: expr_(exp), base_(base), use_type_(use_type), sel_type_(IVL_SEL_OTHER)
: NetExpr(use_type), expr_(exp), base_(base), sel_type_(IVL_SEL_OTHER)
{
expr_width(wid);
}
@ -443,8 +442,8 @@ ivl_select_type_t NetESelect::select_type() const
ivl_variable_type_t NetESelect::expr_type() const
{
if (use_type_)
return use_type_->base_type();
if (net_type())
return net_type()->base_type();
ivl_variable_type_t type = expr_->expr_type();
@ -457,27 +456,19 @@ ivl_variable_type_t NetESelect::expr_type() const
return type;
}
const netenum_t* NetESelect::enumeration() const
{
return dynamic_cast<const netenum_t*> (use_type_);
}
NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t,
unsigned width, unsigned np, bool is_overridden)
: name_(0), type_(t), enum_type_(0), parms_(np), is_overridden_(is_overridden)
: name_(0), type_(t), parms_(np), is_overridden_(is_overridden)
{
name_ = lex_strings.add(n);
expr_width(width);
}
NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
: NetExpr(rtype), name_(0), type_(rtype->base_type()),
enum_type_(dynamic_cast<const netenum_t*>(rtype)), parms_(np),
: NetExpr(rtype), name_(0), type_(rtype->base_type()), parms_(np),
is_overridden_(false)
{
name_ = lex_strings.add(n);
expr_width(rtype->packed_width());
cast_signed_base_(rtype->get_signed());
}
NetESFunc::~NetESFunc()
@ -523,11 +514,6 @@ ivl_variable_type_t NetESFunc::expr_type() const
return type_;
}
const netenum_t* NetESFunc::enumeration() const
{
return enum_type_;
}
NetEShallowCopy::NetEShallowCopy(NetExpr*arg1, NetExpr*arg2)
: arg1_(arg1), arg2_(arg2)
{

View File

@ -2156,10 +2156,8 @@ const NetExpr* NetSTask::parm(unsigned idx) const
NetEUFunc::NetEUFunc(NetScope*scope, NetScope*def, NetESignal*res,
vector<NetExpr*>&p, bool nc)
: scope_(scope), func_(def), result_sig_(res), parms_(p), need_const_(nc)
: NetExpr(res->net_type()), scope_(scope), func_(def), result_sig_(res), parms_(p), need_const_(nc)
{
expr_width(result_sig_->expr_width());
cast_signed_base_(result_sig_->has_sign());
}
NetEUFunc::~NetEUFunc()
@ -2194,22 +2192,6 @@ const NetScope* NetEUFunc::func() const
return func_;
}
ivl_variable_type_t NetEUFunc::expr_type() const
{
if (result_sig_)
return result_sig_->expr_type();
return IVL_VT_VOID;
}
const netenum_t* NetEUFunc::enumeration() const
{
if (result_sig_)
return result_sig_->enumeration();
return 0;
}
NetUTask::NetUTask(NetScope*def)
: task_(def)
{
@ -2308,6 +2290,14 @@ NetEConst::NetEConst(const verinum&val)
cast_signed_base_(value_.has_sign());
}
NetEConst::NetEConst(ivl_type_t type, const verinum&val)
: NetExpr(type), value_(val)
{
ivl_assert(*this, type->packed());
ivl_assert(*this, type->packed_width() == val.len());
ivl_assert(*this, type->get_signed() == val.has_sign());
}
NetEConst::~NetEConst()
{
}
@ -2401,11 +2391,10 @@ const NetScope* NetEScope::scope() const
}
NetESignal::NetESignal(NetNet*n)
: NetExpr(n->vector_width()), net_(n), enum_type_(n->enumeration()), word_(0)
: NetExpr(n->net_type()), net_(n), word_(0)
{
net_->incr_eref();
set_line(*n);
cast_signed_base_(net_->get_signed());
}
NetESignal::NetESignal(NetNet*n, NetExpr*w)
@ -2413,7 +2402,11 @@ NetESignal::NetESignal(NetNet*n, NetExpr*w)
{
net_->incr_eref();
set_line(*n);
cast_signed_base_(net_->get_signed());
// If it is an array we don't have a type for it yet. But for array
// elements the NetNet returns the element type.
if (word_)
set_net_type(net_->net_type());
}
NetESignal::~NetESignal()
@ -2426,11 +2419,6 @@ perm_string NetESignal::name() const
return net_->name();
}
const netenum_t* NetESignal::enumeration() const
{
return enum_type_;
}
const NetExpr* NetESignal::word_index() const
{
return word_;

View File

@ -2077,6 +2077,7 @@ class NetExpr : public LineInfo {
protected:
void expr_width(unsigned wid) { width_ = wid; }
void cast_signed_base_(bool flag) { signed_flag_ = flag; }
void set_net_type(ivl_type_t type);
private:
ivl_type_t net_type_;
@ -2116,6 +2117,7 @@ class NetEArrayPattern : public NetExpr {
class NetEConst : public NetExpr {
public:
explicit NetEConst(ivl_type_t type, const verinum&val);
explicit NetEConst(const verinum&val);
~NetEConst();
@ -2153,7 +2155,6 @@ class NetEConstEnum : public NetEConst {
~NetEConstEnum();
perm_string name() const;
const netenum_t*enumeration() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual void dump(std::ostream&) const;
@ -2161,7 +2162,6 @@ class NetEConstEnum : public NetEConst {
virtual NetEConstEnum* dup_expr() const;
private:
const netenum_t*enum_set_;
perm_string name_;
};
@ -2836,6 +2836,11 @@ class NetAssign_ {
// that the expression calculates a CANONICAL bit address.
void set_part(NetExpr* loff, unsigned wid,
ivl_select_type_t = IVL_SEL_OTHER);
// Set a part select expression for the l-value vector. Note
// that the expression calculates a CANONICAL bit address.
// The part select has a specific type and the width of the select will
// be that of the type.
void set_part(NetExpr *loff, ivl_type_t data_type);
// Set the member or property name if the signal type is a
// class.
void set_property(const perm_string&name, unsigned int idx);
@ -2856,11 +2861,7 @@ class NetAssign_ {
// Get the expression type of the l-value. This may be
// different from the type of the contained signal if for
// example a darray is indexed.
const ivl_type_s* net_type() const;
// Return the enumeration type of this l-value, or nil if it's
// not an enumeration.
const netenum_t*enumeration() const;
ivl_type_t net_type() const;
// Get the name of the underlying object.
perm_string name() const;
@ -2905,6 +2906,7 @@ class NetAssign_ {
NetExpr*base_;
unsigned lwid_;
ivl_select_type_t sel_type_;
ivl_type_t part_data_type_ = nullptr;
};
class NetAssignBase : public NetProc {
@ -3924,8 +3926,6 @@ class NetEUFunc : public NetExpr {
const NetScope* func() const;
virtual ivl_variable_type_t expr_type() const;
virtual const netenum_t* enumeration() const;
virtual void dump(std::ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const;
@ -4470,7 +4470,6 @@ class NetESelect : public NetExpr {
// sub-expression. The type of an array/member select is
// the base type of the element/member.
virtual ivl_variable_type_t expr_type() const;
virtual const netenum_t* enumeration() const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
bool nested_func = false) const;
@ -4485,7 +4484,6 @@ class NetESelect : public NetExpr {
private:
NetExpr*expr_;
NetExpr*base_;
ivl_type_t use_type_;
ivl_select_type_t sel_type_;
};
@ -4543,7 +4541,6 @@ class NetENew : public NetExpr {
explicit NetENew(ivl_type_t, NetExpr*size, NetExpr* init_val=0);
~NetENew();
inline ivl_type_t get_type() const { return obj_type_; }
inline const NetExpr*size_expr() const { return size_; }
inline const NetExpr*init_expr() const { return init_val_; }
@ -4557,7 +4554,6 @@ class NetENew : public NetExpr {
virtual void dump(std::ostream&os) const;
private:
ivl_type_t obj_type_;
NetExpr*size_;
NetExpr*init_val_;
};
@ -4598,7 +4594,6 @@ class NetEProperty : public NetExpr {
inline const NetExpr*get_index() const { return index_; }
public: // Overridden methods
ivl_variable_type_t expr_type() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEProperty* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
@ -4663,7 +4658,6 @@ class NetESFunc : public NetExpr {
virtual ivl_variable_type_t expr_type() const;
virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false,
bool nested_func = false) const;
virtual const netenum_t* enumeration() const;
virtual void dump(std::ostream&) const;
virtual void expr_scan(struct expr_scan_t*) const;
@ -4739,7 +4733,6 @@ class NetESFunc : public NetExpr {
const char* name_;
ivl_variable_type_t type_;
const netenum_t*enum_type_;
std::vector<NetExpr*>parms_;
bool is_overridden_;
@ -4969,7 +4962,6 @@ class NetESignal : public NetExpr {
bool nested_func = false) const;
NexusSet* nex_input_base(bool rem_out, bool always_sens, bool nested_func,
unsigned base, unsigned width) const;
const netenum_t*enumeration() const;
virtual NetExpr*evaluate_function(const LineInfo&loc,
std::map<perm_string,LocalVar>&ctx) const;
@ -4994,7 +4986,6 @@ class NetESignal : public NetExpr {
private:
NetNet*net_;
const netenum_t*enum_type_;
// Expression to select a word from the net.
NetExpr*word_;
};

View File

@ -403,7 +403,7 @@ void dll_target::expr_new(const NetENew*net)
expr_->type_ = IVL_EX_NEW;
FILE_NAME(expr_, net);
expr_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS
expr_->net_type= net->get_type();
expr_->net_type= net->net_type();
expr_->u_.new_.size = size;
expr_->u_.new_.init_val = init_val;
}