annotate dmd/IfStatement.d @ 178:e3afd1303184

Many small bugs fixed Made all classes derive from TObject to detect memory leaks (functionality is disabled for now) Began work on overriding backend memory allocations (to avoid memory leaks)
author korDen
date Sun, 17 Oct 2010 07:42:00 +0400
parents af724d3510d7
children b0d41ff5e0df
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.IfStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
114
e28b18c23469 added a module dmd.common for commonly used stuff
Trass3r
parents: 72
diff changeset
3 import dmd.common;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.Statement;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
5 import dmd.Parameter;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
6 import dmd.Loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.Expression;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
8 import dmd.VarDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
9 import dmd.Scope;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
10 import dmd.InterState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11 import dmd.OutBuffer;
154
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
12 import dmd.GlobalExpressions;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import dmd.HdrGenState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14 import dmd.InlineCostState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15 import dmd.InlineDoState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
16 import dmd.InlineScanState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
17 import dmd.IRState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 import dmd.BE;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 import dmd.WANT;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20 import dmd.ScopeDsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
21 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22 import dmd.CondExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23 import dmd.AndAndExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 import dmd.OrOrExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25 import dmd.AssignExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 import dmd.VarExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 import dmd.backend.elem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29 import dmd.backend.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 import dmd.backend.block;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31 import dmd.backend.Blockx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 import dmd.backend.BC;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34 class IfStatement : Statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
36 Parameter arg;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 Expression condition;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
38 Statement ifbody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
39 Statement elsebody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41 VarDeclaration match; // for MatchExpression results
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
43 this(Loc loc, Parameter arg, Expression condition, Statement ifbody, Statement elsebody)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 {
178
e3afd1303184 Many small bugs fixed
korDen
parents: 174
diff changeset
45 register();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 super(loc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 this.arg = arg;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 this.condition = condition;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49 this.ifbody = ifbody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
50 this.elsebody = elsebody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
51 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
53 override Statement syntaxCopy()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 {
51
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
55 Statement i = null;
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
56 if (ifbody)
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
57 i = ifbody.syntaxCopy();
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
58
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
59 Statement e = null;
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
60 if (elsebody)
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
61 e = elsebody.syntaxCopy();
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
62
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
63 Parameter a = arg ? arg.syntaxCopy() : null;
51
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
64 IfStatement s = new IfStatement(loc, a, condition.syntaxCopy(), i, e);
b7d29f613539 StaticAssertStatement.syntaxCopy
korDen
parents: 0
diff changeset
65 return s;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
68 override Statement semantic(Scope sc)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
69 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70 condition = condition.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
71 condition = resolveProperties(sc, condition);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
72 condition = condition.checkToBoolean();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
73
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
74 // If we can short-circuit evaluate the if statement, don't do the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
75 // semantic analysis of the skipped code.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
76 // This feature allows a limited form of conditional compilation.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77 condition = condition.optimize(WANT.WANTflags);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
78
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 // Evaluate at runtime
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
80 uint cs0 = sc.callSuper;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
81 uint cs1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
82
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
83 Scope scd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
84 if (arg)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
85 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
86 /* Declare arg, which we will set to be the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
87 * result of condition.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
88 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
89 ScopeDsymbol sym = new ScopeDsymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
90 sym.parent = sc.scopesym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
91 scd = sc.push(sym);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
92
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
93 Type t = arg.type ? arg.type : condition.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
94 match = new VarDeclaration(loc, t, arg.ident, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
95 match.noauto = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
96 match.semantic(scd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
97 if (!scd.insert(match))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
98 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
99
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
100 match.parent = sc.func;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
101
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
102 /* Generate:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
103 * (arg = condition)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
104 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
105 VarExp v = new VarExp(Loc(0), match);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
106 condition = new AssignExp(loc, v, condition);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
107 condition = condition.semantic(scd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
108 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
109 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
110 scd = sc.push();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
111
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
112 ifbody = ifbody.semantic(scd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
113 scd.pop();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
114
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
115 cs1 = sc.callSuper;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
116 sc.callSuper = cs0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
117 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
118 elsebody = elsebody.semanticScope(sc, null, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
119
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
120 sc.mergeCallSuper(loc, cs1);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
121
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
122 return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
123 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
124
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
125 override Expression interpret(InterState istate)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
126 {
154
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
127 version(LOG)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
128 writef("IfStatement::interpret(%s)\n", condition.toChars());
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
129
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
130 if (istate.start is this)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
131 istate.start = null;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
132 if (istate.start)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
133 {
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
134 Expression e = null;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
135 if (ifbody)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
136 e = ifbody.interpret(istate);
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
137 if (istate.start && elsebody)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
138 e = elsebody.interpret(istate);
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
139 return e;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
140 }
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
141
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
142 Expression e = condition.interpret(istate);
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
143 assert(e);
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
144 //if (e is EXP_CANT_INTERPRET) writef("cannot interpret\n");
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
145 if (e !is EXP_CANT_INTERPRET)
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
146 {
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
147 if (e.isBool(true))
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
148 e = ifbody ? ifbody.interpret(istate) : null;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
149 else if (e.isBool(false))
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
150 e = elsebody ? elsebody.interpret(istate) : null;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
151 else
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
152 {
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
153 e = EXP_CANT_INTERPRET;
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
154 }
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
155 }
14feb7ae01a6 * changed the build system to build a release version if the debug one compiles
trass3r
parents: 130
diff changeset
156 return e;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
157 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
158
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
159 override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
160 {
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
161 buf.writestring("if (");
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
162 if (arg)
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
163 {
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
164 if (arg.type)
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
165 arg.type.toCBuffer(buf, arg.ident, hgs);
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
166 else
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
167 {
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
168 buf.writestring("auto ");
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
169 buf.writestring(arg.ident.toChars());
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
170 }
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
171 buf.writestring(" = ");
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
172 }
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
173 condition.toCBuffer(buf, hgs);
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
174 buf.writebyte(')');
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
175 buf.writenl();
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
176 ifbody.toCBuffer(buf, hgs);
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
177 if (elsebody)
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
178 {
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
179 buf.writestring("else");
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
180 buf.writenl();
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
181 elsebody.toCBuffer(buf, hgs);
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 154
diff changeset
182 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
183 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
184
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
185 override bool usesEH()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
186 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
187 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
188 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
189
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
190 override BE blockExit()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
191 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
192 //printf("IfStatement::blockExit(%p)\n", this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
193
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
194 BE result = BE.BEnone;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
195 if (condition.canThrow())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
196 result |= BE.BEthrow;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
197 if (condition.isBool(true))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
198 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
199 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
200 result |= ifbody.blockExit();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
201 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
202 result |= BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
203 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
204 else if (condition.isBool(false))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
205 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
206 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
207 result |= elsebody.blockExit();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
208 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
209 result |= BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
210 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
211 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
212 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
213 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
214 result |= ifbody.blockExit();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
215 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
216 result |= BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
217
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
218 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
219 result |= elsebody.blockExit();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
220 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
221 result |= BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
222 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
223
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
224 //printf("IfStatement::blockExit(%p) = x%x\n", this, result);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
225 return result;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
226 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
227
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
228 override IfStatement isIfStatement() { return this; }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
229
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
230 override int inlineCost(InlineCostState* ics)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
231 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
232 int cost;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
233
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
234 /* Can't declare variables inside ?: expressions, so
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
235 * we cannot inline if a variable is declared.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
236 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
237 if (arg)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
238 return COST_MAX;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
239
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
240 cost = condition.inlineCost(ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
241
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
242 /* Specifically allow:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
243 * if (condition)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
244 * return exp1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
245 * else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
246 * return exp2;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
247 * Otherwise, we can't handle return statements nested in if's.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
248 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
249
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
250 if (elsebody && ifbody &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
251 ifbody.isReturnStatement() &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
252 elsebody.isReturnStatement())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
253 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
254 cost += ifbody.inlineCost(ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
255 cost += elsebody.inlineCost(ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
256 //printf("cost = %d\n", cost);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
257 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
258 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
259 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
260 ics.nested += 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
261 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
262 cost += ifbody.inlineCost(ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
263 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
264 cost += elsebody.inlineCost(ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
265 ics.nested -= 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
266 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
267 return cost;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
268 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
269
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
270 override Expression doInline(InlineDoState ids)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
271 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
272 Expression econd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
273 Expression e1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
274 Expression e2;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
275 Expression e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
276
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
277 assert(!arg);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
278 econd = condition.doInline(ids);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
279 assert(econd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
280 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
281 e1 = ifbody.doInline(ids);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
282 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
283 e1 = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
284 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
285 e2 = elsebody.doInline(ids);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
286 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
287 e2 = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
288 if (e1 && e2)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
289 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
290 e = new CondExp(econd.loc, econd, e1, e2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
291 e.type = e1.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
292 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
293 else if (e1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
294 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
295 e = new AndAndExp(econd.loc, econd, e1);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
296 e.type = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
297 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
298 else if (e2)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
299 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
300 e = new OrOrExp(econd.loc, econd, e2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
301 e.type = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
302 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
303 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
304 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
305 e = econd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
306 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
307 return e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
308 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
309
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
310 override Statement inlineScan(InlineScanState* iss)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
311 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
312 condition = condition.inlineScan(iss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
313 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
314 ifbody = ifbody.inlineScan(iss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
315 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
316 elsebody = elsebody.inlineScan(iss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
317 return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
318 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
319
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
320 override void toIR(IRState* irs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
321 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
322 elem* e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
323 Blockx* blx = irs.blx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
324
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
325 //printf("IfStatement::toIR('%s')\n", condition.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
326
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
327 IRState mystate = IRState(irs, this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
328
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
329 // bexit is the block that gets control after this IfStatement is done
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
330 block* bexit = mystate.breakBlock ? mystate.breakBlock : block_calloc();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
331
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
332 incUsage(irs, loc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
333 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
334 if (match)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
335 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
336 /* Generate:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
337 * if (match = RTLSYM_IFMATCH(string, pattern)) ...
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
338 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
339 assert(condition.op == TOK.TOKmatch);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
340 e = matchexp_toelem(cast(MatchExp)condition, &mystate, RTLSYM.RTLSYM_IFMATCH);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
341 Symbol *s = match.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
342 symbol_add(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
343 e = el_bin(OPeq, TYnptr, el_var(s), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
344 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
345 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
346 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
347 e = condition.toElem(&mystate);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
348 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
349 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
350 e = condition.toElem(&mystate);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
351 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
352 block_appendexp(blx.curblock, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
353 block* bcond = blx.curblock;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
354 block_next(blx, BC.BCiftrue, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
355
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
356 list_append(&bcond.Bsucc, blx.curblock);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
357 if (ifbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
358 ifbody.toIR(&mystate);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
359
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
360 list_append(&blx.curblock.Bsucc, bexit);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
361
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
362 if (elsebody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
363 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
364 block_next(blx, BC.BCgoto, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
365 list_append(&bcond.Bsucc, blx.curblock);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
366 elsebody.toIR(&mystate);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
367 list_append(&blx.curblock.Bsucc, bexit);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
368 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
369 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
370 list_append(&bcond.Bsucc, bexit);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
371
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
372 block_next(blx, BC.BCgoto, bexit);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
373 }
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 63
diff changeset
374 }