mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
glsl: Process redeclarations before initializers
If an array redeclaration includes an initializer, the initializer would previously be dropped on the floor. Instead, directly apply the initializer to the correct ir_variable instance and append the generated instructions. Fixes bugzilla #34374 and piglit tests glsl-{vs,fs}-array-redeclaration. NOTE: This is a candidate for stable release branches.0292ffb8and8e6cb9feare also necessary.
This commit is contained in:
parent
0292ffb85c
commit
09a4ba0fc3
1 changed files with 46 additions and 45 deletions
|
|
@ -2693,8 +2693,11 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||||
* instruction stream.
|
* instruction stream.
|
||||||
*/
|
*/
|
||||||
exec_list initializer_instructions;
|
exec_list initializer_instructions;
|
||||||
|
ir_variable *earlier = get_variable_being_redeclared(var, decl, state);
|
||||||
|
|
||||||
if (decl->initializer != NULL) {
|
if (decl->initializer != NULL) {
|
||||||
result = process_initializer(var, decl, this->type,
|
result = process_initializer((earlier == NULL) ? var : earlier,
|
||||||
|
decl, this->type,
|
||||||
&initializer_instructions, state);
|
&initializer_instructions, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2710,52 +2713,50 @@ ast_declarator_list::hir(exec_list *instructions,
|
||||||
decl->identifier);
|
decl->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_variable *earlier = get_variable_being_redeclared(var, decl, state);
|
/* If the declaration is not a redeclaration, there are a few additional
|
||||||
if (earlier != NULL) {
|
* semantic checks that must be applied. In addition, variable that was
|
||||||
continue;
|
* created for the declaration should be added to the IR stream.
|
||||||
|
*/
|
||||||
|
if (earlier == NULL) {
|
||||||
|
/* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
|
||||||
|
*
|
||||||
|
* "Identifiers starting with "gl_" are reserved for use by
|
||||||
|
* OpenGL, and may not be declared in a shader as either a
|
||||||
|
* variable or a function."
|
||||||
|
*/
|
||||||
|
if (strncmp(decl->identifier, "gl_", 3) == 0)
|
||||||
|
_mesa_glsl_error(& loc, state,
|
||||||
|
"identifier `%s' uses reserved `gl_' prefix",
|
||||||
|
decl->identifier);
|
||||||
|
|
||||||
|
/* Add the variable to the symbol table. Note that the initializer's
|
||||||
|
* IR was already processed earlier (though it hasn't been emitted
|
||||||
|
* yet), without the variable in scope.
|
||||||
|
*
|
||||||
|
* This differs from most C-like languages, but it follows the GLSL
|
||||||
|
* specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
|
||||||
|
* spec:
|
||||||
|
*
|
||||||
|
* "Within a declaration, the scope of a name starts immediately
|
||||||
|
* after the initializer if present or immediately after the name
|
||||||
|
* being declared if not."
|
||||||
|
*/
|
||||||
|
if (!state->symbols->add_variable(var)) {
|
||||||
|
YYLTYPE loc = this->get_location();
|
||||||
|
_mesa_glsl_error(&loc, state, "name `%s' already taken in the "
|
||||||
|
"current scope", decl->identifier);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push the variable declaration to the top. It means that all the
|
||||||
|
* variable declarations will appear in a funny last-to-first order,
|
||||||
|
* but otherwise we run into trouble if a function is prototyped, a
|
||||||
|
* global var is decled, then the function is defined with usage of
|
||||||
|
* the global var. See glslparsertest's CorrectModule.frag.
|
||||||
|
*/
|
||||||
|
instructions->push_head(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* By now, we know it's a new variable declaration (we didn't hit the
|
|
||||||
* above "continue").
|
|
||||||
*
|
|
||||||
* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec,
|
|
||||||
*
|
|
||||||
* "Identifiers starting with "gl_" are reserved for use by
|
|
||||||
* OpenGL, and may not be declared in a shader as either a
|
|
||||||
* variable or a function."
|
|
||||||
*/
|
|
||||||
if (strncmp(decl->identifier, "gl_", 3) == 0)
|
|
||||||
_mesa_glsl_error(& loc, state,
|
|
||||||
"identifier `%s' uses reserved `gl_' prefix",
|
|
||||||
decl->identifier);
|
|
||||||
|
|
||||||
/* Add the variable to the symbol table. Note that the initializer's
|
|
||||||
* IR was already processed earlier (though it hasn't been emitted yet),
|
|
||||||
* without the variable in scope.
|
|
||||||
*
|
|
||||||
* This differs from most C-like languages, but it follows the GLSL
|
|
||||||
* specification. From page 28 (page 34 of the PDF) of the GLSL 1.50
|
|
||||||
* spec:
|
|
||||||
*
|
|
||||||
* "Within a declaration, the scope of a name starts immediately
|
|
||||||
* after the initializer if present or immediately after the name
|
|
||||||
* being declared if not."
|
|
||||||
*/
|
|
||||||
if (!state->symbols->add_variable(var)) {
|
|
||||||
YYLTYPE loc = this->get_location();
|
|
||||||
_mesa_glsl_error(&loc, state, "name `%s' already taken in the "
|
|
||||||
"current scope", decl->identifier);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Push the variable declaration to the top. It means that all
|
|
||||||
* the variable declarations will appear in a funny
|
|
||||||
* last-to-first order, but otherwise we run into trouble if a
|
|
||||||
* function is prototyped, a global var is decled, then the
|
|
||||||
* function is defined with usage of the global var. See
|
|
||||||
* glslparsertest's CorrectModule.frag.
|
|
||||||
*/
|
|
||||||
instructions->push_head(var);
|
|
||||||
instructions->append_list(&initializer_instructions);
|
instructions->append_list(&initializer_instructions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue