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