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