diff --git a/design_dump.cc b/design_dump.cc index 95a8634b9..3e7139472 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -1509,6 +1509,11 @@ void NetENetenum::dump(ostream&o) const o << ""; } +void NetENew::dump(ostream&o) const +{ + o << "new "; +} + void NetENull::dump(ostream&o) const { o << ""; diff --git a/dup_expr.cc b/dup_expr.cc index 69bdc411a..43d43a68c 100644 --- a/dup_expr.cc +++ b/dup_expr.cc @@ -177,6 +177,12 @@ NetENetenum* NetENetenum::dup_expr() const return 0; } +NetENew* NetENew::dup_expr() const +{ + ivl_assert(*this, 0); + return 0; +} + NetENull* NetENull::dup_expr() const { ivl_assert(*this, 0); diff --git a/elab_expr.cc b/elab_expr.cc index c4f70c010..bba38a273 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -4041,7 +4041,7 @@ unsigned PENewClass::test_width(Design*, NetScope*, width_mode_t&) NetExpr* PENewClass::elaborate_expr(Design*, NetScope*, ivl_type_t ntype, unsigned) const { - NetESFunc*tmp = new NetESFunc("$ivl_class_method$new", ntype, 0); + NetENew*tmp = new NetENew(ntype); tmp->set_line(*this); return tmp; } diff --git a/emit.cc b/emit.cc index 57e093aec..9fd251c6d 100644 --- a/emit.cc +++ b/emit.cc @@ -551,6 +551,11 @@ void NetENetenum::expr_scan(struct expr_scan_t*tgt) const tgt->expr_netenum(this); } +void NetENew::expr_scan(struct expr_scan_t*tgt) const +{ + tgt->expr_new(this); +} + void NetENull::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_null(this); diff --git a/ivl_target.h b/ivl_target.h index 005aec748..148fc30e6 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -224,6 +224,7 @@ typedef enum ivl_expr_type_e { IVL_EX_ENUMTYPE = 21, IVL_EX_EVENT = 17, IVL_EX_MEMORY = 4, + IVL_EX_NEW = 23, IVL_EX_NULL = 22, IVL_EX_NUMBER = 5, IVL_EX_REALNUM = 16, diff --git a/net_expr.cc b/net_expr.cc index 4b9b33822..a60136487 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -321,6 +321,15 @@ netenum_t* NetENetenum::netenum() const return netenum_; } +NetENew::NetENew(ivl_type_t t) +: obj_type_(t) +{ +} + +NetENew::~NetENew() +{ +} + NetENull::NetENull() { } diff --git a/net_nex_input.cc b/net_nex_input.cc index 19bad21b0..5ca6e2be1 100644 --- a/net_nex_input.cc +++ b/net_nex_input.cc @@ -96,6 +96,11 @@ NexusSet* NetENetenum::nex_input(bool) return new NexusSet; } +NexusSet* NetENew::nex_input(bool) +{ + return new NexusSet; +} + NexusSet* NetENull::nex_input(bool) { return new NexusSet; diff --git a/netlist.h b/netlist.h index 26265768f..2a214d03a 100644 --- a/netlist.h +++ b/netlist.h @@ -3877,6 +3877,23 @@ class NetENetenum : public NetExpr { netenum_t*netenum_; }; +class NetENew : public NetExpr { + public: + explicit NetENew(ivl_type_t); + ~NetENew(); + + inline ivl_type_t get_type() const { return obj_type_; } + + virtual void expr_scan(struct expr_scan_t*) const; + virtual NetENew* dup_expr() const; + virtual NexusSet* nex_input(bool rem_out = true); + + virtual void dump(ostream&os) const; + + private: + ivl_type_t obj_type_; +}; + /* * The NetENull node represents the SystemVerilog (null) * expression. This is always a null class handle. diff --git a/t-dll-expr.cc b/t-dll-expr.cc index dff404f11..1b2ae8576 100644 --- a/t-dll-expr.cc +++ b/t-dll-expr.cc @@ -316,6 +316,19 @@ void dll_target::expr_creal(const NetECReal*net) expr_->u_.real_.value = net->value().as_double(); } +void dll_target::expr_new(const NetENew*net) +{ + assert(expr_ == 0); + expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); + expr_->width_ = net->expr_width(); + expr_->signed_ = 0; + expr_->sized_ = 1; + expr_->type_ = IVL_EX_NEW; + FILE_NAME(expr_, net); + expr_->value_ = IVL_VT_CLASS; + expr_->net_type= net->get_type(); +} + void dll_target::expr_null(const NetENull*net) { assert(expr_ == 0); @@ -328,7 +341,7 @@ void dll_target::expr_null(const NetENull*net) expr_->value_ = IVL_VT_CLASS; expr_->net_type= 0; } - + void dll_target::expr_event(const NetEEvent*net) { assert(expr_ == 0); diff --git a/t-dll.h b/t-dll.h index a999547d8..8f966379a 100644 --- a/t-dll.h +++ b/t-dll.h @@ -137,6 +137,7 @@ struct dll_target : public target_t, public expr_scan_t { void expr_concat(const NetEConcat*); void expr_const(const NetEConst*); void expr_creal(const NetECReal*); + void expr_new(const NetENew*); void expr_null(const NetENull*); void expr_param(const NetEConstParam*); void expr_rparam(const NetECRealParam*); diff --git a/target.cc b/target.cc index a0539ba7b..7b5403282 100644 --- a/target.cc +++ b/target.cc @@ -444,6 +444,12 @@ void expr_scan_t::expr_const(const NetEConst*) "unhandled expr_const." << endl; } +void expr_scan_t::expr_new(const NetENew*) +{ + cerr << "expr_scan_t (" << typeid(*this).name() << "): " + "unhandled expr_new." << endl; +} + void expr_scan_t::expr_null(const NetENull*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " diff --git a/target.h b/target.h index 4db422fb6..69d13092e 100644 --- a/target.h +++ b/target.h @@ -150,6 +150,7 @@ struct expr_scan_t { virtual ~expr_scan_t(); virtual void expr_access_func(const NetEAccess*); virtual void expr_const(const NetEConst*); + virtual void expr_new(const NetENew*); virtual void expr_null(const NetENull*); virtual void expr_param(const NetEConstParam*); virtual void expr_rparam(const NetECRealParam*); diff --git a/tgt-stub/expression.c b/tgt-stub/expression.c index 669969d6f..894a48c7e 100644 --- a/tgt-stub/expression.c +++ b/tgt-stub/expression.c @@ -165,6 +165,16 @@ static void show_memory_expression(ivl_expr_t net, unsigned ind) width); } +static void show_new_expression(ivl_expr_t net, unsigned ind) +{ + fprintf(out, "%*snew \n", ind, ""); + if (ivl_expr_value(net) != IVL_VT_CLASS) { + fprintf(out, "%sERROR: new expression must be IVL_VT_CLASS, got %s.\n", + ind+3, "", vt_type_string(net)); + stub_errors += 1; + } +} + static void show_null_expression(ivl_expr_t net, unsigned ind) { fprintf(out, "%*s\n", ind, ""); @@ -361,6 +371,10 @@ void show_expression(ivl_expr_t net, unsigned ind) show_memory_expression(net, ind); break; + case IVL_EX_NEW: + show_new_expression(net, ind); + break; + case IVL_EX_NULL: show_null_expression(net, ind); break;