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