Process ast_jump_statement into ir_loop_jump
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 6 Apr 2010 00:13:47 +0000 (17:13 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 7 Apr 2010 18:42:36 +0000 (11:42 -0700)
Specifically, handle 'break' and 'continue' inside loops.

This causes the following tests to pass:

    glslparsertest/shaders/break.frag
    glslparsertest/shaders/continue.frag

ast_to_hir.cpp

index 444cb7d54e30e974c8dda0921edb06c8fba30e91..ae5a8d51f78c4b589926e38189865c8254ce974d 100644 (file)
@@ -2021,6 +2021,32 @@ ast_jump_statement::hir(exec_list *instructions,
 
    case ast_break:
    case ast_continue:
+      /* FINISHME: Handle switch-statements.  They cannot contain 'continue',
+       * FINISHME: and they use a different IR instruction for 'break'.
+       */
+      /* FINISHME: Correctly handle the nesting.  If a switch-statement is
+       * FINISHME: inside a loop, a 'continue' is valid and will bind to the
+       * FINISHME: loop.
+       */
+      if (state->loop_or_switch_nesting == NULL) {
+        YYLTYPE loc = this->get_location();
+
+        _mesa_glsl_error(& loc, state,
+                         "`%s' may only appear in a loop",
+                         (mode == ast_break) ? "break" : "continue");
+      } else {
+        ir_loop *const loop = state->loop_or_switch_nesting->as_loop();
+
+        if (loop != NULL) {
+           ir_loop_jump *const jump =
+              new ir_loop_jump(loop,
+                               (mode == ast_break)
+                               ? ir_loop_jump::jump_break
+                               : ir_loop_jump::jump_continue);
+           instructions->push_tail(jump);
+        }
+      }
+
       break;
    }