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