Mercurial > projects > ddmd
annotate dmd/TryCatchStatement.d @ 192:eb38fdcb3e62 default tip
updated to compile with dmd2.062
author | korDen |
---|---|
date | Sat, 02 Mar 2013 01:25:52 -0800 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
0 | 1 module dmd.TryCatchStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.Array; | |
6 import dmd.Loc; | |
7 import dmd.Id; | |
8 import dmd.Identifier; | |
9 import dmd.Scope; | |
10 import dmd.InlineScanState; | |
11 import dmd.IRState; | |
12 import dmd.OutBuffer; | |
13 import dmd.Catch; | |
14 import dmd.HdrGenState; | |
15 import dmd.BE; | |
16 | |
17 import dmd.backend.BC; | |
18 import dmd.codegen.Util; | |
19 import dmd.backend.Util; | |
20 import dmd.backend.Blockx; | |
21 import dmd.backend.block; | |
22 import dmd.backend.mTY; | |
23 import dmd.backend.TYM; | |
24 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
25 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
26 |
0 | 27 class TryCatchStatement : Statement |
28 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
29 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 |
0 | 31 Statement body_; |
32 Array catches; | |
33 | |
34 this(Loc loc, Statement body_, Array catches) | |
35 { | |
178 | 36 register(); |
0 | 37 super(loc); |
38 this.body_ = body_; | |
39 this.catches = catches; | |
40 } | |
41 | |
72 | 42 override Statement syntaxCopy() |
0 | 43 { |
63 | 44 Array a = new Array(); |
45 a.setDim(catches.dim); | |
46 for (int i = 0; i < a.dim; i++) | |
47 { | |
48 Catch c; | |
49 | |
50 c = cast(Catch)catches.data[i]; | |
51 c = c.syntaxCopy(); | |
52 a.data[i] = cast(void*)c; | |
53 } | |
54 TryCatchStatement s = new TryCatchStatement(loc, body_.syntaxCopy(), a); | |
55 return s; | |
0 | 56 } |
57 | |
72 | 58 override Statement semantic(Scope sc) |
0 | 59 { |
60 body_ = body_.semanticScope(sc, null /*this*/, null); | |
61 | |
62 /* Even if body is null, still do semantic analysis on catches | |
63 */ | |
64 for (size_t i = 0; i < catches.dim; i++) | |
65 { | |
66 Catch c = cast(Catch)catches.data[i]; | |
67 c.semantic(sc); | |
68 | |
69 // Determine if current catch 'hides' any previous catches | |
70 for (size_t j = 0; j < i; j++) | |
71 { | |
72 Catch cj = cast(Catch)catches.data[j]; | |
73 string si = c.loc.toChars(); | |
74 string sj = cj.loc.toChars(); | |
75 | |
76 if (c.type.toBasetype().implicitConvTo(cj.type.toBasetype())) | |
77 error("catch at %s hides catch at %s", sj, si); | |
78 } | |
79 } | |
80 | |
81 if (!body_ || body_.isEmpty()) | |
82 { | |
83 return null; | |
84 } | |
85 return this; | |
86 } | |
87 | |
72 | 88 override bool hasBreak() |
0 | 89 { |
90 assert(false); | |
91 } | |
92 | |
72 | 93 override bool usesEH() |
0 | 94 { |
95 assert(false); | |
96 } | |
97 | |
72 | 98 override BE blockExit() |
0 | 99 { |
100 assert(body_); | |
101 BE result = body_.blockExit(); | |
102 | |
103 BE catchresult = BE.BEnone; | |
104 for (size_t i = 0; i < catches.dim; i++) | |
105 { | |
106 Catch c = cast(Catch)catches.data[i]; | |
107 catchresult |= c.blockExit(); | |
108 | |
109 /* If we're catching Object, then there is no throwing | |
110 */ | |
111 Identifier id = c.type.toBasetype().isClassHandle().ident; | |
112 if (i == 0 && | |
113 (id is Id.Object_ || id is Id.Throwable || id is Id.Exception)) | |
114 { | |
115 result &= ~BE.BEthrow; | |
116 } | |
117 } | |
118 return result | catchresult; | |
119 } | |
120 | |
72 | 121 override Statement inlineScan(InlineScanState* iss) |
0 | 122 { |
123 if (body_) | |
124 body_ = body_.inlineScan(iss); | |
125 if (catches) | |
126 { | |
127 for (int i = 0; i < catches.dim; i++) | |
128 { | |
129 Catch c = cast(Catch)catches.data[i]; | |
130 | |
131 if (c.handler) | |
132 c.handler = c.handler.inlineScan(iss); | |
133 } | |
134 } | |
135 return this; | |
136 } | |
137 | |
138 /*************************************** | |
139 * Builds the following: | |
140 * _try | |
141 * block | |
142 * jcatch | |
143 * handler | |
144 * A try-catch statement. | |
145 */ | |
72 | 146 override void toIR(IRState *irs) |
0 | 147 { |
148 Blockx *blx = irs.blx; | |
149 | |
150 version (SEH) { | |
151 nteh_declarvars(blx); | |
152 } | |
153 | |
154 IRState mystate = IRState(irs, this); | |
155 | |
156 block* tryblock = block_goto(blx,BCgoto,null); | |
157 | |
158 int previndex = blx.scope_index; | |
159 tryblock.Blast_index = previndex; | |
160 blx.scope_index = tryblock.Bscope_index = blx.next_index++; | |
161 | |
162 // Set the current scope index | |
163 setScopeIndex(blx,tryblock,tryblock.Bscope_index); | |
164 | |
165 // This is the catch variable | |
166 tryblock.jcatchvar = symbol_genauto(type_fake(mTYvolatile | TYnptr)); | |
167 | |
168 blx.tryblock = tryblock; | |
169 block *breakblock = block_calloc(blx); | |
170 block_goto(blx,BC_try,null); | |
171 if (body_) | |
172 { | |
173 body_.toIR(&mystate); | |
174 } | |
175 blx.tryblock = tryblock.Btry; | |
176 | |
177 // break block goes here | |
178 block_goto(blx, BCgoto, breakblock); | |
179 | |
180 setScopeIndex(blx,blx.curblock, previndex); | |
181 blx.scope_index = previndex; | |
182 | |
183 // create new break block that follows all the catches | |
184 breakblock = block_calloc(blx); | |
185 | |
186 list_append(&blx.curblock.Bsucc, breakblock); | |
187 block_next(blx,BCgoto,null); | |
188 | |
189 assert(catches); | |
190 for (int i = 0 ; i < catches.dim; i++) | |
191 { | |
192 Catch cs = cast(Catch)(catches.data[i]); | |
193 if (cs.var) | |
194 cs.var.csym = tryblock.jcatchvar; | |
195 block* bcatch = blx.curblock; | |
196 if (cs.type) | |
197 bcatch.Bcatchtype = cs.type.toBasetype().toSymbol(); | |
198 list_append(&tryblock.Bsucc,bcatch); | |
199 block_goto(blx,BCjcatch,null); | |
200 if (cs.handler !is null) | |
201 { | |
202 IRState catchState = IRState(irs, this); | |
203 cs.handler.toIR(&catchState); | |
204 } | |
205 list_append(&blx.curblock.Bsucc, breakblock); | |
206 block_next(blx, BCgoto, null); | |
207 } | |
208 | |
209 block_next(blx,cast(BC)blx.curblock.BC, breakblock); | |
210 } | |
211 | |
72 | 212 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 213 { |
174 | 214 buf.writestring("try"); |
215 buf.writenl(); | |
216 if (body_) | |
217 body_.toCBuffer(buf, hgs); | |
218 for (size_t i = 0; i < catches.dim; i++) | |
219 { | |
220 Catch c = cast(Catch)catches.data[i]; | |
221 c.toCBuffer(buf, hgs); | |
222 } | |
0 | 223 } |
224 | |
72 | 225 override TryCatchStatement isTryCatchStatement() { return this; } |
226 } |