1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.impl.*;
15 import org.eclipse.jdt.internal.compiler.codegen.*;
16 import org.eclipse.jdt.internal.compiler.flow.*;
17 import org.eclipse.jdt.internal.compiler.lookup.*;
19 public class DoStatement extends Statement {
21 public Expression condition;
22 public Statement action;
24 private Label breakLabel, continueLabel;
26 // for local variables table attributes
27 int mergedInitStateIndex = -1;
29 public DoStatement(Expression condition, Statement action, int s, int e) {
33 this.condition = condition;
35 // remember useful empty statement
36 if (action instanceof EmptyStatement) action.bits |= IsUsefulEmptyStatementMASK;
39 public FlowInfo analyseCode(
40 BlockScope currentScope,
41 FlowContext flowContext,
44 breakLabel = new Label();
45 continueLabel = new Label();
46 LoopingFlowContext loopingContext =
47 new LoopingFlowContext(
54 Constant cst = condition.constant;
55 boolean isConditionTrue = cst != NotAConstant && cst.booleanValue() == true;
56 cst = condition.optimizedBooleanConstant();
57 boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true;
58 boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false;
60 int previousMode = flowInfo.reachMode();
62 FlowInfo actionInfo = flowInfo.copy().unconditionalInits().discardNullRelatedInitializations();
63 if ((action != null) && !action.isEmptyBlock()) {
64 actionInfo = action.analyseCode(currentScope, loopingContext, actionInfo);
66 // code generation can be optimized when no need to continue in the loop
67 if (!actionInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) {
71 /* Reset reach mode, to address following scenario.
73 * do { if (true) break; else blank = 0; } while(false);
74 * blank = 1; // may be initialized already
76 actionInfo.setReachMode(previousMode);
79 condition.analyseCode(
84 : (actionInfo.mergedWith(loopingContext.initsOnContinue))));
85 if (!isConditionOptimizedFalse && continueLabel != null) {
86 loopingContext.complainOnDeferredChecks(currentScope, actionInfo);
90 FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
91 loopingContext.initsOnBreak,
92 isConditionOptimizedTrue,
93 actionInfo.initsWhenFalse().addInitializationsFrom(flowInfo), // recover null inits from before condition analysis
94 false, // never consider opt false case for DO loop, since break can always occur (47776)
95 !isConditionTrue /*do{}while(true); unreachable(); */);
96 mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
101 * Do statement code generation
104 public void generateCode(BlockScope currentScope, CodeStream codeStream) {
106 if ((bits & IsReachableMASK) == 0) {
109 int pc = codeStream.position;
112 Label actionLabel = new Label(codeStream);
114 breakLabel.initialize(codeStream);
115 if (continueLabel != null) {
116 continueLabel.initialize(codeStream);
120 if (action != null) {
121 action.generateCode(currentScope, codeStream);
123 // generate condition
124 if (continueLabel != null) {
125 continueLabel.place();
126 condition.generateOptimizedBoolean(
135 // May loose some local variable initializations : affecting the local variable attributes
136 if (mergedInitStateIndex != -1) {
137 codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
138 codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
140 codeStream.recordPositionsFrom(pc, this.sourceStart);
144 public StringBuffer printStatement(int indent, StringBuffer output) {
146 printIndent(indent, output).append("do"); //$NON-NLS-1$
148 output.append(" ;\n"); //$NON-NLS-1$
151 action.printStatement(indent + 1, output).append('\n');
153 output.append("while ("); //$NON-NLS-1$
154 return condition.printExpression(0, output).append(");"); //$NON-NLS-1$
156 public void resolve(BlockScope scope) {
158 TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding);
159 condition.computeConversion(scope, type, type);
161 action.resolve(scope);
164 public void traverse(ASTVisitor visitor, BlockScope scope) {
166 if (visitor.visit(this, scope)) {
167 if (action != null) {
168 action.traverse(visitor, scope);
170 condition.traverse(visitor, scope);
172 visitor.endVisit(this, scope);