From 46e10173f84e3aa80a407f24aac4a27d4a3a3d0d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 8 Jun 2020 22:33:57 -0400 Subject: [PATCH] Support --bbox-unsup parsing of class extern function/task. --- src/V3ParseSym.h | 7 +++++++ src/verilog.y | 36 ++++++++++++++++---------------- test_regress/t/t_class_extern.pl | 18 ++++++++++++++++ test_regress/t/t_class_extern.v | 18 ++++++++++++++++ 4 files changed, 61 insertions(+), 18 deletions(-) create mode 100755 test_regress/t/t_class_extern.pl create mode 100644 test_regress/t/t_class_extern.v diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index b9bdd13fd..474b4630b 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -100,6 +100,13 @@ public: reinsert(nodep, parentp); pushScope(symp); } + void pushNewUnderNodeOrCurrent(AstNode* nodep, AstNode* parentp) { + if (parentp) { + pushNewUnder(nodep, findNewTable(parentp)); + } else { + pushNewUnder(nodep, NULL); + } + } void pushScope(VSymEnt* symp) { m_sympStack.push_back(symp); m_symCurrentp = symp; diff --git a/src/verilog.y b/src/verilog.y index d0a3f567b..d841259d8 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3782,7 +3782,7 @@ lifetime: // ==IEEE: lifetime taskId: tfIdScoped { $$ = new AstTask($1, *$1, NULL); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $1); } ; funcId: // IEEE: function_data_type_or_implicit + part of function_body_declaration @@ -3791,22 +3791,22 @@ funcId: // IEEE: function_data_type_or_implicit + part of function_bod /**/ tfIdScoped { $$ = new AstFunc($1,*$1,NULL, new AstBasicDType($1, LOGIC_IMPLICIT)); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $1); } | signingE rangeList tfIdScoped { $$ = new AstFunc($3,*$3,NULL, GRAMMARP->addRange(new AstBasicDType($3, LOGIC_IMPLICIT, $1), $2,true)); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $3); } | signing tfIdScoped { $$ = new AstFunc($2,*$2,NULL, new AstBasicDType($2, LOGIC_IMPLICIT, $1)); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $2); } | data_type tfIdScoped { $$ = new AstFunc($2,*$2,NULL,$1); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $2); } // // To verilator tasks are the same as void functions (we separately detect time passing) | yVOID tfIdScoped { $$ = new AstTask($2, *$2, NULL); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $2); } ; funcIdNew: // IEEE: from class_constructor_declaration @@ -3822,7 +3822,7 @@ funcIdNew: // IEEE: from class_constructor_declaration { $$ = new AstFunc($2, "new", NULL, NULL); BBUNSUP($2, "Unsupported: scoped new constructor"); $$->isConstructor(true); - SYMP->pushNewUnder($$, NULL); } + SYMP->pushNewUnderNodeOrCurrent($$, $1); } ; tfIdScoped: // IEEE: part of function_body_declaration/task_body_declaration @@ -5876,7 +5876,7 @@ ps_id_etc: // package_scope + general id //=== Below rules assume special scoping per above packageClassScopeNoId: // IEEE: [package_scope] not followed by yaID - packageClassScope { $$ = $1; SYMP->nextId(NULL); } + packageClassScope { $$ = $1; $$ = $1; SYMP->nextId(NULL); } ; packageClassScopeE: // IEEE: [package_scope] @@ -5884,8 +5884,8 @@ packageClassScopeE: // IEEE: [package_scope] // // if not needed must use packageClassScopeNoId // // TODO: To support classes should return generic type, not packagep // // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ] - /* empty */ { $$ = NULL; } - | packageClassScope { $$ = $1; } + /* empty */ { $$ = NULL; $$ = NULL; } + | packageClassScope { $$ = $1; $$ = $1; } ; packageClassScope: // IEEE: class_scope + type @@ -5893,10 +5893,10 @@ packageClassScope: // IEEE: class_scope + type // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // In this parser :: and :: are indistinguishible - packageClassScopeList { $$ = $1; } - | localNextId yP_COLONCOLON { $$ = $1; } - | dollarUnitNextId yP_COLONCOLON { $$ = $1; } - | dollarUnitNextId yP_COLONCOLON packageClassScopeList { $$ = $3; } + packageClassScopeList { $$ = $1; $$ = $1; } + | localNextId yP_COLONCOLON { $$ = $1; $$ = $1; } + | dollarUnitNextId yP_COLONCOLON { $$ = $1; $$ = $1; } + | dollarUnitNextId yP_COLONCOLON packageClassScopeList { $$ = $3; $$ = $3; } ; packageClassScopeList: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE @@ -5905,8 +5905,8 @@ packageClassScopeList: // IEEE: class_type: "id [ parameter_value_assi // // if not needed must use packageClassScopeNoId // // In this parser :: and :: are indistinguishible // // If you follow the rules down, class_type is really a list via ps_class_identifier - packageClassScopeItem { $$ = $1; } - | packageClassScopeList packageClassScopeItem { $$ = $2; BBUNSUP($2, "Unsupported: Nested :: references"); } + packageClassScopeItem { $$ = $1; $$ = $1; } + | packageClassScopeList packageClassScopeItem { $$ = $2; $$ = $2; BBUNSUP($2, "Unsupported: Nested :: references"); } ; packageClassScopeItem: // IEEE: package_scope or [package_scope]::[class_scope] @@ -5917,12 +5917,12 @@ packageClassScopeItem: // IEEE: package_scope or [package_scope]::[cla idCC /*mid*/ { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON - { $$ = VN_CAST($1, Package); } // UNSUP classes + { $$ = VN_CAST($1, Package); $$ = $1; } // UNSUP classes // | idCC parameter_value_assignment /*mid*/ { SYMP->nextId($1); } // Change next *after* we handle parameters, not before /*cont*/ yP_COLONCOLON - { $$ = VN_CAST($1, Package); // UNSUP classes + { $$ = VN_CAST($1, Package); $$ = $1; // UNSUP classes if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); } ; diff --git a/test_regress/t/t_class_extern.pl b/test_regress/t/t_class_extern.pl new file mode 100755 index 000000000..988090fc2 --- /dev/null +++ b/test_regress/t/t_class_extern.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +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 +# 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( + v_flags2 => ["--bbox-unsup --debug-exit-parse"], # Unsupported + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_extern.v b/test_regress/t/t_class_extern.v new file mode 100644 index 000000000..60a319422 --- /dev/null +++ b/test_regress/t/t_class_extern.v @@ -0,0 +1,18 @@ +// 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 + +class Cls #(type REQ=int); + extern virtual function void extfunc(); +endclass + +function void Cls::extfunc(); + REQ t; // Declared in class when externed, so must be found there +endfunction + +module f; + function void normal(); + endfunction +endmodule