Provide data type for more NetExpr subclasses

There are a few NetExpr subclasses where the data type of the expression
is known, but it not attached to the NetExpr and only kept as a private
member in the subclass.

Attaching the type directly to the NetExpr allows to query it externally
and implement better type checking.

It also allows to remove a bit of duplicated code in the subclasses and
rely on the default implementation in the NetExpr base class.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-09-30 10:51:52 +02:00
parent 05d5c9b35f
commit f63a162329
5 changed files with 42 additions and 71 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

@ -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);
@ -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,11 +456,6 @@ 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), parms_(np), is_overridden_(is_overridden)
@ -475,8 +469,6 @@ NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np)
is_overridden_(false)
{
name_ = lex_strings.add(n);
expr_width(rtype->packed_width());
cast_signed_base_(rtype->get_signed());
}
NetESFunc::~NetESFunc()

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_;
};
@ -3924,8 +3924,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 +4468,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 +4482,6 @@ class NetESelect : public NetExpr {
private:
NetExpr*expr_;
NetExpr*base_;
ivl_type_t use_type_;
ivl_select_type_t sel_type_;
};
@ -4543,7 +4539,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 +4552,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 +4592,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,
@ -4967,7 +4960,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;
@ -4992,7 +4984,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;
}