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 "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netparray.h"
|
||||
# include "netenum.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 lwid_ value.
|
||||
ivl_type_t ntype = net_type();
|
||||
if (ntype == 0)
|
||||
return lwid_;
|
||||
if (ntype)
|
||||
return ntype->packed_width();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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 or a part select, it does not have a type
|
||||
if (more || base_)
|
||||
return nullptr;
|
||||
|
||||
ivl_type_t ntype;
|
||||
if (nest_) {
|
||||
const ivl_type_s*ntype = nest_->net_type();
|
||||
if (member_.nil())
|
||||
return ntype;
|
||||
ntype = nest_->net_type();
|
||||
} else {
|
||||
ivl_assert(*this, sig_);
|
||||
|
||||
if (const netclass_t*class_type = dynamic_cast<const netclass_t*>(ntype)) {
|
||||
return class_type->get_prop_type(member_idx_);
|
||||
}
|
||||
// We don't have types for array signals yet.
|
||||
if (sig_->unpacked_dimensions() && !word_)
|
||||
return nullptr;
|
||||
|
||||
if (const netdarray_t*darray = dynamic_cast<const netdarray_t*> (ntype)) {
|
||||
if (word_ == 0)
|
||||
return ntype;
|
||||
else
|
||||
return darray->element_type();
|
||||
}
|
||||
|
||||
return 0;
|
||||
ntype = sig_->net_type();
|
||||
}
|
||||
|
||||
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 (!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_);
|
||||
}
|
||||
|
||||
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();
|
||||
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 0;
|
||||
return ntype;
|
||||
}
|
||||
|
||||
const netenum_t*NetAssign_::enumeration() const
|
||||
{
|
||||
const netenum_t*tmp = 0;
|
||||
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;
|
||||
return dynamic_cast<const netenum_t*>(net_type());
|
||||
}
|
||||
|
||||
perm_string NetAssign_::name() const
|
||||
|
|
|
|||
|
|
@ -2856,7 +2856,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;
|
||||
ivl_type_t net_type() const;
|
||||
|
||||
// Return the enumeration type of this l-value, or nil if it's
|
||||
// not an enumeration.
|
||||
|
|
|
|||
Loading…
Reference in New Issue