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:
parent
05d5c9b35f
commit
f63a162329
|
|
@ -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;
|
||||
|
|
|
|||
54
net_expr.cc
54
net_expr.cc
|
|
@ -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()
|
||||
|
|
|
|||
42
netlist.cc
42
netlist.cc
|
|
@ -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_;
|
||||
|
|
|
|||
13
netlist.h
13
netlist.h
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue