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