Support --bbox-unsup parsing of class extern function/task.
This commit is contained in:
parent
d84c7df38f
commit
46e10173f8
|
|
@ -100,6 +100,13 @@ public:
|
||||||
reinsert(nodep, parentp);
|
reinsert(nodep, parentp);
|
||||||
pushScope(symp);
|
pushScope(symp);
|
||||||
}
|
}
|
||||||
|
void pushNewUnderNodeOrCurrent(AstNode* nodep, AstNode* parentp) {
|
||||||
|
if (parentp) {
|
||||||
|
pushNewUnder(nodep, findNewTable(parentp));
|
||||||
|
} else {
|
||||||
|
pushNewUnder(nodep, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
void pushScope(VSymEnt* symp) {
|
void pushScope(VSymEnt* symp) {
|
||||||
m_sympStack.push_back(symp);
|
m_sympStack.push_back(symp);
|
||||||
m_symCurrentp = symp;
|
m_symCurrentp = symp;
|
||||||
|
|
|
||||||
|
|
@ -3782,7 +3782,7 @@ lifetime<lifetime>: // ==IEEE: lifetime
|
||||||
taskId<ftaskp>:
|
taskId<ftaskp>:
|
||||||
tfIdScoped
|
tfIdScoped
|
||||||
{ $$ = new AstTask($<fl>1, *$<strp>1, NULL);
|
{ $$ = new AstTask($<fl>1, *$<strp>1, NULL);
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
|
funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_body_declaration
|
||||||
|
|
@ -3791,22 +3791,22 @@ funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_bod
|
||||||
/**/ tfIdScoped
|
/**/ tfIdScoped
|
||||||
{ $$ = new AstFunc($<fl>1,*$<strp>1,NULL,
|
{ $$ = new AstFunc($<fl>1,*$<strp>1,NULL,
|
||||||
new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
|
new AstBasicDType($<fl>1, LOGIC_IMPLICIT));
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); }
|
||||||
| signingE rangeList tfIdScoped
|
| signingE rangeList tfIdScoped
|
||||||
{ $$ = new AstFunc($<fl>3,*$<strp>3,NULL,
|
{ $$ = new AstFunc($<fl>3,*$<strp>3,NULL,
|
||||||
GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
|
GRAMMARP->addRange(new AstBasicDType($<fl>3, LOGIC_IMPLICIT, $1), $2,true));
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>3); }
|
||||||
| signing tfIdScoped
|
| signing tfIdScoped
|
||||||
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,
|
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,
|
||||||
new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
|
new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $1));
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
|
||||||
| data_type tfIdScoped
|
| data_type tfIdScoped
|
||||||
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,$1);
|
{ $$ = new AstFunc($<fl>2,*$<strp>2,NULL,$1);
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
|
||||||
// // To verilator tasks are the same as void functions (we separately detect time passing)
|
// // To verilator tasks are the same as void functions (we separately detect time passing)
|
||||||
| yVOID tfIdScoped
|
| yVOID tfIdScoped
|
||||||
{ $$ = new AstTask($<fl>2, *$<strp>2, NULL);
|
{ $$ = new AstTask($<fl>2, *$<strp>2, NULL);
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
|
funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
|
||||||
|
|
@ -3822,7 +3822,7 @@ funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
|
||||||
{ $$ = new AstFunc($<fl>2, "new", NULL, NULL);
|
{ $$ = new AstFunc($<fl>2, "new", NULL, NULL);
|
||||||
BBUNSUP($<fl>2, "Unsupported: scoped new constructor");
|
BBUNSUP($<fl>2, "Unsupported: scoped new constructor");
|
||||||
$$->isConstructor(true);
|
$$->isConstructor(true);
|
||||||
SYMP->pushNewUnder($$, NULL); }
|
SYMP->pushNewUnderNodeOrCurrent($$, $<scp>1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
|
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
|
||||||
|
|
@ -5876,7 +5876,7 @@ ps_id_etc<varrefp>: // package_scope + general id
|
||||||
//=== Below rules assume special scoping per above
|
//=== Below rules assume special scoping per above
|
||||||
|
|
||||||
packageClassScopeNoId<packagep>: // IEEE: [package_scope] not followed by yaID
|
packageClassScopeNoId<packagep>: // IEEE: [package_scope] not followed by yaID
|
||||||
packageClassScope { $$ = $1; SYMP->nextId(NULL); }
|
packageClassScope { $$ = $1; $<scp>$ = $<scp>1; SYMP->nextId(NULL); }
|
||||||
;
|
;
|
||||||
|
|
||||||
packageClassScopeE<packagep>: // IEEE: [package_scope]
|
packageClassScopeE<packagep>: // IEEE: [package_scope]
|
||||||
|
|
@ -5884,8 +5884,8 @@ packageClassScopeE<packagep>: // IEEE: [package_scope]
|
||||||
// // if not needed must use packageClassScopeNoId
|
// // if not needed must use packageClassScopeNoId
|
||||||
// // TODO: To support classes should return generic type, not packagep
|
// // TODO: To support classes should return generic type, not packagep
|
||||||
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
|
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
|
||||||
/* empty */ { $$ = NULL; }
|
/* empty */ { $$ = NULL; $<scp>$ = NULL; }
|
||||||
| packageClassScope { $$ = $1; }
|
| packageClassScope { $$ = $1; $<scp>$ = $<scp>1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
packageClassScope<packagep>: // IEEE: class_scope + type
|
packageClassScope<packagep>: // IEEE: class_scope + type
|
||||||
|
|
@ -5893,10 +5893,10 @@ packageClassScope<packagep>: // IEEE: class_scope + type
|
||||||
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
// // IMPORTANT: The lexer will parse the following ID to be in the found package
|
||||||
// // if not needed must use packageClassScopeNoId
|
// // if not needed must use packageClassScopeNoId
|
||||||
// // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
|
// // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
|
||||||
packageClassScopeList { $$ = $1; }
|
packageClassScopeList { $$ = $1; $<scp>$ = $<scp>1; }
|
||||||
| localNextId yP_COLONCOLON { $$ = $1; }
|
| localNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||||
| dollarUnitNextId yP_COLONCOLON { $$ = $1; }
|
| dollarUnitNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||||
| dollarUnitNextId yP_COLONCOLON packageClassScopeList { $$ = $3; }
|
| dollarUnitNextId yP_COLONCOLON packageClassScopeList { $$ = $3; $<scp>$ = $<scp>3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
packageClassScopeList<packagep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
|
packageClassScopeList<packagep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
|
||||||
|
|
@ -5905,8 +5905,8 @@ packageClassScopeList<packagep>: // IEEE: class_type: "id [ parameter_value_assi
|
||||||
// // if not needed must use packageClassScopeNoId
|
// // if not needed must use packageClassScopeNoId
|
||||||
// // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
|
// // In this parser <package_identifier>:: and <class_identifier>:: are indistinguishible
|
||||||
// // If you follow the rules down, class_type is really a list via ps_class_identifier
|
// // If you follow the rules down, class_type is really a list via ps_class_identifier
|
||||||
packageClassScopeItem { $$ = $1; }
|
packageClassScopeItem { $$ = $1; $<scp>$ = $<scp>1; }
|
||||||
| packageClassScopeList packageClassScopeItem { $$ = $2; BBUNSUP($2, "Unsupported: Nested :: references"); }
|
| packageClassScopeList packageClassScopeItem { $$ = $2; $<scp>$ = $<scp>2; BBUNSUP($2, "Unsupported: Nested :: references"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
packageClassScopeItem<packagep>: // IEEE: package_scope or [package_scope]::[class_scope]
|
packageClassScopeItem<packagep>: // IEEE: package_scope or [package_scope]::[class_scope]
|
||||||
|
|
@ -5917,12 +5917,12 @@ packageClassScopeItem<packagep>: // IEEE: package_scope or [package_scope]::[cla
|
||||||
idCC
|
idCC
|
||||||
/*mid*/ { SYMP->nextId($<scp>1); }
|
/*mid*/ { SYMP->nextId($<scp>1); }
|
||||||
/*cont*/ yP_COLONCOLON
|
/*cont*/ yP_COLONCOLON
|
||||||
{ $$ = VN_CAST($<scp>1, Package); } // UNSUP classes
|
{ $$ = VN_CAST($<scp>1, Package); $<scp>$ = $<scp>1; } // UNSUP classes
|
||||||
//
|
//
|
||||||
| idCC parameter_value_assignment
|
| idCC parameter_value_assignment
|
||||||
/*mid*/ { SYMP->nextId($<scp>1); } // Change next *after* we handle parameters, not before
|
/*mid*/ { SYMP->nextId($<scp>1); } // Change next *after* we handle parameters, not before
|
||||||
/*cont*/ yP_COLONCOLON
|
/*cont*/ yP_COLONCOLON
|
||||||
{ $$ = VN_CAST($<scp>1, Package); // UNSUP classes
|
{ $$ = VN_CAST($<scp>1, Package); $<scp>$ = $<scp>1; // UNSUP classes
|
||||||
if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }
|
if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue