comparison dmd/DotIdExp.d @ 0:10317f0c89a5

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