Support --bbox-unsup parsing of class extend typedefs

This commit is contained in:
Wilson Snyder 2020-06-09 20:59:45 -04:00
parent 91f30af01f
commit cef56c6fca
5 changed files with 95 additions and 36 deletions

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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; }

View File

@ -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

View File

@ -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