*/
/**
- * Process a list of nodes using a hierarchical vistor
+ * Process a list of nodes using a hierarchical vistor.
+ *
+ * If statement_list is true (the default), this is a list of statements, so
+ * v->base_ir will be set to point to each statement just before iterating
+ * over it, and restored after iteration is complete. If statement_list is
+ * false, this is a list that appears inside a statement (e.g. a parameter
+ * list), so v->base_ir will be left alone.
*
* \warning
* This function will operate correctly if a node being processed is removed
* processed, some of the added nodes may not be processed.
*/
ir_visitor_status
-visit_list_elements(ir_hierarchical_visitor *v, exec_list *l)
+visit_list_elements(ir_hierarchical_visitor *v, exec_list *l,
+ bool statement_list)
{
ir_instruction *prev_base_ir = v->base_ir;
foreach_list_safe(n, l) {
ir_instruction *const ir = (ir_instruction *) n;
- v->base_ir = ir;
+ if (statement_list)
+ v->base_ir = ir;
ir_visitor_status s = ir->accept(v);
if (s != visit_continue)
return s;
}
- v->base_ir = prev_base_ir;
+ if (statement_list)
+ v->base_ir = prev_base_ir;
return visit_continue;
}
+ir_visitor_status
+ir_rvalue::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
ir_visitor_status
ir_variable::accept(ir_hierarchical_visitor *v)
{
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
+ if (this->counter) {
+ s = this->counter->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
s = visit_list_elements(v, &this->body_instructions);
if (s == visit_stop)
return s;
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
- s = visit_list_elements(v, &this->signatures);
+ s = visit_list_elements(v, &this->signatures, false);
return (s == visit_stop) ? s : v->visit_leave(this);
}
switch (this->op) {
case ir_tex:
+ case ir_lod:
+ case ir_query_levels:
break;
case ir_txb:
s = this->lod_info.bias->accept(v);
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
break;
+ case ir_txf_ms:
+ s = this->lod_info.sample_index->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
case ir_txd:
s = this->lod_info.grad.dPdx->accept(v);
if (s != visit_continue)
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
break;
+ case ir_tg4:
+ s = this->lod_info.component->accept(v);
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ break;
}
return (s == visit_stop) ? s : v->visit_leave(this);
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
- s = visit_list_elements(v, &this->actual_parameters);
+ if (this->return_deref != NULL) {
+ v->in_assignee = true;
+ s = this->return_deref->accept(v);
+ v->in_assignee = false;
+ if (s != visit_continue)
+ return (s == visit_continue_with_parent) ? visit_continue : s;
+ }
+
+ s = visit_list_elements(v, &this->actual_parameters, false);
if (s == visit_stop)
return s;
return v->visit_leave(this);
}
+
+ir_visitor_status
+ir_emit_vertex::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}
+
+
+ir_visitor_status
+ir_end_primitive::accept(ir_hierarchical_visitor *v)
+{
+ return v->visit(this);
+}