summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir_hv_accept.cpp
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2011-08-18 21:37:31 -0700
committerPaul Berry <stereotype441@gmail.com>2011-09-23 13:28:00 -0700
commitcc81eb09b928389f926b3512c18b3298777d2928 (patch)
tree8e9c7047d6d18eb740b2e512894d3c8898ff3bcf /src/glsl/ir_hv_accept.cpp
parentdeff7fff494a04314fe9ad859029f0436bcc9e9f (diff)
glsl hierarchical visitor: Do not overwrite base_ir for parameter lists.
This patch fixes a bug in ir_hirearchical_visitor: when traversing an exec_list representing the formal or actual parameters of a function, it modified base_ir to point to each parameter in turn, rather than leaving it as a pointer to the enclosing statement. This was a problem, since base_ir is used by visitor classes to locate the statement containing the node being visited (usually so that additional statements can be inserted before or after it). Without this fix, visitors might attempt to insert statements into parameter lists. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Diffstat (limited to 'src/glsl/ir_hv_accept.cpp')
-rw-r--r--src/glsl/ir_hv_accept.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
index d33fc85bf0a..0e78fda81fd 100644
--- a/src/glsl/ir_hv_accept.cpp
+++ b/src/glsl/ir_hv_accept.cpp
@@ -30,7 +30,13 @@
*/
/**
- * 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
@@ -38,19 +44,22 @@
* 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;
}
@@ -129,7 +138,7 @@ ir_function::accept(ir_hierarchical_visitor *v)
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);
}
@@ -317,7 +326,7 @@ ir_call::accept(ir_hierarchical_visitor *v)
if (s != visit_continue)
return (s == visit_continue_with_parent) ? visit_continue : s;
- s = visit_list_elements(v, &this->actual_parameters);
+ s = visit_list_elements(v, &this->actual_parameters, false);
if (s == visit_stop)
return s;