Skip to content

Commit e042948

Browse files
authored
Merge pull request #957 from diffblue/package-scope-typedef
SystemVerilog: use typedefs from package scopes
2 parents d3b36a4 + 6c1c0d4 commit e042948

File tree

6 files changed

+89
-5
lines changed

6 files changed

+89
-5
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* SystemVerilog: package scope operator
1313
* SystemVerilog: checkers
1414
* SystemVerilog: clocking block declarations
15+
* SystemVerilog: typedefs from package scopes
1516

1617
# EBMC 5.4
1718

regression/verilog/packages/package_typedef1.sv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ module main;
1010

1111
moo::my_type some_var;
1212

13-
assert final ($typename(some_var) == "byte");
13+
assert final ($typename(some_var) == "bit signed[7:0]");
1414

1515
endmodule

src/verilog/parser.y

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,10 +1546,13 @@ data_type:
15461546
{ init($$, ID_verilog_chandle); }
15471547
| TOK_VIRTUAL interface_opt interface_identifier
15481548
{ init($$, "virtual_interface"); }
1549-
| /*scope_opt*/ type_identifier packed_dimension_brace
1550-
{ stack_expr($1).id(ID_typedef_type);
1551-
add_as_subtype(stack_type($2), stack_type($1));
1549+
| type_identifier packed_dimension_brace
1550+
{ add_as_subtype(stack_type($2), stack_type($1));
15521551
$$ = $2; }
1552+
| package_scope type_identifier packed_dimension_brace
1553+
{ mto($1, $2);
1554+
add_as_subtype(stack_type($3), stack_type($2));
1555+
$$ = $3; }
15531556
// | class_type
15541557
| TOK_EVENT
15551558
{ init($$, ID_verilog_event); }

src/verilog/verilog_elaborate_type.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,42 @@ typet verilog_typecheck_exprt::convert_packed_array_type(
149149

150150
/*******************************************************************\
151151
152+
Function: verilog_typecheck_exprt::elaborate_package_scope_typedef
153+
154+
Inputs:
155+
156+
Outputs:
157+
158+
Purpose:
159+
160+
\*******************************************************************/
161+
162+
typet verilog_typecheck_exprt::elaborate_package_scope_typedef(
163+
const type_with_subtypest &src)
164+
{
165+
auto location = src.source_location();
166+
167+
if(src.subtypes()[1].id() != ID_typedef_type)
168+
throw errort().with_location(location)
169+
<< "verilog_package_scope expects typedef_type on the rhs";
170+
171+
auto package_base_name = src.subtypes()[0].id();
172+
auto typedef_base_name = src.subtypes()[1].get(ID_base_name);
173+
174+
// stitch together
175+
irep_idt full_identifier =
176+
id2string(verilog_package_identifier(package_base_name)) + '.' +
177+
id2string(typedef_base_name);
178+
179+
// recursive call
180+
verilog_typedef_typet full_typedef_type(full_identifier);
181+
full_typedef_type.set(ID_identifier, full_identifier);
182+
183+
return elaborate_type(full_typedef_type);
184+
}
185+
186+
/*******************************************************************\
187+
152188
Function: verilog_typecheck_exprt::elaborate_type
153189
154190
Inputs:
@@ -283,7 +319,7 @@ typet verilog_typecheck_exprt::elaborate_type(const typet &src)
283319
// Look it up!
284320
const symbolt *symbol_ptr;
285321

286-
auto identifier = src.get(ID_identifier);
322+
auto identifier = to_verilog_typedef_type(src).identifier();
287323

288324
if(ns.lookup(identifier, symbol_ptr))
289325
throw errort().with_location(source_location)
@@ -402,6 +438,11 @@ typet verilog_typecheck_exprt::elaborate_type(const typet &src)
402438
{
403439
return src;
404440
}
441+
else if(src.id() == ID_verilog_package_scope)
442+
{
443+
// package::typedef
444+
return elaborate_package_scope_typedef(to_type_with_subtypes(src));
445+
}
405446
else
406447
{
407448
throw errort().with_location(source_location)

src/verilog/verilog_typecheck_expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class verilog_typecheck_exprt:public verilog_typecheck_baset
6666
void propagate_type(exprt &expr, const typet &type);
6767

6868
typet elaborate_type(const typet &);
69+
typet elaborate_package_scope_typedef(const type_with_subtypest &);
6970
typet convert_enum(const class verilog_enum_typet &);
7071
array_typet convert_unpacked_array_type(const type_with_subtypet &);
7172
typet convert_packed_array_type(const type_with_subtypet &);

src/verilog/verilog_types.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,4 +618,42 @@ inline verilog_event_typet &to_verilog_event_type(typet &type)
618618
return static_cast<verilog_event_typet &>(type);
619619
}
620620

621+
/// A typedef
622+
class verilog_typedef_typet : public typet
623+
{
624+
public:
625+
explicit verilog_typedef_typet(const irep_idt &_identifier)
626+
: typet(ID_typedef_type)
627+
{
628+
identifier(_identifier);
629+
}
630+
631+
void identifier(const irep_idt &identifier)
632+
{
633+
set(ID_identifier, identifier);
634+
}
635+
636+
const irep_idt &identifier() const
637+
{
638+
return get(ID_identifier);
639+
}
640+
};
641+
642+
/// Cast a generic typet to a \ref verilog_typedef_typet. This is an unchecked
643+
/// conversion. \a type must be known to be \ref verilog_typedef_typet.
644+
/// \param type: Source type
645+
/// \return Object of type \ref verilog_typedef_typet
646+
inline const verilog_typedef_typet &to_verilog_typedef_type(const typet &type)
647+
{
648+
PRECONDITION(type.id() == ID_typedef_type);
649+
return static_cast<const verilog_typedef_typet &>(type);
650+
}
651+
652+
/// \copydoc to_verilog_typedef_type(const typet &)
653+
inline verilog_typedef_typet &to_verilog_typedef_type(typet &type)
654+
{
655+
PRECONDITION(type.id() == ID_typedef_type);
656+
return static_cast<verilog_typedef_typet &>(type);
657+
}
658+
621659
#endif

0 commit comments

Comments
 (0)