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