Mercurial > projects > ldc
annotate dmd/scope.c @ 1635:601d3eea4a68
Make -nodefaultlib override -de{fault,bug}lib=foo instead of vice versa.
author | Matti Niemenmaa <matti.niemenmaa+hg@iki.fi> |
---|---|
date | Fri, 05 Mar 2010 21:40:51 +0200 |
parents | def7a1d494fd |
children | 9bf06e02070b |
rev | line source |
---|---|
159 | 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; | |
1141
f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
55 this->enclosingFinally = NULL; |
f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
56 this->enclosingScopeExit = NULL; |
561
d4e95db0e62b
Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents:
215
diff
changeset
|
57 this->tinst = NULL; |
159 | 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; | |
1587 | 74 this->mustsemantic = 0; |
159 | 75 this->intypeof = 0; |
76 this->parameterSpecialization = 0; | |
77 this->callSuper = 0; | |
78 this->flags = 0; | |
79 this->anonAgg = NULL; | |
80 this->lastdc = NULL; | |
81 this->lastoffset = 0; | |
82 this->docbuf = NULL; | |
83 } | |
84 | |
85 Scope::Scope(Scope *enclosing) | |
86 { | |
87 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this); | |
88 assert(!(enclosing->flags & SCOPEfree)); | |
89 this->module = enclosing->module; | |
90 this->func = enclosing->func; | |
91 this->parent = enclosing->parent; | |
92 this->scopesym = NULL; | |
93 this->sd = NULL; | |
94 this->sw = enclosing->sw; | |
1141
f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
95 this->enclosingFinally = enclosing->enclosingFinally; |
f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
96 this->enclosingScopeExit = enclosing->enclosingScopeExit; |
561
d4e95db0e62b
Introducing template instantiation traces for static asserts and errors within templates.
Christian Kamm <kamm incasoftware de>
parents:
215
diff
changeset
|
97 this->tinst = enclosing->tinst; |
159 | 98 this->sbreak = enclosing->sbreak; |
99 this->scontinue = enclosing->scontinue; | |
100 this->fes = enclosing->fes; | |
101 this->structalign = enclosing->structalign; | |
102 this->enclosing = enclosing; | |
103 #ifdef DEBUG | |
104 if (enclosing->enclosing) | |
105 assert(!(enclosing->enclosing->flags & SCOPEfree)); | |
106 if (this == enclosing->enclosing) | |
107 { | |
108 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing); | |
109 } | |
110 assert(this != enclosing->enclosing); | |
111 #endif | |
112 this->slabel = NULL; | |
113 this->linkage = enclosing->linkage; | |
114 this->protection = enclosing->protection; | |
115 this->explicitProtection = enclosing->explicitProtection; | |
116 this->stc = enclosing->stc; | |
117 this->offset = 0; | |
118 this->inunion = enclosing->inunion; | |
119 this->incontract = enclosing->incontract; | |
120 this->nofree = 0; | |
121 this->noctor = enclosing->noctor; | |
122 this->noaccesscheck = enclosing->noaccesscheck; | |
1587 | 123 this->mustsemantic = enclosing->mustsemantic; |
159 | 124 this->intypeof = enclosing->intypeof; |
125 this->parameterSpecialization = enclosing->parameterSpecialization; | |
126 this->callSuper = enclosing->callSuper; | |
127 this->flags = 0; | |
128 this->anonAgg = NULL; | |
129 this->lastdc = NULL; | |
130 this->lastoffset = 0; | |
131 this->docbuf = enclosing->docbuf; | |
132 assert(this != enclosing); | |
133 } | |
134 | |
135 Scope *Scope::createGlobal(Module *module) | |
136 { | |
137 Scope *sc; | |
138 | |
139 sc = new Scope(); | |
140 sc->module = module; | |
141 sc->scopesym = new ScopeDsymbol(); | |
142 sc->scopesym->symtab = new DsymbolTable(); | |
143 | |
144 // Add top level package as member of this global scope | |
145 Dsymbol *m = module; | |
146 while (m->parent) | |
147 m = m->parent; | |
148 m->addMember(NULL, sc->scopesym, 1); | |
149 m->parent = NULL; // got changed by addMember() | |
150 | |
151 // Create the module scope underneath the global scope | |
152 sc = sc->push(module); | |
153 sc->parent = module; | |
154 return sc; | |
155 } | |
156 | |
157 Scope *Scope::push() | |
158 { | |
159 //printf("Scope::push()\n"); | |
160 Scope *s = new Scope(this); | |
161 assert(this != s); | |
162 return s; | |
163 } | |
164 | |
165 Scope *Scope::push(ScopeDsymbol *ss) | |
166 { | |
167 //printf("Scope::push(%s)\n", ss->toChars()); | |
168 Scope *s = push(); | |
169 s->scopesym = ss; | |
170 return s; | |
171 } | |
172 | |
173 Scope *Scope::pop() | |
174 { | |
175 //printf("Scope::pop() %p nofree = %d\n", this, nofree); | |
176 Scope *enc = enclosing; | |
177 | |
178 if (enclosing) | |
179 enclosing->callSuper |= callSuper; | |
180 | |
181 if (!nofree) | |
182 { enclosing = freelist; | |
183 freelist = this; | |
184 flags |= SCOPEfree; | |
185 } | |
186 | |
187 return enc; | |
188 } | |
189 | |
190 void Scope::mergeCallSuper(Loc loc, unsigned cs) | |
191 { | |
192 // This does a primitive flow analysis to support the restrictions | |
193 // regarding when and how constructors can appear. | |
194 // It merges the results of two paths. | |
195 // The two paths are callSuper and cs; the result is merged into callSuper. | |
196 | |
197 if (cs != callSuper) | |
198 { int a; | |
199 int b; | |
200 | |
201 callSuper |= cs & (CSXany_ctor | CSXlabel); | |
202 if (cs & CSXreturn) | |
203 { | |
204 } | |
205 else if (callSuper & CSXreturn) | |
206 { | |
207 callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel)); | |
208 } | |
209 else | |
210 { | |
211 a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0; | |
212 b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0; | |
213 if (a != b) | |
214 error(loc, "one path skips constructor"); | |
215 callSuper |= cs; | |
216 } | |
217 } | |
218 } | |
219 | |
220 Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym) | |
221 { Dsymbol *s; | |
222 Scope *sc; | |
223 | |
224 //printf("Scope::search(%p, '%s')\n", this, ident->toChars()); | |
225 if (ident == Id::empty) | |
226 { | |
227 // Look for module scope | |
228 for (sc = this; sc; sc = sc->enclosing) | |
229 { | |
230 assert(sc != sc->enclosing); | |
231 if (sc->scopesym) | |
232 { | |
233 s = sc->scopesym->isModule(); | |
234 if (s) | |
235 { | |
236 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars()); | |
237 if (pscopesym) | |
238 *pscopesym = sc->scopesym; | |
239 return s; | |
240 } | |
241 } | |
242 } | |
243 return NULL; | |
244 } | |
245 | |
246 for (sc = this; sc; sc = sc->enclosing) | |
247 { | |
248 assert(sc != sc->enclosing); | |
249 if (sc->scopesym) | |
250 { | |
251 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind()); | |
252 s = sc->scopesym->search(loc, ident, 0); | |
253 if (s) | |
254 { | |
255 if ((global.params.warnings || | |
256 global.params.Dversion > 1) && | |
257 ident == Id::length && | |
258 sc->scopesym->isArrayScopeSymbol() && | |
259 sc->enclosing && | |
260 sc->enclosing->search(loc, ident, NULL)) | |
261 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
561
diff
changeset
|
262 warning(s->loc, "array 'length' hides other 'length' name in outer scope"); |
159 | 263 } |
264 | |
265 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); | |
266 if (pscopesym) | |
267 *pscopesym = sc->scopesym; | |
268 return s; | |
269 } | |
270 } | |
271 } | |
272 | |
273 return NULL; | |
274 } | |
275 | |
276 Dsymbol *Scope::insert(Dsymbol *s) | |
277 { Scope *sc; | |
278 | |
279 for (sc = this; sc; sc = sc->enclosing) | |
280 { | |
281 //printf("\tsc = %p\n", sc); | |
282 if (sc->scopesym) | |
283 { | |
284 //printf("\t\tsc->scopesym = %p\n", sc->scopesym); | |
285 if (!sc->scopesym->symtab) | |
286 sc->scopesym->symtab = new DsymbolTable(); | |
1587 | 287 return sc->scopesym->symtabInsert(s); |
159 | 288 } |
289 } | |
290 assert(0); | |
291 return NULL; | |
292 } | |
293 | |
294 /******************************************** | |
295 * Search enclosing scopes for ClassDeclaration. | |
296 */ | |
297 | |
298 ClassDeclaration *Scope::getClassScope() | |
299 { Scope *sc; | |
300 | |
301 for (sc = this; sc; sc = sc->enclosing) | |
302 { | |
303 ClassDeclaration *cd; | |
304 | |
305 if (sc->scopesym) | |
306 { | |
307 cd = sc->scopesym->isClassDeclaration(); | |
308 if (cd) | |
309 return cd; | |
310 } | |
311 } | |
312 return NULL; | |
313 } | |
314 | |
315 /******************************************** | |
316 * Search enclosing scopes for ClassDeclaration. | |
317 */ | |
318 | |
319 AggregateDeclaration *Scope::getStructClassScope() | |
320 { Scope *sc; | |
321 | |
322 for (sc = this; sc; sc = sc->enclosing) | |
323 { | |
324 AggregateDeclaration *ad; | |
325 | |
326 if (sc->scopesym) | |
327 { | |
328 ad = sc->scopesym->isClassDeclaration(); | |
329 if (ad) | |
330 return ad; | |
331 else | |
332 { ad = sc->scopesym->isStructDeclaration(); | |
333 if (ad) | |
334 return ad; | |
335 } | |
336 } | |
337 } | |
338 return NULL; | |
339 } | |
340 | |
341 /******************************************* | |
342 * For TemplateDeclarations, we need to remember the Scope | |
343 * where it was declared. So mark the Scope as not | |
344 * to be free'd. | |
345 */ | |
346 | |
347 void Scope::setNoFree() | |
348 { Scope *sc; | |
349 //int i = 0; | |
350 | |
351 //printf("Scope::setNoFree(this = %p)\n", this); | |
352 for (sc = this; sc; sc = sc->enclosing) | |
353 { | |
354 //printf("\tsc = %p\n", sc); | |
355 sc->nofree = 1; | |
356 | |
357 assert(!(flags & SCOPEfree)); | |
358 //assert(sc != sc->enclosing); | |
359 //assert(!sc->enclosing || sc != sc->enclosing->enclosing); | |
360 //if (++i == 10) | |
361 //assert(0); | |
362 } | |
363 } |