Support --bbox-unsup parsing of class extend typedefs
This commit is contained in:
parent
91f30af01f
commit
cef56c6fca
|
|
@ -145,11 +145,19 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
void importExtends(AstNode* classp) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(classp);
|
||||
UASSERT_OBJ(symp, classp, // Internal problem, because we earlier found it
|
||||
"Extends class package not found");
|
||||
// Walk old sym table and reinsert into current table
|
||||
// We let V3LinkDot report the error instead of us
|
||||
symCurrentp()->importFromClass(&m_syms, symp);
|
||||
}
|
||||
void importItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
UASSERT_OBJ(symp, packagep,
|
||||
// Internal problem, because we earlier found pkg in parsing
|
||||
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
|
||||
"Import package not found");
|
||||
// Walk old sym table and reinsert into current table
|
||||
// We let V3LinkDot report the error instead of us
|
||||
|
|
@ -158,8 +166,7 @@ public:
|
|||
void exportItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Export from this the remote package::id_or_star
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
UASSERT_OBJ(symp, packagep,
|
||||
// Internal problem, because we earlier found pkg in parsing
|
||||
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
|
||||
"Export package not found");
|
||||
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,8 +181,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
|
||||
if (srcp->exported() && !findIdFlat(name)) { // Don't insert over existing entry
|
||||
void importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp,
|
||||
bool honorExport) {
|
||||
if ((!honorExport || srcp->exported())
|
||||
&& !findIdFlat(name)) { // Don't insert over existing entry
|
||||
VSymEnt* symp = new VSymEnt(graphp, srcp);
|
||||
symp->exported(false); // Can't reimport an import without an export
|
||||
symp->imported(true);
|
||||
|
|
@ -198,15 +200,25 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
void importFromClass(VSymGraph* graphp, const VSymEnt* srcp) {
|
||||
// Import tokens from source symbol table into this symbol table
|
||||
// Used for classes in early parsing only to handle "extends"
|
||||
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
|
||||
it != srcp->m_idNameMap.end(); ++it) {
|
||||
importOneSymbol(graphp, it->first, it->second, false);
|
||||
}
|
||||
}
|
||||
void importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
|
||||
// Import tokens from source symbol table into this symbol table
|
||||
if (id_or_star != "*") {
|
||||
IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star);
|
||||
if (it != srcp->m_idNameMap.end()) importOneSymbol(graphp, it->first, it->second);
|
||||
if (it != srcp->m_idNameMap.end()) {
|
||||
importOneSymbol(graphp, it->first, it->second, true);
|
||||
}
|
||||
} else {
|
||||
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
|
||||
it != srcp->m_idNameMap.end(); ++it) {
|
||||
importOneSymbol(graphp, it->first, it->second);
|
||||
importOneSymbol(graphp, it->first, it->second, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2519,7 +2519,7 @@ delay_control<nodep>: //== IEEE: delay_control
|
|||
|
||||
delay_value<nodep>: // ==IEEE:delay_value
|
||||
// // IEEE: ps_identifier
|
||||
ps_id_etc { $$ = $1; }
|
||||
packageClassScopeE varRefBase { $$ = $2; $2->packagep($1); }
|
||||
| yaINTNUM { $$ = new AstConst($<fl>1, *$1); }
|
||||
| yaFLOATNUM { $$ = new AstConst($<fl>1, AstConst::RealDouble(), $1); }
|
||||
| timeNumAdjusted { $$ = $1; }
|
||||
|
|
@ -3824,10 +3824,16 @@ funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
|
|||
|
||||
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
|
||||
// // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
|
||||
id { $<fl>$=$<fl>1; $<strp>$ = $1; }
|
||||
| id/*interface_identifier*/ '.' id { $<fl>$=$<fl>3; $<strp>$ = $3; BBUNSUP($2, "Unsupported: Out of block function declaration"); }
|
||||
| packageClassScope id { $<fl>$=$<fl>2; $<scp>$=$<scp>1; $<strp>$=$<strp>2;
|
||||
BBUNSUP($<fl>1, "Unsupported: Out of class block function declaration"); }
|
||||
id
|
||||
{ $<fl>$ = $<fl>1; $<scp>$ = NULL; $<strp>$ = $1; }
|
||||
//
|
||||
| id/*interface_identifier*/ '.' id
|
||||
{ $<fl>$ = $<fl>3; $<scp>$ = NULL; $<strp>$ = $3;
|
||||
BBUNSUP($2, "Unsupported: Out of block function declaration"); }
|
||||
//
|
||||
| packageClassScope id
|
||||
{ $<fl>$ = $<fl>2; $<scp>$ = $<scp>1; $<strp>$ = $<strp>2;
|
||||
BBUNSUP($<fl>1, "Unsupported: Out of class block function declaration"); }
|
||||
;
|
||||
|
||||
tfGuts<nodep>:
|
||||
|
|
@ -5762,13 +5768,16 @@ class_declaration<nodep>: // ==IEEE: part of class_declaration
|
|||
// // The classExtendsE rule relys on classFront having the
|
||||
// // new class scope correct via classFront
|
||||
classFront parameter_port_listE classExtendsE classImplementsE ';'
|
||||
/*mid*/ { // Allow resolving types declared in base extends class
|
||||
if ($<scp>3) SYMP->importExtends($<scp>3);
|
||||
}
|
||||
/*cont*/ class_itemListE yENDCLASS endLabelE
|
||||
{ $$ = $1; $1->addMembersp($2);
|
||||
$1->extendsp($3);
|
||||
$1->addMembersp($4);
|
||||
$1->addMembersp($6);
|
||||
$1->addMembersp($7);
|
||||
SYMP->popScope($$);
|
||||
GRAMMARP->endLabel($<fl>7, $1, $8); }
|
||||
GRAMMARP->endLabel($<fl>7, $1, $9); }
|
||||
;
|
||||
|
||||
classFront<classp>: // IEEE: part of class_declaration
|
||||
|
|
@ -5792,23 +5801,26 @@ classVirtualE:
|
|||
classExtendsE<nodep>: // IEEE: part of class_declaration
|
||||
// // The classExtendsE rule relys on classFront having the
|
||||
// // new class scope correct via classFront
|
||||
/* empty */ { $$ = NULL; }
|
||||
| yEXTENDS classExtendsList { $$ = $2; }
|
||||
/* empty */ { $$ = NULL; $<scp>$ = NULL; }
|
||||
| yEXTENDS classExtendsList { $$ = $2; $<scp>$ = $<scp>2; }
|
||||
;
|
||||
|
||||
classExtendsList<nodep>: // IEEE: part of class_declaration
|
||||
classExtendsOne { $$ = $1; }
|
||||
classExtendsOne { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| classExtendsList ',' classExtendsOne
|
||||
{ $$ = $3; BBUNSUP($3, "Multiple inheritance illegal on non-interface classes (IEEE 1800-2017 8.13)"
|
||||
", and unsupported for interface classes."); }
|
||||
{ $$ = $3; $<scp>$ = $<scp>3;
|
||||
BBUNSUP($3, "Multiple inheritance illegal on non-interface classes (IEEE 1800-2017 8.13), "
|
||||
"and unsupported for interface classes."); }
|
||||
;
|
||||
|
||||
classExtendsOne<nodep>: // IEEE: part of class_declaration
|
||||
class_typeExtImpList
|
||||
{ $$ = new AstClassExtends($1->fileline(), $1); }
|
||||
// // IEEE: Might not be legal to have more than one set of parameters in an extends
|
||||
{ $$ = new AstClassExtends($1->fileline(), $1);
|
||||
$<scp>$ = $<scp>1; }
|
||||
//
|
||||
| class_typeExtImpList '(' list_of_argumentsE ')'
|
||||
{ $$ = new AstClassExtends($1->fileline(), $1);
|
||||
$<scp>$ = $<scp>1;
|
||||
if ($3) BBUNSUP($3, "Unsupported: extends with parameters"); }
|
||||
;
|
||||
|
||||
|
|
@ -5827,9 +5839,9 @@ classImplementsList<nodep>: // IEEE: part of class_declaration
|
|||
class_typeExtImpList<nodep>: // 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; }
|
||||
class_typeExtImpOne { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| class_typeExtImpList yP_COLONCOLON class_typeExtImpOne
|
||||
{ $$ = $3;
|
||||
{ $$ = $3; $<scp>$ = $<scp>1;
|
||||
// Cannot just add as next() as that breaks implements lists
|
||||
//UNSUP $$ = new AstDot($<fl>1, true, $1, $3);
|
||||
BBUNSUP($2, "Unsupported: Hierarchical class references"); }
|
||||
|
|
@ -5845,13 +5857,18 @@ class_typeExtImpOne<nodep>: // part of IEEE: class_type, where we either get a p
|
|||
/*mid*/ { /* no nextId as not refing it above this*/ }
|
||||
/*cont*/ parameter_value_assignmentE
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, *$1, NULL, NULL);
|
||||
$<scp>$ = $<scp>1;
|
||||
if ($3) BBUNSUP($3->fileline(), "Unsupported: Parameterized classes"); }
|
||||
//
|
||||
// // package_sopeIdFollows expanded
|
||||
| yD_UNIT yP_COLONCOLON
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, "$unit", NULL, NULL);
|
||||
$<scp>$ = NULL; // No purpose otherwise, every symtab can see root
|
||||
SYMP->nextId(PARSEP->rootp()); }
|
||||
//
|
||||
| yLOCAL__COLONCOLON yP_COLONCOLON
|
||||
{ $$ = new AstParseRef($<fl>1, VParseRefExp::PX_TEXT, "local", NULL, NULL);
|
||||
$<scp>$ = NULL; // UNSUP
|
||||
SYMP->nextId(PARSEP->rootp());
|
||||
BBUNSUP($1, "Unsupported: Randomize 'local::'"); }
|
||||
;
|
||||
|
|
@ -5861,10 +5878,6 @@ class_typeExtImpOne<nodep>: // part of IEEE: class_type, where we either get a p
|
|||
// must be included in the rules below.
|
||||
// Each of these must end with {symsPackageDone | symsClassDone}
|
||||
|
||||
ps_id_etc<varrefp>: // package_scope + general id
|
||||
packageClassScopeE varRefBase { $$ = $2; $2->packagep($1); }
|
||||
;
|
||||
|
||||
//=== Below rules assume special scoping per above
|
||||
|
||||
packageClassScopeNoId<packagep>: // IEEE: [package_scope] not followed by yaID
|
||||
|
|
@ -5885,6 +5898,7 @@ packageClassScope<packagep>: // 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 <package_identifier>:: and <class_identifier>:: are indistinguishible
|
||||
// // This copies <scp> to document it is important
|
||||
packageClassScopeList { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| localNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
| dollarUnitNextId yP_COLONCOLON { $$ = $1; $<scp>$ = $<scp>1; }
|
||||
|
|
|
|||
|
|
@ -4,16 +4,25 @@
|
|||
%Error: t/t_class_extends.v:13:21: Found definition of 'Base0' as a CLASS but expected a variable
|
||||
13 | class Base1 extends Base0;
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:17:21: Unsupported: class extends
|
||||
17 | class Base2 extends Base1;
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:18:21: Unsupported: class extends
|
||||
18 | class Base2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:17:21: Found definition of 'Base1' as a CLASS but expected a variable
|
||||
17 | class Base2 extends Base1;
|
||||
%Error: t/t_class_extends.v:18:21: Found definition of 'Base1' as a CLASS but expected a variable
|
||||
18 | class Base2 extends Base1;
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:21:19: Unsupported: class extends
|
||||
21 | class Cls extends Base2;
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:22:19: Unsupported: class extends
|
||||
22 | class Cls extends Base2;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:21:19: Found definition of 'Base2' as a CLASS but expected a variable
|
||||
21 | class Cls extends Base2;
|
||||
%Error: t/t_class_extends.v:22:19: Found definition of 'Base2' as a CLASS but expected a variable
|
||||
22 | class Cls extends Base2;
|
||||
| ^~~~~
|
||||
%Error: t/t_class_extends.v:25:4: Can't find typedef: 'T'
|
||||
25 | T imemberc;
|
||||
| ^
|
||||
%Error-UNSUPPORTED: t/t_class_extends.v:33:43: Unsupported: class extends
|
||||
33 | class uvm__registry #(type T=int) extends uvm_object_wrapper;
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: t/t_class_extends.v:33:43: Found definition of 'uvm_object_wrapper' as a CLASS but expected a variable
|
||||
33 | class uvm__registry #(type T=int) extends uvm_object_wrapper;
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ endclass
|
|||
|
||||
class Base1 extends Base0;
|
||||
int b1member;
|
||||
typedef int T;
|
||||
endclass
|
||||
|
||||
class Base2 extends Base1;
|
||||
|
|
@ -21,8 +22,22 @@ endclass
|
|||
class Cls extends Base2;
|
||||
int imembera;
|
||||
int imemberb;
|
||||
T imemberc;
|
||||
endclass : Cls
|
||||
|
||||
class uvm_object_wrapper;
|
||||
function int create ();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class uvm__registry #(type T=int) extends uvm_object_wrapper;
|
||||
// This override must be in the new symbol table, not
|
||||
// under the extend's symbol table
|
||||
function int create ();
|
||||
T obj;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
initial begin
|
||||
Cls c;
|
||||
|
|
@ -31,11 +46,13 @@ module t (/*AUTOARG*/);
|
|||
c.b2member = 30;
|
||||
c.imembera = 100;
|
||||
c.imemberb = 110;
|
||||
c.imemberc = 120;
|
||||
$display("Display: set = \"%p\"", c); // '{all 4 members}
|
||||
if (c.b1member != 10) $stop;
|
||||
if (c.b2member != 30) $stop;
|
||||
if (c.imembera != 100) $stop;
|
||||
if (c.imemberb != 110) $stop;
|
||||
if (c.imemberc != 120) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue