Merge pull request #584 from larsclausen/enum-put-in-scope

Put enum type into scope when declaring it
This commit is contained in:
Stephen Williams 2022-01-15 13:21:50 -08:00 committed by GitHub
commit 6222a84d67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 134 additions and 54 deletions

View File

@ -0,0 +1,52 @@
// Check that when a enum type is declared inside a class that the enum is
// properly installed in the scope and the enum items are available.
//
// Also check that when using a typedef of a enum inside a class that the enum
// is not elaborated inside the class and it is possible to have a enum with the
// same names inside the class scope.
module test;
typedef enum integer {
A = 1
} e1_t;
class C;
typedef enum integer {
A = 10
} e2_t;
e1_t e1;
e2_t e2;
function new();
e1 = test.A;
e2 = A;
endfunction
function void set(e2_t new_e2);
e2 = new_e2;
endfunction
endclass
C c;
initial begin
c = new;
c.e1 = A;
c.set(c.e2);
// Not yet supported
// c.e2 = C::A;
// c.e2 = c.A;
// Check that they have the numerical value from the right scope
if (c.e1 == 1 && c.e2 == 10) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,13 @@
// Check that the enum names are added to the lexor scope of the class and
// name collisions with other symbols are reported as errors.
module test;
class C;
enum {
A = 10
} e;
typedef int A;
endclass
endmodule

View File

@ -0,0 +1,21 @@
// Check that when a enum type is declared inside a struct that the enum is
// properly installed in the scope and the enum items are available
module test;
struct packed {
enum integer {
A
} e;
} s;
initial begin
s.e = A;
if (s.e == A) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -231,6 +231,9 @@ edge normal,-g2009 ivltests
enum_base_range normal,-g2005-sv ivltests
enum_elem_ranges normal,-g2005-sv ivltests
enum_dims_invalid CE,-g2005-sv ivltests
enum_in_struct normal,-g2005-sv ivltests
enum_in_class normal,-g2005-sv ivltests
enum_in_class_name_coll CE,-g2005-sv ivltests
enum_next normal,-g2005-sv ivltests
enum_ports normal,-g2005-sv ivltests
enum_test1 normal,-g2005-sv ivltests

View File

@ -336,6 +336,8 @@ br_gh391 CE,-g2009 ivltests
br_gh437 CE,-g2009 ivltests
br_gh445 CE,-g2009 ivltests
br_gh461 CE,-g2009 ivltests
enum_in_class CE,-g2005-sv ivltests
enum_in_class_name_coll CE,-g2005-sv ivltests
sv_class1 CE,-g2009 ivltests
sv_class2 CE,-g2009 ivltests
sv_class3 CE,-g2009 ivltests

View File

@ -2006,6 +2006,9 @@ test_mos_strength_reduction: Passed.
enum_base_range: Passed.
enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed.
enum_ports: Passed.
enum_test1: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed.
============================================================================
Test results:
Total=2560, Passed=2554, Failed=3, Not Implemented=0, Expected Fail=3
Total=2563, Passed=2557, Failed=3, Not Implemented=0, Expected Fail=3

View File

@ -2013,6 +2013,9 @@ test_mos_strength_reduction: Passed.
enum_base_range: Passed.
enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed.
enum_ports: Passed.
enum_test1: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed.
============================================================================
Test results:
Total=2560, Passed=2540, Failed=17, Not Implemented=3, Expected Fail=0
Total=2563, Passed=2543, Failed=17, Not Implemented=3, Expected Fail=0

View File

@ -2002,6 +2002,9 @@ test_mos_strength_reduction: Passed.
enum_base_range: Passed.
enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed.
enum_ports: Passed.
enum_test1: Passed.
@ -2559,4 +2562,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed.
============================================================================
Test results:
Total=2557, Passed=2551, Failed=3, Not Implemented=0, Expected Fail=3
Total=2560, Passed=2554, Failed=3, Not Implemented=0, Expected Fail=3

View File

@ -248,6 +248,8 @@ Running vlog95 compiler/VVP tests for Icarus Verilog version: 12.
br_gh437: Passed - CE.
br_gh445: Passed - CE.
br_gh461: Passed - CE.
enum_in_class: Passed - CE.
enum_in_class_name_coll: Passed - CE.
sv_class1: Passed - CE.
sv_class2: Passed - CE.
sv_class3: Passed - CE.
@ -2309,6 +2311,7 @@ test_mos_strength_reduction: Passed.
edge: Passed.
enum_base_range: Passed.
enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_test2: Passed.
enum_test3: Passed - CE.
enum_test4: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
synth_if_no_else: Passed.
============================================================================
Test results:
Total=2560, Passed=2521, Failed=2, Not Implemented=3, Expected Fail=34
Total=2563, Passed=2524, Failed=2, Not Implemented=3, Expected Fail=34

62
parse.y
View File

@ -600,7 +600,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
%type <expr> tf_port_item_expr_opt value_range_expression
%type <named_pexprs> enum_name_list enum_name
%type <enum_type> enum_data_type
%type <enum_type> enum_data_type enum_base_type
%type <tf_ports> function_item function_item_list function_item_list_opt
%type <tf_ports> task_item task_item_list task_item_list_opt
@ -2863,65 +2863,51 @@ type_declaration
for an optional base type. The default base type is "int", but it
can be any of the integral or vector types. */
enum_data_type
: K_enum '{' enum_name_list '}'
enum_base_type /* IEEE 1800-2012 A.2.2.1 */
:
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($3);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = true;
enum_type->integer_flag = false;
enum_type->range.reset(make_range_from_width(32));
$$ = enum_type;
}
| K_enum atom2_type signed_unsigned_opt '{' enum_name_list '}'
| atom2_type signed_unsigned_opt
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->signed_flag = $2;
enum_type->integer_flag = false;
enum_type->range.reset(make_range_from_width($2));
enum_type->range.reset(make_range_from_width($1));
$$ = enum_type;
}
| K_enum K_integer signed_unsigned_opt '{' enum_name_list '}'
| K_integer signed_unsigned_opt
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->signed_flag = $2;
enum_type->integer_flag = true;
enum_type->range.reset(make_range_from_width(integer_width));
$$ = enum_type;
}
| K_enum K_logic unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
| integer_vector_type unsigned_signed_opt dimensions_opt
{ ivl_variable_type_t use_vtype = $1;
if (use_vtype == IVL_VT_NO_TYPE)
use_vtype = IVL_VT_LOGIC;
enum_type_t*enum_type = new enum_type_t;
enum_type->base_type = use_vtype;
enum_type->signed_flag = $2;
enum_type->integer_flag = false;
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
enum_type->range.reset($3 ? $3 : make_range_from_width(1));
$$ = enum_type;
}
| K_enum K_reg unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
;
enum_data_type /* IEEE 1800-2012 A.2.2.1 */
: K_enum enum_base_type '{' enum_name_list '}'
{ enum_type_t*enum_type = $2;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->integer_flag = false;
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
$$ = enum_type;
}
| K_enum K_bit unsigned_signed_opt dimensions_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->integer_flag = false;
enum_type->range.reset($4 ? $4 : make_range_from_width(1));
enum_type->names.reset($4);
pform_put_enum_type_in_scope(enum_type);
$$ = enum_type;
}
;

View File

@ -827,7 +827,7 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net)
lexical_scope->wires[name] = net;
}
static void pform_put_enum_type_in_scope(enum_type_t*enum_set)
void pform_put_enum_type_in_scope(enum_type_t*enum_set)
{
if (lexical_scope->enum_sets.count(enum_set))
return;
@ -888,9 +888,6 @@ void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_
ivl_assert(*data_type, ref == 0);
ref = data_type;
ref->name = name;
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(data_type))
pform_put_enum_type_in_scope(enum_type);
}
void pform_set_type_referenced(const struct vlltype&loc, const char*name)
@ -3592,10 +3589,6 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
// Add the file and line information to the enumeration type.
FILE_NAME(&(enum_type->li), li);
// If this is an anonymous enumeration, attach it to the current scope.
if (enum_type->name.nil())
pform_put_enum_type_in_scope(enum_type);
// Now apply the checked enumeration type to the variables
// that are being declared with this type.
for (list<perm_string>::iterator cur = names->begin()

View File

@ -613,4 +613,6 @@ extern void pform_set_timeprec(const char*txt, bool initial_decl);
extern bool allow_timeunit_decl;
extern bool allow_timeprec_decl;
void pform_put_enum_type_in_scope(enum_type_t*enum_set);
#endif /* IVL_pform_H */

View File

@ -69,10 +69,6 @@ void pform_class_property(const struct vlltype&loc,
{
assert(pform_cur_class);
if (enum_type_t*enum_set = dynamic_cast<enum_type_t*>(data_type)) {
pform_cur_class->enum_sets .insert(enum_set);
}
// Add the non-static properties to the class type
// object. Unwind the list of names to make a map of name to
// type.