Support for and foreach identifiers shadowing type identifiers
SystemVerilog allows a declaration in an inner scope to use the same name as a type identifier from an outer scope. The lexer reports such names as `TYPE_IDENTIFIER` until the new declaration has been installed. The parser previously created the synthetic loop scope and declared the loop variable only after parsing the complete `for` header. When the variable name matches a visible typedef, this is too late: the lexer can continue returning `TYPE_IDENTIFIER` for references to the variable in the initializer, condition, and step expressions. Accept `identifier_name` for the declaration name and create the loop scope and variable in a mid-rule action immediately after it, so the declaration is visible while the rest of the header is parsed. The executable foreach grammar also used to require the array expression name before the index list to be an `IDENTIFIER`. Use `identifier_name` there as well, since this position is an expression name followed by `[` and not a type name. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
36a79568b7
commit
9ec8f8e2dd
13
parse.y
13
parse.y
|
|
@ -2030,7 +2030,9 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
// statement in a synthetic named block. We can name the block
|
// statement in a synthetic named block. We can name the block
|
||||||
// after the variable that we are creating, that identifier is
|
// after the variable that we are creating, that identifier is
|
||||||
// safe in the controlling scope.
|
// safe in the controlling scope.
|
||||||
| K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression_opt ';' for_step_opt ')'
|
| K_for '(' K_var_opt data_type identifier_name
|
||||||
|
// Make the loop variable symbol visible while parsing the rest of
|
||||||
|
// the header.
|
||||||
{ static unsigned for_counter = 0;
|
{ static unsigned for_counter = 0;
|
||||||
char for_block_name [64];
|
char for_block_name [64];
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
||||||
|
|
@ -2044,6 +2046,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
assign_list.push_back(tmp_assign);
|
assign_list.push_back(tmp_assign);
|
||||||
pform_make_var(@5, &assign_list, $4);
|
pform_make_var(@5, &assign_list, $4);
|
||||||
}
|
}
|
||||||
|
'=' expression ';' expression_opt ';' for_step_opt ')'
|
||||||
statement_or_null
|
statement_or_null
|
||||||
{ pform_name_t tmp_hident;
|
{ pform_name_t tmp_hident;
|
||||||
tmp_hident.push_back(name_component_t(lex_strings.make($5)));
|
tmp_hident.push_back(name_component_t(lex_strings.make($5)));
|
||||||
|
|
@ -2051,8 +2054,8 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
PEIdent*tmp_ident = pform_new_ident(@5, tmp_hident);
|
PEIdent*tmp_ident = pform_new_ident(@5, tmp_hident);
|
||||||
FILE_NAME(tmp_ident, @5);
|
FILE_NAME(tmp_ident, @5);
|
||||||
|
|
||||||
check_for_loop(@1, $7, $9, $11);
|
check_for_loop(@1, $8, $10, $12);
|
||||||
PForStatement*tmp_for = new PForStatement(tmp_ident, $7, $9, $11, $14);
|
PForStatement*tmp_for = new PForStatement(tmp_ident, $8, $10, $12, $14);
|
||||||
FILE_NAME(tmp_for, @1);
|
FILE_NAME(tmp_for, @1);
|
||||||
|
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
|
|
@ -2091,7 +2094,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
|
|
||||||
// When matching a foreach loop, implicitly create a named block
|
// When matching a foreach loop, implicitly create a named block
|
||||||
// to hold the definitions for the index variables.
|
// to hold the definitions for the index variables.
|
||||||
| K_foreach '(' IDENTIFIER '[' loop_variables ']' ')'
|
| K_foreach '(' identifier_name '[' loop_variables ']' ')'
|
||||||
{ static unsigned foreach_counter = 0;
|
{ static unsigned foreach_counter = 0;
|
||||||
char for_block_name[64];
|
char for_block_name[64];
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_foreach%u", foreach_counter);
|
snprintf(for_block_name, sizeof for_block_name, "$ivl_foreach%u", foreach_counter);
|
||||||
|
|
@ -2143,7 +2146,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
yyerror(@1, "error: Error in do/while loop condition.");
|
yyerror(@1, "error: Error in do/while loop condition.");
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_foreach '(' IDENTIFIER '[' error ']' ')' statement_or_null
|
| K_foreach '(' identifier_name '[' error ']' ')' statement_or_null
|
||||||
{ $$ = 0;
|
{ $$ = 0;
|
||||||
yyerror(@4, "error: Errors in foreach loop variables list.");
|
yyerror(@4, "error: Errors in foreach loop variables list.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue