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