Mercurial > projects > ddmd
annotate dmd/CompoundStatement.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 | 1475fd394c9e |
children | b0d41ff5e0df |
rev | line source |
---|---|
0 | 1 module dmd.CompoundStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.Statement; | |
6 import dmd.Array; | |
7 import dmd.TryCatchStatement; | |
8 import dmd.TryFinallyStatement; | |
9 import dmd.Catch; | |
10 import dmd.ScopeStatement; | |
11 import dmd.Identifier; | |
12 import dmd.Lexer; | |
13 import dmd.ThrowStatement; | |
14 import dmd.IdentifierExp; | |
15 import dmd.Scope; | |
16 import dmd.OutBuffer; | |
17 import dmd.HdrGenState; | |
18 import dmd.ArrayTypes; | |
19 import dmd.ReturnStatement; | |
20 import dmd.Expression; | |
21 import dmd.InterState; | |
22 import dmd.InlineDoState; | |
23 import dmd.InlineCostState; | |
24 import dmd.InlineScanState; | |
25 import dmd.IfStatement; | |
26 import dmd.IRState; | |
27 import dmd.BE; | |
28 import dmd.Util; | |
29 | |
30 class CompoundStatement : Statement | |
31 { | |
32 Statements statements; | |
33 | |
34 this(Loc loc, Statements s) | |
35 { | |
178 | 36 register(); |
0 | 37 super(loc); |
38 statements = s; | |
39 } | |
40 | |
41 this(Loc loc, Statement s1, Statement s2) | |
42 { | |
178 | 43 register(); |
0 | 44 super(loc); |
45 | |
46 statements = new Statements(); | |
47 statements.reserve(2); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
48 statements.push(s1); |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
49 statements.push(s2); |
0 | 50 } |
51 | |
72 | 52 override Statement syntaxCopy() |
0 | 53 { |
54 Statements a = new Statements(); | |
55 a.setDim(statements.dim); | |
56 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
57 foreach (size_t i, Statement s; statements) |
0 | 58 { |
59 if (s) | |
60 s = s.syntaxCopy(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
61 a[i] = s; |
0 | 62 } |
63 | |
64 return new CompoundStatement(loc, a); | |
65 } | |
66 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
67 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 68 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
69 foreach (s; statements) |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
70 { |
177 | 71 if (s) |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
72 s.toCBuffer(buf, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
73 } |
0 | 74 } |
75 | |
167
50a6d232176c
rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents:
123
diff
changeset
|
76 override Statement semantic(Scope sc) |
0 | 77 { |
78 Statement s; | |
79 | |
80 //printf("CompoundStatement.semantic(this = %p, sc = %p)\n", this, sc); | |
81 | |
82 for (size_t i = 0; i < statements.dim; ) | |
83 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
84 s = statements[i]; |
0 | 85 if (s) |
86 { | |
87 Statements a = s.flatten(sc); | |
88 | |
89 if (a) | |
90 { | |
91 statements.remove(i); | |
92 statements.insert(i, a); | |
93 continue; | |
94 } | |
27 | 95 |
96 s = s.semantic(sc); | |
0 | 97 |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
98 statements[i] = s; |
0 | 99 if (s) |
100 { | |
101 Statement sentry; | |
102 Statement sexception; | |
103 Statement sfinally; | |
104 | |
105 s.scopeCode(sc, &sentry, &sexception, &sfinally); | |
106 if (sentry) | |
107 { | |
108 sentry = sentry.semantic(sc); | |
109 if (s.isDeclarationStatement()) | |
110 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
111 statements.insert(i, sentry); |
0 | 112 i++; |
113 } | |
114 else | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
115 statements[i] = sentry; |
0 | 116 } |
117 if (sexception) | |
118 { | |
119 if (i + 1 == statements.dim && !sfinally) | |
120 { | |
121 static if (true) { | |
122 sexception = sexception.semantic(sc); | |
123 } else { | |
124 statements.push(sexception); | |
125 if (sfinally) | |
126 // Assume sexception does not throw | |
127 statements.push(sfinally); | |
128 } | |
129 } | |
130 else | |
131 { | |
132 /* Rewrite: | |
133 * s; s1; s2; | |
134 * As: | |
135 * s; | |
136 * try { s1; s2; } | |
137 * catch (Object __o) | |
138 * { sexception; throw __o; } | |
139 */ | |
140 Statement body_; | |
141 Statements aa = new Statements(); | |
142 | |
143 for (int j = i + 1; j < statements.dim; j++) | |
144 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
145 aa.push(statements[j]); |
0 | 146 } |
147 body_ = new CompoundStatement(Loc(0), aa); | |
148 body_ = new ScopeStatement(Loc(0), body_); | |
149 | |
150 Identifier id = Lexer.uniqueId("__o"); | |
151 | |
152 Statement handler = new ThrowStatement(Loc(0), new IdentifierExp(Loc(0), id)); | |
153 handler = new CompoundStatement(Loc(0), sexception, handler); | |
154 | |
155 Array catches = new Array(); | |
156 Catch ctch = new Catch(Loc(0), null, id, handler); | |
157 catches.push(cast(void*)ctch); | |
158 s = new TryCatchStatement(Loc(0), body_, catches); | |
159 | |
160 if (sfinally) | |
161 s = new TryFinallyStatement(Loc(0), s, sfinally); | |
162 s = s.semantic(sc); | |
163 statements.setDim(i + 1); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
164 statements.push(s); |
0 | 165 break; |
166 } | |
167 } | |
168 else if (sfinally) | |
169 { | |
170 if (0 && i + 1 == statements.dim) | |
171 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
172 statements.push(sfinally); |
0 | 173 } |
174 else | |
175 { | |
176 /* Rewrite: | |
177 * s; s1; s2; | |
178 * As: | |
179 * s; try { s1; s2; } finally { sfinally; } | |
180 */ | |
181 Statement body_; | |
182 Statements aa = new Statements(); | |
183 | |
184 for (int j = i + 1; j < statements.dim; j++) | |
185 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
186 aa.push(statements[j]); |
0 | 187 } |
188 body_ = new CompoundStatement(Loc(0), aa); | |
189 s = new TryFinallyStatement(Loc(0), body_, sfinally); | |
190 s = s.semantic(sc); | |
191 statements.setDim(i + 1); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
192 statements.push(s); |
0 | 193 break; |
194 } | |
195 } | |
196 } | |
197 } | |
198 i++; | |
199 } | |
200 if (statements.dim == 1) | |
201 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
202 return statements[0]; |
0 | 203 } |
204 return this; | |
205 } | |
206 | |
72 | 207 override bool usesEH() |
0 | 208 { |
123 | 209 foreach (Statement s; statements) |
210 { | |
211 if (s && s.usesEH()) | |
212 return true; | |
213 } | |
214 | |
215 return false; | |
0 | 216 } |
217 | |
72 | 218 override BE blockExit() |
0 | 219 { |
220 //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); | |
221 BE result = BE.BEfallthru; | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
222 foreach (s; statements) |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
223 { |
0 | 224 if (s) |
225 { | |
226 //printf("result = x%x\n", result); | |
227 //printf("%s\n", s->toChars()); | |
228 if (!(result & BE.BEfallthru) && !s.comeFrom()) | |
229 { | |
79 | 230 if (s.blockExit() != BE.BEhalt && !s.isEmpty()) |
0 | 231 s.warning("statement is not reachable"); |
232 } | |
79 | 233 else |
234 { | |
235 result &= ~BE.BEfallthru; | |
236 result |= s.blockExit(); | |
237 } | |
0 | 238 } |
239 } | |
240 | |
241 return result; | |
242 } | |
243 | |
72 | 244 override bool comeFrom() |
0 | 245 { |
246 assert(false); | |
247 } | |
248 | |
72 | 249 override bool isEmpty() |
0 | 250 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
251 foreach (s; statements) |
0 | 252 { |
253 if (s && !s.isEmpty()) | |
254 return false; | |
255 } | |
256 return true; | |
257 } | |
258 | |
72 | 259 override Statements flatten(Scope sc) |
0 | 260 { |
261 return statements; | |
262 } | |
263 | |
72 | 264 override ReturnStatement isReturnStatement() |
0 | 265 { |
266 ReturnStatement rs = null; | |
267 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
268 foreach(s; statements) |
0 | 269 { |
270 if (s) | |
271 { | |
272 rs = s.isReturnStatement(); | |
273 if (rs) | |
274 break; | |
275 } | |
276 } | |
277 return rs; | |
278 } | |
279 | |
72 | 280 override Expression interpret(InterState istate) |
0 | 281 { |
63 | 282 Expression e = null; |
283 | |
284 version (LOG) { | |
285 printf("CompoundStatement.interpret()\n"); | |
286 } | |
287 if (istate.start == this) | |
288 istate.start = null; | |
289 if (statements) | |
290 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
291 foreach(s; statements) |
63 | 292 { |
293 if (s) | |
294 { | |
295 e = s.interpret(istate); | |
296 if (e) | |
297 break; | |
298 } | |
299 } | |
300 } | |
301 version (LOG) { | |
302 printf("-CompoundStatement.interpret() %p\n", e); | |
303 } | |
304 return e; | |
0 | 305 } |
306 | |
72 | 307 override int inlineCost(InlineCostState* ics) |
0 | 308 { |
309 int cost = 0; | |
310 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
311 foreach(s; statements) |
0 | 312 { |
313 if (s) | |
314 { | |
315 cost += s.inlineCost(ics); | |
316 if (cost >= COST_MAX) | |
317 break; | |
318 } | |
319 } | |
320 | |
321 return cost; | |
322 } | |
323 | |
72 | 324 override Expression doInline(InlineDoState ids) |
0 | 325 { |
326 Expression e = null; | |
327 | |
328 //printf("CompoundStatement.doInline() %d\n", statements.dim); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
329 foreach(s; statements) |
0 | 330 { |
331 if (s) | |
332 { | |
333 Expression e2 = s.doInline(ids); | |
334 e = Expression.combine(e, e2); | |
335 if (s.isReturnStatement()) | |
336 break; | |
337 | |
338 /* Check for: | |
339 * if (condition) | |
340 * return exp1; | |
341 * else | |
342 * return exp2; | |
343 */ | |
344 IfStatement ifs = s.isIfStatement(); | |
345 if (ifs && ifs.elsebody && ifs.ifbody && | |
346 ifs.ifbody.isReturnStatement() && | |
347 ifs.elsebody.isReturnStatement() | |
348 ) | |
349 break; | |
350 } | |
351 } | |
352 return e; | |
353 } | |
354 | |
72 | 355 override Statement inlineScan(InlineScanState* iss) |
0 | 356 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
357 foreach(ref Statement s; statements) |
0 | 358 { |
359 if (s) | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
360 s = s.inlineScan(iss); |
0 | 361 } |
362 | |
363 return this; | |
364 } | |
365 | |
72 | 366 override void toIR(IRState* irs) |
0 | 367 { |
368 if (statements) | |
369 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
370 foreach(s; statements) |
0 | 371 { |
372 if (s !is null) | |
373 { | |
174 | 374 //writeln(s.classinfo.name); |
0 | 375 s.toIR(irs); |
376 } | |
377 } | |
378 } | |
379 } | |
380 | |
72 | 381 override CompoundStatement isCompoundStatement() { return this; } |
382 } |