@@ -101,8 +101,7 @@ public static ImStmt translate(StmtForFrom s, ImTranslator t, ImFunction f) {
101101 ImExpr nextCallWrapped = ExprTranslation .wrapTranslation (s , t , nextCall , nextReturn , loopVarType );
102102
103103 imBody .add (ImSet (s , ImVarAccess (t .getVarFor (s .getLoopVar ())), nextCallWrapped ));
104- ImVar continueFlag = createContinueFlagVar (s , f );
105- imBody .addAll (translateLoopBodyWithContinue (t , f , s .getBody (), continueFlag , s ));
104+ imBody .addAll (translateLoopBody (t , f , s .getBody (), s ));
106105
107106 result .add (ImLoop (s , imBody ));
108107 }
@@ -207,8 +206,7 @@ public static ImStmt translate(StmtForIn forIn, ImTranslator t, ImFunction f) {
207206 imBody .add (ImSet (forIn , ImVarAccess (t .getVarFor (forIn .getLoopVar ())), nextCallWrapped ));
208207
209208 // loop body
210- ImVar continueFlag = createContinueFlagVar (forIn , f );
211- imBody .addAll (translateLoopBodyWithContinue (t , f , forIn .getBody (), continueFlag , forIn ));
209+ imBody .addAll (translateLoopBody (t , f , forIn .getBody (), forIn ));
212210
213211 // optional close()<S>()
214212 Optional <FuncLink > closeFunc = forIn .attrCloseFunc ();
@@ -296,8 +294,7 @@ private static ImStmt case_StmtForRange(ImTranslator t, ImFunction f, LocalVarDe
296294 // exitwhen imLoopVar > toExpr
297295 imBody .add (ImExitwhen (trace , ImOperatorCall (opCompare , ImExprs (ImVarAccess (imLoopVar ), toExpr ))));
298296 // loop body:
299- ImVar continueFlag = createContinueFlagVar (trace , f );
300- imBody .addAll (translateLoopBodyWithContinue (t , f , body , continueFlag , trace ));
297+ imBody .addAll (translateLoopBody (t , f , body , trace ));
301298 // set imLoopVar = imLoopVar + stepExpr
302299 imBody .add (ImSet (trace , ImVarAccess (imLoopVar ), ImOperatorCall (opStep , ImExprs (ImVarAccess (imLoopVar ), stepExpr ))));
303300 result .add (ImLoop (trace , imBody ));
@@ -323,8 +320,7 @@ public static ImStmt translate(StmtIf s, ImTranslator t, ImFunction f) {
323320
324321
325322 public static ImStmt translate (StmtLoop s , ImTranslator t , ImFunction f ) {
326- ImVar continueFlag = createContinueFlagVar (s , f );
327- return ImLoop (s , ImStmts (translateLoopBodyWithContinue (t , f , s .getBody (), continueFlag , s )));
323+ return ImLoop (s , ImStmts (translateLoopBody (t , f , s .getBody (), s )));
328324 }
329325
330326
@@ -344,8 +340,7 @@ public static ImStmt translate(StmtWhile s, ImTranslator t, ImFunction f) {
344340 List <ImStmt > body = Lists .newArrayList ();
345341 // exitwhen not while_condition
346342 body .add (ImExitwhen (s .getCond (), ImOperatorCall (WurstOperator .NOT , ImExprs (s .getCond ().imTranslateExpr (t , f )))));
347- ImVar continueFlag = createContinueFlagVar (s , f );
348- body .addAll (translateLoopBodyWithContinue (t , f , s .getBody (), continueFlag , s ));
343+ body .addAll (translateLoopBody (t , f , s .getBody (), s ));
349344 return ImLoop (s , ImStmts (body ));
350345 }
351346
@@ -371,6 +366,55 @@ private static List<ImStmt> translateLoopBodyWithContinue(ImTranslator t, ImFunc
371366 return guardedBody ;
372367 }
373368
369+ private static List <ImStmt > translateLoopBody (ImTranslator t , ImFunction f , List <WStatement > body , Element trace ) {
370+ if (!hasContinueForCurrentLoop (body )) {
371+ return t .translateStatements (f , body );
372+ }
373+ ImVar continueFlag = createContinueFlagVar (trace , f );
374+ return translateLoopBodyWithContinue (t , f , body , continueFlag , trace );
375+ }
376+
377+ private static boolean hasContinueForCurrentLoop (List <WStatement > body ) {
378+ for (WStatement statement : body ) {
379+ if (statement instanceof StmtContinue ) {
380+ return true ;
381+ }
382+ if (statement instanceof StmtLoop
383+ || statement instanceof StmtWhile
384+ || statement instanceof StmtForIn
385+ || statement instanceof StmtForFrom
386+ || statement instanceof StmtForRangeUp
387+ || statement instanceof StmtForRangeDown ) {
388+ // Continue inside nested loops should not trigger guarding for the outer loop.
389+ continue ;
390+ }
391+ if (statement instanceof WBlock && hasContinueForCurrentLoop (((WBlock ) statement ).getBody ())) {
392+ return true ;
393+ }
394+ if (statement instanceof StmtIf ) {
395+ StmtIf stmtIf = (StmtIf ) statement ;
396+ if (hasContinueForCurrentLoop (stmtIf .getThenBlock ()) || hasContinueForCurrentLoop (stmtIf .getElseBlock ())) {
397+ return true ;
398+ }
399+ }
400+ if (statement instanceof SwitchStmt ) {
401+ SwitchStmt switchStmt = (SwitchStmt ) statement ;
402+ for (SwitchCase switchCase : switchStmt .getCases ()) {
403+ if (hasContinueForCurrentLoop (switchCase .getStmts ())) {
404+ return true ;
405+ }
406+ }
407+ if (switchStmt .getSwitchDefault () instanceof SwitchDefaultCaseStatements ) {
408+ SwitchDefaultCaseStatements defaultCase = (SwitchDefaultCaseStatements ) switchStmt .getSwitchDefault ();
409+ if (hasContinueForCurrentLoop (defaultCase .getStmts ())) {
410+ return true ;
411+ }
412+ }
413+ }
414+ }
415+ return false ;
416+ }
417+
374418 public static ImStmt translate (StmtSkip s , ImTranslator translator , ImFunction f ) {
375419 return ImHelper .nullExpr ();
376420 }
0 commit comments