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_base_range normal,-g2005-sv ivltests
enum_elem_ranges normal,-g2005-sv ivltests enum_elem_ranges normal,-g2005-sv ivltests
enum_dims_invalid CE,-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_next normal,-g2005-sv ivltests
enum_ports normal,-g2005-sv ivltests enum_ports normal,-g2005-sv ivltests
enum_test1 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_gh437 CE,-g2009 ivltests
br_gh445 CE,-g2009 ivltests br_gh445 CE,-g2009 ivltests
br_gh461 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_class1 CE,-g2009 ivltests
sv_class2 CE,-g2009 ivltests sv_class2 CE,-g2009 ivltests
sv_class3 CE,-g2009 ivltests sv_class3 CE,-g2009 ivltests

View File

@ -2006,6 +2006,9 @@ test_mos_strength_reduction: Passed.
enum_base_range: Passed. enum_base_range: Passed.
enum_elem_ranges: Passed. enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE. enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed. enum_next: Passed.
enum_ports: Passed. enum_ports: Passed.
enum_test1: Passed. enum_test1: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed. ufuncsynth1: Passed.
============================================================================ ============================================================================
Test results: 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_base_range: Passed.
enum_elem_ranges: Passed. enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE. enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed. enum_next: Passed.
enum_ports: Passed. enum_ports: Passed.
enum_test1: Passed. enum_test1: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed. ufuncsynth1: Passed.
============================================================================ ============================================================================
Test results: 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_base_range: Passed.
enum_elem_ranges: Passed. enum_elem_ranges: Passed.
enum_dims_invalid: Passed - CE. enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_in_class: Passed.
enum_in_class_name_coll: Passed - CE.
enum_next: Passed. enum_next: Passed.
enum_ports: Passed. enum_ports: Passed.
enum_test1: Passed. enum_test1: Passed.
@ -2559,4 +2562,4 @@ test_mos_strength_reduction: Passed.
ufuncsynth1: Passed. ufuncsynth1: Passed.
============================================================================ ============================================================================
Test results: 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_gh437: Passed - CE.
br_gh445: Passed - CE. br_gh445: Passed - CE.
br_gh461: Passed - CE. br_gh461: Passed - CE.
enum_in_class: Passed - CE.
enum_in_class_name_coll: Passed - CE.
sv_class1: Passed - CE. sv_class1: Passed - CE.
sv_class2: Passed - CE. sv_class2: Passed - CE.
sv_class3: Passed - CE. sv_class3: Passed - CE.
@ -2309,6 +2311,7 @@ test_mos_strength_reduction: Passed.
edge: Passed. edge: Passed.
enum_base_range: Passed. enum_base_range: Passed.
enum_dims_invalid: Passed - CE. enum_dims_invalid: Passed - CE.
enum_in_struct: Passed.
enum_test2: Passed. enum_test2: Passed.
enum_test3: Passed - CE. enum_test3: Passed - CE.
enum_test4: Passed. enum_test4: Passed.
@ -2562,4 +2565,4 @@ test_mos_strength_reduction: Passed.
synth_if_no_else: Passed. synth_if_no_else: Passed.
============================================================================ ============================================================================
Test results: 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 <expr> tf_port_item_expr_opt value_range_expression
%type <named_pexprs> enum_name_list enum_name %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> function_item function_item_list function_item_list_opt
%type <tf_ports> task_item task_item_list task_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 for an optional base type. The default base type is "int", but it
can be any of the integral or vector types. */ can be any of the integral or vector types. */
enum_data_type enum_base_type /* IEEE 1800-2012 A.2.2.1 */
: K_enum '{' enum_name_list '}' :
{ enum_type_t*enum_type = new enum_type_t; { 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->base_type = IVL_VT_BOOL;
enum_type->signed_flag = true; enum_type->signed_flag = true;
enum_type->integer_flag = false; enum_type->integer_flag = false;
enum_type->range.reset(make_range_from_width(32)); enum_type->range.reset(make_range_from_width(32));
$$ = enum_type; $$ = 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; { 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->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3; enum_type->signed_flag = $2;
enum_type->integer_flag = false; 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; $$ = 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; { 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->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3; enum_type->signed_flag = $2;
enum_type->integer_flag = true; enum_type->integer_flag = true;
enum_type->range.reset(make_range_from_width(integer_width)); enum_type->range.reset(make_range_from_width(integer_width));
$$ = enum_type; $$ = enum_type;
} }
| K_enum K_logic unsigned_signed_opt dimensions_opt '{' enum_name_list '}' | integer_vector_type unsigned_signed_opt dimensions_opt
{ enum_type_t*enum_type = new enum_type_t; { ivl_variable_type_t use_vtype = $1;
FILE_NAME(enum_type, @1); if (use_vtype == IVL_VT_NO_TYPE)
enum_type->names .reset($6); use_vtype = IVL_VT_LOGIC;
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3; 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->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; $$ = 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); FILE_NAME(enum_type, @1);
enum_type->names .reset($6); enum_type->names.reset($4);
enum_type->base_type = IVL_VT_LOGIC; pform_put_enum_type_in_scope(enum_type);
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; $$ = 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; 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)) if (lexical_scope->enum_sets.count(enum_set))
return; 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); ivl_assert(*data_type, ref == 0);
ref = data_type; ref = data_type;
ref->name = name; 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) 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. // Add the file and line information to the enumeration type.
FILE_NAME(&(enum_type->li), li); 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 // Now apply the checked enumeration type to the variables
// that are being declared with this type. // that are being declared with this type.
for (list<perm_string>::iterator cur = names->begin() 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_timeunit_decl;
extern bool allow_timeprec_decl; extern bool allow_timeprec_decl;
void pform_put_enum_type_in_scope(enum_type_t*enum_set);
#endif /* IVL_pform_H */ #endif /* IVL_pform_H */

View File

@ -69,10 +69,6 @@ void pform_class_property(const struct vlltype&loc,
{ {
assert(pform_cur_class); 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 // Add the non-static properties to the class type
// object. Unwind the list of names to make a map of name to // object. Unwind the list of names to make a map of name to
// type. // type.