return this->var->as_rvalue()->is_lvalue();
}
+
+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;
+ }
+ }
+
+ assert(!"Should not get here.");
+ return NULL;
+}
+
+
ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
unsigned w, unsigned count)
: val(val)
#undef S
#undef I
+ir_variable *
+ir_swizzle::variable_referenced()
+{
+ return this->val->variable_referenced();
+}
ir_variable::ir_variable(const struct glsl_type *type, const char *name)
: max_array_access(0), read_only(false), centroid(false), invariant(false),
return false;
}
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced()
+ {
+ return NULL;
+ }
+
protected:
ir_rvalue()
{
return val->is_lvalue() && !mask.has_duplicates;
}
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced();
+
ir_rvalue *val;
ir_swizzle_mask mask;
};
bool is_lvalue();
+ /**
+ * Get the variable that is ultimately referenced by an r-value
+ */
+ virtual ir_variable *variable_referenced();
+
enum {
ir_reference_variable,
ir_reference_array,