From 04c21e1982aec1b019276e522eb405148cfeed95 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 9 Aug 2026 14:45:43 -0700 Subject: [PATCH] Distinguish queue dimensions from `null` expressions Queue dimensions use a `PENull` expression as an internal marker for `$`. This also represents a source `null` expression, so declarations such as: integer value[null:2]; are accepted and elaborated as bounded queues. Use a dedicated `PEQueueDimension` marker for queue dimensions. This lets source `null` expressions follow normal range expression validation while preserving the existing representation of dynamic and fixed dimensions. Signed-off-by: Lars-Peter Clausen --- PExpr.h | 6 ++++++ elab_type.cc | 5 ++--- netmisc.cc | 2 +- parse.y | 4 ++-- pform_dump.cc | 5 +++++ pform_types.h | 6 +++++- 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/PExpr.h b/PExpr.h index 931fd4b30..0aef99878 100644 --- a/PExpr.h +++ b/PExpr.h @@ -635,6 +635,12 @@ class PENull : public PExpr { unsigned flags) const override; }; +// Internal marker for the '$' in a queue dimension. +class PEQueueDimension : public PExpr { + public: + void dump(std::ostream&) const override; +}; + class PENumber : public PExpr { public: diff --git a/elab_type.cc b/elab_type.cc index c905791e1..89ecf311e 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -374,9 +374,8 @@ ivl_type_t elaborate_array_type(Design *des, NetScope *scope, type = elaborate_darray_check_type(des, li, type, "Dynamic array"); type = new netdarray_t(type); continue; - } else if (dynamic_cast(lidx)) { - // Special case: Detect the mark for a QUEUE declaration, - // which is the dimensions [null:max_idx]. + } else if (dynamic_cast(lidx)) { + // Special case: Detect the mark for a QUEUE declaration. type = elaborate_static_array_type(des, li, type, dimensions); type = elaborate_queue_type(des, scope, li, type, ridx); continue; diff --git a/netmisc.cc b/netmisc.cc index 0620eb359..46f38f8ef 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -1087,7 +1087,7 @@ bool evaluate_range(Design*des, NetScope*scope, const LineInfo*li, "An unsized dimension is not allowed here." << endl; dimension_ok = false; des->errors += 1; - } else if (dynamic_cast(range.first)) { + } else if (dynamic_cast(range.first)) { cerr << li->get_fileline() << ": error: " "A queue dimension is not allowed here." << endl; dimension_ok = false; diff --git a/parse.y b/parse.y index 15f856e18..3e09e739f 100644 --- a/parse.y +++ b/parse.y @@ -3197,7 +3197,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ | '[' '$' ']' { // SystemVerilog queue list *tmp = new std::list; - pform_range_t index (new PENull,0); + pform_range_t index (new PEQueueDimension,0); pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; @@ -3205,7 +3205,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ | '[' '$' ':' expression ']' { // SystemVerilog queue with a max size list *tmp = new std::list; - pform_range_t index (new PENull,$4); + pform_range_t index (new PEQueueDimension,$4); pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; diff --git a/pform_dump.cc b/pform_dump.cc index 0361bec15..fcba4b18a 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -506,6 +506,11 @@ void PENull::dump(ostream&out) const out << "null"; } +void PEQueueDimension::dump(ostream&out) const +{ + out << "$"; +} + void PENumber::dump(ostream&out) const { out << value(); diff --git a/pform_types.h b/pform_types.h index f0ff20ada..fa54f0795 100644 --- a/pform_types.h +++ b/pform_types.h @@ -91,8 +91,12 @@ typedef std::pair pform_ident_t; * second = 0 * * [ $ ] -- Queue type - * first = PENull + * first = PEQueueDimension * second = 0 + * + * [ $ : ] -- Bounded queue type + * first = PEQueueDimension + * second = */ typedef std::pair pform_range_t;