Mercurial > projects > ddmd
annotate dmd/DotIdExp.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 |
---|---|
72 | 1 module dmd.DotIdExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.Identifier; | |
6 import dmd.IntegerExp; | |
7 import dmd.Type; | |
8 import dmd.TY; | |
9 import dmd.ScopeExp; | |
10 import dmd.StringExp; | |
11 import dmd.PtrExp; | |
12 import dmd.TypePointer; | |
13 import dmd.Dsymbol; | |
14 import dmd.EnumMember; | |
15 import dmd.VarDeclaration; | |
16 import dmd.ThisExp; | |
17 import dmd.DotVarExp; | |
18 import dmd.VarExp; | |
19 import dmd.CommaExp; | |
20 import dmd.FuncDeclaration; | |
21 import dmd.OverloadSet; | |
22 import dmd.OverExp; | |
23 import dmd.TypeExp; | |
24 import dmd.TupleDeclaration; | |
25 import dmd.ScopeDsymbol; | |
26 import dmd.Import; | |
27 import dmd.Id; | |
28 import dmd.TupleExp; | |
29 import dmd.ArrayTypes; | |
30 import dmd.UnaExp; | |
31 import dmd.OutBuffer; | |
32 import dmd.Loc; | |
33 import dmd.Scope; | |
34 import dmd.TOK; | |
35 import dmd.HdrGenState; | |
36 import dmd.ClassDeclaration; | |
37 import dmd.StructDeclaration; | |
38 import dmd.AggregateDeclaration; | |
39 import dmd.DotExp; | |
40 import dmd.Global; | |
41 import dmd.IdentifierExp; | |
42 import dmd.CallExp; | |
43 import dmd.PREC; | |
44 | |
45 import dmd.expression.Util; | |
46 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
47 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
|
48 |
0 | 49 class DotIdExp : UnaExp |
50 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
51 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
|
52 |
0 | 53 Identifier ident; |
54 | |
55 this(Loc loc, Expression e, Identifier ident) | |
56 { | |
178 | 57 register(); |
72 | 58 super(loc, TOK.TOKdot, DotIdExp.sizeof, e); |
0 | 59 this.ident = ident; |
60 } | |
61 | |
72 | 62 override Expression semantic(Scope sc) |
0 | 63 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
64 // Indicate we didn't come from CallExp::semantic() |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
65 return semantic(sc, 0); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
66 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
67 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
68 Expression semantic(Scope sc, int flag) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
69 { |
72 | 70 Expression e; |
71 Expression eleft; | |
72 Expression eright; | |
73 | |
74 version (LOGSEMANTIC) { | |
75 printf("DotIdExp.semantic(this = %p, '%s')\n", this, toChars()); | |
76 //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op)); | |
77 } | |
78 | |
79 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } | |
80 | |
81 static if (false) { | |
82 /* Don't do semantic analysis if we'll be converting | |
83 * it to a string. | |
84 */ | |
85 if (ident == Id.stringof) | |
86 { | |
87 char *s = e1.toChars(); | |
88 e = new StringExp(loc, s, strlen(s), 'c'); | |
89 e = e.semantic(sc); | |
90 return e; | |
91 } | |
92 } | |
93 | |
94 /* Special case: rewrite this.id and super.id | |
95 * to be classtype.id and baseclasstype.id | |
96 * if we have no this pointer. | |
97 */ | |
98 if ((e1.op == TOK.TOKthis || e1.op == TOK.TOKsuper) && !hasThis(sc)) | |
99 { | |
100 ClassDeclaration cd; | |
101 StructDeclaration sd; | |
102 AggregateDeclaration ad; | |
103 | |
104 ad = sc.getStructClassScope(); | |
105 if (ad) | |
106 { | |
107 cd = ad.isClassDeclaration(); | |
108 if (cd) | |
109 { | |
110 if (e1.op == TOK.TOKthis) | |
111 { | |
112 e = typeDotIdExp(loc, cd.type, ident); | |
113 return e.semantic(sc); | |
114 } | |
115 else if (cd.baseClass && e1.op == TOK.TOKsuper) | |
116 { | |
117 e = typeDotIdExp(loc, cd.baseClass.type, ident); | |
118 return e.semantic(sc); | |
119 } | |
120 } | |
121 else | |
122 { | |
123 sd = ad.isStructDeclaration(); | |
124 if (sd) | |
125 { | |
126 if (e1.op == TOK.TOKthis) | |
127 { | |
128 e = typeDotIdExp(loc, sd.type, ident); | |
129 return e.semantic(sc); | |
130 } | |
131 } | |
132 } | |
133 } | |
134 } | |
135 | |
136 UnaExp.semantic(sc); | |
137 | |
138 if (e1.op == TOK.TOKdotexp) | |
139 { | |
140 DotExp de = cast(DotExp)e1; | |
141 eleft = de.e1; | |
142 eright = de.e2; | |
143 } | |
144 else | |
145 { | |
146 e1 = resolveProperties(sc, e1); | |
147 eleft = null; | |
148 eright = e1; | |
149 } | |
150 | |
151 version (DMDV2) { | |
152 if (e1.op == TOK.TOKtuple && ident == Id.offsetof) | |
153 { | |
154 /* 'distribute' the .offsetof to each of the tuple elements. | |
155 */ | |
156 TupleExp te = cast(TupleExp)e1; | |
157 Expressions exps = new Expressions(); | |
158 exps.setDim(te.exps.dim); | |
159 for (int i = 0; i < exps.dim; i++) | |
160 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
161 auto ee = te.exps[i]; |
72 | 162 ee = ee.semantic(sc); |
136 | 163 ee = new DotIdExp(ee.loc, ee, Id.offsetof); |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
164 exps[i] = ee; |
72 | 165 } |
166 e = new TupleExp(loc, exps); | |
167 e = e.semantic(sc); | |
168 return e; | |
169 } | |
170 } | |
171 | |
172 if (e1.op == TOK.TOKtuple && ident == Id.length) | |
173 { | |
174 TupleExp te = cast(TupleExp)e1; | |
175 e = new IntegerExp(loc, te.exps.dim, Type.tsize_t); | |
176 return e; | |
177 } | |
178 | |
179 if (e1.op == TOK.TOKdottd) | |
180 { | |
181 error("template %s does not have property %s", e1.toChars(), ident.toChars()); | |
182 return e1; | |
183 } | |
184 | |
185 if (!e1.type) | |
186 { | |
187 error("expression %s does not have property %s", e1.toChars(), ident.toChars()); | |
188 return e1; | |
189 } | |
190 | |
191 Type t1b = e1.type.toBasetype(); | |
192 | |
193 if (eright.op == TOK.TOKimport) // also used for template alias's | |
194 { | |
195 ScopeExp ie = cast(ScopeExp)eright; | |
196 | |
197 /* Disable access to another module's private imports. | |
198 * The check for 'is sds our current module' is because | |
199 * the current module should have access to its own imports. | |
200 */ | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
201 Dsymbol s = ie.sds.search(loc, ident, //0); |
72 | 202 (ie.sds.isModule() && ie.sds != sc.module_) ? 1 : 0); |
203 if (s) | |
204 { | |
205 s = s.toAlias(); | |
206 checkDeprecated(sc, s); | |
207 | |
208 EnumMember em = s.isEnumMember(); | |
209 if (em) | |
210 { | |
211 e = em.value; | |
212 e = e.semantic(sc); | |
213 return e; | |
214 } | |
215 | |
216 VarDeclaration v = s.isVarDeclaration(); | |
217 if (v) | |
218 { | |
219 //printf("DotIdExp. Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); | |
220 if (v.inuse) | |
221 { | |
222 error("circular reference to '%s'", v.toChars()); | |
223 type = Type.tint32; | |
224 return this; | |
225 } | |
226 type = v.type; | |
227 if (v.needThis()) | |
228 { | |
229 if (!eleft) | |
230 eleft = new ThisExp(loc); | |
231 e = new DotVarExp(loc, eleft, v); | |
232 e = e.semantic(sc); | |
233 } | |
234 else | |
235 { | |
236 e = new VarExp(loc, v); | |
237 if (eleft) | |
238 { | |
239 e = new CommaExp(loc, eleft, e); | |
240 e.type = v.type; | |
241 } | |
242 } | |
243 return e.deref(); | |
244 } | |
245 | |
246 FuncDeclaration f = s.isFuncDeclaration(); | |
247 if (f) | |
248 { | |
249 //printf("it's a function\n"); | |
250 if (f.needThis()) | |
251 { | |
252 if (!eleft) | |
253 eleft = new ThisExp(loc); | |
254 e = new DotVarExp(loc, eleft, f); | |
255 e = e.semantic(sc); | |
256 } | |
257 else | |
258 { | |
259 e = new VarExp(loc, f, 1); | |
260 if (eleft) | |
261 { e = new CommaExp(loc, eleft, e); | |
262 e.type = f.type; | |
263 } | |
264 } | |
265 return e; | |
266 } | |
267 version (DMDV2) { | |
268 OverloadSet o = s.isOverloadSet(); | |
269 if (o) | |
270 { | |
271 //printf("'%s' is an overload set\n", o.toChars()); | |
272 return new OverExp(o); | |
273 } | |
274 } | |
275 | |
276 Type t = s.getType(); | |
277 if (t) | |
278 { | |
279 return new TypeExp(loc, t); | |
280 } | |
281 | |
282 TupleDeclaration tup = s.isTupleDeclaration(); | |
283 if (tup) | |
284 { | |
285 if (eleft) | |
286 error("cannot have e.tuple"); | |
287 e = new TupleExp(loc, tup); | |
288 e = e.semantic(sc); | |
289 return e; | |
290 } | |
291 | |
292 ScopeDsymbol sds = s.isScopeDsymbol(); | |
293 if (sds) | |
294 { | |
295 //printf("it's a ScopeDsymbol\n"); | |
296 e = new ScopeExp(loc, sds); | |
297 e = e.semantic(sc); | |
298 if (eleft) | |
299 e = new DotExp(loc, eleft, e); | |
300 return e; | |
301 } | |
302 | |
303 Import imp = s.isImport(); | |
304 if (imp) | |
305 { | |
306 ScopeExp iee = new ScopeExp(loc, imp.pkg); | |
307 return iee.semantic(sc); | |
308 } | |
309 | |
310 // BUG: handle other cases like in IdentifierExp.semantic() | |
311 version (DEBUG) { | |
312 printf("s = '%s', kind = '%s'\n", s.toChars(), s.kind()); | |
313 } | |
314 assert(0); | |
315 } | |
316 else if (ident is Id.stringof_) | |
317 { | |
318 string ss = ie.toChars(); | |
319 e = new StringExp(loc, ss, 'c'); | |
320 e = e.semantic(sc); | |
321 return e; | |
322 } | |
323 error("undefined identifier %s", toChars()); | |
324 type = Type.tvoid; | |
325 return this; | |
326 } | |
327 else if (t1b.ty == TY.Tpointer && | |
328 ident !is Id.init_ && ident !is Id.__sizeof && | |
329 ident !is Id.alignof_ && ident !is Id.offsetof && | |
330 ident !is Id.mangleof_ && ident !is Id.stringof_) | |
331 { /* Rewrite: | |
332 * p.ident | |
333 * as: | |
334 * (*p).ident | |
335 */ | |
336 e = new PtrExp(loc, e1); | |
337 e.type = (cast(TypePointer)t1b).next; | |
338 return e.type.dotExp(sc, e, ident); | |
339 } | |
340 ///version (DMDV2) { | |
341 else if (t1b.ty == TY.Tarray || | |
342 t1b.ty == TY.Tsarray || | |
343 t1b.ty == TY.Taarray) | |
344 { | |
345 /* If ident is not a valid property, rewrite: | |
346 * e1.ident | |
347 * as: | |
348 * .ident(e1) | |
349 */ | |
350 uint errors = global.errors; | |
351 global.gag++; | |
109 | 352 Type t1 = e1.type; |
72 | 353 e = e1.type.dotExp(sc, e1, ident); |
354 global.gag--; | |
355 if (errors != global.errors) // if failed to find the property | |
356 { | |
357 global.errors = errors; | |
109 | 358 e1.type = t1; // kludge to restore type |
72 | 359 e = new DotIdExp(loc, new IdentifierExp(loc, Id.empty), ident); |
360 e = new CallExp(loc, e, e1); | |
361 } | |
362 e = e.semantic(sc); | |
363 return e; | |
364 } | |
365 ///} | |
366 else | |
367 { | |
368 e = e1.type.dotExp(sc, e1, ident); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
369 if (!(flag && e.op == TOK.TOKdotti)) // let CallExp::semantic() handle this |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
370 e = e.semantic(sc); |
72 | 371 return e; |
0 | 372 } |
373 } | |
374 | |
72 | 375 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 376 { |
72 | 377 //printf("DotIdExp.toCBuffer()\n"); |
378 expToCBuffer(buf, hgs, e1, PREC.PREC_primary); | |
379 buf.writeByte('.'); | |
0 | 380 buf.writestring(ident.toChars()); |
381 } | |
382 | |
72 | 383 override void dump(int i) |
0 | 384 { |
385 assert(false); | |
386 } | |
387 } | |
388 |