Add helper function to check end label
Most named constructs support a end label in SystemVerilog. The handling of this end label is always the same. * Generate an error if the end label does not match the name of the block * Generate an error if not in SystemVerilog mode * Delete the end label Factor this into a common helper function. This reduces code size a bit and results in consistent error messages. The latter requires refreshing of some gold files to match the slightly different error messages. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
bc0fc4ab89
commit
7e18eba848
|
|
@ -1,15 +1,15 @@
|
|||
./ivltests/sv_end_label_fail.v:4: error: End label doesn't match begin name
|
||||
./ivltests/sv_end_label_fail.v:7: error: End label doesn't match fork name
|
||||
./ivltests/sv_end_label_fail.v:10: error: End label doesn't match fork name
|
||||
./ivltests/sv_end_label_fail.v:13: error: End label doesn't match fork name
|
||||
./ivltests/sv_end_label_fail.v:16: error: End label doesn't match task name
|
||||
./ivltests/sv_end_label_fail.v:19: error: End label doesn't match task name
|
||||
./ivltests/sv_end_label_fail.v:23: error: End label doesn't match function name
|
||||
./ivltests/sv_end_label_fail.v:26: error: End label doesn't match function name
|
||||
./ivltests/sv_end_label_fail.v:28: error: End label doesn't match module name.
|
||||
./ivltests/sv_end_label_fail.v:38: error: End label doesn't match begin name
|
||||
./ivltests/sv_end_label_fail.v:40: error: End label doesn't match module name.
|
||||
./ivltests/sv_end_label_fail.v:43: error: End label doesn't match package name
|
||||
./ivltests/sv_end_label_fail.v:47: error: Class end label doesn't match class name.
|
||||
./ivltests/sv_end_label_fail.v:48: error: End label doesn't match program name.
|
||||
./ivltests/sv_end_label_fail.v:64: error: End label doesn't match primitive name
|
||||
./ivltests/sv_end_label_fail.v:4: error: block end label `b_label_f` doesn't match block name `b_label`.
|
||||
./ivltests/sv_end_label_fail.v:7: error: fork end label `fj_label_f` doesn't match fork name `fj_label`.
|
||||
./ivltests/sv_end_label_fail.v:10: error: fork end label `fja_label_f` doesn't match fork name `fja_label`.
|
||||
./ivltests/sv_end_label_fail.v:13: error: fork end label `fjn_label_f` doesn't match fork name `fjn_label`.
|
||||
./ivltests/sv_end_label_fail.v:16: error: task end label `t_label_f` doesn't match task name `t_label`.
|
||||
./ivltests/sv_end_label_fail.v:19: error: task end label `twa_label_f` doesn't match task name `twa_label`.
|
||||
./ivltests/sv_end_label_fail.v:23: error: function end label `fn_label_f` doesn't match function name `fn_label`.
|
||||
./ivltests/sv_end_label_fail.v:26: error: function end label `fa_label_f` doesn't match function name `fa_label`.
|
||||
./ivltests/sv_end_label_fail.v:28: error: module end label `top_f` doesn't match module name `top`.
|
||||
./ivltests/sv_end_label_fail.v:38: error: block end label `g_label_f` doesn't match block name `g_label`.
|
||||
./ivltests/sv_end_label_fail.v:40: error: module end label `extra_f` doesn't match module name `extra`.
|
||||
./ivltests/sv_end_label_fail.v:43: error: package end label `pkg_f` doesn't match package name `pkg`.
|
||||
./ivltests/sv_end_label_fail.v:47: error: class end label `foo_f` doesn't match class name `foo`.
|
||||
./ivltests/sv_end_label_fail.v:48: error: program end label `pgm_f` doesn't match program name `pgm`.
|
||||
./ivltests/sv_end_label_fail.v:64: error: primitive end label `pinv_f` doesn't match primitive name `pinv`.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
./ivltests/sv_end_labels_bad.v:14: error: End label doesn't match begin name
|
||||
./ivltests/sv_end_labels_bad.v:16: error: End label doesn't match module name.
|
||||
./ivltests/sv_end_labels_bad.v:14: error: block end label `dummy_label_bad` doesn't match block name `dummy_label`.
|
||||
./ivltests/sv_end_labels_bad.v:16: error: module end label `test_bad` doesn't match module name `test`.
|
||||
|
|
|
|||
193
parse.y
193
parse.y
|
|
@ -284,6 +284,22 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
|
|||
return value;
|
||||
}
|
||||
|
||||
static void check_end_label(const struct vlltype&loc, const char *type,
|
||||
const char *begin, const char *end)
|
||||
{
|
||||
if (!end)
|
||||
return;
|
||||
|
||||
if (strcmp(begin, end) != 0)
|
||||
yyerror(loc, "error: %s end label `%s` doesn't match %s name"
|
||||
" `%s`.", type, end, type, begin);
|
||||
|
||||
if (!gn_system_verilog())
|
||||
yyerror(loc, "error: %s end label requires SystemVerilog.", type);
|
||||
|
||||
delete[] end;
|
||||
}
|
||||
|
||||
static void current_task_set_statement(const YYLTYPE&loc, std::vector<Statement*>*s)
|
||||
{
|
||||
if (s == 0) {
|
||||
|
|
@ -788,10 +804,7 @@ class_declaration /* IEEE1800-2005: A.1.2 */
|
|||
}
|
||||
class_declaration_endlabel_opt
|
||||
{ // Wrap up the class.
|
||||
if ($11 && $4 && $4->name != $11) {
|
||||
yyerror(@11, "error: Class end label doesn't match class name.");
|
||||
delete[]$11;
|
||||
}
|
||||
check_end_label(@11, "class", $4->name, $11);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1456,17 +1469,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name.
|
||||
if ($11) {
|
||||
if (strcmp($4,$11) != 0) {
|
||||
yyerror(@11, "error: End label doesn't match "
|
||||
"function name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@11, "error: Function end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$11;
|
||||
}
|
||||
check_end_label(@11, "function", $4, $11);
|
||||
delete[]$4;
|
||||
}
|
||||
|
||||
|
|
@ -1490,17 +1493,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name.
|
||||
if ($14) {
|
||||
if (strcmp($4,$14) != 0) {
|
||||
yyerror(@14, "error: End label doesn't match "
|
||||
"function name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@14, "error: Function end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$14;
|
||||
}
|
||||
check_end_label(@14, "function", $4, $14);
|
||||
delete[]$4;
|
||||
}
|
||||
|
||||
|
|
@ -1518,16 +1511,7 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
|||
}
|
||||
endlabel_opt
|
||||
{ // Last step: check any closing name.
|
||||
if ($8) {
|
||||
if (strcmp($4,$8) != 0) {
|
||||
yyerror(@8, "error: End label doesn't match function name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@8, "error: Function end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$8;
|
||||
}
|
||||
check_end_label(@8, "function", $4, $8);
|
||||
delete[]$4;
|
||||
}
|
||||
|
||||
|
|
@ -1998,13 +1982,7 @@ package_declaration /* IEEE1800-2005 A.1.2 */
|
|||
package_item_list_opt
|
||||
K_endpackage endlabel_opt
|
||||
{ pform_end_package_declaration(@1);
|
||||
// If an end label is present make sure it match the package name.
|
||||
if ($10) {
|
||||
if (strcmp($3,$10) != 0) {
|
||||
yyerror(@10, "error: End label doesn't match package name");
|
||||
}
|
||||
delete[]$10;
|
||||
}
|
||||
check_end_label(@10, "package", $3, $10);
|
||||
delete[]$3;
|
||||
}
|
||||
;
|
||||
|
|
@ -2336,16 +2314,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
// endlabel_opt but still have the pform_endmodule() called
|
||||
// early enough that the lexor can know we are outside the
|
||||
// module.
|
||||
if ($10) {
|
||||
if (strcmp($3,$10) != 0) {
|
||||
yyerror(@10, "error: End label doesn't match task name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@10, "error: Task end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$10;
|
||||
}
|
||||
check_end_label(@10, "task", $3, $10);
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
|
|
@ -2374,16 +2343,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
// endlabel_opt but still have the pform_endmodule() called
|
||||
// early enough that the lexor can know we are outside the
|
||||
// module.
|
||||
if ($13) {
|
||||
if (strcmp($3,$13) != 0) {
|
||||
yyerror(@13, "error: End label doesn't match task name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@13, "error: Task end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$13;
|
||||
}
|
||||
check_end_label(@13, "task", $3, $13);
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
|
|
@ -2400,16 +2360,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
|||
// endlabel_opt but still have the pform_endmodule() called
|
||||
// early enough that the lexor can know we are outside the
|
||||
// module.
|
||||
if ($7) {
|
||||
if (strcmp($3,$7) != 0) {
|
||||
yyerror(@7, "error: End label doesn't match task name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@7, "error: Task end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$7;
|
||||
}
|
||||
check_end_label(@7, "task", $3, $7);
|
||||
delete[]$3;
|
||||
}
|
||||
|
||||
|
|
@ -4927,30 +4878,18 @@ module
|
|||
// endlabel_opt but still have the pform_endmodule() called
|
||||
// early enough that the lexor can know we are outside the
|
||||
// module.
|
||||
if ($17) {
|
||||
if (strcmp($4,$17) != 0) {
|
||||
switch ($2) {
|
||||
case K_module:
|
||||
yyerror(@17, "error: End label doesn't match "
|
||||
"module name.");
|
||||
break;
|
||||
case K_program:
|
||||
yyerror(@17, "error: End label doesn't match "
|
||||
"program name.");
|
||||
break;
|
||||
case K_interface:
|
||||
yyerror(@17, "error: End label doesn't match "
|
||||
"interface name.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (($2 == K_module) && (! gn_system_verilog())) {
|
||||
yyerror(@8, "error: Module end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$17;
|
||||
switch ($2) {
|
||||
case K_module:
|
||||
check_end_label(@17, "module", $4, $17);
|
||||
break;
|
||||
case K_program:
|
||||
check_end_label(@17, "program", $4, $17);
|
||||
break;
|
||||
case K_interface:
|
||||
check_end_label(@17, "interface", $4, $17);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete[]$4;
|
||||
}
|
||||
|
|
@ -5589,17 +5528,7 @@ generate_block
|
|||
| K_begin generate_item_list_opt K_end
|
||||
| K_begin ':' IDENTIFIER generate_item_list_opt K_end endlabel_opt
|
||||
{ pform_generate_block_name($3);
|
||||
if ($6) {
|
||||
if (strcmp($3,$6) != 0) {
|
||||
yyerror(@6, "error: End label doesn't match "
|
||||
"begin name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@6, "error: Begin end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$6;
|
||||
}
|
||||
check_end_label(@6, "block", $3, $6);
|
||||
delete[]$3;
|
||||
}
|
||||
;
|
||||
|
|
@ -6633,16 +6562,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
|||
current_block_stack.pop();
|
||||
if ($6) tmp->set_statement(*$6);
|
||||
delete $6;
|
||||
if ($8) {
|
||||
if (strcmp($3,$8) != 0) {
|
||||
yyerror(@8, "error: End label doesn't match begin name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@8, "error: Begin end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$8;
|
||||
}
|
||||
check_end_label(@8, "block", $3, $8);
|
||||
delete[]$3;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
@ -6701,16 +6621,7 @@ statement_item /* This is roughly statement_item in the LRM */
|
|||
tmp->set_join_type($7);
|
||||
if ($6) tmp->set_statement(*$6);
|
||||
delete $6;
|
||||
if ($8) {
|
||||
if (strcmp($3,$8) != 0) {
|
||||
yyerror(@8, "error: End label doesn't match fork name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@8, "error: Fork end labels require "
|
||||
"SystemVerilog.");
|
||||
}
|
||||
delete[]$8;
|
||||
}
|
||||
check_end_label(@8, "fork", $3, $8);
|
||||
delete[]$3;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
|
@ -7403,17 +7314,8 @@ udp_primitive
|
|||
{ perm_string tmp2 = lex_strings.make($2);
|
||||
pform_make_udp(tmp2, $4, $7, $9, $8,
|
||||
@2.text, @2.first_line);
|
||||
if ($11) {
|
||||
if (strcmp($2,$11) != 0) {
|
||||
yyerror(@11, "error: End label doesn't match "
|
||||
"primitive name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@11, "error: Primitive end labels "
|
||||
"require SystemVerilog.");
|
||||
}
|
||||
delete[]$11;
|
||||
}
|
||||
|
||||
check_end_label(@11, "primitive", $2, $11);
|
||||
delete[]$2;
|
||||
}
|
||||
|
||||
|
|
@ -7430,17 +7332,8 @@ udp_primitive
|
|||
perm_string tmp6 = lex_strings.make($6);
|
||||
pform_make_udp(tmp2, $5, tmp6, $7, $9, $12,
|
||||
@2.text, @2.first_line);
|
||||
if ($14) {
|
||||
if (strcmp($2,$14) != 0) {
|
||||
yyerror(@14, "error: End label doesn't match "
|
||||
"primitive name");
|
||||
}
|
||||
if (! gn_system_verilog()) {
|
||||
yyerror(@14, "error: Primitive end labels "
|
||||
"require SystemVerilog.");
|
||||
}
|
||||
delete[]$14;
|
||||
}
|
||||
|
||||
check_end_label(@14, "primitive", $2, $14);
|
||||
delete[]$2;
|
||||
delete[]$6;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue