Mesa (master): glsl: Process redeclarations before initializers

Ian Romanick idr at kemper.freedesktop.org
Sat Mar 5 00:34:20 UTC 2011


Module: Mesa
Branch: master
Commit: 09a4ba0fc31fa8fc193dfb7b4fd78e32722b8312
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=09a4ba0fc31fa8fc193dfb7b4fd78e32722b8312

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Mar  4 16:15:20 2011 -0800

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.

---

 src/glsl/ast_to_hir.cpp |   87 ++++++++++++++++++++++++-----------------------
 1 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 0074ed2..651fae8 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);
    }
 




More information about the mesa-commit mailing list