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