comparison dmd/scope.c @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children 8f704cb9969b
comparison
equal deleted inserted replaced
0:a9e71648e74d 1:c53b6e3fe49a
1
2 // Copyright (c) 1999-2005 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <assert.h>
12
13 #include "root.h"
14
15 #include "mars.h"
16 #include "init.h"
17 #include "identifier.h"
18 #include "attrib.h"
19 #include "dsymbol.h"
20 #include "scope.h"
21 #include "declaration.h"
22 #include "aggregate.h"
23 #include "module.h"
24 #include "id.h"
25
26 Scope *Scope::freelist = NULL;
27
28 void *Scope::operator new(size_t size)
29 {
30 if (freelist)
31 {
32 Scope *s = freelist;
33 freelist = s->enclosing;
34 //printf("freelist %p\n", s);
35 assert(s->flags & SCOPEfree);
36 s->flags &= ~SCOPEfree;
37 return s;
38 }
39
40 void *p = ::operator new(size);
41 //printf("new %p\n", p);
42 return p;
43 }
44
45 Scope::Scope()
46 { // Create root scope
47
48 //printf("Scope::Scope() %p\n", this);
49 this->module = NULL;
50 this->scopesym = NULL;
51 this->sd = NULL;
52 this->enclosing = NULL;
53 this->parent = NULL;
54 this->sw = NULL;
55 this->tf = NULL;
56 this->sbreak = NULL;
57 this->scontinue = NULL;
58 this->fes = NULL;
59 this->structalign = global.structalign;
60 this->func = NULL;
61 this->slabel = NULL;
62 this->linkage = LINKd;
63 this->protection = PROTpublic;
64 this->explicitProtection = 0;
65 this->stc = 0;
66 this->offset = 0;
67 this->inunion = 0;
68 this->incontract = 0;
69 this->nofree = 0;
70 this->noctor = 0;
71 this->intypeof = 0;
72 this->parameterSpecialization = 0;
73 this->callSuper = 0;
74 this->flags = 0;
75 this->anonAgg = NULL;
76 this->lastdc = NULL;
77 this->lastoffset = 0;
78 this->docbuf = NULL;
79 }
80
81 Scope::Scope(Scope *enclosing)
82 {
83 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
84 assert(!(enclosing->flags & SCOPEfree));
85 this->module = enclosing->module;
86 this->func = enclosing->func;
87 this->parent = enclosing->parent;
88 this->scopesym = NULL;
89 this->sd = NULL;
90 this->sw = enclosing->sw;
91 this->tf = enclosing->tf;
92 this->sbreak = enclosing->sbreak;
93 this->scontinue = enclosing->scontinue;
94 this->fes = enclosing->fes;
95 this->structalign = enclosing->structalign;
96 this->enclosing = enclosing;
97 #ifdef DEBUG
98 if (enclosing->enclosing)
99 assert(!(enclosing->enclosing->flags & SCOPEfree));
100 if (this == enclosing->enclosing)
101 {
102 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
103 }
104 assert(this != enclosing->enclosing);
105 #endif
106 this->slabel = NULL;
107 this->linkage = enclosing->linkage;
108 this->protection = enclosing->protection;
109 this->explicitProtection = enclosing->explicitProtection;
110 this->stc = enclosing->stc;
111 this->offset = 0;
112 this->inunion = enclosing->inunion;
113 this->incontract = enclosing->incontract;
114 this->nofree = 0;
115 this->noctor = enclosing->noctor;
116 this->intypeof = enclosing->intypeof;
117 this->parameterSpecialization = enclosing->parameterSpecialization;
118 this->callSuper = enclosing->callSuper;
119 this->flags = 0;
120 this->anonAgg = NULL;
121 this->lastdc = NULL;
122 this->lastoffset = 0;
123 this->docbuf = enclosing->docbuf;
124 assert(this != enclosing);
125 }
126
127 Scope *Scope::createGlobal(Module *module)
128 {
129 Scope *sc;
130
131 sc = new Scope();
132 sc->module = module;
133 sc->scopesym = new ScopeDsymbol();
134 sc->scopesym->symtab = new DsymbolTable();
135
136 // Add top level package as member of this global scope
137 Dsymbol *m = module;
138 while (m->parent)
139 m = m->parent;
140 m->addMember(NULL, sc->scopesym, 1);
141 m->parent = NULL; // got changed by addMember()
142
143 // Create the module scope underneath the global scope
144 sc = sc->push(module);
145 sc->parent = module;
146 return sc;
147 }
148
149 Scope *Scope::push()
150 {
151 //printf("Scope::push()\n");
152 Scope *s = new Scope(this);
153 assert(this != s);
154 return s;
155 }
156
157 Scope *Scope::push(ScopeDsymbol *ss)
158 {
159 //printf("Scope::push(%s)\n", ss->toChars());
160 Scope *s = push();
161 s->scopesym = ss;
162 return s;
163 }
164
165 Scope *Scope::pop()
166 {
167 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
168 Scope *enc = enclosing;
169
170 if (enclosing)
171 enclosing->callSuper |= callSuper;
172
173 if (!nofree)
174 { enclosing = freelist;
175 freelist = this;
176 flags |= SCOPEfree;
177 }
178
179 return enc;
180 }
181
182 void Scope::mergeCallSuper(Loc loc, unsigned cs)
183 {
184 // This does a primitive flow analysis to support the restrictions
185 // regarding when and how constructors can appear.
186 // It merges the results of two paths.
187 // The two paths are callSuper and cs; the result is merged into callSuper.
188
189 if (cs != callSuper)
190 { int a;
191 int b;
192
193 callSuper |= cs & (CSXany_ctor | CSXlabel);
194 if (cs & CSXreturn)
195 {
196 }
197 else if (callSuper & CSXreturn)
198 {
199 callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
200 }
201 else
202 {
203 a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
204 b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
205 if (a != b)
206 error(loc, "one path skips constructor");
207 callSuper |= cs;
208 }
209 }
210 }
211
212 Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
213 { Dsymbol *s;
214 Scope *sc;
215
216 //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
217 if (ident == Id::empty)
218 {
219 // Look for module scope
220 for (sc = this; sc; sc = sc->enclosing)
221 {
222 assert(sc != sc->enclosing);
223 if (sc->scopesym)
224 {
225 s = sc->scopesym->isModule();
226 if (s)
227 {
228 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
229 if (pscopesym)
230 *pscopesym = sc->scopesym;
231 return s;
232 }
233 }
234 }
235 return NULL;
236 }
237
238 for (sc = this; sc; sc = sc->enclosing)
239 {
240 assert(sc != sc->enclosing);
241 if (sc->scopesym)
242 {
243 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
244 s = sc->scopesym->search(loc, ident, 0);
245 if (s)
246 {
247 if ((global.params.warnings ||
248 global.params.Dversion > 1) &&
249 ident == Id::length &&
250 sc->scopesym->isArrayScopeSymbol() &&
251 sc->enclosing &&
252 sc->enclosing->search(loc, ident, NULL))
253 {
254 if (global.params.warnings)
255 fprintf(stdmsg, "warning - ");
256 error(s->loc, "array 'length' hides other 'length' name in outer scope");
257 }
258
259 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
260 if (pscopesym)
261 *pscopesym = sc->scopesym;
262 return s;
263 }
264 }
265 }
266
267 return NULL;
268 }
269
270 Dsymbol *Scope::insert(Dsymbol *s)
271 { Scope *sc;
272
273 for (sc = this; sc; sc = sc->enclosing)
274 {
275 //printf("\tsc = %p\n", sc);
276 if (sc->scopesym)
277 {
278 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
279 if (!sc->scopesym->symtab)
280 sc->scopesym->symtab = new DsymbolTable();
281 return sc->scopesym->symtab->insert(s);
282 }
283 }
284 assert(0);
285 return NULL;
286 }
287
288 /********************************************
289 * Search enclosing scopes for ClassDeclaration.
290 */
291
292 ClassDeclaration *Scope::getClassScope()
293 { Scope *sc;
294
295 for (sc = this; sc; sc = sc->enclosing)
296 {
297 ClassDeclaration *cd;
298
299 if (sc->scopesym)
300 {
301 cd = sc->scopesym->isClassDeclaration();
302 if (cd)
303 return cd;
304 }
305 }
306 return NULL;
307 }
308
309 /********************************************
310 * Search enclosing scopes for ClassDeclaration.
311 */
312
313 AggregateDeclaration *Scope::getStructClassScope()
314 { Scope *sc;
315
316 for (sc = this; sc; sc = sc->enclosing)
317 {
318 AggregateDeclaration *ad;
319
320 if (sc->scopesym)
321 {
322 ad = sc->scopesym->isClassDeclaration();
323 if (ad)
324 return ad;
325 else
326 { ad = sc->scopesym->isStructDeclaration();
327 if (ad)
328 return ad;
329 }
330 }
331 }
332 return NULL;
333 }
334
335 /*******************************************
336 * For TemplateDeclarations, we need to remember the Scope
337 * where it was declared. So mark the Scope as not
338 * to be free'd.
339 */
340
341 void Scope::setNoFree()
342 { Scope *sc;
343 //int i = 0;
344
345 //printf("Scope::setNoFree(this = %p)\n", this);
346 for (sc = this; sc; sc = sc->enclosing)
347 {
348 //printf("\tsc = %p\n", sc);
349 sc->nofree = 1;
350
351 assert(!(flags & SCOPEfree));
352 //assert(sc != sc->enclosing);
353 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);
354 //if (++i == 10)
355 //assert(0);
356 }
357 }