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