Mercurial > projects > ddmd
annotate dmd/Scope.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 96c0fff6897d |
children | b0d41ff5e0df |
rev | line source |
---|---|
0 | 1 module dmd.Scope; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Module; |
5 import dmd.ScopeDsymbol; | |
6 import dmd.FuncDeclaration; | |
7 import dmd.Id; | |
8 import dmd.Dsymbol; | |
9 import dmd.LabelStatement; | |
10 import dmd.SwitchStatement; | |
11 import dmd.TryFinallyStatement; | |
12 import dmd.TemplateInstance; | |
13 import dmd.Statement; | |
14 import dmd.ForeachStatement; | |
15 import dmd.LINK; | |
16 import dmd.PROT; | |
17 import dmd.STC; | |
18 import dmd.AnonymousAggregateDeclaration; | |
19 import dmd.AggregateDeclaration; | |
20 import dmd.ClassDeclaration; | |
21 import dmd.Identifier; | |
22 import dmd.Loc; | |
23 import dmd.OutBuffer; | |
24 import dmd.DocComment; | |
25 import dmd.DsymbolTable; | |
26 import dmd.Global; | |
27 import dmd.CSX; | |
28 import dmd.Util; | |
29 | |
83
ee670dd808a8
malloc -> GC.malloc change, plus compilation issues fixed (always check before commiting stuff!!!)
korDen
parents:
82
diff
changeset
|
30 import core.memory; |
ee670dd808a8
malloc -> GC.malloc change, plus compilation issues fixed (always check before commiting stuff!!!)
korDen
parents:
82
diff
changeset
|
31 |
0 | 32 enum SCOPE |
33 { | |
34 SCOPEctor = 1, // constructor type | |
35 SCOPEstaticif = 2, // inside static if | |
36 SCOPEfree = 4, // is on free list | |
37 } | |
38 | |
178 | 39 import dmd.TObject; |
40 | |
41 class Scope : TObject | |
0 | 42 { |
43 Scope enclosing; // enclosing Scope | |
44 | |
45 Module module_; // Root module | |
46 ScopeDsymbol scopesym; // current symbol | |
47 ScopeDsymbol sd; // if in static if, and declaring new symbols, | |
48 // sd gets the addMember() | |
49 FuncDeclaration func; // function we are in | |
50 Dsymbol parent; // parent to use | |
51 LabelStatement slabel; // enclosing labelled statement | |
52 SwitchStatement sw; // enclosing switch statement | |
53 TryFinallyStatement tf; // enclosing try finally statement | |
54 TemplateInstance tinst; // enclosing template instance | |
55 Statement sbreak; // enclosing statement that supports "break" | |
56 Statement scontinue; // enclosing statement that supports "continue" | |
57 ForeachStatement fes; // if nested function for ForeachStatement, this is it | |
58 uint offset; // next offset to use in aggregate | |
59 int inunion; // we're processing members of a union | |
60 int incontract; // we're inside contract code | |
61 int nofree; // set if shouldn't free it | |
62 int noctor; // set if constructor calls aren't allowed | |
63 int intypeof; // in typeof(exp) | |
64 int parameterSpecialization; // if in template parameter specialization | |
65 int noaccesscheck; // don't do access checks | |
66 int mustsemantic; // cannot defer semantic() | |
67 | |
68 uint callSuper; // primitive flow analysis for constructors | |
69 ///#define CSXthis_ctor 1 // called this() | |
70 ///#define CSXsuper_ctor 2 // called super() | |
71 ///#define CSXthis 4 // referenced this | |
72 ///#define CSXsuper 8 // referenced super | |
73 ///#define CSXlabel 0x10 // seen a label | |
74 ///#define CSXreturn 0x20 // seen a return statement | |
75 ///#define CSXany_ctor 0x40 // either this() or super() was called | |
76 | |
77 uint structalign; // alignment for struct members | |
78 LINK linkage = LINK.LINKd; // linkage for external functions | |
79 | |
80 PROT protection = PROT.PROTpublic; // protection for class members | |
81 int explicitProtection; // set if in an explicit protection attribute | |
82 | |
131
206db751bd4c
dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
83 StorageClass stc; // storage class |
0 | 84 |
85 SCOPE flags; | |
86 | |
87 AnonymousAggregateDeclaration anonAgg; // for temporary analysis | |
88 | |
89 DocComment lastdc; // documentation comment for last symbol at this scope | |
90 uint lastoffset; // offset in docbuf of where to insert next dec | |
91 OutBuffer docbuf; // buffer for documentation output | |
92 | |
93 /// static void *operator new(size_t sz); | |
94 static Scope createGlobal(Module module_) | |
95 { | |
96 Scope sc = new Scope(); | |
97 sc.module_ = module_; | |
98 sc.scopesym = new ScopeDsymbol(); | |
99 sc.scopesym.symtab = new DsymbolTable(); | |
100 | |
101 // Add top level package as member of this global scope | |
102 Dsymbol m = module_; | |
103 while (m.parent !is null) | |
104 m = m.parent; | |
105 | |
13 | 106 m.addMember(null, sc.scopesym, true); |
0 | 107 m.parent = null; // got changed by addMember() |
108 | |
109 // Create the module scope underneath the global scope | |
110 sc = sc.push(module_); | |
111 sc.parent = module_; | |
112 return sc; | |
113 } | |
114 | |
115 this() | |
116 { | |
178 | 117 register(); |
0 | 118 // Create root scope |
119 | |
120 //printf("Scope.Scope() %p\n", this); | |
21
26b9f97f6162
Added in some = new OutBuffer();'s to be on the safe side, been getting some issues with null OutBuffers.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
121 this.docbuf = new OutBuffer; |
0 | 122 this.structalign = global.structalign; |
123 } | |
124 | |
125 this(Module module_) | |
126 { | |
178 | 127 register(); |
0 | 128 assert(false); |
21
26b9f97f6162
Added in some = new OutBuffer();'s to be on the safe side, been getting some issues with null OutBuffers.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
129 this.docbuf = new OutBuffer; |
0 | 130 } |
131 | |
132 this(Scope enclosing) | |
133 { | |
178 | 134 register(); |
0 | 135 //printf("Scope.Scope(enclosing = %p) %p\n", enclosing, this); |
136 assert(!(enclosing.flags & SCOPE.SCOPEfree)); | |
137 this.module_ = enclosing.module_; | |
138 this.func = enclosing.func; | |
139 this.parent = enclosing.parent; | |
79 | 140 this.scopesym = null; |
141 this.sd = null; | |
0 | 142 this.sw = enclosing.sw; |
143 this.tf = enclosing.tf; | |
135 | 144 this.tinst = enclosing.tinst; |
0 | 145 this.tinst = enclosing.tinst; |
146 this.sbreak = enclosing.sbreak; | |
147 this.scontinue = enclosing.scontinue; | |
148 this.fes = enclosing.fes; | |
149 this.structalign = enclosing.structalign; | |
150 this.enclosing = enclosing; | |
151 debug { | |
152 if (enclosing.enclosing) | |
153 assert(!(enclosing.enclosing.flags & SCOPE.SCOPEfree)); | |
154 | |
155 if (this is enclosing.enclosing) /// huh? | |
156 { | |
157 writef("this = %p, enclosing = %p, enclosing.enclosing = %p\n", this, enclosing, enclosing.enclosing); | |
158 } | |
159 assert(this !is enclosing.enclosing); | |
160 } | |
161 this.linkage = enclosing.linkage; | |
162 this.protection = enclosing.protection; | |
163 this.explicitProtection = enclosing.explicitProtection; | |
164 this.stc = enclosing.stc; | |
165 this.inunion = enclosing.inunion; | |
166 this.incontract = enclosing.incontract; | |
167 this.noctor = enclosing.noctor; | |
168 this.noaccesscheck = enclosing.noaccesscheck; | |
169 this.mustsemantic = enclosing.mustsemantic; | |
170 this.intypeof = enclosing.intypeof; | |
171 this.parameterSpecialization = enclosing.parameterSpecialization; | |
172 this.callSuper = enclosing.callSuper; | |
173 this.docbuf = enclosing.docbuf; | |
174 assert(this !is enclosing); /// huh? | |
175 } | |
82 | 176 |
177 Scope clone() | |
178 { | |
129 | 179 return cloneThis(this); |
82 | 180 } |
0 | 181 |
182 Scope push() | |
183 { | |
184 //printf("Scope.push()\n"); | |
185 Scope s = new Scope(this); | |
186 assert(this !is s); /// huh? | |
187 return s; | |
188 } | |
189 | |
190 Scope push(ScopeDsymbol ss) | |
191 { | |
192 //printf("Scope.push(%s)\n", ss.toChars()); | |
193 Scope s = push(); | |
194 s.scopesym = ss; | |
195 return s; | |
196 } | |
197 | |
198 Scope pop() | |
199 { | |
200 //printf("Scope.pop() %p nofree = %d\n", this, nofree); | |
201 Scope enc = enclosing; | |
202 | |
203 if (enclosing) | |
204 enclosing.callSuper |= callSuper; | |
205 | |
206 if (!nofree) | |
207 { | |
170 | 208 enclosing = global.scope_freelist; |
209 global.scope_freelist = this; | |
0 | 210 flags |= SCOPE.SCOPEfree; |
211 } | |
212 | |
213 return enc; | |
214 } | |
215 | |
216 void mergeCallSuper(Loc loc, uint cs) | |
217 { | |
218 // This does a primitive flow analysis to support the restrictions | |
219 // regarding when and how constructors can appear. | |
220 // It merges the results of two paths. | |
221 // The two paths are callSuper and cs; the result is merged into callSuper. | |
222 | |
223 if (cs != callSuper) | |
224 { | |
225 int a; | |
226 int b; | |
227 | |
228 callSuper |= cs & (CSX.CSXany_ctor | CSX.CSXlabel); | |
229 if (cs & CSX.CSXreturn) | |
230 { | |
231 ; | |
232 } | |
233 else if (callSuper & CSX.CSXreturn) | |
234 { | |
235 callSuper = cs | (callSuper & (CSX.CSXany_ctor | CSX.CSXlabel)); | |
236 } | |
237 else | |
238 { | |
239 a = (cs & (CSX.CSXthis_ctor | CSX.CSXsuper_ctor)) != 0; | |
240 b = (callSuper & (CSX.CSXthis_ctor | CSX.CSXsuper_ctor)) != 0; | |
241 | |
242 if (a != b) | |
243 error(loc, "one path skips constructor"); | |
244 callSuper |= cs; | |
245 } | |
246 } | |
247 } | |
248 | |
249 Dsymbol search(Loc loc, Identifier ident, Dsymbol* pscopesym) | |
250 { | |
251 Dsymbol s; | |
252 Scope sc; | |
253 | |
254 //printf("Scope.search(%p, '%s')\n", this, ident.toChars()); | |
255 if (ident is Id.empty) | |
256 { | |
257 // Look for module scope | |
258 for (sc = this; sc; sc = sc.enclosing) | |
259 { | |
260 assert(sc != sc.enclosing); | |
261 if (sc.scopesym) | |
262 { | |
263 s = sc.scopesym.isModule(); | |
264 if (s) | |
265 { | |
266 //printf("\tfound %s.%s\n", s.parent ? s.parent.toChars() : "", s.toChars()); | |
267 if (pscopesym) | |
268 *pscopesym = sc.scopesym; | |
269 return s; | |
270 } | |
271 } | |
272 } | |
273 return null; | |
274 } | |
275 | |
276 for (sc = this; sc; sc = sc.enclosing) | |
277 { | |
278 assert(sc != sc.enclosing); | |
279 if (sc.scopesym) | |
280 { | |
281 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc.scopesym.toChars(), sc.scopesym.kind()); | |
282 s = sc.scopesym.search(loc, ident, 0); | |
283 if (s) | |
284 { | |
285 if ((global.params.warnings || | |
286 global.params.Dversion > 1) && | |
287 ident == Id.length && | |
288 sc.scopesym.isArrayScopeSymbol() && | |
289 sc.enclosing && | |
290 sc.enclosing.search(loc, ident, null)) | |
291 { | |
292 warning(s.loc, "array 'length' hides other 'length' name in outer scope"); | |
293 } | |
294 | |
295 //printf("\tfound %s.%s, kind = '%s'\n", s.parent ? s.parent.toChars() : "", s.toChars(), s.kind()); | |
296 if (pscopesym) | |
297 *pscopesym = sc.scopesym; | |
298 return s; | |
299 } | |
300 } | |
301 } | |
302 | |
303 return null; | |
304 } | |
305 | |
306 Dsymbol insert(Dsymbol s) | |
307 { | |
308 for (Scope sc = this; sc; sc = sc.enclosing) | |
309 { | |
310 //printf("\tsc = %p\n", sc); | |
311 if (sc.scopesym) | |
312 { | |
313 //printf("\t\tsc.scopesym = %p\n", sc.scopesym); | |
314 if (!sc.scopesym.symtab) | |
315 sc.scopesym.symtab = new DsymbolTable(); | |
316 | |
79 | 317 return sc.scopesym.symtabInsert(s); |
0 | 318 } |
319 } | |
320 | |
321 assert(false); | |
322 } | |
323 | |
324 ClassDeclaration getClassScope() | |
325 { | |
326 assert(false); | |
327 } | |
328 | |
329 /******************************************** | |
330 * Search enclosing scopes for ClassDeclaration. | |
331 */ | |
332 AggregateDeclaration getStructClassScope() | |
333 { | |
334 for (Scope sc = this; sc; sc = sc.enclosing) | |
335 { | |
336 AggregateDeclaration ad; | |
337 | |
338 if (sc.scopesym) | |
339 { | |
340 ad = sc.scopesym.isClassDeclaration(); | |
341 if (ad) | |
342 return ad; | |
343 else | |
344 { | |
345 ad = sc.scopesym.isStructDeclaration(); | |
346 if (ad) | |
347 return ad; | |
348 } | |
349 } | |
350 } | |
351 | |
352 return null; | |
353 } | |
354 | |
355 void setNoFree() | |
356 { | |
357 //int i = 0; | |
358 | |
359 //printf("Scope.setNoFree(this = %p)\n", this); | |
360 for (Scope sc = this; sc; sc = sc.enclosing) | |
361 { | |
362 //printf("\tsc = %p\n", sc); | |
363 sc.nofree = 1; | |
364 | |
365 assert(!(flags & SCOPE.SCOPEfree)); | |
366 //assert(sc != sc.enclosing); | |
367 //assert(!sc.enclosing || sc != sc.enclosing.enclosing); | |
368 //if (++i == 10) | |
369 //assert(0); | |
370 } | |
371 } | |
21
26b9f97f6162
Added in some = new OutBuffer();'s to be on the safe side, been getting some issues with null OutBuffers.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
372 } |