Mercurial > projects > ddmd
annotate dmd/DotVarExp.d @ 84:be2ab491772e
Expressions -> Vector!Expression
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 16:12:19 +0100 |
parents | ef02e2e203c2 |
children | acd69f84627e |
rev | line source |
---|---|
72 | 1 module dmd.DotVarExp; |
2 | |
3 import dmd.Expression; | |
4 import dmd.Declaration; | |
5 import dmd.backend.elem; | |
6 import dmd.UnaExp; | |
7 import dmd.InterState; | |
8 import dmd.OutBuffer; | |
9 import dmd.Loc; | |
10 import dmd.Scope; | |
11 import dmd.IRState; | |
12 import dmd.HdrGenState; | |
13 import dmd.TOK; | |
14 import dmd.TupleDeclaration; | |
15 import dmd.ArrayTypes; | |
16 import dmd.DsymbolExp; | |
17 import dmd.TupleExp; | |
18 import dmd.Global; | |
19 import dmd.Type; | |
20 import dmd.Dsymbol; | |
21 import dmd.AggregateDeclaration; | |
22 import dmd.VarDeclaration; | |
23 import dmd.WANT; | |
24 import dmd.TY; | |
25 import dmd.ErrorExp; | |
26 import dmd.FuncDeclaration; | |
27 import dmd.STC; | |
28 import dmd.GlobalExpressions; | |
29 import dmd.VarExp; | |
30 import dmd.StructLiteralExp; | |
31 import dmd.PREC; | |
32 | |
33 import dmd.expression.Util; | |
34 import dmd.codegen.Util; | |
35 import dmd.backend.Util; | |
36 import dmd.backend.mTY; | |
37 import dmd.backend.OPER; | |
38 import dmd.backend.TYM; | |
39 | |
0 | 40 class DotVarExp : UnaExp |
41 { | |
42 Declaration var; | |
43 | |
73 | 44 bool hasOverloads; |
0 | 45 |
73 | 46 this(Loc loc, Expression e, Declaration var, bool hasOverloads = false) |
0 | 47 { |
72 | 48 super(loc, TOK.TOKdotvar, DotVarExp.sizeof, e); |
49 //printf("DotVarExp()\n"); | |
50 this.var = var; | |
51 this.hasOverloads = hasOverloads; | |
0 | 52 } |
53 | |
72 | 54 override Expression semantic(Scope sc) |
0 | 55 { |
72 | 56 version (LOGSEMANTIC) { |
57 printf("DotVarExp.semantic('%s')\n", toChars()); | |
58 } | |
59 if (!type) | |
60 { | |
61 var = var.toAlias().isDeclaration(); | |
62 | |
63 TupleDeclaration tup = var.isTupleDeclaration(); | |
64 if (tup) | |
65 { | |
66 /* Replace: | |
67 * e1.tuple(a, b, c) | |
68 * with: | |
69 * tuple(e1.a, e1.b, e1.c) | |
70 */ | |
71 Expressions exps = new Expressions; | |
72 | |
73 exps.reserve(tup.objects.dim); | |
74 for (size_t i = 0; i < tup.objects.dim; i++) | |
75 { | |
76 Object o = cast(Object)tup.objects.data[i]; | |
77 if (auto e = cast(Expression)o) | |
78 { | |
79 if (e.op != TOK.TOKdsymbol) | |
80 error("%s is not a member", e.toChars()); | |
81 else | |
82 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
83 auto ve = cast(DsymbolExp)e; |
72 | 84 e = new DotVarExp(loc, e1, ve.s.isDeclaration()); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
73
diff
changeset
|
85 exps.push(e); |
72 | 86 } |
87 } else { | |
88 error("%s is not an expression", o.toString()); | |
89 } | |
90 } | |
91 Expression e = new TupleExp(loc, exps); | |
92 e = e.semantic(sc); | |
93 return e; | |
94 } | |
95 | |
96 e1 = e1.semantic(sc); | |
97 type = var.type; | |
98 if (!type && global.errors) | |
99 { | |
100 // var is goofed up, just return 0 | |
101 return new ErrorExp(); | |
102 } | |
103 assert(type); | |
104 | |
105 if (!var.isFuncDeclaration()) // for functions, do checks after overload resolution | |
106 { | |
107 Type t1 = e1.type; | |
108 if (t1.ty == TY.Tpointer) | |
109 t1 = t1.nextOf(); | |
110 | |
111 type = type.addMod(t1.mod); | |
112 | |
113 Dsymbol vparent = var.toParent(); | |
114 AggregateDeclaration ad = vparent ? vparent.isAggregateDeclaration() : null; | |
115 e1 = getRightThis(loc, sc, ad, e1, var); | |
116 if (!sc.noaccesscheck) | |
117 accessCheck(loc, sc, e1, var); | |
118 | |
119 VarDeclaration v = var.isVarDeclaration(); | |
120 Expression e = expandVar(WANT.WANTvalue, v); | |
121 if (e) | |
122 return e; | |
123 } | |
124 } | |
125 //printf("-DotVarExp.semantic('%s')\n", toChars()); | |
0 | 126 return this; |
127 } | |
128 | |
72 | 129 override int isLvalue() |
0 | 130 { |
58 | 131 return 1; |
0 | 132 } |
133 | |
72 | 134 override Expression toLvalue(Scope sc, Expression e) |
0 | 135 { |
72 | 136 //printf("DotVarExp::toLvalue(%s)\n", toChars()); |
0 | 137 return this; |
138 } | |
139 | |
72 | 140 override Expression modifiableLvalue(Scope sc, Expression e) |
0 | 141 { |
72 | 142 static if (false) { |
143 printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); | |
144 printf("e1.type = %s\n", e1.type.toChars()); | |
145 printf("var.type = %s\n", var.type.toChars()); | |
146 } | |
147 | |
148 if (var.isCtorinit()) | |
149 { | |
150 // It's only modifiable if inside the right constructor | |
151 Dsymbol s = sc.func; | |
152 while (true) | |
153 { | |
154 FuncDeclaration fd = null; | |
155 if (s) | |
156 fd = s.isFuncDeclaration(); | |
157 if (fd && ((fd.isCtorDeclaration() && var.storage_class & STC.STCfield) || | |
158 (fd.isStaticCtorDeclaration() && !(var.storage_class & STC.STCfield))) && | |
159 fd.toParent() == var.toParent() && e1.op == TOK.TOKthis) | |
160 { | |
161 VarDeclaration v = var.isVarDeclaration(); | |
162 assert(v); | |
163 v.ctorinit = 1; | |
164 //printf("setting ctorinit\n"); | |
165 } | |
166 else | |
167 { | |
168 if (s) | |
169 { | |
170 s = s.toParent2(); | |
171 continue; | |
172 } | |
173 else | |
174 { | |
175 string p = var.isStatic() ? "static " : ""; | |
176 error("can only initialize %sconst member %s inside %sconstructor", p, var.toChars(), p); | |
177 } | |
178 } | |
179 break; | |
180 } | |
181 } | |
182 else | |
183 { | |
184 version (DMDV2) { | |
185 Type t1 = e1.type.toBasetype(); | |
186 | |
187 if (!t1.isMutable() || (t1.ty == TY.Tpointer && !t1.nextOf().isMutable()) || | |
188 !var.type.isMutable() || !var.type.isAssignable() || var.storage_class & STC.STCmanifest) | |
189 { | |
190 error("cannot modify const/immutable expression %s", toChars()); | |
191 } | |
192 } | |
193 } | |
194 | |
0 | 195 return this; |
196 } | |
197 | |
72 | 198 override Expression optimize(int result) |
0 | 199 { |
72 | 200 //printf("DotVarExp.optimize(result = x%x) %s\n", result, toChars()); |
201 e1 = e1.optimize(result); | |
202 | |
203 if (e1.op == TOK.TOKvar) | |
204 { | |
205 VarExp ve = cast(VarExp)e1; | |
206 VarDeclaration v = ve.var.isVarDeclaration(); | |
207 Expression e = expandVar(result, v); | |
208 if (e && e.op == TOK.TOKstructliteral) | |
209 { | |
210 StructLiteralExp sle = cast(StructLiteralExp)e; | |
211 VarDeclaration vf = var.isVarDeclaration(); | |
212 if (vf) | |
213 { | |
214 e = sle.getField(type, vf.offset); | |
215 if (e && e !is EXP_CANT_INTERPRET) | |
216 return e; | |
217 } | |
218 } | |
219 } | |
220 else if (e1.op == TOK.TOKstructliteral) | |
221 { | |
222 StructLiteralExp sle = cast(StructLiteralExp)e1; | |
223 VarDeclaration vf = var.isVarDeclaration(); | |
224 if (vf) | |
225 { | |
226 Expression e = sle.getField(type, vf.offset); | |
227 if (e && e !is EXP_CANT_INTERPRET) | |
228 return e; | |
229 } | |
230 } | |
231 | |
0 | 232 return this; |
233 } | |
234 | |
72 | 235 override Expression interpret(InterState istate) |
0 | 236 { |
237 assert(false); | |
238 } | |
239 | |
72 | 240 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 241 { |
72 | 242 expToCBuffer(buf, hgs, e1, PREC.PREC_primary); |
243 buf.writeByte('.'); | |
0 | 244 buf.writestring(var.toChars()); |
245 } | |
246 | |
72 | 247 override void dump(int indent) |
0 | 248 { |
249 assert(false); | |
250 } | |
251 | |
72 | 252 override elem* toElem(IRState* irs) |
0 | 253 { |
72 | 254 // *(&e + offset) |
255 //printf("DotVarExp.toElem('%s')\n", toChars()); | |
256 | |
257 VarDeclaration v = var.isVarDeclaration(); | |
258 if (!v) | |
259 { | |
260 error("%s is not a field, but a %s", var.toChars(), var.kind()); | |
261 } | |
262 | |
263 elem* e = e1.toElem(irs); | |
264 Type tb1 = e1.type.toBasetype(); | |
265 | |
266 if (tb1.ty != TY.Tclass && tb1.ty != TY.Tpointer) | |
267 //e = el_una(OPaddr, TYnptr, e); | |
268 e = addressElem(e, tb1); | |
269 | |
270 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, v ? v.offset : 0)); | |
271 e = el_una(OPER.OPind, type.totym(), e); | |
272 if (tybasic(e.Ety) == TYM.TYstruct) | |
273 { | |
274 e.Enumbytes = cast(uint)type.size(); | |
275 } | |
276 el_setLoc(e,loc); | |
277 | |
0 | 278 return e; |
279 } | |
280 } | |
281 |