From 50c28fa9d3d1bb9191a17e6dc71155ec2cb3ef33 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 2 Jul 2020 08:24:35 -0400 Subject: [PATCH] Parser: Move 'pure virtual' and 'extern' unsupported messages down out of parser. --- src/V3Ast.h | 8 ++++++++ src/V3LinkDot.cpp | 3 +++ src/V3Width.cpp | 2 +- src/verilog.y | 12 ++++++------ test_regress/t/t_class_extern.out | 4 ++++ test_regress/t/t_class_extern.pl | 13 +++++++++---- test_regress/t/t_class_extern.v | 15 +++++++++------ test_regress/t/t_class_unsup_bad.out | 6 ------ test_regress/t/t_class_virtual_pure.out | 7 +++++++ test_regress/t/t_class_virtual_pure.pl | 19 +++++++++++++++++++ test_regress/t/t_class_virtual_pure.v | 9 +++++++++ test_regress/t/t_class_vparam_unsup.out | 3 --- 12 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 test_regress/t/t_class_extern.out create mode 100644 test_regress/t/t_class_virtual_pure.out create mode 100755 test_regress/t/t_class_virtual_pure.pl create mode 100644 test_regress/t/t_class_virtual_pure.v diff --git a/src/V3Ast.h b/src/V3Ast.h index b64d67134..44102ce33 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2638,6 +2638,7 @@ private: bool m_taskPublic : 1; // Public task bool m_attrIsolateAssign : 1; // User isolate_assignments attribute bool m_classMethod : 1; // Class method + bool m_extern : 1; // Extern prototype bool m_prototype : 1; // Just a prototype bool m_dpiExport : 1; // DPI exported bool m_dpiImport : 1; // DPI imported @@ -2646,6 +2647,7 @@ private: bool m_dpiTask : 1; // DPI import task (vs. void function) bool m_isConstructor : 1; // Class constructor bool m_pure : 1; // DPI import pure (vs. virtual pure) + bool m_pureVirtual : 1; // Pure virtual bool m_virtual : 1; // Virtual method in class VLifetime m_lifetime; // Lifetime public: @@ -2656,6 +2658,7 @@ public: , m_taskPublic(false) , m_attrIsolateAssign(false) , m_classMethod(false) + , m_extern(false) , m_prototype(false) , m_dpiExport(false) , m_dpiImport(false) @@ -2664,6 +2667,7 @@ public: , m_dpiTask(false) , m_isConstructor(false) , m_pure(false) + , m_pureVirtual(false) , m_virtual(false) { addNOp3p(stmtsp); cname(name); // Might be overridden by dpi import/export @@ -2697,6 +2701,8 @@ public: bool attrIsolateAssign() const { return m_attrIsolateAssign; } void classMethod(bool flag) { m_classMethod = flag; } bool classMethod() const { return m_classMethod; } + void isExtern(bool flag) { m_extern = flag; } + bool isExtern() const { return m_extern; } void prototype(bool flag) { m_prototype = flag; } bool prototype() const { return m_prototype; } void dpiExport(bool flag) { m_dpiExport = flag; } @@ -2713,6 +2719,8 @@ public: bool isConstructor() const { return m_isConstructor; } void pure(bool flag) { m_pure = flag; } bool pure() const { return m_pure; } + void pureVirtual(bool flag) { m_pureVirtual = flag; } + bool pureVirtual() const { return m_pureVirtual; } void isVirtual(bool flag) { m_virtual = flag; } bool isVirtual() const { return m_virtual; } void lifetime(const VLifetime& flag) { m_lifetime = flag; } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 034a73c98..6edddc5f5 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2606,6 +2606,9 @@ private: if (nodep->classMethod() && nodep->lifetime().isStatic()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' class method"); } + if (nodep->isExtern()) { + nodep->v3warn(E_UNSUPPORTED, "Unsupported: extern class methods"); + } VSymEnt* oldCurSymp = m_curSymp; { m_ftaskp = nodep; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index e2222f5d7..de04c0a82 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3700,7 +3700,7 @@ private: nodep->didWidth(true); return; } - if (nodep->isVirtual()) { + if (nodep->isVirtual() || nodep->pureVirtual()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'virtual' class method"); } // Function hasn't been widthed, so make it so. diff --git a/src/verilog.y b/src/verilog.y index 0aae0da4b..a270ccf72 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3767,9 +3767,9 @@ funcIsolateE: | yVL_ISOLATE_ASSIGNMENTS { $$ = 1; } ; -method_prototype: - task_prototype { } - | function_prototype { } +method_prototype: + task_prototype { $$ = $1; } + | function_prototype { $$ = $1; } ; lifetimeE: // IEEE: [lifetime] @@ -6010,13 +6010,13 @@ class_method: // ==IEEE: class_method memberQualListE task_declaration { $$ = $2; $1.applyToNodes($2); } | memberQualListE function_declaration { $$ = $2; $1.applyToNodes($2); } | yPURE yVIRTUAL__ETC memberQualListE method_prototype ';' - { $$ = NULL; BBUNSUP($1, "Unsupported: pure virtual class method"); } + { $$ = $4; $3.applyToNodes($4); $4->pureVirtual(true); $4->isVirtual(true); } | yEXTERN memberQualListE method_prototype ';' - { $$ = NULL; BBUNSUP($1, "Unsupported: extern class method prototype"); } + { $$ = $3; $2.applyToNodes($3); $3->isExtern(true); } // // IEEE: "method_qualifierE class_constructor_declaration" // // part of function_declaration | yEXTERN memberQualListE class_constructor_prototype - { $$ = NULL; BBUNSUP($1, "Unsupported: extern class"); } + { $$ = $3; $2.applyToNodes($3); $3->isExtern(true); } ; // IEEE: class_constructor_prototype diff --git a/test_regress/t/t_class_extern.out b/test_regress/t/t_class_extern.out new file mode 100644 index 000000000..6adffc70c --- /dev/null +++ b/test_regress/t/t_class_extern.out @@ -0,0 +1,4 @@ +%Error-UNSUPPORTED: t/t_class_extern.v:11:15: Unsupported: Out of class block function declaration + 11 | function void Cls::extfunc(); + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_extern.pl b/test_regress/t/t_class_extern.pl index 988090fc2..b8b56e6f0 100755 --- a/test_regress/t/t_class_extern.pl +++ b/test_regress/t/t_class_extern.pl @@ -2,17 +2,22 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # -# Copyright 2019 by Wilson Snyder. This program is free software; you +# 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(vlt => 1); +scenarios(simulator => 1); -lint( - v_flags2 => ["--bbox-unsup --debug-exit-parse"], # Unsupported +compile( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, ); +#execute( +# check_finished => 1, +# ); + ok(1); 1; diff --git a/test_regress/t/t_class_extern.v b/test_regress/t/t_class_extern.v index 60a319422..231031ff1 100644 --- a/test_regress/t/t_class_extern.v +++ b/test_regress/t/t_class_extern.v @@ -4,15 +4,18 @@ // any use, without warranty, 2020 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 -class Cls #(type REQ=int); - extern virtual function void extfunc(); +class Cls; + extern function void extfunc(); endclass function void Cls::extfunc(); - REQ t; // Declared in class when externed, so must be found there + $write("*-* All Finished *-*\n"); + $finish; endfunction -module f; - function void normal(); - endfunction +module t (/*AUTOARG*/); + initial begin + Cls c; + c.extfunc(); + end endmodule diff --git a/test_regress/t/t_class_unsup_bad.out b/test_regress/t/t_class_unsup_bad.out index 23492861e..f5260c57b 100644 --- a/test_regress/t/t_class_unsup_bad.out +++ b/test_regress/t/t_class_unsup_bad.out @@ -7,13 +7,7 @@ %Error-UNSUPPORTED: t/t_class_unsup_bad.v:14:26: Unsupported: class parameters 14 | localparam LOCPAR = 10; | ^ -%Error-UNSUPPORTED: t/t_class_unsup_bad.v:27:4: Unsupported: pure virtual class method - 27 | pure virtual function void func_pure_virtual; - | ^~~~ %Error: t/t_class_unsup_bad.v:29:24: Syntax error: 'const'/'rand'/'randc' not allowed before function/task declaration 29 | const function void func_const; endfunction | ^~~~~~~~~~ -%Error-UNSUPPORTED: t/t_class_unsup_bad.v:30:4: Unsupported: extern class method prototype - 30 | extern task exttask; - | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_virtual_pure.out b/test_regress/t/t_class_virtual_pure.out new file mode 100644 index 000000000..ec7ef63ac --- /dev/null +++ b/test_regress/t/t_class_virtual_pure.out @@ -0,0 +1,7 @@ +%Error-UNSUPPORTED: t/t_class_virtual_pure.v:8:22: Unsupported: 'virtual' class method + 8 | pure virtual task hello(); + | ^~~~~ +%Error-UNSUPPORTED: t/t_class_virtual_pure.v:7:9: Unsupported: virtual class + 7 | virtual class VC; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_virtual_pure.pl b/test_regress/t/t_class_virtual_pure.pl new file mode 100755 index 000000000..009248fc5 --- /dev/null +++ b/test_regress/t/t_class_virtual_pure.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(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_virtual_pure.v b/test_regress/t/t_class_virtual_pure.v new file mode 100644 index 000000000..a87698cb4 --- /dev/null +++ b/test_regress/t/t_class_virtual_pure.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2019 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +virtual class VC; + pure virtual task hello(); +endclass diff --git a/test_regress/t/t_class_vparam_unsup.out b/test_regress/t/t_class_vparam_unsup.out index 084f5eeb2..66f55b199 100644 --- a/test_regress/t/t_class_vparam_unsup.out +++ b/test_regress/t/t_class_vparam_unsup.out @@ -1,7 +1,4 @@ %Error-UNSUPPORTED: t/t_class_vparam_unsup.v:13:58: Unsupported: Parameter classes 13 | pure virtual function void funcname(paramed_class_t #(CTYPE_t) v); | ^~~~~~~ -%Error-UNSUPPORTED: t/t_class_vparam_unsup.v:13:4: Unsupported: pure virtual class method - 13 | pure virtual function void funcname(paramed_class_t #(CTYPE_t) v); - | ^~~~ %Error: Exiting due to