diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 8be28c54e..89abc2c2a 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3255,6 +3255,10 @@ private: " (IEEE 1800-2017 8.13)"); } if (cextp->childDTypep() || cextp->dtypep()) continue; // Already converted + if (VN_IS(cextp->classOrPkgsp(), Dot)) { + itemp->v3warn(E_UNSUPPORTED, "Unsupported: Hierarchical class references"); + continue; + } AstClassOrPackageRef* const cpackagerefp = VN_CAST(cextp->classOrPkgsp(), ClassOrPackageRef); if (VL_UNCOVERABLE(!cpackagerefp)) { diff --git a/src/verilog.y b/src/verilog.y index 677d9d2b4..fba31aa97 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6643,11 +6643,6 @@ classExtendsOne: // IEEE: part of class_declaration class_typeExtImpList { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; $$ = $1; } - // - | class_typeExtImpList '(' list_of_argumentsE ')' - { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; - $$ = $1; - if ($3) BBUNSUP($3, "Unsupported: extends with parameters"); } ; classImplementsE: // IEEE: part of class_declaration @@ -6667,18 +6662,16 @@ classImplementsList: // IEEE: part of class_declaration { $$ = addNextNull($1, $3); $$ = $3; } ; -class_typeExtImpList: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]" +class_typeExtImpList: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]" // // but allow yaID__aTYPE for extends/implements // // If you follow the rules down, class_type is really a list via ps_class_identifier class_typeExtImpOne { $$ = $1; $$ = $1; } | class_typeExtImpList yP_COLONCOLON class_typeExtImpOne - { $$ = $3; $$ = $1; - // Cannot just add as next() as that breaks implements lists - //UNSUP $$ = new AstDot{$1, true, $1, $3}; - BBUNSUP($2, "Unsupported: Hierarchical class references"); } + { $$ = new AstDot{$1, true, $1, $3}; + $$ = $3; } ; -class_typeExtImpOne: // part of IEEE: class_type, where we either get a package_scope component or class +class_typeExtImpOne: // part of IEEE: class_type, where we either get a package_scope component or class // // If you follow the rules down, class_type is really a list via ps_class_identifier // // Not listed in IEEE, but see bug627 any parameter type maybe a class // // If idAny below is a class, parameter_value is legal @@ -6686,6 +6679,11 @@ class_typeExtImpOne: // part of IEEE: class_type, where we either get // // If idAny below is otherwise, not legal idAny /*mid*/ { /* no nextId as not refing it above this*/ } + /*cont*/ parameter_value_assignmentE + { $$ = new AstClassOrPackageRef{$1, *$1, $1, $3}; + $$ = $1; } + | idCC + /*mid*/ { /* no nextId as not refing it above this*/ } /*cont*/ parameter_value_assignmentE { $$ = new AstClassOrPackageRef{$1, *$1, $1, $3}; $$ = $1; } diff --git a/test_regress/t/t_class_extends2.out b/test_regress/t/t_class_extends2.out new file mode 100644 index 000000000..9b587f905 --- /dev/null +++ b/test_regress/t/t_class_extends2.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_class_extends2.v:18:19: Unsupported: Hierarchical class references + 18 | class Ext extends Pkg::Base0; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_class_extends2.pl b/test_regress/t/t_class_extends2.pl new file mode 100755 index 000000000..8a9b721f2 --- /dev/null +++ b/test_regress/t/t_class_extends2.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(linter => 1); + +lint( + fails => $Self->{vlt}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_extends2.v b/test_regress/t/t_class_extends2.v new file mode 100644 index 000000000..8c30f0c6b --- /dev/null +++ b/test_regress/t/t_class_extends2.v @@ -0,0 +1,47 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +package Pkg; +class Base0; + int baseonly; + int baseover; + + function void b_set_bo(int v); baseover = v; endfunction + function int b_get_bo(); return baseover; endfunction + function int get_bo(); return baseover; endfunction +endclass +endpackage + +class Ext extends Pkg::Base0; + int baseover; + int extonly; + + function void e_set_bo(int v); baseover = v; endfunction + function int e_get_bo(); return baseover; endfunction + function int get_bo(); return baseover; endfunction +endclass + +module t (/*AUTOARG*/); + initial begin + Ext c; + c = new; + c.baseonly = 10; + c.baseover = 20; + c.extonly = 30; + if (c.baseonly != 10) $stop; + if (c.baseover != 20) $stop; + if (c.extonly != 30) $stop; + + c.b_set_bo(100); + c.e_set_bo(200); + if (c.b_get_bo() != 100) $stop; + if (c.e_get_bo() != 200) $stop; + if (c.get_bo() != 200) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_class_extends_colon.out b/test_regress/t/t_class_extends_colon.out new file mode 100644 index 000000000..ae67bbf79 --- /dev/null +++ b/test_regress/t/t_class_extends_colon.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_class_extends_colon.v:20:21: Unsupported: Hierarchical class references + 20 | class Cls12 extends Pkg::Icls1; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_class_extends_colon.pl b/test_regress/t/t_class_extends_colon.pl new file mode 100755 index 000000000..8a9b721f2 --- /dev/null +++ b/test_regress/t/t_class_extends_colon.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(linter => 1); + +lint( + fails => $Self->{vlt}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_extends_colon.v b/test_regress/t/t_class_extends_colon.v new file mode 100644 index 000000000..cf4fea9a0 --- /dev/null +++ b/test_regress/t/t_class_extends_colon.v @@ -0,0 +1,35 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface class Icempty; +endclass : Icempty + +package Pkg; +class Icls1 #(parameter PARAM = 12); + localparam LP1 = 1; + function int getParam(); + return PARAM; + endfunction +endclass + +endpackage + +class Cls12 extends Pkg::Icls1; +endclass + +module t(/*AUTOARG*/); + + Cls12 cp12; + + initial begin + cp12 = new; + if (cp12.getParam() != 12) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule