Support class properties shadowing type names
SystemVerilog allows a class property to have the same name as a visible type. The lexer reports the visible type name as `TYPE_IDENTIFIER` before the property has been installed, which made constructs such as `typedef int T; class C; int T; endclass` fail in the class item grammar. A class property with the same name as the class itself hits the same problem. Member references such as `obj.T` or `obj.C` can also hit the same tokenization problem in hierarchical names. Parse class properties through the same declaration helper used for variables so the first type/name pair can be disambiguated. Also let hierarchical member names use `identifier_name`. Stop type lookup when a class scope already has a property with the same name. This makes method body references resolve as properties instead of visible types, including type names found through wildcard imports. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
d01efc910b
commit
dc66f2fe7e
15
parse.y
15
parse.y
|
|
@ -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;
|
||||
|
|
|
|||
10
pform.cc
10
pform.cc
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue