Merge pull request #1423 from larsclausen/type-id-class-property

Support class properties shadowing type names
This commit is contained in:
Cary R. 2026-07-02 19:01:57 -07:00 committed by GitHub
commit 98d10727f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 166 additions and 10 deletions

View File

@ -0,0 +1,37 @@
// Check that a class property can have the same name as the class.
module test;
bit failed = 1'b0;
`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)
class C;
int C;
function int get;
return C;
endfunction
endclass
C obj;
initial begin
obj = new;
obj.C = 23;
`check(obj.get(), 23);
`check(obj.C, 23);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,39 @@
// Check that a class property can have the same name as an outer type.
module test;
typedef int T;
bit failed = 1'b0;
`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)
class C;
int T;
function int get;
return T;
endfunction
endclass
C obj;
initial begin
obj = new;
obj.T = 11;
`check(obj.get(), 11);
`check(obj.T, 11);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,45 @@
// Check that a class property can shadow a wildcard-imported type name.
package P;
typedef int T;
endpackage
module test;
import P::*;
bit failed = 1'b0;
`define check(val, exp) do \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end \
while(0)
class C;
int T;
function int get;
return T;
endfunction
endclass
C obj;
initial begin
obj = new;
obj.T = 47;
`check(obj.get(), 47);
`check(obj.T, 47);
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -279,8 +279,11 @@ sv_chained_constructor4 vvp_tests/sv_chained_constructor4.json
sv_chained_constructor5 vvp_tests/sv_chained_constructor5.json
sv_class_prop_assign_op1 vvp_tests/sv_class_prop_assign_op1.json
sv_class_prop_assign_op2 vvp_tests/sv_class_prop_assign_op2.json
sv_class_prop_class_name vvp_tests/sv_class_prop_class_name.json
sv_class_prop_logic vvp_tests/sv_class_prop_logic.json
sv_class_prop_packed_dims vvp_tests/sv_class_prop_packed_dims.json
sv_class_prop_type_name vvp_tests/sv_class_prop_type_name.json
sv_class_prop_wildcard_type_name vvp_tests/sv_class_prop_wildcard_type_name.json
sv_class_prop_nest_darray1 vvp_tests/sv_class_prop_nest_darray1.json
sv_class_prop_nest_obj1 vvp_tests/sv_class_prop_nest_obj1.json
sv_class_prop_nest_real1 vvp_tests/sv_class_prop_nest_real1.json

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_class_prop_class_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Classes are not supported",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_class_prop_type_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Classes are not supported",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_class_prop_wildcard_type_name.v",
"iverilog-args" : [ "-g2005-sv" ],
"vlog95" : {
"__comment" : "Classes are not supported",
"type" : "CE"
}
}

15
parse.y
View File

@ -1172,11 +1172,11 @@ class_item /* IEEE1800-2005: A.1.8 */
/* IEEE1800-2017: A.1.9 Class items: Class properties... */
| property_qualifier_opt data_type list_of_variable_decl_assignments ';'
{ pform_class_property(@2, $1, $2, $3); }
| property_qualifier_opt list_of_variable_decl_assignments_with_type ';'
{ pform_class_property(@2, $1, $2.type, $2.decl_assignments); }
| K_const class_item_qualifier_opt data_type list_of_variable_decl_assignments ';'
{ pform_class_property(@1, $2 | property_qualifier_t::make_const(), $3, $4); }
| K_const class_item_qualifier_opt list_of_variable_decl_assignments_with_type ';'
{ pform_class_property(@1, $2 | property_qualifier_t::make_const(), $3.type, $3.decl_assignments); }
/* IEEEE1800-2017: A.1.9 Class items: class_item ::= { property_qualifier} data_declaration */
@ -1212,11 +1212,6 @@ class_item /* IEEE1800-2005: A.1.8 */
/* Here are some error matching rules to help recover from various
syntax errors within a class declaration. */
| property_qualifier_opt data_type error ';'
{ yyerror(@3, "error: Errors in variable names after data type.");
yyerrok;
}
| property_qualifier_opt IDENTIFIER error ';'
{ yyerror(@3, "error: %s doesn't name a type.", $2);
yyerrok;
@ -4749,7 +4744,7 @@ hierarchy_identifier
$$->push_back(name_component_t(lex_strings.make($1)));
delete[]$1;
}
| hierarchy_identifier '.' IDENTIFIER
| hierarchy_identifier '.' identifier_name
{ pform_name_t * tmp = $1;
tmp->push_back(name_component_t(lex_strings.make($3)));
delete[]$3;

View File

@ -929,6 +929,16 @@ typedef_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt)
if (sym != cur_scope->local_symbols.end())
return nullptr;
// Class properties are tracked in the class type, not in
// local_symbols, but still shadow type names before lookup falls
// through to wildcard imports.
if (auto cur_class = dynamic_cast<PClass*> (cur_scope)) {
if (cur_class->type &&
cur_class->type->properties.find(name) !=
cur_class->type->properties.end())
return nullptr;
}
PPackage*pkg = pform_find_potential_import(loc, cur_scope, name, false, false);
if (pkg) {
cur = pkg->typedefs.find(name);