Mercurial > projects > ddmd
annotate dmd/DeclarationExp.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 60bb0fe4563e |
children | e3afd1303184 |
rev | line source |
---|---|
72 | 1 module dmd.DeclarationExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.backend.elem; | |
6 import dmd.InterState; | |
7 import dmd.ExpInitializer; | |
8 import dmd.OutBuffer; | |
9 import dmd.Loc; | |
79 | 10 import dmd.STC; |
72 | 11 import dmd.Scope; |
12 import dmd.InlineCostState; | |
13 import dmd.IRState; | |
14 import dmd.InlineDoState; | |
15 import dmd.HdrGenState; | |
16 import dmd.TupleDeclaration; | |
17 import dmd.InlineScanState; | |
18 import dmd.Dsymbol; | |
19 import dmd.AttribDeclaration; | |
20 import dmd.VarDeclaration; | |
21 import dmd.Global; | |
22 import dmd.TOK; | |
23 import dmd.VoidInitializer; | |
24 import dmd.GlobalExpressions; | |
25 import dmd.Type; | |
26 import dmd.codegen.Util; | |
27 | |
28 // Declaration of a symbol | |
29 | |
0 | 30 class DeclarationExp : Expression |
31 { | |
32 Dsymbol declaration; | |
33 | |
34 this(Loc loc, Dsymbol declaration) | |
35 { | |
72 | 36 super(loc, TOK.TOKdeclaration, DeclarationExp.sizeof); |
0 | 37 this.declaration = declaration; |
38 } | |
39 | |
72 | 40 override Expression syntaxCopy() |
0 | 41 { |
42 return new DeclarationExp(loc, declaration.syntaxCopy(null)); | |
43 } | |
44 | |
72 | 45 override Expression semantic(Scope sc) |
0 | 46 { |
72 | 47 if (type) |
48 return this; | |
49 | |
50 version (LOGSEMANTIC) { | |
51 printf("DeclarationExp.semantic() %s\n", toChars()); | |
52 } | |
53 | |
54 /* This is here to support extern(linkage) declaration, | |
55 * where the extern(linkage) winds up being an AttribDeclaration | |
56 * wrapper. | |
57 */ | |
58 Dsymbol s = declaration; | |
59 | |
60 AttribDeclaration ad = declaration.isAttribDeclaration(); | |
61 if (ad) | |
62 { | |
63 if (ad.decl && ad.decl.dim == 1) | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
64 s = ad.decl[0]; |
72 | 65 } |
66 | |
67 if (s.isVarDeclaration()) | |
68 { | |
69 // Do semantic() on initializer first, so: | |
70 // int a = a; | |
71 // will be illegal. | |
72 declaration.semantic(sc); | |
73 s.parent = sc.parent; | |
74 } | |
75 | |
76 //printf("inserting '%s' %p into sc = %p\n", s.toChars(), s, sc); | |
77 // Insert into both local scope and function scope. | |
78 // Must be unique in both. | |
79 if (s.ident) | |
80 { | |
81 if (!sc.insert(s)) | |
82 error("declaration %s is already defined", s.toPrettyChars()); | |
83 else if (sc.func) | |
84 { | |
85 VarDeclaration v = s.isVarDeclaration(); | |
86 if (s.isFuncDeclaration() && !sc.func.localsymtab.insert(s)) | |
87 error("declaration %s is already defined in another scope in %s", s.toPrettyChars(), sc.func.toChars()); | |
88 else if (!global.params.useDeprecated) | |
89 { | |
90 // Disallow shadowing | |
91 | |
92 for (Scope scx = sc.enclosing; scx && scx.func is sc.func; scx = scx.enclosing) | |
93 { | |
94 Dsymbol s2; | |
95 | |
96 if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2) | |
97 { | |
98 error("shadowing declaration %s is deprecated", s.toPrettyChars()); | |
99 } | |
100 } | |
101 } | |
102 } | |
103 } | |
104 if (!s.isVarDeclaration()) | |
105 { | |
79 | 106 Scope sc2 = sc; |
107 if (sc2.stc & (STC.STCpure | STC.STCnothrow)) | |
108 sc2 = sc.push(); | |
109 sc2.stc &= ~(STC.STCpure | STC.STCnothrow); | |
110 declaration.semantic(sc2); | |
111 if (sc2 != sc) | |
112 sc2.pop(); | |
113 | |
72 | 114 s.parent = sc.parent; |
115 } | |
116 if (!global.errors) | |
117 { | |
118 declaration.semantic2(sc); | |
119 if (!global.errors) | |
120 { | |
121 declaration.semantic3(sc); | |
122 | |
123 if (!global.errors && global.params.useInline) | |
124 declaration.inlineScan(); | |
125 } | |
126 } | |
127 | |
128 type = Type.tvoid; | |
0 | 129 return this; |
130 } | |
131 | |
72 | 132 override Expression interpret(InterState istate) |
0 | 133 { |
72 | 134 version (LOG) { |
135 printf("DeclarationExp.interpret() %s\n", toChars()); | |
136 } | |
137 Expression e; | |
138 VarDeclaration v = declaration.isVarDeclaration(); | |
139 if (v) | |
140 { | |
141 Dsymbol s = v.toAlias(); | |
142 if (s == v && !v.isStatic() && v.init) | |
143 { | |
144 ExpInitializer ie = v.init.isExpInitializer(); | |
145 if (ie) | |
146 e = ie.exp.interpret(istate); | |
147 else if (v.init.isVoidInitializer()) | |
148 e = null; | |
149 } | |
150 ///version (DMDV2) { | |
135 | 151 else if (s == v && (v.isConst() || v.isImmutable()) && v.init) |
72 | 152 ///} else { |
153 /// else if (s == v && v.isConst() && v.init) | |
154 ///} | |
155 { | |
156 e = v.init.toExpression(); | |
157 if (!e) | |
158 e = EXP_CANT_INTERPRET; | |
159 else if (!e.type) | |
160 e.type = v.type; | |
161 } | |
162 } | |
163 else if (declaration.isAttribDeclaration() || | |
164 declaration.isTemplateMixin() || | |
165 declaration.isTupleDeclaration()) | |
166 { | |
167 // These can be made to work, too lazy now | |
168 error("Declaration %s is not yet implemented in CTFE", toChars()); | |
169 | |
170 e = EXP_CANT_INTERPRET; | |
171 } | |
172 else | |
173 { // Others should not contain executable code, so are trivial to evaluate | |
174 e = null; | |
175 } | |
176 version (LOG) { | |
177 printf("-DeclarationExp.interpret(%.*s): %p\n", toChars(), e); | |
178 } | |
63 | 179 return e; |
0 | 180 } |
181 | |
72 | 182 override bool checkSideEffect(int flag) |
0 | 183 { |
184 return true; | |
185 } | |
186 | |
72 | 187 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 188 { |
189 declaration.toCBuffer(buf, hgs); | |
190 } | |
191 | |
72 | 192 override elem* toElem(IRState* irs) |
0 | 193 { |
72 | 194 //printf("DeclarationExp::toElem() %s\n", toChars()); |
195 elem* e = Dsymbol_toElem(declaration, irs); | |
0 | 196 return e; |
197 } | |
198 | |
72 | 199 override void scanForNestedRef(Scope sc) |
0 | 200 { |
123 | 201 //printf("DeclarationExp.scanForNestedRef() %s\n", toChars()); |
202 declaration.parent = sc.parent; | |
0 | 203 } |
72 | 204 |
0 | 205 version (DMDV2) { |
72 | 206 override bool canThrow() |
0 | 207 { |
72 | 208 VarDeclaration v = declaration.isVarDeclaration(); |
209 if (v && v.init) | |
210 { | |
211 ExpInitializer ie = v.init.isExpInitializer(); | |
212 return ie && ie.exp.canThrow(); | |
213 } | |
214 | |
0 | 215 return false; |
216 } | |
217 } | |
72 | 218 override int inlineCost(InlineCostState* ics) |
0 | 219 { |
72 | 220 int cost = 0; |
221 VarDeclaration vd; | |
222 | |
223 //printf("DeclarationExp.inlineCost()\n"); | |
224 vd = declaration.isVarDeclaration(); | |
225 if (vd) | |
226 { | |
227 TupleDeclaration td = vd.toAlias().isTupleDeclaration(); | |
228 if (td) | |
229 { | |
230 static if (true) { | |
231 return COST_MAX; // finish DeclarationExp.doInline | |
232 } else { | |
233 for (size_t i = 0; i < td.objects.dim; i++) | |
234 { | |
235 Object o = cast(Object)td.objects.data[i]; | |
236 Expression eo = cast(Expression)o; | |
237 if (eo is null) | |
238 return COST_MAX; | |
239 | |
240 if (eo.op != TOKdsymbol) | |
241 return COST_MAX; | |
242 } | |
243 | |
244 return td.objects.dim; | |
245 } | |
246 } | |
247 if (!ics.hdrscan && vd.isDataseg()) | |
248 return COST_MAX; | |
249 | |
250 cost += 1; | |
251 | |
252 // Scan initializer (vd.init) | |
253 if (vd.init) | |
254 { | |
255 ExpInitializer ie = vd.init.isExpInitializer(); | |
256 | |
257 if (ie) | |
258 { | |
259 cost += ie.exp.inlineCost(ics); | |
260 } | |
261 } | |
262 } | |
263 | |
264 // These can contain functions, which when copied, get output twice. | |
265 if (declaration.isStructDeclaration() || | |
266 declaration.isClassDeclaration() || | |
267 declaration.isFuncDeclaration() || | |
268 declaration.isTypedefDeclaration() || | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
123
diff
changeset
|
269 declaration.isAttribDeclaration() || |
72 | 270 declaration.isTemplateMixin() |
271 ) | |
272 return COST_MAX; | |
273 | |
274 //printf("DeclarationExp.inlineCost('%s')\n", toChars()); | |
0 | 275 return cost; |
276 } | |
277 | |
72 | 278 override Expression doInline(InlineDoState ids) |
0 | 279 { |
72 | 280 DeclarationExp de = cast(DeclarationExp)copy(); |
281 VarDeclaration vd; | |
282 | |
283 //printf("DeclarationExp.doInline(%s)\n", toChars()); | |
284 vd = declaration.isVarDeclaration(); | |
285 if (vd) | |
286 { | |
287 static if (false) { | |
288 // Need to figure this out before inlining can work for tuples | |
289 TupleDeclaration td = vd.toAlias().isTupleDeclaration(); | |
290 if (td) | |
291 { | |
292 for (size_t i = 0; i < td.objects.dim; i++) | |
293 { | |
294 DsymbolExp se = cast(DsymbolExp)td.objects.data[i]; | |
295 assert(se.op == TOKdsymbol); | |
296 se.s; | |
297 } | |
298 return st.objects.dim; | |
299 } | |
300 } | |
301 if (vd.isStatic()) | |
302 { | |
303 ; | |
304 } | |
305 else | |
306 { | |
307 VarDeclaration vto = new VarDeclaration(vd.loc, vd.type, vd.ident, vd.init); | |
308 | |
309 ///*vto = *vd; | |
310 memcpy(cast(void*)vto, cast(void*)vd, VarDeclaration.classinfo.init.length); | |
311 | |
312 vto.parent = ids.parent; | |
313 vto.csym = null; | |
314 vto.isym = null; | |
315 | |
316 ids.from.push(cast(void*)vd); | |
317 ids.to.push(cast(void*)vto); | |
318 | |
319 if (vd.init) | |
320 { | |
321 if (vd.init.isVoidInitializer()) | |
322 { | |
323 vto.init = new VoidInitializer(vd.init.loc); | |
324 } | |
325 else | |
326 { | |
327 Expression e = vd.init.toExpression(); | |
328 assert(e); | |
329 vto.init = new ExpInitializer(e.loc, e.doInline(ids)); | |
330 } | |
331 } | |
332 de.declaration = vto; | |
333 } | |
334 } | |
335 /* This needs work, like DeclarationExp.toElem(), if we are | |
336 * to handle TemplateMixin's. For now, we just don't inline them. | |
337 */ | |
0 | 338 return de; |
339 } | |
340 | |
72 | 341 override Expression inlineScan(InlineScanState* iss) |
0 | 342 { |
72 | 343 //printf("DeclarationExp.inlineScan()\n"); |
344 scanVar(declaration, iss); | |
0 | 345 return this; |
346 } | |
347 } | |
348 |