Mercurial > projects > ldc
annotate dmd/scope.c @ 323:0d52412d5b1a trunk
[svn r344] Fixed some very minor issues with the usage listing when calling llvmdc with no arguments.
Changed the way moduleinfo is registered to use the same approach as DMD, this eliminates the need for correct linking order and should make the way for using a natively compiled runtime library. This should speed up linking tremendously and should now be possible.
Fixed the llvm.used array to only be emitted if really necessary.
author | lindquist |
---|---|
date | Wed, 09 Jul 2008 23:43:51 +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 } |