Provide data type for more lvalue expressions
The NetAssign_:net_type() function return the type of lvalue expression. But it only does so for a limited amount of cases. Refactor the function so that it works for the general case and always returns the data type, if the data type of the lvalue expression is known. This will allow to implement better type checking and other constructs such as pattern assignments that require to know the type of the lvalue. It also allows to remove some duplicated code in other methods of NetAssign_ that want to lookup the type. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
f63a162329
commit
f9909562fd
100
net_assign.cc
100
net_assign.cc
|
|
@ -22,6 +22,7 @@
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
# include "netclass.h"
|
# include "netclass.h"
|
||||||
# include "netdarray.h"
|
# include "netdarray.h"
|
||||||
|
# include "netparray.h"
|
||||||
# include "netenum.h"
|
# include "netenum.h"
|
||||||
# include "ivl_assert.h"
|
# include "ivl_assert.h"
|
||||||
|
|
||||||
|
|
@ -116,105 +117,64 @@ unsigned NetAssign_::lwidth() const
|
||||||
// the type of the member. If this returns nil, then resort to
|
// the type of the member. If this returns nil, then resort to
|
||||||
// the lwid_ value.
|
// the lwid_ value.
|
||||||
ivl_type_t ntype = net_type();
|
ivl_type_t ntype = net_type();
|
||||||
if (ntype == 0)
|
if (ntype)
|
||||||
return lwid_;
|
return ntype->packed_width();
|
||||||
|
|
||||||
// If the type is a darray, and there is a word index, then we
|
return lwid_;
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ntype->packed_width();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ivl_variable_type_t NetAssign_::expr_type() const
|
ivl_variable_type_t NetAssign_::expr_type() const
|
||||||
{
|
{
|
||||||
ivl_type_t ntype = net_type();
|
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)
|
if (sig_ && sig_->data_type()==IVL_VT_STRING && base_!=0)
|
||||||
return IVL_VT_BOOL;
|
return IVL_VT_BOOL;
|
||||||
|
|
||||||
if (ntype) return ntype->base_type();
|
if (ntype)
|
||||||
|
return ntype->base_type();
|
||||||
|
|
||||||
ivl_assert(*this, sig_);
|
ivl_assert(*this, sig_);
|
||||||
return sig_->data_type();
|
return sig_->data_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ivl_type_s* NetAssign_::net_type() const
|
ivl_type_t NetAssign_::net_type() const
|
||||||
{
|
{
|
||||||
|
// This is a concatenation or a part select, it does not have a type
|
||||||
|
if (more || base_)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ivl_type_t ntype;
|
||||||
if (nest_) {
|
if (nest_) {
|
||||||
const ivl_type_s*ntype = nest_->net_type();
|
ntype = nest_->net_type();
|
||||||
if (member_.nil())
|
} else {
|
||||||
return ntype;
|
ivl_assert(*this, sig_);
|
||||||
|
|
||||||
if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(ntype)) {
|
// We don't have types for array signals yet.
|
||||||
return class_type->get_prop_type(member_idx_);
|
if (sig_->unpacked_dimensions() && !word_)
|
||||||
}
|
return nullptr;
|
||||||
|
|
||||||
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (ntype)) {
|
ntype = sig_->net_type();
|
||||||
if (word_ == 0)
|
|
||||||
return ntype;
|
|
||||||
else
|
|
||||||
return darray->element_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const netclass_t*class_type = sig_->class_type()) {
|
if (!member_.nil()) {
|
||||||
if (member_.nil())
|
const netclass_t *class_type = dynamic_cast<const netclass_t*>(ntype);
|
||||||
return sig_->net_type();
|
ivl_assert(*this, class_type);
|
||||||
|
ntype = class_type->get_prop_type(member_idx_);
|
||||||
return class_type->get_prop_type(member_idx_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (sig_->net_type())) {
|
if (word_) {
|
||||||
if (word_ == 0)
|
if (const netdarray_t *darray = dynamic_cast<const netdarray_t*>(ntype))
|
||||||
return sig_->net_type();
|
ntype = darray->element_type();
|
||||||
else
|
else if (const netuarray_t *uarray = dynamic_cast<const netuarray_t*>(ntype))
|
||||||
return darray->element_type();
|
ntype = uarray->element_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ntype;
|
||||||
}
|
}
|
||||||
|
|
||||||
const netenum_t*NetAssign_::enumeration() const
|
const netenum_t*NetAssign_::enumeration() const
|
||||||
{
|
{
|
||||||
const netenum_t*tmp = 0;
|
return dynamic_cast<const netenum_t*>(net_type());
|
||||||
ivl_type_t ntype = net_type();
|
|
||||||
if (ntype == 0) {
|
|
||||||
|
|
||||||
ivl_assert(*this, sig_);
|
|
||||||
|
|
||||||
// If the base signal is not an enumeration, return nil.
|
|
||||||
if ( (tmp = sig_->enumeration()) == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
tmp = dynamic_cast<const netenum_t*>(ntype);
|
|
||||||
if (tmp == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Part select of an enumeration is not an enumeration.
|
|
||||||
if (base_ != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Concatenation of enumerations is not an enumeration.
|
|
||||||
if (more != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
perm_string NetAssign_::name() const
|
perm_string NetAssign_::name() const
|
||||||
|
|
|
||||||
|
|
@ -2856,7 +2856,7 @@ class NetAssign_ {
|
||||||
// Get the expression type of the l-value. This may be
|
// Get the expression type of the l-value. This may be
|
||||||
// different from the type of the contained signal if for
|
// different from the type of the contained signal if for
|
||||||
// example a darray is indexed.
|
// example a darray is indexed.
|
||||||
const ivl_type_s* net_type() const;
|
ivl_type_t net_type() const;
|
||||||
|
|
||||||
// Return the enumeration type of this l-value, or nil if it's
|
// Return the enumeration type of this l-value, or nil if it's
|
||||||
// not an enumeration.
|
// not an enumeration.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue