summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-07-22 12:55:16 -0700
committerEric Anholt <[email protected]>2010-07-22 13:02:40 -0700
commit2d1ed7b1b112cf13dd7eda7f500691f4c98a1ccc (patch)
tree18c00c9467da957a9edaebdd023374835338e0fd /src/glsl
parent748c343f8bdbbc8c5f00403b790ad7130424c35f (diff)
glsl2: When a "continue" happens in a "for" loop, run the loop expression.
Fixes: glsl1-for-loop with continue Bug #29097
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ast_to_hir.cpp14
-rw-r--r--src/glsl/glsl_parser_extras.h1
2 files changed, 15 insertions, 0 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 99a2183cf86..0cb3863b3ef 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2308,6 +2308,16 @@ ast_jump_statement::hir(exec_list *instructions,
} else {
ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
+ /* Inline the for loop expression again, since we don't know
+ * where near the end of the loop body the normal copy of it
+ * is going to be placed.
+ */
+ if (mode == ast_continue &&
+ state->loop_or_switch_nesting_ast->rest_expression) {
+ state->loop_or_switch_nesting_ast->rest_expression->hir(instructions,
+ state);
+ }
+
if (loop != NULL) {
ir_loop_jump *const jump =
new(ctx) ir_loop_jump((mode == ast_break)
@@ -2422,7 +2432,10 @@ ast_iteration_statement::hir(exec_list *instructions,
/* Track the current loop and / or switch-statement nesting.
*/
ir_instruction *const nesting = state->loop_or_switch_nesting;
+ ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast;
+
state->loop_or_switch_nesting = stmt;
+ state->loop_or_switch_nesting_ast = this;
if (mode != ast_do_while)
condition_to_hir(stmt, state);
@@ -2442,6 +2455,7 @@ ast_iteration_statement::hir(exec_list *instructions,
/* Restore previous nesting before returning.
*/
state->loop_or_switch_nesting = nesting;
+ state->loop_or_switch_nesting_ast = nesting_ast;
/* Loops do not have r-values.
*/
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 56f6e18e0bd..3865843fd10 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -104,6 +104,7 @@ struct _mesa_glsl_parse_state {
/** Loop or switch statement containing the current instructions. */
class ir_instruction *loop_or_switch_nesting;
+ class ast_iteration_statement *loop_or_switch_nesting_ast;
/** List of structures defined in user code. */
const glsl_type **user_structures;