Mercurial > projects > ldc
annotate dmd/scope.c @ 1536:49ae9728bea4
Check for ldc.conf next to the ldc binary before home and etc.
The new search order is
* current working directory
* next to executable
* user home directory
* prefix/etc
* prefix/etc/ldc
* /etc
* /etc/ldc
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Mon, 13 Jul 2009 22:24:12 +0200 |
parents | f99a3b393c03 |
children | def7a1d494fd |
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; | |
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; | |
1141
f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
94 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
|
95 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
|
96 this->tinst = enclosing->tinst; |
159 | 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 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
561
diff
changeset
|
260 warning(s->loc, "array 'length' hides other 'length' name in outer scope"); |
159 | 261 } |
262 | |
263 //printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind()); | |
264 if (pscopesym) | |
265 *pscopesym = sc->scopesym; | |
266 return s; | |
267 } | |
268 } | |
269 } | |
270 | |
271 return NULL; | |
272 } | |
273 | |
274 Dsymbol *Scope::insert(Dsymbol *s) | |
275 { Scope *sc; | |
276 | |
277 for (sc = this; sc; sc = sc->enclosing) | |
278 { | |
279 //printf("\tsc = %p\n", sc); | |
280 if (sc->scopesym) | |
281 { | |
282 //printf("\t\tsc->scopesym = %p\n", sc->scopesym); | |
283 if (!sc->scopesym->symtab) | |
284 sc->scopesym->symtab = new DsymbolTable(); | |
285 return sc->scopesym->symtab->insert(s); | |
286 } | |
287 } | |
288 assert(0); | |
289 return NULL; | |
290 } | |
291 | |
292 /******************************************** | |
293 * Search enclosing scopes for ClassDeclaration. | |
294 */ | |
295 | |
296 ClassDeclaration *Scope::getClassScope() | |
297 { Scope *sc; | |
298 | |
299 for (sc = this; sc; sc = sc->enclosing) | |
300 { | |
301 ClassDeclaration *cd; | |
302 | |
303 if (sc->scopesym) | |
304 { | |
305 cd = sc->scopesym->isClassDeclaration(); | |
306 if (cd) | |
307 return cd; | |
308 } | |
309 } | |
310 return NULL; | |
311 } | |
312 | |
313 /******************************************** | |
314 * Search enclosing scopes for ClassDeclaration. | |
315 */ | |
316 | |
317 AggregateDeclaration *Scope::getStructClassScope() | |
318 { Scope *sc; | |
319 | |
320 for (sc = this; sc; sc = sc->enclosing) | |
321 { | |
322 AggregateDeclaration *ad; | |
323 | |
324 if (sc->scopesym) | |
325 { | |
326 ad = sc->scopesym->isClassDeclaration(); | |
327 if (ad) | |
328 return ad; | |
329 else | |
330 { ad = sc->scopesym->isStructDeclaration(); | |
331 if (ad) | |
332 return ad; | |
333 } | |
334 } | |
335 } | |
336 return NULL; | |
337 } | |
338 | |
339 /******************************************* | |
340 * For TemplateDeclarations, we need to remember the Scope | |
341 * where it was declared. So mark the Scope as not | |
342 * to be free'd. | |
343 */ | |
344 | |
345 void Scope::setNoFree() | |
346 { Scope *sc; | |
347 //int i = 0; | |
348 | |
349 //printf("Scope::setNoFree(this = %p)\n", this); | |
350 for (sc = this; sc; sc = sc->enclosing) | |
351 { | |
352 //printf("\tsc = %p\n", sc); | |
353 sc->nofree = 1; | |
354 | |
355 assert(!(flags & SCOPEfree)); | |
356 //assert(sc != sc->enclosing); | |
357 //assert(!sc->enclosing || sc != sc->enclosing->enclosing); | |
358 //if (++i == 10) | |
359 //assert(0); | |
360 } | |
361 } |