Mercurial > projects > ddmd
annotate dmd/DeleteExp.d @ 174:af724d3510d7
lot os toCBuffer methods implemented
moved shared Type.* stuff into Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 03:47:23 +0400 |
parents | e28b18c23469 |
children | e3afd1303184 |
rev | line source |
---|---|
72 | 1 module dmd.DeleteExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.backend.elem; | |
6 import dmd.UnaExp; | |
7 import dmd.OutBuffer; | |
8 import dmd.Loc; | |
9 import dmd.Scope; | |
10 import dmd.IRState; | |
0 | 11 import dmd.HdrGenState; |
12 import dmd.Type; | |
13 import dmd.IndexExp; | |
174 | 14 import dmd.PREC; |
0 | 15 import dmd.Global; |
16 import dmd.VarExp; | |
17 import dmd.Identifier; | |
18 import dmd.StructDeclaration; | |
19 import dmd.Lexer; | |
20 import dmd.FuncDeclaration; | |
21 import dmd.TypeStruct; | |
22 import dmd.CallExp; | |
23 import dmd.DotVarExp; | |
24 import dmd.DeclarationExp; | |
25 import dmd.ExpInitializer; | |
26 import dmd.VarDeclaration; | |
27 import dmd.TypePointer; | |
28 import dmd.ClassDeclaration; | |
29 import dmd.TypeClass; | |
72 | 30 import dmd.TY; |
0 | 31 import dmd.TOK; |
32 import dmd.TypeAArray; | |
33 import dmd.TypeSArray; | |
34 | |
174 | 35 import dmd.expression.Util; |
0 | 36 import dmd.codegen.Util; |
37 import dmd.backend.Util; | |
38 import dmd.backend.OPER; | |
39 import dmd.backend.RTLSYM; | |
40 import dmd.backend.mTY; | |
41 import dmd.backend.Symbol; | |
72 | 42 import dmd.backend.TYM; |
43 | |
0 | 44 class DeleteExp : UnaExp |
45 { | |
46 this(Loc loc, Expression e) | |
47 { | |
48 super(loc, TOK.TOKdelete, DeleteExp.sizeof, e); | |
49 } | |
50 | |
72 | 51 override Expression semantic(Scope sc) |
0 | 52 { |
53 Type tb; | |
54 | |
55 UnaExp.semantic(sc); | |
56 e1 = resolveProperties(sc, e1); | |
57 e1 = e1.toLvalue(sc, null); | |
58 type = Type.tvoid; | |
59 | |
60 tb = e1.type.toBasetype(); | |
61 switch (tb.ty) | |
174 | 62 { |
0 | 63 case Tclass: |
174 | 64 { |
0 | 65 TypeClass tc = cast(TypeClass)tb; |
66 ClassDeclaration cd = tc.sym; | |
67 | |
68 if (cd.isCOMinterface()) | |
69 { /* Because COM classes are deleted by IUnknown.Release() | |
70 */ | |
71 error("cannot delete instance of COM interface %s", cd.toChars()); | |
72 } | |
73 break; | |
74 } | |
75 case Tpointer: | |
76 tb = (cast(TypePointer)tb).next.toBasetype(); | |
77 if (tb.ty == Tstruct) | |
78 { | |
79 TypeStruct ts = cast(TypeStruct)tb; | |
80 StructDeclaration sd = ts.sym; | |
81 FuncDeclaration f = sd.aggDelete; | |
82 FuncDeclaration fd = sd.dtor; | |
83 | |
84 if (!f && !fd) | |
85 break; | |
86 | |
87 /* Construct: | |
88 * ea = copy e1 to a tmp to do side effects only once | |
89 * eb = call destructor | |
90 * ec = call deallocator | |
91 */ | |
92 Expression ea = null; | |
93 Expression eb = null; | |
94 Expression ec = null; | |
95 VarDeclaration v; | |
96 | |
97 if (fd && f) | |
174 | 98 { |
0 | 99 Identifier id = Lexer.idPool("__tmp"); |
100 v = new VarDeclaration(loc, e1.type, id, new ExpInitializer(loc, e1)); | |
101 v.semantic(sc); | |
102 v.parent = sc.parent; | |
103 ea = new DeclarationExp(loc, v); | |
104 ea.type = v.type; | |
105 } | |
106 | |
107 if (fd) | |
174 | 108 { |
0 | 109 Expression e = ea ? new VarExp(loc, v) : e1; |
110 e = new DotVarExp(Loc(0), e, fd, 0); | |
111 eb = new CallExp(loc, e); | |
112 eb = eb.semantic(sc); | |
113 } | |
114 | |
115 if (f) | |
116 { | |
117 Type tpv = Type.tvoid.pointerTo(); | |
118 Expression e = ea ? new VarExp(loc, v) : e1.castTo(sc, tpv); | |
119 e = new CallExp(loc, new VarExp(loc, f), e); | |
120 ec = e.semantic(sc); | |
121 } | |
122 ea = combine(ea, eb); | |
123 ea = combine(ea, ec); | |
124 assert(ea); | |
125 return ea; | |
126 } | |
127 break; | |
128 | |
129 case Tarray: | |
130 /* BUG: look for deleting arrays of structs with dtors. | |
131 */ | |
132 break; | |
133 | |
134 default: | |
135 if (e1.op == TOKindex) | |
136 { | |
137 IndexExp ae = cast(IndexExp)e1; | |
138 Type tb1 = ae.e1.type.toBasetype(); | |
139 if (tb1.ty == Taarray) | |
140 break; | |
141 } | |
142 error("cannot delete type %s", e1.type.toChars()); | |
143 break; | |
144 } | |
174 | 145 |
0 | 146 if (e1.op == TOKindex) |
147 { | |
148 IndexExp ae = cast(IndexExp)e1; | |
149 Type tb1 = ae.e1.type.toBasetype(); | |
150 if (tb1.ty == Taarray) | |
174 | 151 { |
0 | 152 if (!global.params.useDeprecated) |
153 error("delete aa[key] deprecated, use aa.remove(key)"); | |
154 } | |
155 } | |
156 | |
157 return this; | |
158 } | |
159 | |
72 | 160 override Expression checkToBoolean() |
0 | 161 { |
162 assert(false); | |
163 } | |
164 | |
72 | 165 override bool checkSideEffect(int flag) |
0 | 166 { |
167 return true; | |
168 } | |
169 | |
72 | 170 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 171 { |
174 | 172 buf.writestring("delete "); |
173 expToCBuffer(buf, hgs, e1, precedence[op]); | |
0 | 174 } |
175 | |
72 | 176 override elem* toElem(IRState* irs) |
0 | 177 { |
178 elem* e; | |
179 int rtl; | |
180 Type tb; | |
181 | |
182 //printf("DeleteExp.toElem()\n"); | |
183 if (e1.op == TOKindex) | |
184 { | |
185 IndexExp ae = cast(IndexExp)e1; | |
186 tb = ae.e1.type.toBasetype(); | |
187 if (tb.ty == Taarray) | |
188 { | |
189 TypeAArray taa = cast(TypeAArray)tb; | |
190 elem* ea = ae.e1.toElem(irs); | |
191 elem* ekey = ae.e2.toElem(irs); | |
192 elem* ep; | |
193 elem* keyti; | |
194 | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
72
diff
changeset
|
195 if (tybasic(ekey.Ety) == TYstruct || tybasic(ekey.Ety) == TYarray) |
0 | 196 { |
197 ekey = el_una(OPstrpar, TYstruct, ekey); | |
198 ekey.Enumbytes = ekey.E1.Enumbytes; | |
199 assert(ekey.Enumbytes); | |
200 } | |
201 | |
202 Symbol *s = taa.aaGetSymbol("Del", 0); | |
203 keyti = taa.index.getInternalTypeInfo(null).toElem(irs); | |
204 ep = el_params(ekey, keyti, ea, null); | |
205 e = el_bin(OPcall, TYnptr, el_var(s), ep); | |
206 goto Lret; | |
207 } | |
208 } | |
209 //e1.type.print(); | |
210 e = e1.toElem(irs); | |
211 tb = e1.type.toBasetype(); | |
212 switch (tb.ty) | |
213 { | |
214 case Tarray: | |
174 | 215 { |
0 | 216 e = addressElem(e, e1.type); |
217 rtl = RTLSYM_DELARRAYT; | |
218 | |
219 /* See if we need to run destructors on the array contents | |
220 */ | |
221 elem *et = null; | |
222 Type tv = tb.nextOf().toBasetype(); | |
223 while (tv.ty == Tsarray) | |
174 | 224 { |
0 | 225 TypeSArray ta = cast(TypeSArray)tv; |
226 tv = tv.nextOf().toBasetype(); | |
227 } | |
228 if (tv.ty == Tstruct) | |
174 | 229 { |
0 | 230 TypeStruct ts = cast(TypeStruct)tv; |
231 StructDeclaration sd = ts.sym; | |
232 if (sd.dtor) | |
233 et = tb.nextOf().getTypeInfo(null).toElem(irs); | |
234 } | |
235 if (!et) // if no destructors needed | |
236 et = el_long(TYnptr, 0); // pass null for TypeInfo | |
237 e = el_params(et, e, null); | |
238 // call _d_delarray_t(e, et); | |
239 e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e); | |
240 goto Lret; | |
241 } | |
242 case Tclass: | |
243 if (e1.op == TOKvar) | |
174 | 244 { |
0 | 245 VarExp ve = cast(VarExp)e1; |
246 if (ve.var.isVarDeclaration() && | |
247 ve.var.isVarDeclaration().onstack) | |
248 { | |
249 rtl = RTLSYM_CALLFINALIZER; | |
250 if (tb.isClassHandle().isInterfaceDeclaration()) | |
251 rtl = RTLSYM_CALLINTERFACEFINALIZER; | |
252 break; | |
253 } | |
254 } | |
255 e = addressElem(e, e1.type); | |
256 rtl = RTLSYM_DELCLASS; | |
257 if (tb.isClassHandle().isInterfaceDeclaration()) | |
258 rtl = RTLSYM_DELINTERFACE; | |
259 break; | |
260 | |
261 case Tpointer: | |
262 e = addressElem(e, e1.type); | |
263 rtl = RTLSYM_DELMEMORY; | |
264 break; | |
265 | |
266 default: | |
267 assert(0); | |
268 break; | |
269 } | |
270 e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e); | |
271 | |
272 Lret: | |
273 el_setLoc(e,loc); | |
274 return e; | |
275 } | |
276 } | |
277 |