glsl: Track in each ir_variable whether it was ever assigned.
authorEric Anholt <eric@anholt.net>
Fri, 30 Mar 2012 00:02:15 +0000 (17:02 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 19 Apr 2012 23:33:36 +0000 (16:33 -0700)
This will be used for some compile-and-link-time error checking, where
currently we've been doing error checking only at link time.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/ir.h

index 39401017b81439ca71111b9abcb97b734c02334f..8bf0ba2a8767b41536539b3563bf76440230d2ad 100644 (file)
@@ -152,19 +152,22 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
            return false;
         }
 
-        if (actual->variable_referenced()
-            && actual->variable_referenced()->read_only) {
-           _mesa_glsl_error(&loc, state,
-                            "function parameter '%s %s' references the "
-                            "read-only variable '%s'",
-                            mode, formal->name,
-                            actual->variable_referenced()->name);
-           return false;
-        } else if (!actual->is_lvalue()) {
-           _mesa_glsl_error(&loc, state,
-                            "function parameter '%s %s' is not an lvalue",
-                            mode, formal->name);
-           return false;
+        ir_variable *var = actual->variable_referenced();
+        if (var) {
+           if (var->read_only) {
+              _mesa_glsl_error(&loc, state,
+                               "function parameter '%s %s' references the "
+                               "read-only variable '%s'",
+                               mode, formal->name,
+                               actual->variable_referenced()->name);
+              return false;
+           } else if (!actual->is_lvalue()) {
+              _mesa_glsl_error(&loc, state,
+                               "function parameter '%s %s' is not an lvalue",
+                               mode, formal->name);
+              return false;
+           }
+           var->assigned = true;
         }
       }
 
index 820c86c5e6bff196833febb2ebec521f6f3ff742..80ea8bc4af6736e9557fb106e0c0ffed0f3b85d1 100644 (file)
@@ -672,6 +672,10 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    void *ctx = state;
    bool error_emitted = (lhs->type->is_error() || rhs->type->is_error());
 
+   ir_variable *lhs_var = lhs->variable_referenced();
+   if (lhs_var)
+      lhs_var->assigned = true;
+
    if (!error_emitted) {
       if (non_lvalue_description != NULL) {
          _mesa_glsl_error(&lhs_loc, state,
index d6c6a607ae8696ea1965cf11e502ce918a57827a..ddfaf3614aed3287467e8d62cc6e9d8c96402030 100644 (file)
@@ -353,9 +353,22 @@ public:
     * Several GLSL semantic checks require knowledge of whether or not a
     * variable has been used.  For example, it is an error to redeclare a
     * variable as invariant after it has been used.
+    *
+    * This is only maintained in the ast_to_hir.cpp path, not in
+    * Mesa's fixed function or ARB program paths.
     */
    unsigned used:1;
 
+   /**
+    * Has this variable been statically assigned?
+    *
+    * This answers whether the variable was assigned in any path of
+    * the shader during ast_to_hir.  This doesn't answer whether it is
+    * still written after dead code removal, nor is it maintained in
+    * non-ast_to_hir.cpp (GLSL parsing) paths.
+    */
+   unsigned assigned:1;
+
    /**
     * Storage class of the variable.
     *