Mercurial > projects > ldc
annotate dmd/dsymbol.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 |
2 // Compiler implementation of the D programming language | |
1640 | 3 // Copyright (c) 1999-2010 by Digital Mars |
159 | 4 // All Rights Reserved |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <string.h> | |
13 #include <assert.h> | |
14 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
946
diff
changeset
|
15 #include "rmem.h" |
1640 | 16 #include "speller.h" |
159 | 17 |
18 #include "mars.h" | |
19 #include "dsymbol.h" | |
20 #include "aggregate.h" | |
21 #include "identifier.h" | |
22 #include "module.h" | |
23 #include "mtype.h" | |
24 #include "expression.h" | |
25 #include "statement.h" | |
26 #include "declaration.h" | |
27 #include "id.h" | |
28 #include "scope.h" | |
29 #include "init.h" | |
30 #include "import.h" | |
31 #include "template.h" | |
1587 | 32 #include "attrib.h" |
1630
44b145be2ef5
Merge dmd 1.056.
Robert Clipsham <robert@octarineparrot.com>
parents:
1607
diff
changeset
|
33 #if IN_LLVM |
159 | 34 #include "../gen/enums.h" |
1630
44b145be2ef5
Merge dmd 1.056.
Robert Clipsham <robert@octarineparrot.com>
parents:
1607
diff
changeset
|
35 #endif |
159 | 36 |
37 /****************************** Dsymbol ******************************/ | |
38 | |
39 Dsymbol::Dsymbol() | |
40 { | |
41 //printf("Dsymbol::Dsymbol(%p)\n", this); | |
42 this->ident = NULL; | |
43 this->c_ident = NULL; | |
44 this->parent = NULL; | |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
45 #if IN_DMD |
159 | 46 this->csym = NULL; |
47 this->isym = NULL; | |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
48 #endif |
159 | 49 this->loc = 0; |
50 this->comment = NULL; | |
1587 | 51 this->scope = NULL; |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
52 #if IN_LLVM |
159 | 53 this->llvmInternal = LLVMnone; |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
54 this->irsym = NULL; |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
55 #endif |
159 | 56 } |
57 | |
58 Dsymbol::Dsymbol(Identifier *ident) | |
59 { | |
60 //printf("Dsymbol::Dsymbol(%p, ident)\n", this); | |
61 this->ident = ident; | |
62 this->c_ident = NULL; | |
63 this->parent = NULL; | |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
64 #if IN_DMD |
159 | 65 this->csym = NULL; |
66 this->isym = NULL; | |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
67 #endif |
159 | 68 this->loc = 0; |
69 this->comment = NULL; | |
1587 | 70 this->scope = NULL; |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
71 #if IN_LLVM |
159 | 72 this->llvmInternal = LLVMnone; |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
73 this->irsym = NULL; |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
74 #endif |
159 | 75 } |
76 | |
77 int Dsymbol::equals(Object *o) | |
78 { Dsymbol *s; | |
79 | |
80 if (this == o) | |
81 return TRUE; | |
82 s = (Dsymbol *)(o); | |
83 if (s && ident->equals(s->ident)) | |
84 return TRUE; | |
85 return FALSE; | |
86 } | |
87 | |
88 /************************************** | |
89 * Copy the syntax. | |
90 * Used for template instantiations. | |
91 * If s is NULL, allocate the new object, otherwise fill it in. | |
92 */ | |
93 | |
94 Dsymbol *Dsymbol::syntaxCopy(Dsymbol *s) | |
95 { | |
96 print(); | |
97 printf("%s %s\n", kind(), toChars()); | |
98 assert(0); | |
99 return NULL; | |
100 } | |
101 | |
102 /************************************** | |
103 * Determine if this symbol is only one. | |
104 * Returns: | |
105 * FALSE, *ps = NULL: There are 2 or more symbols | |
106 * TRUE, *ps = NULL: There are zero symbols | |
107 * TRUE, *ps = symbol: The one and only one symbol | |
108 */ | |
109 | |
110 int Dsymbol::oneMember(Dsymbol **ps) | |
111 { | |
112 //printf("Dsymbol::oneMember()\n"); | |
113 *ps = this; | |
114 return TRUE; | |
115 } | |
116 | |
117 /***************************************** | |
118 * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. | |
119 */ | |
120 | |
121 int Dsymbol::oneMembers(Array *members, Dsymbol **ps) | |
122 { | |
123 //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); | |
124 Dsymbol *s = NULL; | |
125 | |
126 if (members) | |
127 { | |
128 for (int i = 0; i < members->dim; i++) | |
129 { Dsymbol *sx = (Dsymbol *)members->data[i]; | |
130 | |
131 int x = sx->oneMember(ps); | |
132 //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); | |
133 if (!x) | |
134 { | |
135 //printf("\tfalse 1\n"); | |
136 assert(*ps == NULL); | |
137 return FALSE; | |
138 } | |
139 if (*ps) | |
140 { | |
141 if (s) // more than one symbol | |
142 { *ps = NULL; | |
143 //printf("\tfalse 2\n"); | |
144 return FALSE; | |
145 } | |
146 s = *ps; | |
147 } | |
148 } | |
149 } | |
150 *ps = s; // s is the one symbol, NULL if none | |
151 //printf("\ttrue\n"); | |
152 return TRUE; | |
153 } | |
154 | |
155 /***************************************** | |
156 * Is Dsymbol a variable that contains pointers? | |
157 */ | |
158 | |
159 int Dsymbol::hasPointers() | |
160 { | |
161 //printf("Dsymbol::hasPointers() %s\n", toChars()); | |
162 return 0; | |
163 } | |
164 | |
165 char *Dsymbol::toChars() | |
166 { | |
167 return ident ? ident->toChars() : (char *)"__anonymous"; | |
168 } | |
169 | |
1587 | 170 const char *Dsymbol::toPrettyChars() |
159 | 171 { Dsymbol *p; |
172 char *s; | |
173 char *q; | |
174 size_t len; | |
175 | |
176 //printf("Dsymbol::toPrettyChars() '%s'\n", toChars()); | |
177 if (!parent) | |
178 return toChars(); | |
179 | |
180 len = 0; | |
181 for (p = this; p; p = p->parent) | |
182 len += strlen(p->toChars()) + 1; | |
183 | |
184 s = (char *)mem.malloc(len); | |
185 q = s + len - 1; | |
186 *q = 0; | |
187 for (p = this; p; p = p->parent) | |
188 { | |
189 char *t = p->toChars(); | |
190 len = strlen(t); | |
191 q -= len; | |
192 memcpy(q, t, len); | |
193 if (q == s) | |
194 break; | |
195 q--; | |
1587 | 196 #if TARGET_NET |
197 if (AggregateDeclaration* ad = p->isAggregateDeclaration()) | |
198 { | |
199 if (ad->isNested() && p->parent && p->parent->isAggregateDeclaration()) | |
200 { | |
201 *q = '/'; | |
202 continue; | |
203 } | |
204 } | |
205 #endif | |
159 | 206 *q = '.'; |
207 } | |
208 return s; | |
209 } | |
210 | |
211 char *Dsymbol::locToChars() | |
212 { | |
213 OutBuffer buf; | |
214 char *p; | |
215 | |
216 Module *m = getModule(); | |
217 | |
218 if (m && m->srcfile) | |
219 loc.filename = m->srcfile->toChars(); | |
220 return loc.toChars(); | |
221 } | |
222 | |
336 | 223 const char *Dsymbol::kind() |
159 | 224 { |
225 return "symbol"; | |
226 } | |
227 | |
228 /********************************* | |
229 * If this symbol is really an alias for another, | |
230 * return that other. | |
231 */ | |
232 | |
233 Dsymbol *Dsymbol::toAlias() | |
234 { | |
235 return this; | |
236 } | |
237 | |
238 Dsymbol *Dsymbol::toParent() | |
239 { | |
240 return parent ? parent->pastMixin() : NULL; | |
241 } | |
242 | |
243 Dsymbol *Dsymbol::pastMixin() | |
244 { | |
245 Dsymbol *s = this; | |
246 | |
247 //printf("Dsymbol::pastMixin() %s\n", toChars()); | |
248 while (s && s->isTemplateMixin()) | |
249 s = s->parent; | |
250 return s; | |
251 } | |
252 | |
253 /********************************** | |
254 * Use this instead of toParent() when looking for the | |
255 * 'this' pointer of the enclosing function/class. | |
256 */ | |
257 | |
258 Dsymbol *Dsymbol::toParent2() | |
259 { | |
260 Dsymbol *s = parent; | |
261 while (s && s->isTemplateInstance()) | |
262 s = s->parent; | |
263 return s; | |
264 } | |
265 | |
336 | 266 TemplateInstance *Dsymbol::inTemplateInstance() |
267 { | |
268 for (Dsymbol *parent = this->parent; parent; parent = parent->parent) | |
269 { | |
270 TemplateInstance *ti = parent->isTemplateInstance(); | |
271 if (ti) | |
272 return ti; | |
273 } | |
274 return NULL; | |
275 } | |
159 | 276 |
277 int Dsymbol::isAnonymous() | |
278 { | |
279 return ident ? 0 : 1; | |
280 } | |
281 | |
1587 | 282 /************************************* |
283 * Set scope for future semantic analysis so we can | |
284 * deal better with forward references. | |
285 */ | |
286 | |
287 void Dsymbol::setScope(Scope *sc) | |
288 { | |
289 //printf("Dsymbol::setScope() %p %s\n", this, toChars()); | |
290 if (!sc->nofree) | |
291 sc->setNoFree(); // may need it even after semantic() finishes | |
292 scope = sc; | |
293 } | |
294 | |
295 void Dsymbol::importAll(Scope *sc) | |
296 { | |
297 } | |
298 | |
299 /************************************* | |
300 * Does semantic analysis on the public face of declarations. | |
301 */ | |
302 | |
159 | 303 void Dsymbol::semantic(Scope *sc) |
304 { | |
305 error("%p has no semantic routine", this); | |
306 } | |
307 | |
1587 | 308 /************************************* |
309 * Does semantic analysis on initializers and members of aggregates. | |
310 */ | |
311 | |
159 | 312 void Dsymbol::semantic2(Scope *sc) |
313 { | |
314 // Most Dsymbols have no further semantic analysis needed | |
315 } | |
316 | |
1587 | 317 /************************************* |
318 * Does semantic analysis on function bodies. | |
319 */ | |
320 | |
159 | 321 void Dsymbol::semantic3(Scope *sc) |
322 { | |
323 // Most Dsymbols have no further semantic analysis needed | |
324 } | |
325 | |
1587 | 326 /************************************* |
327 * Look for function inlining possibilities. | |
328 */ | |
329 | |
159 | 330 void Dsymbol::inlineScan() |
331 { | |
1587 | 332 // Most Dsymbols aren't functions |
159 | 333 } |
334 | |
336 | 335 /********************************************* |
336 * Search for ident as member of s. | |
337 * Input: | |
338 * flags: 1 don't find private members | |
339 * 2 don't give error messages | |
340 * 4 return NULL if ambiguous | |
341 * Returns: | |
342 * NULL if not found | |
343 */ | |
344 | |
159 | 345 Dsymbol *Dsymbol::search(Loc loc, Identifier *ident, int flags) |
346 { | |
347 //printf("Dsymbol::search(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars()); | |
348 return NULL; | |
349 } | |
350 | |
1640 | 351 /*************************************************** |
352 * Search for symbol with correct spelling. | |
353 */ | |
354 | |
355 void *symbol_search_fp(void *arg, const char *seed) | |
356 { | |
357 Dsymbol *s = (Dsymbol *)arg; | |
358 Identifier id(seed, 0); | |
359 Module::clearCache(); | |
360 s = s->search(0, &id, 4|2); | |
361 return s; | |
362 } | |
363 | |
364 Dsymbol *Dsymbol::search_correct(Identifier *ident) | |
365 { | |
366 if (global.gag) | |
367 return NULL; // don't do it for speculative compiles; too time consuming | |
368 | |
369 return (Dsymbol *)speller(ident->toChars(), &symbol_search_fp, this, idchars); | |
370 } | |
371 | |
159 | 372 /*************************************** |
373 * Search for identifier id as a member of 'this'. | |
374 * id may be a template instance. | |
375 * Returns: | |
376 * symbol found, NULL if not | |
377 */ | |
378 | |
379 Dsymbol *Dsymbol::searchX(Loc loc, Scope *sc, Identifier *id) | |
380 { | |
381 //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars()); | |
382 Dsymbol *s = toAlias(); | |
383 Dsymbol *sm; | |
384 | |
385 switch (id->dyncast()) | |
386 { | |
387 case DYNCAST_IDENTIFIER: | |
388 sm = s->search(loc, id, 0); | |
389 break; | |
390 | |
391 case DYNCAST_DSYMBOL: | |
392 { // It's a template instance | |
393 //printf("\ttemplate instance id\n"); | |
394 Dsymbol *st = (Dsymbol *)id; | |
395 TemplateInstance *ti = st->isTemplateInstance(); | |
396 id = ti->name; | |
397 sm = s->search(loc, id, 0); | |
398 if (!sm) | |
399 { error("template identifier %s is not a member of %s %s", | |
400 id->toChars(), s->kind(), s->toChars()); | |
401 return NULL; | |
402 } | |
403 sm = sm->toAlias(); | |
404 TemplateDeclaration *td = sm->isTemplateDeclaration(); | |
405 if (!td) | |
406 { | |
407 error("%s is not a template, it is a %s", id->toChars(), sm->kind()); | |
408 return NULL; | |
409 } | |
410 ti->tempdecl = td; | |
1587 | 411 if (!ti->semanticRun) |
159 | 412 ti->semantic(sc); |
413 sm = ti->toAlias(); | |
414 break; | |
415 } | |
416 | |
417 default: | |
418 assert(0); | |
419 } | |
420 return sm; | |
421 } | |
422 | |
423 int Dsymbol::overloadInsert(Dsymbol *s) | |
424 { | |
425 //printf("Dsymbol::overloadInsert('%s')\n", s->toChars()); | |
426 return FALSE; | |
427 } | |
428 | |
429 void Dsymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
430 { | |
431 buf->writestring(toChars()); | |
432 } | |
433 | |
434 unsigned Dsymbol::size(Loc loc) | |
435 { | |
436 error("Dsymbol '%s' has no size\n", toChars()); | |
437 return 0; | |
438 } | |
439 | |
440 int Dsymbol::isforwardRef() | |
441 { | |
442 return FALSE; | |
443 } | |
444 | |
445 AggregateDeclaration *Dsymbol::isThis() | |
446 { | |
447 return NULL; | |
448 } | |
449 | |
450 ClassDeclaration *Dsymbol::isClassMember() // are we a member of a class? | |
451 { | |
452 Dsymbol *parent = toParent(); | |
453 if (parent && parent->isClassDeclaration()) | |
454 return (ClassDeclaration *)parent; | |
455 return NULL; | |
456 } | |
457 | |
458 void Dsymbol::defineRef(Dsymbol *s) | |
459 { | |
460 assert(0); | |
461 } | |
462 | |
463 int Dsymbol::isExport() | |
464 { | |
465 return FALSE; | |
466 } | |
467 | |
468 int Dsymbol::isImportedSymbol() | |
469 { | |
470 return FALSE; | |
471 } | |
472 | |
473 int Dsymbol::isDeprecated() | |
474 { | |
475 return FALSE; | |
476 } | |
477 | |
1587 | 478 #if DMDV2 |
479 int Dsymbol::isOverloadable() | |
480 { | |
481 return 0; | |
482 } | |
483 #endif | |
484 | |
159 | 485 LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()? |
486 { | |
487 return NULL; | |
488 } | |
489 | |
490 AggregateDeclaration *Dsymbol::isMember() // is this a member of an AggregateDeclaration? | |
491 { | |
336 | 492 //printf("Dsymbol::isMember() %s\n", toChars()); |
159 | 493 Dsymbol *parent = toParent(); |
336 | 494 //printf("parent is %s %s\n", parent->kind(), parent->toChars()); |
159 | 495 return parent ? parent->isAggregateDeclaration() : NULL; |
496 } | |
497 | |
498 Type *Dsymbol::getType() | |
499 { | |
500 return NULL; | |
501 } | |
502 | |
503 int Dsymbol::needThis() | |
504 { | |
505 return FALSE; | |
506 } | |
507 | |
508 int Dsymbol::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) | |
509 { | |
510 //printf("Dsymbol::addMember('%s')\n", toChars()); | |
511 //printf("Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd->toChars()); | |
512 //printf("Dsymbol::addMember(this = %p, '%s' sd = %p, sd->symtab = %p)\n", this, toChars(), sd, sd->symtab); | |
513 parent = sd; | |
514 if (!isAnonymous()) // no name, so can't add it to symbol table | |
515 { | |
1587 | 516 if (!sd->symtabInsert(this)) // if name is already defined |
159 | 517 { |
518 Dsymbol *s2; | |
519 | |
520 s2 = sd->symtab->lookup(ident); | |
521 if (!s2->overloadInsert(this)) | |
522 { | |
523 sd->multiplyDefined(0, this, s2); | |
524 } | |
525 } | |
526 if (sd->isAggregateDeclaration() || sd->isEnumDeclaration()) | |
527 { | |
528 if (ident == Id::__sizeof || ident == Id::alignof || ident == Id::mangleof) | |
529 error(".%s property cannot be redefined", ident->toChars()); | |
530 } | |
531 return 1; | |
532 } | |
533 return 0; | |
534 } | |
535 | |
536 void Dsymbol::error(const char *format, ...) | |
537 { | |
538 //printf("Dsymbol::error()\n"); | |
539 if (!global.gag) | |
540 { | |
541 char *p = locToChars(); | |
542 | |
543 if (*p) | |
544 fprintf(stdmsg, "%s: ", p); | |
545 mem.free(p); | |
546 | |
427
f1d37dc5d354
Give errors originating from Dsymbol::error the proper 'Error:' heading.
Christian Kamm <kamm incasoftware de>
parents:
336
diff
changeset
|
547 fprintf(stdmsg, "Error: "); |
159 | 548 if (isAnonymous()) |
549 fprintf(stdmsg, "%s ", kind()); | |
550 else | |
551 fprintf(stdmsg, "%s %s ", kind(), toPrettyChars()); | |
552 | |
553 va_list ap; | |
554 va_start(ap, format); | |
555 vfprintf(stdmsg, format, ap); | |
556 va_end(ap); | |
557 | |
558 fprintf(stdmsg, "\n"); | |
559 fflush(stdmsg); | |
560 } | |
561 global.errors++; | |
562 | |
563 //fatal(); | |
564 } | |
565 | |
566 void Dsymbol::error(Loc loc, const char *format, ...) | |
567 { | |
568 if (!global.gag) | |
569 { | |
570 char *p = loc.toChars(); | |
571 if (!*p) | |
572 p = locToChars(); | |
573 | |
574 if (*p) | |
575 fprintf(stdmsg, "%s: ", p); | |
576 mem.free(p); | |
577 | |
427
f1d37dc5d354
Give errors originating from Dsymbol::error the proper 'Error:' heading.
Christian Kamm <kamm incasoftware de>
parents:
336
diff
changeset
|
578 fprintf(stdmsg, "Error: "); |
159 | 579 fprintf(stdmsg, "%s %s ", kind(), toPrettyChars()); |
580 | |
581 va_list ap; | |
582 va_start(ap, format); | |
583 vfprintf(stdmsg, format, ap); | |
584 va_end(ap); | |
585 | |
586 fprintf(stdmsg, "\n"); | |
587 fflush(stdmsg); | |
588 } | |
589 | |
590 global.errors++; | |
591 | |
592 //fatal(); | |
593 } | |
594 | |
595 void Dsymbol::checkDeprecated(Loc loc, Scope *sc) | |
596 { | |
597 if (!global.params.useDeprecated && isDeprecated()) | |
598 { | |
599 // Don't complain if we're inside a deprecated symbol's scope | |
600 for (Dsymbol *sp = sc->parent; sp; sp = sp->parent) | |
601 { if (sp->isDeprecated()) | |
602 return; | |
603 } | |
604 | |
605 for (; sc; sc = sc->enclosing) | |
606 { | |
607 if (sc->scopesym && sc->scopesym->isDeprecated()) | |
608 return; | |
336 | 609 |
610 // If inside a StorageClassDeclaration that is deprecated | |
611 if (sc->stc & STCdeprecated) | |
612 return; | |
159 | 613 } |
614 | |
615 error(loc, "is deprecated"); | |
616 } | |
617 } | |
618 | |
619 /********************************** | |
620 * Determine which Module a Dsymbol is in. | |
621 */ | |
622 | |
623 Module *Dsymbol::getModule() | |
624 { | |
625 Module *m; | |
626 Dsymbol *s; | |
627 | |
628 //printf("Dsymbol::getModule()\n"); | |
629 s = this; | |
630 while (s) | |
631 { | |
632 //printf("\ts = '%s'\n", s->toChars()); | |
633 m = s->isModule(); | |
634 if (m) | |
635 return m; | |
636 s = s->parent; | |
637 } | |
638 return NULL; | |
639 } | |
640 | |
946
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
641 |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
642 /********************************** |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
643 * Determine which Module a Dsymbol will be compiled in. |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
644 * This may be different from getModule for templates. |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
645 */ |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
646 |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
647 Module *Dsymbol::getCompilationModule() |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
648 { |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
649 Module *m; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
650 TemplateInstance *ti; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
651 Dsymbol *s; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
652 |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
653 //printf("Dsymbol::getModule()\n"); |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
654 s = this; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
655 while (s) |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
656 { |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
657 //printf("\ts = '%s'\n", s->toChars()); |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
658 m = s->isModule(); |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
659 if (m) |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
660 return m; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
661 ti = s->isTemplateInstance(); |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
662 if (ti && ti->tmodule) |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
663 return ti->tmodule; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
664 s = s->parent; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
665 } |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
666 return NULL; |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
667 } |
1714836f2c0b
Mostly rewrite debug info generation in terms of llvm/Analysis/DebugInfo.h.
Christian Kamm <kamm incasoftware de>
parents:
626
diff
changeset
|
668 |
159 | 669 /************************************* |
670 */ | |
671 | |
672 enum PROT Dsymbol::prot() | |
673 { | |
674 return PROTpublic; | |
675 } | |
676 | |
677 /************************************* | |
678 * Do syntax copy of an array of Dsymbol's. | |
679 */ | |
680 | |
681 | |
682 Array *Dsymbol::arraySyntaxCopy(Array *a) | |
683 { | |
684 | |
685 Array *b = NULL; | |
686 if (a) | |
687 { | |
688 b = a->copy(); | |
689 for (int i = 0; i < b->dim; i++) | |
690 { | |
691 Dsymbol *s = (Dsymbol *)b->data[i]; | |
692 | |
693 s = s->syntaxCopy(NULL); | |
694 b->data[i] = (void *)s; | |
695 } | |
696 } | |
697 return b; | |
698 } | |
699 | |
700 | |
701 /**************************************** | |
702 * Add documentation comment to Dsymbol. | |
703 * Ignore NULL comments. | |
704 */ | |
705 | |
706 void Dsymbol::addComment(unsigned char *comment) | |
707 { | |
1587 | 708 //if (comment) |
709 //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); | |
159 | 710 |
711 if (!this->comment) | |
712 this->comment = comment; | |
713 #if 1 | |
714 else if (comment && strcmp((char *)comment, (char *)this->comment)) | |
715 { // Concatenate the two | |
716 this->comment = Lexer::combineComments(this->comment, comment); | |
717 } | |
718 #endif | |
719 } | |
720 | |
1587 | 721 /********************************* OverloadSet ****************************/ |
722 | |
723 #if DMDV2 | |
724 OverloadSet::OverloadSet() | |
725 : Dsymbol() | |
726 { | |
727 } | |
728 | |
729 void OverloadSet::push(Dsymbol *s) | |
730 { | |
731 a.push(s); | |
732 } | |
733 | |
734 const char *OverloadSet::kind() | |
735 { | |
736 return "overloadset"; | |
737 } | |
738 #endif | |
739 | |
159 | 740 |
741 /********************************* ScopeDsymbol ****************************/ | |
742 | |
743 ScopeDsymbol::ScopeDsymbol() | |
744 : Dsymbol() | |
745 { | |
746 members = NULL; | |
747 symtab = NULL; | |
748 imports = NULL; | |
749 prots = NULL; | |
750 } | |
751 | |
752 ScopeDsymbol::ScopeDsymbol(Identifier *id) | |
753 : Dsymbol(id) | |
754 { | |
755 members = NULL; | |
756 symtab = NULL; | |
757 imports = NULL; | |
758 prots = NULL; | |
759 } | |
760 | |
761 Dsymbol *ScopeDsymbol::syntaxCopy(Dsymbol *s) | |
762 { | |
763 //printf("ScopeDsymbol::syntaxCopy('%s')\n", toChars()); | |
764 | |
765 ScopeDsymbol *sd; | |
766 if (s) | |
767 sd = (ScopeDsymbol *)s; | |
768 else | |
769 sd = new ScopeDsymbol(ident); | |
770 sd->members = arraySyntaxCopy(members); | |
771 return sd; | |
772 } | |
773 | |
774 Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) | |
336 | 775 { |
776 //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); | |
1587 | 777 //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; |
159 | 778 |
779 // Look in symbols declared in this module | |
336 | 780 Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; |
626
e83ba4ae4878
Fix import visibility bugs 313 and 314.
Christian Kamm <kamm incasoftware de>
parents:
443
diff
changeset
|
781 |
1358
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
782 // hide the aliases generated by selective or renamed private imports |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
783 if (s && flags & 1) |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
784 if (AliasDeclaration* ad = s->isAliasDeclaration()) |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
785 // may be a private alias to a function that is overloaded. these |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
786 // are sorted out during overload resolution, accept them here |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
787 if (ad->importprot == PROTprivate && !ad->aliassym->isFuncAliasDeclaration()) |
78038e540342
Fix overload resolution issue in dmd bug 313/314 fix.
Christian Kamm <kamm incasoftware de>
parents:
1147
diff
changeset
|
788 s = NULL; |
626
e83ba4ae4878
Fix import visibility bugs 313 and 314.
Christian Kamm <kamm incasoftware de>
parents:
443
diff
changeset
|
789 |
159 | 790 if (s) |
791 { | |
792 //printf("\ts = '%s.%s'\n",toChars(),s->toChars()); | |
793 } | |
794 else if (imports) | |
795 { | |
796 // Look in imported modules | |
336 | 797 for (int i = 0; i < imports->dim; i++) |
159 | 798 { ScopeDsymbol *ss = (ScopeDsymbol *)imports->data[i]; |
799 Dsymbol *s2; | |
800 | |
801 // If private import, don't search it | |
802 if (flags & 1 && prots[i] == PROTprivate) | |
803 continue; | |
804 | |
805 //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); | |
336 | 806 /* Don't find private members if ss is a module |
807 */ | |
159 | 808 s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); |
809 if (!s) | |
810 s = s2; | |
811 else if (s2 && s != s2) | |
812 { | |
813 if (s->toAlias() == s2->toAlias()) | |
814 { | |
336 | 815 /* After following aliases, we found the same symbol, |
816 * so it's not an ambiguity. | |
817 * But if one alias is deprecated, prefer the other. | |
818 */ | |
159 | 819 if (s->isDeprecated()) |
820 s = s2; | |
821 } | |
822 else | |
823 { | |
824 /* Two imports of the same module should be regarded as | |
825 * the same. | |
826 */ | |
827 Import *i1 = s->isImport(); | |
828 Import *i2 = s2->isImport(); | |
829 if (!(i1 && i2 && | |
830 (i1->mod == i2->mod || | |
831 (!i1->parent->isImport() && !i2->parent->isImport() && | |
832 i1->ident->equals(i2->ident)) | |
833 ) | |
834 ) | |
835 ) | |
836 { | |
837 ss->multiplyDefined(loc, s, s2); | |
838 break; | |
839 } | |
840 } | |
841 } | |
842 } | |
843 if (s) | |
844 { | |
845 Declaration *d = s->isDeclaration(); | |
846 if (d && d->protection == PROTprivate && !d->parent->isTemplateMixin()) | |
847 error("%s is private", d->toPrettyChars()); | |
848 } | |
849 } | |
850 return s; | |
851 } | |
852 | |
853 void ScopeDsymbol::importScope(ScopeDsymbol *s, enum PROT protection) | |
854 { | |
855 //printf("%s->ScopeDsymbol::importScope(%s, %d)\n", toChars(), s->toChars(), protection); | |
856 | |
857 // No circular or redundant import's | |
858 if (s != this) | |
859 { | |
860 if (!imports) | |
861 imports = new Array(); | |
862 else | |
863 { | |
864 for (int i = 0; i < imports->dim; i++) | |
865 { ScopeDsymbol *ss; | |
866 | |
867 ss = (ScopeDsymbol *) imports->data[i]; | |
1587 | 868 if (ss == s) // if already imported |
159 | 869 { |
870 if (protection > prots[i]) | |
871 prots[i] = protection; // upgrade access | |
872 return; | |
873 } | |
874 } | |
875 } | |
876 imports->push(s); | |
877 prots = (unsigned char *)mem.realloc(prots, imports->dim * sizeof(prots[0])); | |
878 prots[imports->dim - 1] = protection; | |
879 } | |
880 } | |
881 | |
882 int ScopeDsymbol::isforwardRef() | |
883 { | |
884 return (members == NULL); | |
885 } | |
886 | |
887 void ScopeDsymbol::defineRef(Dsymbol *s) | |
888 { | |
889 ScopeDsymbol *ss; | |
890 | |
891 ss = s->isScopeDsymbol(); | |
892 members = ss->members; | |
893 ss->members = NULL; | |
894 } | |
895 | |
896 void ScopeDsymbol::multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2) | |
897 { | |
898 #if 0 | |
899 printf("ScopeDsymbol::multiplyDefined()\n"); | |
900 printf("s1 = %p, '%s' kind = '%s', parent = %s\n", s1, s1->toChars(), s1->kind(), s1->parent ? s1->parent->toChars() : ""); | |
901 printf("s2 = %p, '%s' kind = '%s', parent = %s\n", s2, s2->toChars(), s2->kind(), s2->parent ? s2->parent->toChars() : ""); | |
902 #endif | |
903 if (loc.filename) | |
904 { ::error(loc, "%s at %s conflicts with %s at %s", | |
905 s1->toPrettyChars(), | |
906 s1->locToChars(), | |
907 s2->toPrettyChars(), | |
908 s2->locToChars()); | |
909 } | |
910 else | |
911 { | |
912 s1->error(loc, "conflicts with %s %s at %s", | |
913 s2->kind(), | |
914 s2->toPrettyChars(), | |
915 s2->locToChars()); | |
916 } | |
917 } | |
918 | |
919 Dsymbol *ScopeDsymbol::nameCollision(Dsymbol *s) | |
920 { | |
921 Dsymbol *sprev; | |
922 | |
923 // Look to see if we are defining a forward referenced symbol | |
924 | |
925 sprev = symtab->lookup(s->ident); | |
926 assert(sprev); | |
927 if (s->equals(sprev)) // if the same symbol | |
928 { | |
929 if (s->isforwardRef()) // if second declaration is a forward reference | |
930 return sprev; | |
931 if (sprev->isforwardRef()) | |
932 { | |
933 sprev->defineRef(s); // copy data from s into sprev | |
934 return sprev; | |
935 } | |
936 } | |
937 multiplyDefined(0, s, sprev); | |
938 return sprev; | |
939 } | |
940 | |
336 | 941 const char *ScopeDsymbol::kind() |
159 | 942 { |
943 return "ScopeDsymbol"; | |
944 } | |
945 | |
1587 | 946 Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s) |
947 { | |
948 return symtab->insert(s); | |
949 } | |
950 | |
951 /*************************************** | |
952 * Determine number of Dsymbols, folding in AttribDeclaration members. | |
953 */ | |
954 | |
955 #if DMDV2 | |
956 size_t ScopeDsymbol::dim(Array *members) | |
957 { | |
958 size_t n = 0; | |
959 if (members) | |
960 { | |
961 for (size_t i = 0; i < members->dim; i++) | |
962 { Dsymbol *s = (Dsymbol *)members->data[i]; | |
963 AttribDeclaration *a = s->isAttribDeclaration(); | |
964 | |
965 if (a) | |
966 { | |
967 n += dim(a->decl); | |
968 } | |
969 else | |
970 n++; | |
971 } | |
972 } | |
973 return n; | |
974 } | |
975 #endif | |
976 | |
977 /*************************************** | |
978 * Get nth Dsymbol, folding in AttribDeclaration members. | |
979 * Returns: | |
980 * Dsymbol* nth Dsymbol | |
981 * NULL not found, *pn gets incremented by the number | |
982 * of Dsymbols | |
983 */ | |
984 | |
985 #if DMDV2 | |
986 Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) | |
987 { | |
988 if (!members) | |
989 return NULL; | |
990 | |
991 size_t n = 0; | |
992 for (size_t i = 0; i < members->dim; i++) | |
993 { Dsymbol *s = (Dsymbol *)members->data[i]; | |
994 AttribDeclaration *a = s->isAttribDeclaration(); | |
995 | |
996 if (a) | |
997 { | |
998 s = getNth(a->decl, nth - n, &n); | |
999 if (s) | |
1000 return s; | |
1001 } | |
1002 else if (n == nth) | |
1003 return s; | |
1004 else | |
1005 n++; | |
1006 } | |
1007 | |
1008 if (pn) | |
1009 *pn += n; | |
1010 return NULL; | |
1011 } | |
1012 #endif | |
159 | 1013 |
1014 /******************************************* | |
1015 * Look for member of the form: | |
1016 * const(MemberInfo)[] getMembers(string); | |
1017 * Returns NULL if not found | |
1018 */ | |
1019 | |
336 | 1020 #if DMDV2 |
159 | 1021 FuncDeclaration *ScopeDsymbol::findGetMembers() |
1022 { | |
1023 Dsymbol *s = search_function(this, Id::getmembers); | |
1024 FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL; | |
1025 | |
1026 #if 0 // Finish | |
1027 static TypeFunction *tfgetmembers; | |
1028 | |
1029 if (!tfgetmembers) | |
1030 { | |
1031 Scope sc; | |
1607
207a8a438dea
Merge DMD r253: refactor: Argument => Parameter
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1032 Parameters *arguments = new Parameters; |
207a8a438dea
Merge DMD r253: refactor: Argument => Parameter
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1033 Parameters *arg = new Parameter(STCin, Type::tchar->constOf()->arrayOf(), NULL, NULL); |
159 | 1034 arguments->push(arg); |
1035 | |
1036 Type *tret = NULL; | |
1037 tfgetmembers = new TypeFunction(arguments, tret, 0, LINKd); | |
1038 tfgetmembers = (TypeFunction *)tfgetmembers->semantic(0, &sc); | |
1039 } | |
1040 if (fdx) | |
1041 fdx = fdx->overloadExactMatch(tfgetmembers); | |
1042 #endif | |
1043 if (fdx && fdx->isVirtual()) | |
1044 fdx = NULL; | |
1045 | |
1046 return fdx; | |
1047 } | |
1048 #endif | |
1049 | |
1050 | |
1051 /****************************** WithScopeSymbol ******************************/ | |
1052 | |
1053 WithScopeSymbol::WithScopeSymbol(WithStatement *withstate) | |
1054 : ScopeDsymbol() | |
1055 { | |
1056 this->withstate = withstate; | |
1057 } | |
1058 | |
1059 Dsymbol *WithScopeSymbol::search(Loc loc, Identifier *ident, int flags) | |
1060 { | |
1061 // Acts as proxy to the with class declaration | |
1062 return withstate->exp->type->toDsymbol(NULL)->search(loc, ident, 0); | |
1063 } | |
1064 | |
1065 /****************************** ArrayScopeSymbol ******************************/ | |
1066 | |
1067 ArrayScopeSymbol::ArrayScopeSymbol(Expression *e) | |
1068 : ScopeDsymbol() | |
1069 { | |
1070 assert(e->op == TOKindex || e->op == TOKslice); | |
1071 exp = e; | |
1072 type = NULL; | |
1073 td = NULL; | |
1074 } | |
1075 | |
1076 ArrayScopeSymbol::ArrayScopeSymbol(TypeTuple *t) | |
1077 : ScopeDsymbol() | |
1078 { | |
1079 exp = NULL; | |
1080 type = t; | |
1081 td = NULL; | |
1082 } | |
1083 | |
1084 ArrayScopeSymbol::ArrayScopeSymbol(TupleDeclaration *s) | |
1085 : ScopeDsymbol() | |
1086 { | |
1087 exp = NULL; | |
1088 type = NULL; | |
1089 td = s; | |
1090 } | |
1091 | |
1092 Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags) | |
1093 { | |
1094 //printf("ArrayScopeSymbol::search('%s', flags = %d)\n", ident->toChars(), flags); | |
1095 if (ident == Id::length || ident == Id::dollar) | |
1096 { VarDeclaration **pvar; | |
1097 Expression *ce; | |
1098 | |
1099 L1: | |
1100 | |
1101 if (td) | |
1587 | 1102 { /* $ gives the number of elements in the tuple |
1103 */ | |
159 | 1104 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
1105 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); | |
1106 v->init = new ExpInitializer(0, e); | |
1107 v->storage_class |= STCconst; | |
1108 return v; | |
1109 } | |
1110 | |
1111 if (type) | |
1587 | 1112 { /* $ gives the number of type entries in the type tuple |
1113 */ | |
159 | 1114 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
1115 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); | |
1116 v->init = new ExpInitializer(0, e); | |
1117 v->storage_class |= STCconst; | |
1118 return v; | |
1119 } | |
1120 | |
1121 if (exp->op == TOKindex) | |
1587 | 1122 { /* array[index] where index is some function of $ |
1123 */ | |
159 | 1124 IndexExp *ie = (IndexExp *)exp; |
1125 | |
1126 pvar = &ie->lengthVar; | |
1127 ce = ie->e1; | |
1128 } | |
1129 else if (exp->op == TOKslice) | |
1587 | 1130 { /* array[lwr .. upr] where lwr or upr is some function of $ |
1131 */ | |
159 | 1132 SliceExp *se = (SliceExp *)exp; |
1133 | |
1134 pvar = &se->lengthVar; | |
1135 ce = se->e1; | |
1136 } | |
1137 else | |
1587 | 1138 /* Didn't find $, look in enclosing scope(s). |
1139 */ | |
159 | 1140 return NULL; |
1141 | |
1587 | 1142 /* If we are indexing into an array that is really a type |
1143 * tuple, rewrite this as an index into a type tuple and | |
1144 * try again. | |
1145 */ | |
159 | 1146 if (ce->op == TOKtype) |
1147 { | |
1148 Type *t = ((TypeExp *)ce)->type; | |
1149 if (t->ty == Ttuple) | |
1150 { type = (TypeTuple *)t; | |
1151 goto L1; | |
1152 } | |
1153 } | |
1154 | |
1587 | 1155 /* *pvar is lazily initialized, so if we refer to $ |
1156 * multiple times, it gets set only once. | |
1157 */ | |
1158 if (!*pvar) // if not already initialized | |
1159 { /* Create variable v and set it to the value of $, | |
1160 * which will be a constant. | |
1161 */ | |
159 | 1162 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
1163 | |
1164 if (ce->op == TOKstring) | |
1165 { /* It is for a string literal, so the | |
1166 * length will be a const. | |
1167 */ | |
1168 Expression *e = new IntegerExp(0, ((StringExp *)ce)->len, Type::tsize_t); | |
1169 v->init = new ExpInitializer(0, e); | |
1170 v->storage_class |= STCconst; | |
1171 } | |
1172 else if (ce->op == TOKarrayliteral) | |
1173 { /* It is for an array literal, so the | |
1174 * length will be a const. | |
1175 */ | |
1176 Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); | |
1177 v->init = new ExpInitializer(0, e); | |
1178 v->storage_class |= STCconst; | |
1179 } | |
1180 else if (ce->op == TOKtuple) | |
1181 { /* It is for an expression tuple, so the | |
1182 * length will be a const. | |
1183 */ | |
1184 Expression *e = new IntegerExp(0, ((TupleExp *)ce)->exps->dim, Type::tsize_t); | |
1185 v->init = new ExpInitializer(0, e); | |
1186 v->storage_class |= STCconst; | |
1187 } | |
1188 *pvar = v; | |
1189 } | |
1190 return (*pvar); | |
1191 } | |
1192 return NULL; | |
1193 } | |
1194 | |
1195 | |
1196 /****************************** DsymbolTable ******************************/ | |
1197 | |
1198 DsymbolTable::DsymbolTable() | |
1199 { | |
1200 tab = new StringTable; | |
1201 } | |
1202 | |
1203 DsymbolTable::~DsymbolTable() | |
1204 { | |
1205 delete tab; | |
1206 } | |
1207 | |
1208 Dsymbol *DsymbolTable::lookup(Identifier *ident) | |
1587 | 1209 { |
159 | 1210 #ifdef DEBUG |
1211 assert(ident); | |
1212 assert(tab); | |
1213 #endif | |
1587 | 1214 StringValue *sv = tab->lookup((char*)ident->string, ident->len); |
159 | 1215 return (Dsymbol *)(sv ? sv->ptrvalue : NULL); |
1216 } | |
1217 | |
1218 Dsymbol *DsymbolTable::insert(Dsymbol *s) | |
1219 { StringValue *sv; | |
1220 Identifier *ident; | |
1221 | |
1222 //printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars()); | |
1223 ident = s->ident; | |
1224 #ifdef DEBUG | |
1225 assert(ident); | |
1226 assert(tab); | |
1227 #endif | |
1228 sv = tab->insert(ident->toChars(), ident->len); | |
1229 if (!sv) | |
1230 return NULL; // already in table | |
1231 sv->ptrvalue = s; | |
1232 return s; | |
1233 } | |
1234 | |
1235 Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s) | |
1236 { StringValue *sv; | |
1237 | |
1238 //printf("DsymbolTable::insert()\n"); | |
1239 sv = tab->insert(ident->toChars(), ident->len); | |
1240 if (!sv) | |
1241 return NULL; // already in table | |
1242 sv->ptrvalue = s; | |
1243 return s; | |
1244 } | |
1245 | |
1246 Dsymbol *DsymbolTable::update(Dsymbol *s) | |
1247 { StringValue *sv; | |
1248 Identifier *ident; | |
1249 | |
1250 ident = s->ident; | |
1251 sv = tab->update(ident->toChars(), ident->len); | |
1252 sv->ptrvalue = s; | |
1253 return s; | |
1254 } | |
1255 | |
1256 | |
1257 | |
1258 |