OSDN Git Service

Handle constant expressions using derefs of const values.
authorEric Anholt <eric@anholt.net>
Tue, 6 Apr 2010 17:30:54 +0000 (10:30 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 6 Apr 2010 18:42:34 +0000 (11:42 -0700)
Fixes CorrectParse1.frag and makes for a ton of folding in
CorrectParse2.frag.

ast_to_hir.cpp
ir.cpp
ir.h
ir_constant_expression.cpp

index 9d067be..ddeab8d 100644 (file)
@@ -1603,12 +1603,15 @@ ast_declarator_list::hir(exec_list *instructions,
          * declaration.
          */
         if (this->type->qualifier.constant) {
-           rhs = rhs->constant_expression_value();
-           if (!rhs) {
+           ir_constant *constant_value = rhs->constant_expression_value();
+           if (!constant_value) {
               _mesa_glsl_error(& initializer_loc, state,
                                "initializer of const variable `%s' must be a "
                                "constant expression",
                                decl->identifier);
+           } else {
+              rhs = constant_value;
+              var->constant_value = constant_value;
            }
         }
 
diff --git a/ir.cpp b/ir.cpp
index 88308ce..0708e49 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -338,6 +338,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name)
 {
    this->type = type;
    this->name = name;
+   this->constant_value = NULL;
 
    if (type && type->base_type == GLSL_TYPE_SAMPLER)
       this->read_only = true;
diff --git a/ir.h b/ir.h
index 5267d2b..a515d9a 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -154,6 +154,11 @@ public:
     * equality).  This flag enables this behavior.
     */
    unsigned array_lvalue:1;
+
+   /**
+    * Value assigned in the initializer of a variable declared "const"
+    */
+   ir_constant *constant_value;
 };
 
 
index 6325df5..9c98ceb 100644 (file)
@@ -395,8 +395,15 @@ ir_constant_visitor::visit(ir_swizzle *ir)
 void
 ir_constant_visitor::visit(ir_dereference *ir)
 {
-   (void) ir;
    value = NULL;
+
+   if (ir->mode == ir_dereference::ir_reference_variable) {
+      ir_variable *var = ir->var->as_variable();
+      if (var && var->constant_value) {
+        value = new ir_constant(ir->type, &var->constant_value->value);
+      }
+   }
+   /* FINISHME: Other dereference modes. */
 }