Mercurial > projects > ldc
annotate dmd/scope.c @ 1650:40bd4a0d4870
Update to work with LLVM 2.7.
Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).
Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.
Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
author | Tomas Lindquist Olsen |
---|---|
date | Wed, 19 May 2010 12:42:32 +0200 |
parents | 9bf06e02070b |
children |
rev | line source |
---|---|
159 | 1 |
1640 | 2 // Copyright (c) 1999-2010 by Digital Mars |
159 | 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" | |
1640 | 14 #include "speller.h" |
159 | 15 |
16 #include "mars.h" | |
17 #include "init.h" | |
18 #include "identifier.h" | |
19 #include "attrib.h" | |
20 #include "dsymbol.h" | |
21 #include "scope.h" | |
22 #include "declaration.h" | |
23 #include "aggregate.h" | |
24 #include "module.h" | |
25 #include "id.h" | |
26 | |
27 Scope *Scope::freelist = NULL; | |
28 | |
29 void *Scope::operator new(size_t size) | |
30 { | |
31 if (freelist) | |
32 { | |
33 Scope *s = freelist; | |
34 freelist = s->enclosing; | |
35 //printf("freelist %p\n", s); | |
36 assert(s->flags & SCOPEfree); | |
37 s->flags &= ~SCOPEfree; | |
38 return s; | |
39 } | |
40 | |
41 void *p = ::operator new(size); | |
42 //printf("new %p\n", p); | |
43 return p; | |
44 } | |
45 | |
46 Scope::Scope() | |
47 { // Create root scope | |
48 | |
49 //printf("Scope::Scope() %p\n", this); | |
50 this->module = NULL; | |
51 this->scopesym = NULL; | |
52 this->sd = NULL; | |
53 this->enclosing = NULL; | |
54 this->parent = NULL; | |
55 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
|
56 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
|
57 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
|
58 this->tinst = NULL; |
159 | 59 this->sbreak = NULL; |
60 this->scontinue = NULL; | |
61 this->fes = NULL; | |
62 this->structalign = global.structalign; | |
63 this->func = NULL; | |
64 this->slabel = NULL; | |
65 this->linkage = LINKd; | |
66 this->protection = PROTpublic; | |
67 this->explicitProtection = 0; | |
68 this->stc = 0; | |
69 this->offset = 0; | |
70 this->inunion = 0; | |
71 this->incontract = 0; | |
72 this->nofree = 0; | |
73 this->noctor = 0; | |
74 this->noaccesscheck = 0; | |
1587 | 75 this->mustsemantic = 0; |
159 | 76 this->intypeof = 0; |
77 this->parameterSpecialization = 0; | |
78 this->callSuper = 0; | |
79 this->flags = 0; | |
80 this->anonAgg = NULL; | |
81 this->lastdc = NULL; | |
82 this->lastoffset = 0; | |
83 this->docbuf = NULL; | |
84 } | |
85 | |
86 Scope::Scope(Scope *enclosing) | |
87 { | |
88 //printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this); | |
89 assert(!(enclosing->flags & SCOPEfree)); | |
90 this->module = enclosing->module; | |
91 this->func = enclosing->func; | |
92 this->parent = enclosing->parent; | |
93 this->scopesym = NULL; | |
94 this->sd = NULL; | |
95 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
|
96 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
|
97 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
|
98 this->tinst = enclosing->tinst; |
159 | 99 this->sbreak = enclosing->sbreak; |
100 this->scontinue = enclosing->scontinue; | |
101 this->fes = enclosing->fes; | |
102 this->structalign = enclosing->structalign; | |
103 this->enclosing = enclosing; | |
104 #ifdef DEBUG | |
105 if (enclosing->enclosing) | |
106 assert(!(enclosing->enclosing->flags & SCOPEfree)); | |
107 if (this == enclosing->enclosing) | |
108 { | |
109 printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing); | |
110 } | |
111 assert(this != enclosing->enclosing); | |
112 #endif | |
113 this->slabel = NULL; | |
114 this->linkage = enclosing->linkage; | |
115 this->protection = enclosing->protection; | |
116 this->explicitProtection = enclosing->explicitProtection; | |
117 this->stc = enclosing->stc; | |
118 this->offset = 0; | |
119 this->inunion = enclosing->inunion; | |
120 this->incontract = enclosing->incontract; | |
121 this->nofree = 0; | |
122 this->noctor = enclosing->noctor; | |
123 this->noaccesscheck = enclosing->noaccesscheck; | |
1587 | 124 this->mustsemantic = enclosing->mustsemantic; |
159 | 125 this->intypeof = enclosing->intypeof; |
126 this->parameterSpecialization = enclosing->parameterSpecialization; | |
127 this->callSuper = enclosing->callSuper; | |
128 this->flags = 0; | |
129 this->anonAgg = NULL; | |
130 this->lastdc = NULL; | |
131 this->lastoffset = 0; | |
132 this->docbuf = enclosing->docbuf; | |
133 assert(this != enclosing); | |
134 } | |
135 | |
136 Scope *Scope::createGlobal(Module *module) | |
137 { | |
138 Scope *sc; | |
139 | |
140 sc = new Scope(); | |
141 sc->module = module; | |
142 sc->scopesym = new ScopeDsymbol(); | |
143 sc->scopesym->symtab = new DsymbolTable(); | |
144 | |
145 // Add top level package as member of this global scope | |
146 Dsymbol *m = module; | |
147 while (m->parent) | |
148 m = m->parent; | |
149 m->addMember(NULL, sc->scopesym, 1); | |
150 m->parent = NULL; // got changed by addMember() | |
151 | |
152 // Create the module scope underneath the global scope | |
153 sc = sc->push(module); | |
154 sc->parent = module; | |
155 return sc; | |
156 } | |
157 | |
158 Scope *Scope::push() | |
159 { | |
160 //printf("Scope::push()\n"); | |
161 Scope *s = new Scope(this); | |
162 assert(this != s); | |
163 return s; | |
164 } | |
165 | |
166 Scope *Scope::push(ScopeDsymbol *ss) | |
167 { | |
168 //printf("Scope::push(%s)\n", ss->toChars()); | |
169 Scope *s = push(); | |
170 s->scopesym = ss; | |
171 return s; | |
172 } | |
173 | |
174 Scope *Scope::pop() | |
175 { | |
176 //printf("Scope::pop() %p nofree = %d\n", this, nofree); | |
177 Scope *enc = enclosing; | |
178 | |
179 if (enclosing) | |
180 enclosing->callSuper |= callSuper; | |
181 | |
182 if (!nofree) | |
183 { enclosing = freelist; | |
184 freelist = this; | |
185 flags |= SCOPEfree; | |
186 } | |
187 | |
188 return enc; | |
189 } | |
190 | |
191 void Scope::mergeCallSuper(Loc loc, unsigned cs) | |
192 { | |
193 // This does a primitive flow analysis to support the restrictions | |
194 // regarding when and how constructors can appear. | |
195 // It merges the results of two paths. | |
196 // The two paths are callSuper and cs; the result is merged into callSuper. | |
197 | |
198 if (cs != callSuper) | |
199 { int a; | |
200 int b; | |
201 | |
202 callSuper |= cs & (CSXany_ctor | CSXlabel); | |
203 if (cs & CSXreturn) | |
204 { | |
205 } | |
206 else if (callSuper & CSXreturn) | |
207 { | |
208 callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel)); | |
209 } | |
210 else | |
211 { | |
212 a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0; | |
213 b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0; | |
214 if (a != b) | |
215 error(loc, "one path skips constructor"); | |
216 callSuper |= cs; | |
217 } | |
218 } | |
219 } | |
220 | |
221 Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym) | |
222 { Dsymbol *s; | |
223 Scope *sc; | |
224 | |
225 //printf("Scope::search(%p, '%s')\n", this, ident->toChars()); | |
226 if (ident == Id::empty) | |
227 { | |
228 // Look for module scope | |
229 for (sc = this; sc; sc = sc->enclosing) | |
230 { | |
231 assert(sc != sc->enclosing); | |
232 if (sc->scopesym) | |
233 { | |
234 s = sc->scopesym->isModule(); | |
235 if (s) | |
236 { | |
237 //printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars()); | |
238 if (pscopesym) | |
239 *pscopesym = sc->scopesym; | |
240 return s; | |
241 } | |
242 } | |
243 } | |
244 return NULL; | |
245 } | |
246 | |
247 for (sc = this; sc; sc = sc->enclosing) | |
248 { | |
249 assert(sc != sc->enclosing); | |
250 if (sc->scopesym) | |
251 { | |
252 //printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind()); | |
253 s = sc->scopesym->search(loc, ident, 0); | |
254 if (s) | |
255 { | |
256 if ((global.params.warnings || | |
257 global.params.Dversion > 1) && | |
258 ident == Id::length && | |
259 sc->scopesym->isArrayScopeSymbol() && | |
260 sc->enclosing && | |
261 sc->enclosing->search(loc, ident, NULL)) | |
262 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
561
diff
changeset
|
263 warning(s->loc, "array 'length' hides other 'length' name in outer scope"); |
159 | 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(); | |
1587 | 288 return sc->scopesym->symtabInsert(s); |
159 | 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 } | |
1640 | 365 |
366 | |
367 /************************************************ | |
368 * Given the failed search attempt, try to find | |
369 * one with a close spelling. | |
370 */ | |
371 | |
372 void *scope_search_fp(void *arg, const char *seed) | |
373 { | |
374 //printf("scope_search_fp('%s')\n", seed); | |
375 Scope *sc = (Scope *)arg; | |
376 Identifier id(seed, 0); | |
377 Module::clearCache(); | |
378 Dsymbol *s = sc->search(0, &id, NULL); | |
379 return s; | |
380 } | |
381 | |
382 Dsymbol *Scope::search_correct(Identifier *ident) | |
383 { | |
384 if (global.gag) | |
385 return NULL; // don't do it for speculative compiles; too time consuming | |
386 | |
387 return (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars); | |
388 } |