[qfcc] Improve glsl scope handling

While storing the scope in a block was the right idea, the
implementation wasn't quite right as it resulted in the current scope
getting set at the wrong times resulting in incorrect symbol access when
shadowing was in effect.
This commit is contained in:
Bill Currie 2024-11-16 20:14:51 +09:00
parent 3797b1083b
commit 2ef72f745d
3 changed files with 9 additions and 11 deletions

View file

@ -165,10 +165,8 @@ proc_label (const expr_t *expr)
static const expr_t * static const expr_t *
proc_block (const expr_t *expr) proc_block (const expr_t *expr)
{ {
if (expr->block.scope) { auto old_scope = current_symtab;
expr->block.scope->parent = current_symtab; current_symtab = expr->block.scope;
current_symtab = expr->block.scope;
}
int count = list_count (&expr->block.list); int count = list_count (&expr->block.list);
int num_out = 0; int num_out = 0;
const expr_t *result = nullptr; const expr_t *result = nullptr;
@ -191,9 +189,8 @@ proc_block (const expr_t *expr)
block->block.scope = expr->block.scope; block->block.scope = expr->block.scope;
block->block.result = result; block->block.result = result;
block->block.is_call = expr->block.is_call; block->block.is_call = expr->block.is_call;
if (expr->block.scope) {
current_symtab = current_symtab->parent; current_symtab = old_scope;
}
return block; return block;
} }

View file

@ -186,7 +186,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
%type <expr> condition %type <expr> condition
%type <expr> compound_statement_no_new_scope compound_statement %type <expr> compound_statement_no_new_scope compound_statement
%type <expr> statement statement_no_new_scope statement_list %type <expr> statement statement_no_new_scope statement_list
%type <expr> new_block new_scope %type <mut_expr> new_block new_scope
%type <expr> simple_statement expression_statement %type <expr> simple_statement expression_statement
%type <expr> declaration_statement selection_statement %type <expr> declaration_statement selection_statement
%type <expr> switch_statement switch_statement_list case_label %type <expr> switch_statement switch_statement_list case_label
@ -1160,6 +1160,7 @@ new_block
: /* empty */ : /* empty */
{ {
auto block = new_block_expr (nullptr); auto block = new_block_expr (nullptr);
block->block.scope = current_symtab;
$$ = block; $$ = block;
} }
; ;
@ -1266,7 +1267,7 @@ case_label
iteration_statement iteration_statement
: WHILE new_scope break_label continue_label '(' condition ')' : WHILE new_scope break_label continue_label '(' condition ')'
statement_no_new_scope { $<mut_expr>$ = $new_scope; } statement_no_new_scope
{ {
$$ = new_loop_expr (false, false, $$ = new_loop_expr (false, false,
$condition, $statement_no_new_scope, $condition, $statement_no_new_scope,
@ -1286,7 +1287,7 @@ iteration_statement
| FOR new_scope break_label continue_label | FOR new_scope break_label continue_label
// '(' for_init_statement for_rest_statement ')' // '(' for_init_statement for_rest_statement ')'
'(' for_init_statement conditionopt ';' expressionopt ')' '(' for_init_statement conditionopt ';' expressionopt ')'
statement_no_new_scope { $<mut_expr>$ = $new_scope; } statement_no_new_scope
{ {
auto loop = new_loop_expr (false, false, auto loop = new_loop_expr (false, false,
$conditionopt, $statement_no_new_scope, $conditionopt, $statement_no_new_scope,

View file

@ -1586,7 +1586,7 @@ spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab,
symtab_addsymbol (symtab, sym); symtab_addsymbol (symtab, sym);
if (symtab->type == stab_local) { if (symtab->type == stab_local) {
if (init) { if (init) {
if (is_constexpr (init)) { if (!block && is_constexpr (init)) {
} else if (block) { } else if (block) {
auto r = pointer_deref (new_symbol_expr (sym)); auto r = pointer_deref (new_symbol_expr (sym));
auto e = assign_expr (r, init); auto e = assign_expr (r, init);