Parser: Move member qualifier unsupporteds out of parser.

This commit is contained in:
Wilson Snyder 2020-07-01 07:31:53 -04:00
parent 236c2141e3
commit 4d5e448664
9 changed files with 126 additions and 62 deletions

View File

@ -2646,6 +2646,7 @@ private:
bool m_dpiTask : 1; // DPI import task (vs. void function)
bool m_isConstructor : 1; // Class constructor
bool m_pure : 1; // DPI import pure (vs. virtual pure)
bool m_virtual : 1; // Virtual method in class
VLifetime m_lifetime; // Lifetime
public:
AstNodeFTask(AstType t, FileLine* fl, const string& name, AstNode* stmtsp)
@ -2662,7 +2663,8 @@ public:
, m_dpiOpenChild(false)
, m_dpiTask(false)
, m_isConstructor(false)
, m_pure(false) {
, m_pure(false)
, m_virtual(false) {
addNOp3p(stmtsp);
cname(name); // Might be overridden by dpi import/export
}
@ -2711,6 +2713,8 @@ public:
bool isConstructor() const { return m_isConstructor; }
void pure(bool flag) { m_pure = flag; }
bool pure() const { return m_pure; }
void isVirtual(bool flag) { m_virtual = flag; }
bool isVirtual() const { return m_virtual; }
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
VLifetime lifetime() const { return m_lifetime; }
};

View File

@ -1041,6 +1041,9 @@ class LinkDotFindVisitor : public AstNVisitor {
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
if (nodep->isClassMember() && nodep->lifetime().isStatic()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' class members");
}
if (!m_statep->forScopeCreation()) {
// Find under either a task or the module's vars
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
@ -2029,8 +2032,7 @@ private:
"ParseRefs should no longer exist");
if (nodep->name() == "this") {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: this");
}
else if (nodep->name() == "super") {
} else if (nodep->name() == "super") {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: super");
}
DotStates lastStates = m_ds;
@ -2630,6 +2632,9 @@ private:
virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE {
UINFO(5, " " << nodep << endl);
checkNoDot(nodep);
if (nodep->classMethod() && nodep->lifetime().isStatic()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' class method");
}
VSymEnt* oldCurSymp = m_curSymp;
{
m_ftaskp = nodep;

View File

@ -41,6 +41,62 @@ typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState
typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty;
//============================================================================
// Member qualifiers
struct VMemberQualifiers {
union {
uint32_t m_flags;
struct {
uint32_t m_local : 1; // Local class item (ignored until warning implemented)
uint32_t m_protected : 1; // Protected class item (ignored until warning implemented)
uint32_t m_rand : 1; // Rand property/member qualifier (ignored until supported)
uint32_t m_randc : 1; // Randc property/member qualifier (ignored until supported)
uint32_t m_virtual : 1; // Virtual property/method qualifier
uint32_t m_automatic : 1; // Automatic property/method qualifier
uint32_t m_const : 1; // Const property/method qualifier
uint32_t m_static : 1; // Static class method
};
};
static VMemberQualifiers none() {
VMemberQualifiers q;
q.m_flags = 0;
return q;
}
static VMemberQualifiers combine(const VMemberQualifiers& a, const VMemberQualifiers& b) {
VMemberQualifiers q;
q.m_flags = a.m_flags | b.m_flags;
return q;
}
void applyToNodes(AstNodeFTask* nodesp) const {
for (AstNodeFTask* nodep = nodesp; nodep; nodep = VN_CAST(nodep->nextp(), NodeFTask)) {
// Ignored for now: m_local
// Ignored for now: m_protected
if (m_virtual) nodep->isVirtual(true);
if (m_automatic) nodep->lifetime(VLifetime::AUTOMATIC);
if (m_static) nodep->lifetime(VLifetime::STATIC);
if (m_const || m_rand || m_randc) {
nodep->v3error("Syntax error: 'const'/'rand'/'randc' not allowed before "
"function/task declaration");
}
}
}
void applyToNodes(AstVar* nodesp) const {
for (AstVar* nodep = nodesp; nodep; nodep = VN_CAST(nodep->nextp(), Var)) {
// Ignored for now: m_local
// Ignored for now: m_protected
// Ignored for now: m_rand
// Ignored for now: m_randc
if (m_automatic) nodep->lifetime(VLifetime::AUTOMATIC);
if (m_static) nodep->lifetime(VLifetime::STATIC);
if (m_const) nodep->isConst(true);
if (m_virtual) {
nodep->v3error("Syntax error: 'virtual' not allowed before var declaration");
}
}
}
};
//============================================================================
// Parser YYSType, e.g. for parser's yylval
// We can't use bison's %union as we want to pass the fileline with all tokens
@ -55,6 +111,7 @@ struct V3ParseBisonYYSType {
int cint;
double cdouble;
bool cbool;
VMemberQualifiers qualifiers;
V3UniqState uniqstate;
V3ImportProperty iprop;
VSigning::en signstate;

View File

@ -3700,6 +3700,9 @@ private:
nodep->didWidth(true);
return;
}
if (nodep->isVirtual()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'virtual' class method");
}
// Function hasn't been widthed, so make it so.
// Would use user1 etc, but V3Width called from too many places to spend a user
nodep->doingWidth(true);

View File

@ -1868,6 +1868,7 @@ struct_union_memberList<nodep>: // IEEE: { struct_union_member }
;
struct_union_member<nodep>: // ==IEEE: struct_union_member
// // UNSUP random_qualifer not propagagted until have randomize support
random_qualifierE data_type_or_void
/*mid*/ { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member.
/*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; }
@ -1904,9 +1905,9 @@ member_decl_assignment<memberp>: // Derived from IEEE: variable_decl_assignment
| '=' class_new { NULL; BBUNSUP($1, "Unsupported: member declaration assignment with new()"); }
;
list_of_variable_decl_assignments<nodep>: // ==IEEE: list_of_variable_decl_assignments
list_of_variable_decl_assignments<varp>: // ==IEEE: list_of_variable_decl_assignments
variable_decl_assignment { $$ = $1; }
| list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = $1->addNextNull($3); }
| list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = VN_CAST($1->addNextNull($3), Var); }
;
variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
@ -1970,14 +1971,14 @@ variable_dimension<rangep>: // ==IEEE: variable_dimension
// // '[' '$' ':' expr ']' -- anyrange:expr:$
;
random_qualifierE: // IEEE: random_qualifier + empty
/*empty*/ { }
| random_qualifier { }
random_qualifierE<qualifiers>: // IEEE: random_qualifier + empty
/*empty*/ { $$ = VMemberQualifiers::none(); }
| random_qualifier { $$ = $1; }
;
random_qualifier: // ==IEEE: random_qualifier
yRAND { } // Ignored until we support randomize()
| yRANDC { } // Ignored until we support randomize()
random_qualifier<qualifiers>: // ==IEEE: random_qualifier
yRAND { $$ = VMemberQualifiers::none(); $$.m_rand = true; }
| yRANDC { $$ = VMemberQualifiers::none(); $$.m_randc = true; }
;
taggedE:
@ -2062,20 +2063,22 @@ data_declaration<nodep>: // ==IEEE: data_declaration
;
class_property<nodep>: // ==IEEE: class_property, which is {property_qualifier} data_declaration
memberQualResetListE data_declarationVarClass { $$ = $2; }
| memberQualResetListE type_declaration { $$ = $2; }
| memberQualResetListE package_import_declaration { $$ = $2; }
memberQualListE data_declarationVarClass { $$ = $2; $1.applyToNodes($2); }
// // UNSUP: Import needs to apply local/protected from memberQualList, and error on others
| memberQualListE type_declaration { $$ = $2; }
// // UNSUP: Import needs to apply local/protected from memberQualList, and error on others
| memberQualListE package_import_declaration { $$ = $2; }
// // IEEE: virtual_interface_declaration
// // "yVIRTUAL yID yID" looks just like a data_declaration
// // Therefore the virtual_interface_declaration term isn't used
;
data_declarationVar<nodep>: // IEEE: part of data_declaration
data_declarationVar<varp>: // IEEE: part of data_declaration
// // The first declaration has complications between assuming what's the type vs ID declaring
data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; }
;
data_declarationVarClass<nodep>: // IEEE: part of data_declaration (for class_property)
data_declarationVarClass<varp>: // IEEE: part of data_declaration (for class_property)
// // The first declaration has complications between assuming what's the type vs ID declaring
data_declarationVarFrontClass list_of_variable_decl_assignments ';' { $$ = $2; }
;
@ -6000,51 +6003,47 @@ class_item<nodep>: // ==IEEE: class_item
;
class_method<nodep>: // ==IEEE: class_method
memberQualResetListE task_declaration { $$ = $2; }
| memberQualResetListE function_declaration { $$ = $2; }
| yPURE yVIRTUAL__ETC memberQualResetListE method_prototype ';'
memberQualListE task_declaration { $$ = $2; $1.applyToNodes($2); }
| memberQualListE function_declaration { $$ = $2; $1.applyToNodes($2); }
| yPURE yVIRTUAL__ETC memberQualListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: pure virtual class method"); }
| yEXTERN memberQualResetListE method_prototype ';'
| yEXTERN memberQualListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class method prototype"); }
// // IEEE: "method_qualifierE class_constructor_declaration"
// // part of function_declaration
| yEXTERN memberQualResetListE class_constructor_prototype
| yEXTERN memberQualListE class_constructor_prototype
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class"); }
;
// IEEE: class_constructor_prototype
// See function_declaration
class_item_qualifier<nodep>: // IEEE: class_item_qualifier minus ySTATIC
// // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
yPROTECTED { $$ = NULL; } // Ignoring protected until warning implemented
| yLOCAL__ETC { $$ = NULL; } // Ignoring local until warning implemented
| ySTATIC__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'static' class item"); }
;
memberQualResetListE<nodep>: // Called from class_property for all qualifiers before yVAR
memberQualListE<qualifiers>: // Called from class_property for all qualifiers before yVAR
// // Also before method declarations, to prevent grammar conflict
// // Thus both types of qualifiers (method/property) are here
/*empty*/ { $$ = NULL; }
/*empty*/ { $$ = VMemberQualifiers::none(); }
| memberQualList { $$ = $1; }
;
memberQualList<nodep>:
memberQualList<qualifiers>:
memberQualOne { $$ = $1; }
| memberQualList memberQualOne { $$ = AstNode::addNextNull($1, $2); }
| memberQualList memberQualOne { $$ = VMemberQualifiers::combine($1, $2); }
;
memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
memberQualOne<qualifiers>: // IEEE: property_qualifier + method_qualifier
// // Part of method_qualifier and property_qualifier
class_item_qualifier { $$ = $1; }
// // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
yPROTECTED { $$ = VMemberQualifiers::none(); $$.m_protected = true; }
| yLOCAL__ETC { $$ = VMemberQualifiers::none(); $$.m_local = true; }
| ySTATIC__ETC { $$ = VMemberQualifiers::none(); $$.m_static = true; }
// // Part of method_qualifier only
| yVIRTUAL__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: virtual class member qualifier"); }
| yVIRTUAL__ETC { $$ = VMemberQualifiers::none(); $$.m_virtual = true; }
// // Part of property_qualifier only
| random_qualifier { $$ = NULL; }
| random_qualifier { $$ = $1; }
// // Part of lifetime, but here as ySTATIC can be in different positions
| yAUTOMATIC { $$ = NULL; BBUNSUP($1, "Unsupported: automatic class member qualifier"); }
| yAUTOMATIC { $$ = VMemberQualifiers::none(); $$.m_automatic = true; }
// // Part of data_declaration, but not in data_declarationVarFrontClass
| yCONST__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: const class member qualifier"); }
| yCONST__ETC { $$ = VMemberQualifiers::none(); $$.m_const = true; }
;
//**********************************************************************

View File

@ -1,4 +1,5 @@
%Error-UNSUPPORTED: t/t_class_name.v:12:4: Unsupported: 'static' class item
%Error-UNSUPPORTED: t/t_class_name.v:12:16: Unsupported: 'static' class method
: ... In instance t
12 | static task static_name;
| ^~~~~~
| ^~~~~~~~~~~
%Error: Exiting due to

View File

@ -1,10 +1,13 @@
%Error-UNSUPPORTED: t/t_class_static_order.v:23:4: Unsupported: 'static' class item
%Error-UNSUPPORTED: t/t_class_static_order.v:23:16: Unsupported: 'static' class members
: ... In instance t
23 | static ClsZ z = new;
| ^~~~~~
%Error-UNSUPPORTED: t/t_class_static_order.v:34:4: Unsupported: 'static' class item
| ^
%Error-UNSUPPORTED: t/t_class_static_order.v:34:16: Unsupported: 'static' class members
: ... In instance t
34 | static ClsA a = new;
| ^~~~~~
%Error-UNSUPPORTED: t/t_class_static_order.v:35:4: Unsupported: 'static' class item
| ^
%Error-UNSUPPORTED: t/t_class_static_order.v:35:16: Unsupported: 'static' class members
: ... In instance t
35 | static ClsB b = new;
| ^~~~~~
| ^
%Error: Exiting due to

View File

@ -7,22 +7,13 @@
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:14:26: Unsupported: class parameters
14 | localparam LOCPAR = 10;
| ^
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:25:4: Unsupported: virtual class member qualifier
25 | virtual function void func_virtual; endfunction
| ^~~~~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:26:4: Unsupported: pure virtual class method
26 | pure virtual function void func_pure_virtual;
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:27:4: Unsupported: pure virtual class method
27 | pure virtual function void func_pure_virtual;
| ^~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:27:4: Unsupported: automatic class member qualifier
27 | automatic function void func_automatic; endfunction
| ^~~~~~~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:28:4: Unsupported: const class member qualifier
28 | const function void func_const; endfunction
| ^~~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:29:4: Unsupported: extern class method prototype
29 | extern task exttask;
%Error: t/t_class_unsup_bad.v:29:24: Syntax error: 'const'/'rand'/'randc' not allowed before function/task declaration
29 | const function void func_const; endfunction
| ^~~~~~~~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:30:4: Unsupported: extern class method prototype
30 | extern task exttask;
| ^~~~~~
%Error-UNSUPPORTED: t/t_class_unsup_bad.v:42:4: Unsupported: virtual class member qualifier
42 | virtual function uvm_root get_root();
| ^~~~~~~
%Error: Exiting due to

View File

@ -13,6 +13,7 @@ typedef interface class ic;
class C #(parameter P=1);
localparam LOCPAR = 10;
int imember;
static int istatic;
local int loc;
protected int prot;