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