From: Ian Romanick Date: Sat, 5 Mar 2011 00:15:20 +0000 (-0800) Subject: glsl: Process redeclarations before initializers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=09a4ba0fc31fa8fc193dfb7b4fd78e32722b8312;p=mesa.git 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. 0292ffb8 and 8e6cb9fe are also necessary. --- diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 0074ed2bd44..651fae808e6 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2693,8 +2693,11 @@ ast_declarator_list::hir(exec_list *instructions, * instruction stream. */ exec_list initializer_instructions; + ir_variable *earlier = get_variable_being_redeclared(var, decl, state); + if (decl->initializer != NULL) { - result = process_initializer(var, decl, this->type, + result = process_initializer((earlier == NULL) ? var : earlier, + decl, this->type, &initializer_instructions, state); } @@ -2710,52 +2713,50 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } - ir_variable *earlier = get_variable_being_redeclared(var, decl, state); - if (earlier != NULL) { - continue; - } - - /* 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 the declaration is not a redeclaration, there are a few additional + * semantic checks that must be applied. In addition, variable that was + * created for the declaration should be added to the IR stream. */ - if (strncmp(decl->identifier, "gl_", 3) == 0) - _mesa_glsl_error(& loc, state, - "identifier `%s' uses reserved `gl_' prefix", - decl->identifier); + 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; + /* 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); } - /* 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); }