comparison dmd2/scope.c @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents
children 638d16625da2
comparison
equal deleted inserted replaced
757:2c730d530c98 758:f04dde6e882c
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->tfOfTry = NULL;
57 this->tinst = NULL;
58 this->sbreak = NULL;
59 this->scontinue = NULL;
60 this->fes = NULL;
61 this->structalign = global.structalign;
62 this->func = NULL;
63 this->slabel = NULL;
64 this->linkage = LINKd;
65 this->protection = PROTpublic;
66 this->explicitProtection = 0;
67 this->stc = 0;
68 this->offset = 0;
69 this->inunion = 0;
70 this->incontract = 0;
71 this->nofree = 0;
72 this->noctor = 0;
73 this->noaccesscheck = 0;
74 this->intypeof = 0;
75 this->parameterSpecialization = 0;
76 this->callSuper = 0;
77 this->flags = 0;
78 this->anonAgg = NULL;
79 this->lastdc = NULL;
80 this->lastoffset = 0;
81 this->docbuf = NULL;
82 }
83
84 Scope::Scope(Scope *enclosing)
85 {
86 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
87 assert(!(enclosing->flags & SCOPEfree));
88 this->module = enclosing->module;
89 this->func = enclosing->func;
90 this->parent = enclosing->parent;
91 this->scopesym = NULL;
92 this->sd = NULL;
93 this->sw = enclosing->sw;
94 this->tf = enclosing->tf;
95 this->tfOfTry = enclosing->tfOfTry;
96 this->tinst = enclosing->tinst;
97 this->sbreak = enclosing->sbreak;
98 this->scontinue = enclosing->scontinue;
99 this->fes = enclosing->fes;
100 this->structalign = enclosing->structalign;
101 this->enclosing = enclosing;
102 #ifdef DEBUG
103 if (enclosing->enclosing)
104 assert(!(enclosing->enclosing->flags & SCOPEfree));
105 if (this == enclosing->enclosing)
106 {
107 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
108 }
109 assert(this != enclosing->enclosing);
110 #endif
111 this->slabel = NULL;
112 this->linkage = enclosing->linkage;
113 this->protection = enclosing->protection;
114 this->explicitProtection = enclosing->explicitProtection;
115 this->stc = enclosing->stc;
116 this->offset = 0;
117 this->inunion = enclosing->inunion;
118 this->incontract = enclosing->incontract;
119 this->nofree = 0;
120 this->noctor = enclosing->noctor;
121 this->noaccesscheck = enclosing->noaccesscheck;
122 this->intypeof = enclosing->intypeof;
123 this->parameterSpecialization = enclosing->parameterSpecialization;
124 this->callSuper = enclosing->callSuper;
125 this->flags = 0;
126 this->anonAgg = NULL;
127 this->lastdc = NULL;
128 this->lastoffset = 0;
129 this->docbuf = enclosing->docbuf;
130 assert(this != enclosing);
131 }
132
133 Scope *Scope::createGlobal(Module *module)
134 {
135 Scope *sc;
136
137 sc = new Scope();
138 sc->module = module;
139 sc->scopesym = new ScopeDsymbol();
140 sc->scopesym->symtab = new DsymbolTable();
141
142 // Add top level package as member of this global scope
143 Dsymbol *m = module;
144 while (m->parent)
145 m = m->parent;
146 m->addMember(NULL, sc->scopesym, 1);
147 m->parent = NULL; // got changed by addMember()
148
149 // Create the module scope underneath the global scope
150 sc = sc->push(module);
151 sc->parent = module;
152 return sc;
153 }
154
155 Scope *Scope::push()
156 {
157 //printf("Scope::push()\n");
158 Scope *s = new Scope(this);
159 assert(this != s);
160 return s;
161 }
162
163 Scope *Scope::push(ScopeDsymbol *ss)
164 {
165 //printf("Scope::push(%s)\n", ss->toChars());
166 Scope *s = push();
167 s->scopesym = ss;
168 return s;
169 }
170
171 Scope *Scope::pop()
172 {
173 //printf("Scope::pop() %p nofree = %d\n", this, nofree);
174 Scope *enc = enclosing;
175
176 if (enclosing)
177 enclosing->callSuper |= callSuper;
178
179 if (!nofree)
180 { enclosing = freelist;
181 freelist = this;
182 flags |= SCOPEfree;
183 }
184
185 return enc;
186 }
187
188 void Scope::mergeCallSuper(Loc loc, unsigned cs)
189 {
190 // This does a primitive flow analysis to support the restrictions
191 // regarding when and how constructors can appear.
192 // It merges the results of two paths.
193 // The two paths are callSuper and cs; the result is merged into callSuper.
194
195 if (cs != callSuper)
196 { int a;
197 int b;
198
199 callSuper |= cs & (CSXany_ctor | CSXlabel);
200 if (cs & CSXreturn)
201 {
202 }
203 else if (callSuper & CSXreturn)
204 {
205 callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
206 }
207 else
208 {
209 a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
210 b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
211 if (a != b)
212 error(loc, "one path skips constructor");
213 callSuper |= cs;
214 }
215 }
216 }
217
218 Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
219 { Dsymbol *s;
220 Scope *sc;
221
222 //printf("Scope::search(%p, '%s')\n", this, ident->toChars());
223 if (ident == Id::empty)
224 {
225 // Look for module scope
226 for (sc = this; sc; sc = sc->enclosing)
227 {
228 assert(sc != sc->enclosing);
229 if (sc->scopesym)
230 {
231 s = sc->scopesym->isModule();
232 if (s)
233 {
234 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
235 if (pscopesym)
236 *pscopesym = sc->scopesym;
237 return s;
238 }
239 }
240 }
241 return NULL;
242 }
243
244 for (sc = this; sc; sc = sc->enclosing)
245 {
246 assert(sc != sc->enclosing);
247 if (sc->scopesym)
248 {
249 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
250 s = sc->scopesym->search(loc, ident, 0);
251 if (s)
252 {
253 if ((global.params.warnings ||
254 global.params.Dversion > 1) &&
255 ident == Id::length &&
256 sc->scopesym->isArrayScopeSymbol() &&
257 sc->enclosing &&
258 sc->enclosing->search(loc, ident, NULL))
259 {
260 // WTF ?
261 if (global.params.warnings)
262 fprintf(stdmsg, "warning - ");
263 error(s->loc, "array 'length' hides other 'length' name in outer scope");
264 }
265
266 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
267 if (pscopesym)
268 *pscopesym = sc->scopesym;
269 return s;
270 }
271 }
272 }
273
274 return NULL;
275 }
276
277 Dsymbol *Scope::insert(Dsymbol *s)
278 { Scope *sc;
279
280 for (sc = this; sc; sc = sc->enclosing)
281 {
282 //printf("\tsc = %p\n", sc);
283 if (sc->scopesym)
284 {
285 //printf("\t\tsc->scopesym = %p\n", sc->scopesym);
286 if (!sc->scopesym->symtab)
287 sc->scopesym->symtab = new DsymbolTable();
288 return sc->scopesym->symtab->insert(s);
289 }
290 }
291 assert(0);
292 return NULL;
293 }
294
295 /********************************************
296 * Search enclosing scopes for ClassDeclaration.
297 */
298
299 ClassDeclaration *Scope::getClassScope()
300 { Scope *sc;
301
302 for (sc = this; sc; sc = sc->enclosing)
303 {
304 ClassDeclaration *cd;
305
306 if (sc->scopesym)
307 {
308 cd = sc->scopesym->isClassDeclaration();
309 if (cd)
310 return cd;
311 }
312 }
313 return NULL;
314 }
315
316 /********************************************
317 * Search enclosing scopes for ClassDeclaration.
318 */
319
320 AggregateDeclaration *Scope::getStructClassScope()
321 { Scope *sc;
322
323 for (sc = this; sc; sc = sc->enclosing)
324 {
325 AggregateDeclaration *ad;
326
327 if (sc->scopesym)
328 {
329 ad = sc->scopesym->isClassDeclaration();
330 if (ad)
331 return ad;
332 else
333 { ad = sc->scopesym->isStructDeclaration();
334 if (ad)
335 return ad;
336 }
337 }
338 }
339 return NULL;
340 }
341
342 /*******************************************
343 * For TemplateDeclarations, we need to remember the Scope
344 * where it was declared. So mark the Scope as not
345 * to be free'd.
346 */
347
348 void Scope::setNoFree()
349 { Scope *sc;
350 //int i = 0;
351
352 //printf("Scope::setNoFree(this = %p)\n", this);
353 for (sc = this; sc; sc = sc->enclosing)
354 {
355 //printf("\tsc = %p\n", sc);
356 sc->nofree = 1;
357
358 assert(!(flags & SCOPEfree));
359 //assert(sc != sc->enclosing);
360 //assert(!sc->enclosing || sc != sc->enclosing->enclosing);
361 //if (++i == 10)
362 //assert(0);
363 }
364 }