diff --git a/elab_scope.cc b/elab_scope.cc index 99a14081d..d6a3bf40a 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -50,6 +50,7 @@ # include "netlist.h" # include "netclass.h" # include "netenum.h" +# include "netqueue.h" # include "parse_api.h" # include "util.h" # include @@ -557,6 +558,13 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) << " Property " << cur->first << " type=" << *tmp << endl; } + + if (dynamic_cast (tmp)) { + cerr << cur->second.get_fileline() << ": sorry: " + << "Queues inside classes are not yet supported." << endl; + des->errors++; + } + use_class->set_property(cur->first, cur->second.qual, tmp); } diff --git a/elab_type.cc b/elab_type.cc index b77138ac3..4471e1b28 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -241,10 +241,6 @@ ivl_type_t uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const // Special case: if the dimension is null:nil. this is a queue. if (dynamic_cast(cur->first)) { - cerr << get_fileline() << ": sorry: " - << "SV queues inside classes are not yet supported." << endl; - des->errors += 1; - // FIXME: Need to set the max size if cur->second is defined ivl_type_s*res = new netqueue_t(btype, -1); return res; diff --git a/ivtest/ivltests/sv_queue_function.v b/ivtest/ivltests/sv_queue_function.v new file mode 100644 index 000000000..9fb52f1eb --- /dev/null +++ b/ivtest/ivltests/sv_queue_function.v @@ -0,0 +1,41 @@ +// Check that a queue return type is supported for functions + +module test; + + typedef int Q[$]; + + // Since this is not an automatic function calling this repeatetly will + // append to the same queue. + function Q f1(int x); + f1.push_back(1 + x); + f1.push_back(2 + x); + endfunction + + // Since this function is automatic a new queue will be created each time it + // is called. + function automatic Q f2(int x); + f2.push_back(1 + x); + f2.push_back(2 + x); + endfunction + + initial begin + Q a, b, c, d; + + a = f1(0); + // `a` should be a copy and not affected by the second call + b = f1(2); + + c = f2(0); + d = f2(2); + + if (a.size() == 2 && a[0] == 1 && a[1] == 2 && + b.size() == 4 && b[0] == 1 && b[1] == 2 && b[2] == 3 && b[3] == 4 && + c.size() == 2 && c[0] == 1 && c[1] == 2 && + d.size() == 2 && d[0] == 3 && d[1] == 4) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index e0503d23c..06b392d6e 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -575,6 +575,7 @@ sv_port_default14 CE,-g2009 ivltests sv_queue1 normal,-g2009 ivltests sv_queue2 normal,-g2009 ivltests sv_queue3 normal,-g2009 ivltests +sv_queue_function normal,-g2009 ivltests sv_queue_parray normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray.gold sv_queue_parray_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray_bounded.gold sv_queue_parray_fail CE,-g2009 ivltests gold=sv_queue_parray_fail.gold diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 7aa9989e8..3f9b3d29b 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -463,6 +463,7 @@ pr3390385b CE,-g2009 ivltests # ++ pr3390385c CE,-g2009 ivltests # ++ pr3390385d CE,-g2009 ivltests # ++ pr3462145 CE,-g2009 ivltests # ++ +sv_queue_function CE,-g2009,-pallowsigned=1 ivltests # queue sv_typedef_darray_base1 CE,-g2009 ivltests # Dyanmic array sv_typedef_darray_base2 CE,-g2009 ivltests # Dyanmic array sv_typedef_darray_base3 CE,-g2009 ivltests # Dyanmic array diff --git a/libmisc/LineInfo.cc b/libmisc/LineInfo.cc index c0daaff14..753b24970 100644 --- a/libmisc/LineInfo.cc +++ b/libmisc/LineInfo.cc @@ -27,11 +27,6 @@ LineInfo::LineInfo() { } -LineInfo::LineInfo(const LineInfo&that) : - file_(that.file_), lineno_(that.lineno_) -{ -} - LineInfo::~LineInfo() { } diff --git a/libmisc/LineInfo.h b/libmisc/LineInfo.h index ec36aee41..b47f194f0 100644 --- a/libmisc/LineInfo.h +++ b/libmisc/LineInfo.h @@ -34,7 +34,6 @@ class LineInfo { public: LineInfo(); - LineInfo(const LineInfo&that); virtual ~LineInfo(); // Get a fully formatted file/lineno diff --git a/netmisc.cc b/netmisc.cc index e27778361..b2ca68a61 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -985,16 +985,17 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, if (tmp == 0) return 0; ivl_variable_type_t cast_type = ivl_type_base(lv_net_type); - if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != tmp->expr_type())) { + ivl_variable_type_t expr_type = tmp->expr_type(); + if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != expr_type)) { // Catch some special cases. switch (cast_type) { case IVL_VT_DARRAY: case IVL_VT_QUEUE: - if (NetESignal*net = dynamic_cast(tmp)) { - ivl_variable_type_t type = net->expr_type(); - if ((type == IVL_VT_DARRAY) || (type == IVL_VT_QUEUE)) - return tmp; - } + if ((expr_type == IVL_VT_DARRAY) || (expr_type == IVL_VT_QUEUE)) + return tmp; + + // This is needed to handle the special case of `'{}` which + // gets elaborated to NetENull. if (dynamic_cast(pe)) return tmp; // fall through diff --git a/pform_pclass.cc b/pform_pclass.cc index a129e19be..f922b9df9 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -86,6 +86,7 @@ void pform_class_property(const struct vlltype&loc, pform_cur_class->type->properties[curp->name] = class_type_t::prop_info_t(property_qual,use_type); + FILE_NAME(&pform_cur_class->type->properties[curp->name], loc); if (PExpr*rval = curp->expr.release()) { PExpr*lval = new PEIdent(curp->name); diff --git a/pform_types.h b/pform_types.h index dc4bb8da4..45e312e6f 100644 --- a/pform_types.h +++ b/pform_types.h @@ -336,7 +336,7 @@ struct class_type_t : public data_type_t { std::listbase_args; // This is a map of the properties. Map the name to the type. - struct prop_info_t { + struct prop_info_t : public LineInfo { inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { } inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { } property_qualifier_t qual;