glsl2: When a "continue" happens in a "for" loop, run the loop expression.
authorEric Anholt <eric@anholt.net>
Thu, 22 Jul 2010 19:55:16 +0000 (12:55 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 22 Jul 2010 20:02:40 +0000 (13:02 -0700)
Fixes:
glsl1-for-loop with continue

Bug #29097

src/glsl/ast_to_hir.cpp
src/glsl/glsl_parser_extras.h

index 99a2183..0cb3863 100644 (file)
@@ -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.
     */
index 56f6e18..3865843 100644 (file)
@@ -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;