summaryrefslogtreecommitdiff
path: root/ir.cpp
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-05-19 11:37:35 +0200
committerIan Romanick <ian.d.romanick@intel.com>2010-05-26 15:23:19 -0700
commit70fe8b66632f4afd87ebb12a450b1e639428e88f (patch)
treea3eae48e0cf4b2ae22a61efd4e825961938137ba /ir.cpp
parent461c294ac57e387aa2355cfd2aa93cefaba03baa (diff)
Begin refactoring ir_dereference
Create separate subclasses of ir_dereference for variable, array, and record dereferences. As a side effect, array and record dereferences no longer point to ir_variable objects directly. Instead they each point to an ir_dereference_variable object. This is the first of several steps in the refactoring process. The intention is that ir_dereference will eventually become an abstract base class.
Diffstat (limited to 'ir.cpp')
-rw-r--r--ir.cpp107
1 files changed, 51 insertions, 56 deletions
diff --git a/ir.cpp b/ir.cpp
index 696feb23f6..f6f2558bc0 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -223,22 +223,40 @@ ir_constant::ir_constant(bool b)
}
-ir_dereference::ir_dereference(ir_instruction *var)
+ir_dereference_variable::ir_dereference_variable(ir_variable *var)
+ : ir_dereference(ir_reference_variable)
{
- this->mode = ir_reference_variable;
this->var = var;
this->type = (var != NULL) ? var->type : glsl_type::error_type;
}
-ir_dereference::ir_dereference(ir_instruction *var,
- ir_rvalue *array_index)
- : mode(ir_reference_array), var(var)
+ir_dereference_array::ir_dereference_array(ir_rvalue *value,
+ ir_rvalue *array_index)
+ : ir_dereference(ir_reference_array)
{
- type = glsl_type::error_type;
+ this->selector.array_index = array_index;
+ this->set_array(value);
+}
+
+
+ir_dereference_array::ir_dereference_array(ir_variable *var,
+ ir_rvalue *array_index)
+ : ir_dereference(ir_reference_array)
+{
+ this->selector.array_index = array_index;
+ this->set_array(new ir_dereference_variable(var));
+}
+
+
+void
+ir_dereference_array::set_array(ir_rvalue *value)
+{
+ this->var = value;
+ this->type = glsl_type::error_type;
- if (var != NULL) {
- const glsl_type *const vt = var->type;
+ if (this->var != NULL) {
+ const glsl_type *const vt = this->var->type;
if (vt->is_array()) {
type = vt->element_type();
@@ -248,68 +266,45 @@ ir_dereference::ir_dereference(ir_instruction *var,
type = vt->get_base_type();
}
}
+}
- this->selector.array_index = array_index;
+
+ir_dereference_record::ir_dereference_record(ir_rvalue *value,
+ const char *field)
+ : ir_dereference(ir_reference_record)
+{
+ this->var = value;
+ this->selector.field = field;
+ this->type = (this->var != NULL)
+ ? this->var->type->field_type(field) : glsl_type::error_type;
}
-ir_dereference::ir_dereference(ir_instruction *variable, const char *field)
- : mode(ir_reference_record), var(variable)
+
+ir_dereference_record::ir_dereference_record(ir_variable *var,
+ const char *field)
+ : ir_dereference(ir_reference_record)
{
+ this->var = new ir_dereference_variable(var);
this->selector.field = field;
- this->type = (var != NULL)
- ? var->type->field_type(field) : glsl_type::error_type;
+ this->type = (this->var != NULL)
+ ? this->var->type->field_type(field) : glsl_type::error_type;
}
+
bool
ir_dereference::is_lvalue()
{
- if (var == NULL)
- return false;
-
- ir_variable *const as_var = var->as_variable();
- if (mode == ir_reference_variable) {
- if (as_var == NULL)
- return false;
-
- if (as_var->type->is_array() && !as_var->array_lvalue)
- return false;
- }
-
- if (as_var != NULL)
- return !as_var->read_only;
+ ir_variable *var = this->variable_referenced();
- /* Walk up the dereference chain and figure out if the variable is read-only.
+ /* Every l-value derference chain eventually ends in a variable.
*/
- return this->var->as_rvalue()->is_lvalue();
-}
-
+ if ((var == NULL) || var->read_only)
+ return false;
-ir_variable *
-ir_dereference::variable_referenced()
-{
- /* Walk down the dereference chain to find the variable at the end.
- *
- * This could be implemented recurrsively, but it would still need to call
- * as_variable and as_rvalue, so the code wouldn't be any cleaner.
- */
- for (ir_instruction *current = this->var; current != NULL; /* empty */ ) {
- ir_dereference *deref;
- ir_variable *v;
-
- if ((deref = current->as_dereference())) {
- current = deref->var;
- } else if ((v = current->as_variable())) {
- return v;
- } else {
- /* This is the case of, for example, an array dereference of the
- * value returned by a function call.
- */
- return NULL;
- }
- }
+ if (this->type->is_array() && !var->array_lvalue)
+ return false;
- assert(!"Should not get here.");
- return NULL;
+ return true;
}