Makefile fixup
[org.ibex.tool.git] / repo / org.ibex.tool / src / org / eclipse / jdt / internal / compiler / ast / DoStatement.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
12
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.*;
18
19 public class DoStatement extends Statement {
20
21         public Expression condition;
22         public Statement action;
23
24         private Label breakLabel, continueLabel;
25
26         // for local variables table attributes
27         int mergedInitStateIndex = -1;
28
29         public DoStatement(Expression condition, Statement action, int s, int e) {
30
31                 this.sourceStart = s;
32                 this.sourceEnd = e;
33                 this.condition = condition;
34                 this.action = action;
35                 // remember useful empty statement
36                 if (action instanceof EmptyStatement) action.bits |= IsUsefulEmptyStatementMASK;
37         }
38
39         public FlowInfo analyseCode(
40                 BlockScope currentScope,
41                 FlowContext flowContext,
42                 FlowInfo flowInfo) {
43
44                 breakLabel = new Label();
45                 continueLabel = new Label();
46                 LoopingFlowContext loopingContext =
47                         new LoopingFlowContext(
48                                 flowContext,
49                                 this,
50                                 breakLabel,
51                                 continueLabel,
52                                 currentScope);
53
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;
59
60                 int previousMode = flowInfo.reachMode();
61                                 
62                 if ((action != null) && !action.isEmptyBlock()) {
63                         flowInfo = action.analyseCode(currentScope, loopingContext, flowInfo);
64
65                         // code generation can be optimized when no need to continue in the loop
66                         if (!flowInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) {
67                                 continueLabel = null;
68                         }
69                 }
70                 /* Reset reach mode, to address following scenario.
71                  *   final blank;
72                  *   do { if (true) break; else blank = 0; } while(false);
73                  *   blank = 1; // may be initialized already 
74                  */
75                 flowInfo.setReachMode(previousMode);
76                 
77                 flowInfo =
78                         condition.analyseCode(
79                                 currentScope,
80                                 loopingContext,
81                                 (action == null
82                                         ? flowInfo
83                                         : (flowInfo.mergedWith(loopingContext.initsOnContinue))));
84                 if (!isConditionOptimizedFalse && continueLabel != null) {
85                         loopingContext.complainOnFinalAssignmentsInLoop(currentScope, flowInfo);
86                 }
87
88                 // end of loop
89                 FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
90                                 loopingContext.initsOnBreak, 
91                                 isConditionOptimizedTrue, 
92                                 flowInfo.initsWhenFalse(), 
93                                 false, // never consider opt false case for DO loop, since break can always occur (47776)
94                                 !isConditionTrue /*do{}while(true); unreachable(); */);
95                 mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
96                 return mergedInfo;
97         }
98
99         /**
100          * Do statement code generation
101          *
102          */
103         public void generateCode(BlockScope currentScope, CodeStream codeStream) {
104
105                 if ((bits & IsReachableMASK) == 0) {
106                         return;
107                 }
108                 int pc = codeStream.position;
109
110                 // labels management
111                 Label actionLabel = new Label(codeStream);
112                 actionLabel.place();
113                 breakLabel.initialize(codeStream);
114                 if (continueLabel != null) {
115                         continueLabel.initialize(codeStream);
116                 }
117
118                 // generate action
119                 if (action != null) {
120                         action.generateCode(currentScope, codeStream);
121                 }
122                 // generate condition
123                 if (continueLabel != null) {
124                         continueLabel.place();
125                         condition.generateOptimizedBoolean(
126                                 currentScope,
127                                 codeStream,
128                                 actionLabel,
129                                 null,
130                                 true);
131                 }
132                 breakLabel.place();
133
134                 // May loose some local variable initializations : affecting the local variable attributes
135                 if (mergedInitStateIndex != -1) {
136                         codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
137                         codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
138                 }
139                 codeStream.recordPositionsFrom(pc, this.sourceStart);
140
141         }
142
143         public StringBuffer printStatement(int indent, StringBuffer output) {
144
145                 printIndent(indent, output).append("do"); //$NON-NLS-1$
146                 if (action == null)
147                         output.append(" ;\n"); //$NON-NLS-1$
148                 else {
149                         output.append('\n');
150                         action.printStatement(indent + 1, output).append('\n');
151                 }
152                 output.append("while ("); //$NON-NLS-1$
153                 return condition.printExpression(0, output).append(");"); //$NON-NLS-1$
154         }
155         public void resolve(BlockScope scope) {
156
157                 TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding);
158                 condition.implicitWidening(type, type);
159                 if (action != null)
160                         action.resolve(scope);
161         }
162
163         public void traverse(ASTVisitor visitor, BlockScope scope) {
164
165                 if (visitor.visit(this, scope)) {
166                         if (action != null) {
167                                 action.traverse(visitor, scope);
168                         }
169                         condition.traverse(visitor, scope);
170                 }
171                 visitor.endVisit(this, scope);
172         }
173 }