Mercurial > projects > ldc
annotate dmd/declaration.c @ 715:30b42a283c8e
Removed TypeOpaque from DMD.
Changed runtime functions taking opaque[] to void[].
Implemented proper type painting, to avoid "resizing" array casts in runtime calls that previously took opaque[].
Implemented dynamic arrays as first class types, this implements proper ABI for these types on x86.
Added dwarf region end after call to assert function, fixes some problems with llvm not allowing this to be missing.
Reverted change to WithStatement from rev [704] it breaks MiniD, mini/with2.d needs to be fixed some other way...
Fixed tango bug 1339 in runtime, problem with _adReverseChar on invalid UTF-8.
Disabled .bc generation in the compiler runtime part, genobj.d triggers some llvm bug when using debug info. the .o seems to work fine.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 14:55:33 +0200 |
parents | 50383e476c7e |
children | 041c1596d217 |
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 <assert.h> | |
13 | |
14 #include "init.h" | |
15 #include "declaration.h" | |
16 #include "attrib.h" | |
17 #include "mtype.h" | |
18 #include "template.h" | |
19 #include "scope.h" | |
20 #include "aggregate.h" | |
21 #include "module.h" | |
22 #include "id.h" | |
23 #include "expression.h" | |
24 #include "hdrgen.h" | |
25 | |
26 /********************************* Declaration ****************************/ | |
27 | |
28 Declaration::Declaration(Identifier *id) | |
29 : Dsymbol(id) | |
30 { | |
31 type = NULL; | |
32 originalType = NULL; | |
33 storage_class = STCundefined; | |
34 protection = PROTundefined; | |
35 linkage = LINKdefault; | |
36 } | |
37 | |
38 void Declaration::semantic(Scope *sc) | |
39 { | |
40 } | |
41 | |
336 | 42 const char *Declaration::kind() |
159 | 43 { |
44 return "declaration"; | |
45 } | |
46 | |
47 unsigned Declaration::size(Loc loc) | |
48 { | |
49 assert(type); | |
50 return type->size(); | |
51 } | |
52 | |
53 int Declaration::isStaticConstructor() | |
54 { | |
55 return FALSE; | |
56 } | |
57 | |
58 int Declaration::isStaticDestructor() | |
59 { | |
60 return FALSE; | |
61 } | |
62 | |
63 int Declaration::isDelete() | |
64 { | |
65 return FALSE; | |
66 } | |
67 | |
68 int Declaration::isDataseg() | |
69 { | |
70 return FALSE; | |
71 } | |
72 | |
73 int Declaration::isCodeseg() | |
74 { | |
75 return FALSE; | |
76 } | |
77 | |
78 enum PROT Declaration::prot() | |
79 { | |
80 return protection; | |
81 } | |
82 | |
336 | 83 /************************************* |
84 * Check to see if declaration can be modified in this context (sc). | |
85 * Issue error if not. | |
86 */ | |
87 | |
88 #if DMDV2 | |
89 void Declaration::checkModify(Loc loc, Scope *sc, Type *t) | |
90 { | |
91 if (sc->incontract && isParameter()) | |
92 error(loc, "cannot modify parameter '%s' in contract", toChars()); | |
93 | |
94 if (isCtorinit()) | |
95 { // It's only modifiable if inside the right constructor | |
96 Dsymbol *s = sc->func; | |
97 while (1) | |
98 { | |
99 FuncDeclaration *fd = NULL; | |
100 if (s) | |
101 fd = s->isFuncDeclaration(); | |
102 if (fd && | |
103 ((fd->isCtorDeclaration() && storage_class & STCfield) || | |
104 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) && | |
105 fd->toParent() == toParent() | |
106 ) | |
107 { | |
108 VarDeclaration *v = isVarDeclaration(); | |
109 assert(v); | |
110 v->ctorinit = 1; | |
111 //printf("setting ctorinit\n"); | |
112 } | |
113 else | |
114 { | |
115 if (s) | |
116 { s = s->toParent2(); | |
117 continue; | |
118 } | |
119 else | |
120 { | |
121 const char *p = isStatic() ? "static " : ""; | |
122 error(loc, "can only initialize %sconst %s inside %sconstructor", | |
123 p, toChars(), p); | |
124 } | |
125 } | |
126 break; | |
127 } | |
128 } | |
129 else | |
130 { | |
131 VarDeclaration *v = isVarDeclaration(); | |
132 if (v && v->canassign == 0) | |
133 { | |
134 char *p = NULL; | |
135 if (isConst()) | |
136 p = "const"; | |
137 else if (isInvariant()) | |
138 p = "invariant"; | |
139 else if (storage_class & STCmanifest) | |
140 p = "manifest constant"; | |
141 else if (!t->isAssignable()) | |
142 p = "struct with immutable members"; | |
143 if (p) | |
144 { error(loc, "cannot modify %s", p); | |
145 halt(); | |
146 } | |
147 } | |
148 } | |
149 } | |
150 #endif | |
151 | |
152 | |
159 | 153 /********************************* TupleDeclaration ****************************/ |
154 | |
155 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) | |
156 : Declaration(id) | |
157 { | |
158 this->type = NULL; | |
159 this->objects = objects; | |
160 this->isexp = 0; | |
161 this->tupletype = NULL; | |
162 } | |
163 | |
164 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) | |
165 { | |
166 assert(0); | |
167 return NULL; | |
168 } | |
169 | |
336 | 170 const char *TupleDeclaration::kind() |
159 | 171 { |
172 return "tuple"; | |
173 } | |
174 | |
175 Type *TupleDeclaration::getType() | |
176 { | |
177 /* If this tuple represents a type, return that type | |
178 */ | |
179 | |
180 //printf("TupleDeclaration::getType() %s\n", toChars()); | |
181 if (isexp) | |
182 return NULL; | |
183 if (!tupletype) | |
184 { | |
185 /* It's only a type tuple if all the Object's are types | |
186 */ | |
187 for (size_t i = 0; i < objects->dim; i++) | |
188 { Object *o = (Object *)objects->data[i]; | |
189 | |
190 if (o->dyncast() != DYNCAST_TYPE) | |
191 { | |
192 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); | |
193 return NULL; | |
194 } | |
195 } | |
196 | |
197 /* We know it's a type tuple, so build the TypeTuple | |
198 */ | |
199 Arguments *args = new Arguments(); | |
200 args->setDim(objects->dim); | |
201 OutBuffer buf; | |
202 for (size_t i = 0; i < objects->dim; i++) | |
203 { Type *t = (Type *)objects->data[i]; | |
204 | |
205 //printf("type = %s\n", t->toChars()); | |
206 #if 0 | |
207 buf.printf("_%s_%d", ident->toChars(), i); | |
208 char *name = (char *)buf.extractData(); | |
209 Identifier *id = new Identifier(name, TOKidentifier); | |
210 Argument *arg = new Argument(STCin, t, id, NULL); | |
211 #else | |
212 Argument *arg = new Argument(STCin, t, NULL, NULL); | |
213 #endif | |
214 args->data[i] = (void *)arg; | |
215 } | |
216 | |
217 tupletype = new TypeTuple(args); | |
218 } | |
219 | |
220 return tupletype; | |
221 } | |
222 | |
223 int TupleDeclaration::needThis() | |
224 { | |
225 //printf("TupleDeclaration::needThis(%s)\n", toChars()); | |
226 for (size_t i = 0; i < objects->dim; i++) | |
227 { Object *o = (Object *)objects->data[i]; | |
228 if (o->dyncast() == DYNCAST_EXPRESSION) | |
229 { Expression *e = (Expression *)o; | |
230 if (e->op == TOKdsymbol) | |
231 { DsymbolExp *ve = (DsymbolExp *)e; | |
232 Declaration *d = ve->s->isDeclaration(); | |
233 if (d && d->needThis()) | |
234 { | |
235 return 1; | |
236 } | |
237 } | |
238 } | |
239 } | |
240 return 0; | |
241 } | |
242 | |
243 /********************************* TypedefDeclaration ****************************/ | |
244 | |
245 TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init) | |
246 : Declaration(id) | |
247 { | |
248 this->type = new TypeTypedef(this); | |
249 this->basetype = basetype->toBasetype(); | |
250 this->init = init; | |
251 #ifdef _DH | |
252 this->htype = NULL; | |
253 this->hbasetype = NULL; | |
254 #endif | |
255 this->sem = 0; | |
256 this->inuse = 0; | |
257 this->loc = loc; | |
258 this->sinit = NULL; | |
259 } | |
260 | |
261 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) | |
262 { | |
263 Type *basetype = this->basetype->syntaxCopy(); | |
264 | |
265 Initializer *init = NULL; | |
266 if (this->init) | |
267 init = this->init->syntaxCopy(); | |
268 | |
269 assert(!s); | |
270 TypedefDeclaration *st; | |
271 st = new TypedefDeclaration(loc, ident, basetype, init); | |
272 #ifdef _DH | |
273 // Syntax copy for header file | |
274 if (!htype) // Don't overwrite original | |
275 { if (type) // Make copy for both old and new instances | |
276 { htype = type->syntaxCopy(); | |
277 st->htype = type->syntaxCopy(); | |
278 } | |
279 } | |
280 else // Make copy of original for new instance | |
281 st->htype = htype->syntaxCopy(); | |
282 if (!hbasetype) | |
283 { if (basetype) | |
284 { hbasetype = basetype->syntaxCopy(); | |
285 st->hbasetype = basetype->syntaxCopy(); | |
286 } | |
287 } | |
288 else | |
289 st->hbasetype = hbasetype->syntaxCopy(); | |
290 #endif | |
291 return st; | |
292 } | |
293 | |
294 void TypedefDeclaration::semantic(Scope *sc) | |
295 { | |
296 //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem); | |
297 if (sem == 0) | |
298 { sem = 1; | |
299 basetype = basetype->semantic(loc, sc); | |
300 sem = 2; | |
301 type = type->semantic(loc, sc); | |
302 if (sc->parent->isFuncDeclaration() && init) | |
303 semantic2(sc); | |
336 | 304 storage_class |= sc->stc & STCdeprecated; |
159 | 305 } |
306 else if (sem == 1) | |
307 { | |
308 error("circular definition"); | |
309 } | |
310 } | |
311 | |
312 void TypedefDeclaration::semantic2(Scope *sc) | |
313 { | |
314 //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); | |
315 if (sem == 2) | |
316 { sem = 3; | |
317 if (init) | |
318 { | |
319 init = init->semantic(sc, basetype); | |
320 | |
321 ExpInitializer *ie = init->isExpInitializer(); | |
322 if (ie) | |
323 { | |
324 if (ie->exp->type == basetype) | |
325 ie->exp->type = type; | |
326 } | |
327 } | |
328 } | |
329 } | |
330 | |
336 | 331 const char *TypedefDeclaration::kind() |
159 | 332 { |
333 return "typedef"; | |
334 } | |
335 | |
336 Type *TypedefDeclaration::getType() | |
337 { | |
338 return type; | |
339 } | |
340 | |
341 void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
342 { | |
343 buf->writestring("typedef "); | |
344 basetype->toCBuffer(buf, ident, hgs); | |
345 if (init) | |
346 { | |
347 buf->writestring(" = "); | |
348 init->toCBuffer(buf, hgs); | |
349 } | |
350 buf->writeByte(';'); | |
351 buf->writenl(); | |
352 } | |
353 | |
354 /********************************* AliasDeclaration ****************************/ | |
355 | |
356 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) | |
357 : Declaration(id) | |
358 { | |
359 //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type); | |
360 //printf("type = '%s'\n", type->toChars()); | |
361 this->loc = loc; | |
362 this->type = type; | |
363 this->aliassym = NULL; | |
364 #ifdef _DH | |
365 this->htype = NULL; | |
366 this->haliassym = NULL; | |
367 #endif | |
368 this->overnext = NULL; | |
369 this->inSemantic = 0; | |
370 assert(type); | |
371 } | |
372 | |
373 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) | |
374 : Declaration(id) | |
375 { | |
376 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); | |
377 assert(s != this); | |
378 this->loc = loc; | |
379 this->type = NULL; | |
380 this->aliassym = s; | |
381 #ifdef _DH | |
382 this->htype = NULL; | |
383 this->haliassym = NULL; | |
384 #endif | |
385 this->overnext = NULL; | |
386 this->inSemantic = 0; | |
387 assert(s); | |
388 } | |
389 | |
390 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) | |
391 { | |
336 | 392 //printf("AliasDeclaration::syntaxCopy()\n"); |
159 | 393 assert(!s); |
394 AliasDeclaration *sa; | |
395 if (type) | |
396 sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); | |
397 else | |
398 sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL)); | |
399 #ifdef _DH | |
400 // Syntax copy for header file | |
401 if (!htype) // Don't overwrite original | |
402 { if (type) // Make copy for both old and new instances | |
403 { htype = type->syntaxCopy(); | |
404 sa->htype = type->syntaxCopy(); | |
405 } | |
406 } | |
407 else // Make copy of original for new instance | |
408 sa->htype = htype->syntaxCopy(); | |
409 if (!haliassym) | |
410 { if (aliassym) | |
411 { haliassym = aliassym->syntaxCopy(s); | |
412 sa->haliassym = aliassym->syntaxCopy(s); | |
413 } | |
414 } | |
415 else | |
416 sa->haliassym = haliassym->syntaxCopy(s); | |
417 #endif | |
418 return sa; | |
419 } | |
420 | |
421 void AliasDeclaration::semantic(Scope *sc) | |
422 { | |
423 //printf("AliasDeclaration::semantic() %s\n", toChars()); | |
424 if (aliassym) | |
425 { | |
426 if (aliassym->isTemplateInstance()) | |
427 aliassym->semantic(sc); | |
428 return; | |
429 } | |
430 this->inSemantic = 1; | |
431 | |
432 if (storage_class & STCconst) | |
433 error("cannot be const"); | |
434 | |
435 storage_class |= sc->stc & STCdeprecated; | |
436 | |
437 // Given: | |
438 // alias foo.bar.abc def; | |
439 // it is not knowable from the syntax whether this is an alias | |
440 // for a type or an alias for a symbol. It is up to the semantic() | |
441 // pass to distinguish. | |
442 // If it is a type, then type is set and getType() will return that | |
443 // type. If it is a symbol, then aliassym is set and type is NULL - | |
444 // toAlias() will return aliasssym. | |
445 | |
446 Dsymbol *s; | |
447 Type *t; | |
448 Expression *e; | |
449 | |
450 /* This section is needed because resolve() will: | |
451 * const x = 3; | |
452 * alias x y; | |
453 * try to alias y to 3. | |
454 */ | |
455 s = type->toDsymbol(sc); | |
456 if (s) | |
457 goto L2; // it's a symbolic alias | |
458 | |
459 //printf("alias type is %s\n", type->toChars()); | |
460 type->resolve(loc, sc, &e, &t, &s); | |
461 if (s) | |
462 { | |
463 goto L2; | |
464 } | |
465 else if (e) | |
466 { | |
467 // Try to convert Expression to Dsymbol | |
468 if (e->op == TOKvar) | |
469 { s = ((VarExp *)e)->var; | |
470 goto L2; | |
471 } | |
472 else if (e->op == TOKfunction) | |
473 { s = ((FuncExp *)e)->fd; | |
474 goto L2; | |
475 } | |
476 else | |
477 { error("cannot alias an expression %s", e->toChars()); | |
478 t = e->type; | |
479 } | |
480 } | |
481 else if (t) | |
482 type = t; | |
483 if (overnext) | |
484 ScopeDsymbol::multiplyDefined(0, this, overnext); | |
485 this->inSemantic = 0; | |
486 return; | |
487 | |
488 L2: | |
489 //printf("alias is a symbol %s %s\n", s->kind(), s->toChars()); | |
490 type = NULL; | |
491 VarDeclaration *v = s->isVarDeclaration(); | |
492 if (v && v->linkage == LINKdefault) | |
493 { | |
494 error("forward reference of %s", v->toChars()); | |
495 s = NULL; | |
496 } | |
497 else | |
498 { | |
499 FuncDeclaration *f = s->toAlias()->isFuncDeclaration(); | |
500 if (f) | |
501 { | |
502 if (overnext) | |
503 { | |
504 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); | |
505 if (!fa->overloadInsert(overnext)) | |
506 ScopeDsymbol::multiplyDefined(0, f, overnext); | |
507 overnext = NULL; | |
508 s = fa; | |
509 s->parent = sc->parent; | |
510 } | |
511 } | |
512 if (overnext) | |
513 ScopeDsymbol::multiplyDefined(0, s, overnext); | |
514 if (s == this) | |
515 { | |
516 assert(global.errors); | |
517 s = NULL; | |
518 } | |
519 } | |
520 aliassym = s; | |
521 this->inSemantic = 0; | |
522 } | |
523 | |
524 int AliasDeclaration::overloadInsert(Dsymbol *s) | |
525 { | |
526 /* Don't know yet what the aliased symbol is, so assume it can | |
527 * be overloaded and check later for correctness. | |
528 */ | |
529 | |
530 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); | |
531 if (overnext == NULL) | |
532 { overnext = s; | |
533 return TRUE; | |
534 } | |
535 else | |
536 { | |
537 return overnext->overloadInsert(s); | |
538 } | |
539 } | |
540 | |
336 | 541 const char *AliasDeclaration::kind() |
159 | 542 { |
543 return "alias"; | |
544 } | |
545 | |
546 Type *AliasDeclaration::getType() | |
547 { | |
548 return type; | |
549 } | |
550 | |
551 Dsymbol *AliasDeclaration::toAlias() | |
552 { | |
553 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); | |
554 assert(this != aliassym); | |
555 //static int count; if (++count == 10) *(char*)0=0; | |
556 if (inSemantic) | |
557 { error("recursive alias declaration"); | |
558 // return this; | |
559 } | |
560 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | |
561 return s; | |
562 } | |
563 | |
564 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
565 { | |
566 buf->writestring("alias "); | |
567 #if 0 && _DH | |
568 if (hgs->hdrgen) | |
569 { | |
570 if (haliassym) | |
571 { | |
572 haliassym->toCBuffer(buf, hgs); | |
573 buf->writeByte(' '); | |
574 buf->writestring(ident->toChars()); | |
575 } | |
576 else | |
577 htype->toCBuffer(buf, ident, hgs); | |
578 } | |
579 else | |
580 #endif | |
581 { | |
582 if (aliassym) | |
583 { | |
584 aliassym->toCBuffer(buf, hgs); | |
585 buf->writeByte(' '); | |
586 buf->writestring(ident->toChars()); | |
587 } | |
588 else | |
589 type->toCBuffer(buf, ident, hgs); | |
590 } | |
591 buf->writeByte(';'); | |
592 buf->writenl(); | |
593 } | |
594 | |
595 /********************************* VarDeclaration ****************************/ | |
596 | |
597 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) | |
598 : Declaration(id) | |
599 { | |
600 //printf("VarDeclaration('%s')\n", id->toChars()); | |
601 #ifdef DEBUG | |
602 if (!type && !init) | |
603 { printf("VarDeclaration('%s')\n", id->toChars()); | |
604 //*(char*)0=0; | |
605 } | |
606 #endif | |
607 assert(type || init); | |
608 this->type = type; | |
609 this->init = init; | |
610 #ifdef _DH | |
611 this->htype = NULL; | |
612 this->hinit = NULL; | |
613 #endif | |
614 this->loc = loc; | |
615 offset = 0; | |
616 noauto = 0; | |
617 nestedref = 0; | |
618 inuse = 0; | |
619 ctorinit = 0; | |
620 aliassym = NULL; | |
621 onstack = 0; | |
622 canassign = 0; | |
623 value = NULL; | |
624 } | |
625 | |
626 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) | |
627 { | |
628 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); | |
629 | |
630 VarDeclaration *sv; | |
631 if (s) | |
632 { sv = (VarDeclaration *)s; | |
633 } | |
634 else | |
635 { | |
636 Initializer *init = NULL; | |
637 if (this->init) | |
638 { init = this->init->syntaxCopy(); | |
639 //init->isExpInitializer()->exp->print(); | |
640 //init->isExpInitializer()->exp->dump(0); | |
641 } | |
642 | |
643 sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); | |
644 sv->storage_class = storage_class; | |
645 } | |
646 #ifdef _DH | |
647 // Syntax copy for header file | |
648 if (!htype) // Don't overwrite original | |
649 { if (type) // Make copy for both old and new instances | |
650 { htype = type->syntaxCopy(); | |
651 sv->htype = type->syntaxCopy(); | |
652 } | |
653 } | |
654 else // Make copy of original for new instance | |
655 sv->htype = htype->syntaxCopy(); | |
656 if (!hinit) | |
657 { if (init) | |
658 { hinit = init->syntaxCopy(); | |
659 sv->hinit = init->syntaxCopy(); | |
660 } | |
661 } | |
662 else | |
663 sv->hinit = hinit->syntaxCopy(); | |
664 #endif | |
665 return sv; | |
666 } | |
667 | |
668 void VarDeclaration::semantic(Scope *sc) | |
669 { | |
670 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); | |
336 | 671 //printf(" type = %s\n", type ? type->toChars() : "null"); |
672 //printf(" stc = x%x\n", sc->stc); | |
673 //printf(" storage_class = x%x\n", storage_class); | |
159 | 674 //printf("linkage = %d\n", sc->linkage); |
675 //if (strcmp(toChars(), "mul") == 0) halt(); | |
676 | |
677 storage_class |= sc->stc; | |
678 if (storage_class & STCextern && init) | |
679 error("extern symbols cannot have initializers"); | |
680 | |
681 /* If auto type inference, do the inference | |
682 */ | |
683 int inferred = 0; | |
684 if (!type) | |
685 { inuse++; | |
686 type = init->inferType(sc); | |
687 inuse--; | |
688 inferred = 1; | |
689 | |
690 /* This is a kludge to support the existing syntax for RAII | |
691 * declarations. | |
692 */ | |
693 storage_class &= ~STCauto; | |
694 originalType = type; | |
695 } | |
696 else | |
697 { if (!originalType) | |
698 originalType = type; | |
699 type = type->semantic(loc, sc); | |
700 } | |
336 | 701 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); |
159 | 702 |
703 type->checkDeprecated(loc, sc); | |
704 linkage = sc->linkage; | |
705 this->parent = sc->parent; | |
706 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); | |
707 protection = sc->protection; | |
708 //printf("sc->stc = %x\n", sc->stc); | |
336 | 709 //printf("storage_class = x%x\n", storage_class); |
159 | 710 |
711 Dsymbol *parent = toParent(); | |
712 FuncDeclaration *fd = parent->isFuncDeclaration(); | |
713 | |
714 Type *tb = type->toBasetype(); | |
715 if (tb->ty == Tvoid && !(storage_class & STClazy)) | |
716 { error("voids have no value"); | |
717 type = Type::terror; | |
718 tb = type; | |
719 } | |
720 if (tb->ty == Tfunction) | |
721 { error("cannot be declared to be a function"); | |
722 type = Type::terror; | |
723 tb = type; | |
724 } | |
725 if (tb->ty == Tstruct) | |
726 { TypeStruct *ts = (TypeStruct *)tb; | |
727 | |
728 if (!ts->sym->members) | |
729 { | |
730 error("no definition of struct %s", ts->toChars()); | |
731 } | |
732 } | |
733 | |
734 if (tb->ty == Ttuple) | |
735 { /* Instead, declare variables for each of the tuple elements | |
736 * and add those. | |
737 */ | |
738 TypeTuple *tt = (TypeTuple *)tb; | |
739 size_t nelems = Argument::dim(tt->arguments); | |
740 Objects *exps = new Objects(); | |
741 exps->setDim(nelems); | |
742 Expression *ie = init ? init->toExpression() : NULL; | |
743 | |
744 for (size_t i = 0; i < nelems; i++) | |
745 { Argument *arg = Argument::getNth(tt->arguments, i); | |
746 | |
747 OutBuffer buf; | |
305
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
245
diff
changeset
|
748 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); |
159 | 749 buf.writeByte(0); |
750 char *name = (char *)buf.extractData(); | |
751 Identifier *id = new Identifier(name, TOKidentifier); | |
752 | |
753 Expression *einit = ie; | |
754 if (ie && ie->op == TOKtuple) | |
755 { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; | |
756 } | |
757 Initializer *ti = init; | |
758 if (einit) | |
759 { ti = new ExpInitializer(einit->loc, einit); | |
760 } | |
761 | |
762 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); | |
763 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); | |
764 v->semantic(sc); | |
765 | |
766 if (sc->scopesym) | |
767 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); | |
768 if (sc->scopesym->members) | |
769 sc->scopesym->members->push(v); | |
770 } | |
771 | |
772 Expression *e = new DsymbolExp(loc, v); | |
773 exps->data[i] = e; | |
774 } | |
775 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); | |
776 v2->isexp = 1; | |
777 aliassym = v2; | |
778 return; | |
779 } | |
780 | |
781 if (storage_class & STCconst && !init && !fd) | |
782 // Initialize by constructor only | |
783 storage_class = (storage_class & ~STCconst) | STCctorinit; | |
784 | |
785 if (isConst()) | |
786 { | |
787 } | |
788 else if (isStatic()) | |
789 { | |
790 } | |
791 else if (isSynchronized()) | |
792 { | |
793 error("variable %s cannot be synchronized", toChars()); | |
794 } | |
795 else if (isOverride()) | |
796 { | |
797 error("override cannot be applied to variable"); | |
798 } | |
799 else if (isAbstract()) | |
800 { | |
801 error("abstract cannot be applied to variable"); | |
802 } | |
803 else if (storage_class & STCtemplateparameter) | |
804 { | |
805 } | |
806 else | |
807 { | |
808 AggregateDeclaration *aad = sc->anonAgg; | |
809 if (!aad) | |
810 aad = parent->isAggregateDeclaration(); | |
811 if (aad) | |
812 { | |
813 aad->addField(sc, this); | |
814 } | |
815 | |
816 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); | |
817 if (id) | |
818 { | |
819 error("field not allowed in interface"); | |
820 } | |
821 | |
336 | 822 /* Templates cannot add fields to aggregates |
823 */ | |
159 | 824 TemplateInstance *ti = parent->isTemplateInstance(); |
825 if (ti) | |
826 { | |
827 // Take care of nested templates | |
828 while (1) | |
829 { | |
830 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); | |
831 if (!ti2) | |
832 break; | |
833 ti = ti2; | |
834 } | |
835 | |
836 // If it's a member template | |
837 AggregateDeclaration *ad = ti->tempdecl->isMember(); | |
838 if (ad && storage_class != STCundefined) | |
839 { | |
840 error("cannot use template to add field to aggregate '%s'", ad->toChars()); | |
841 } | |
842 } | |
843 } | |
844 | |
845 if (type->isauto() && !noauto) | |
846 { | |
847 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) | |
848 { | |
849 error("globals, statics, fields, ref and out parameters cannot be auto"); | |
850 } | |
851 | |
852 if (!(storage_class & (STCauto | STCscope))) | |
853 { | |
854 if (!(storage_class & STCparameter) && ident != Id::withSym) | |
855 error("reference to scope class must be scope"); | |
856 } | |
857 } | |
858 | |
859 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && | |
860 !(storage_class & (STCfield | STCin | STCforeach)) && | |
861 type->size() != 0) | |
862 { | |
863 // Provide a default initializer | |
864 //printf("Providing default initializer for '%s'\n", toChars()); | |
865 if (type->ty == Tstruct && | |
866 ((TypeStruct *)type)->sym->zeroInit == 1) | |
867 { /* If a struct is all zeros, as a special case | |
868 * set it's initializer to the integer 0. | |
869 * In AssignExp::toElem(), we check for this and issue | |
870 * a memset() to initialize the struct. | |
871 * Must do same check in interpreter. | |
872 */ | |
873 Expression *e = new IntegerExp(loc, 0, Type::tint32); | |
874 Expression *e1; | |
875 e1 = new VarExp(loc, this); | |
876 e = new AssignExp(loc, e1, e); | |
877 e->type = e1->type; | |
878 init = new ExpInitializer(loc, e/*->type->defaultInit()*/); | |
879 return; | |
880 } | |
881 else if (type->ty == Ttypedef) | |
882 { TypeTypedef *td = (TypeTypedef *)type; | |
883 if (td->sym->init) | |
884 { init = td->sym->init; | |
885 ExpInitializer *ie = init->isExpInitializer(); | |
886 if (ie) | |
887 // Make copy so we can modify it | |
888 init = new ExpInitializer(ie->loc, ie->exp); | |
889 } | |
890 else | |
891 init = getExpInitializer(); | |
892 } | |
893 else | |
894 { | |
895 init = getExpInitializer(); | |
896 } | |
897 } | |
898 | |
899 if (init) | |
900 { | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
901 sc = sc->push(); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
902 sc->stc &= ~(STCconst | STCinvariant | STCpure); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
903 |
159 | 904 ArrayInitializer *ai = init->isArrayInitializer(); |
905 if (ai && tb->ty == Taarray) | |
906 { | |
907 init = ai->toAssocArrayInitializer(); | |
908 } | |
909 | |
910 StructInitializer *si = init->isStructInitializer(); | |
911 ExpInitializer *ei = init->isExpInitializer(); | |
912 | |
913 // See if we can allocate on the stack | |
914 if (ei && isScope() && ei->exp->op == TOKnew) | |
915 { NewExp *ne = (NewExp *)ei->exp; | |
916 if (!(ne->newargs && ne->newargs->dim)) | |
917 { ne->onstack = 1; | |
918 onstack = 1; | |
919 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) | |
920 onstack = 2; | |
921 } | |
922 } | |
923 | |
924 // If inside function, there is no semantic3() call | |
925 if (sc->func) | |
926 { | |
927 // If local variable, use AssignExp to handle all the various | |
928 // possibilities. | |
929 if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) | |
930 { | |
931 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); | |
932 if (!ei) | |
933 { | |
934 Expression *e = init->toExpression(); | |
935 if (!e) | |
936 { | |
937 init = init->semantic(sc, type); | |
938 e = init->toExpression(); | |
939 if (!e) | |
940 { error("is not a static and cannot have static initializer"); | |
941 return; | |
942 } | |
943 } | |
944 ei = new ExpInitializer(init->loc, e); | |
945 init = ei; | |
946 } | |
947 | |
336 | 948 Expression *e1 = new VarExp(loc, this); |
159 | 949 |
336 | 950 Type *t = type->toBasetype(); |
159 | 951 if (t->ty == Tsarray) |
952 { | |
953 ei->exp = ei->exp->semantic(sc); | |
954 if (!ei->exp->implicitConvTo(type)) | |
955 { | |
336 | 956 int dim = ((TypeSArray *)t)->dim->toInteger(); |
159 | 957 // If multidimensional static array, treat as one large array |
958 while (1) | |
959 { | |
960 t = t->nextOf()->toBasetype(); | |
961 if (t->ty != Tsarray) | |
962 break; | |
963 dim *= ((TypeSArray *)t)->dim->toInteger(); | |
964 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); | |
965 } | |
966 } | |
967 e1 = new SliceExp(loc, e1, NULL, NULL); | |
968 } | |
969 else if (t->ty == Tstruct) | |
970 { | |
971 ei->exp = ei->exp->semantic(sc); | |
972 if (!ei->exp->implicitConvTo(type)) | |
973 ei->exp = new CastExp(loc, ei->exp, type); | |
974 } | |
975 ei->exp = new AssignExp(loc, e1, ei->exp); | |
976 ei->exp->op = TOKconstruct; | |
977 canassign++; | |
978 ei->exp = ei->exp->semantic(sc); | |
979 canassign--; | |
980 ei->exp->optimize(WANTvalue); | |
981 } | |
982 else | |
983 { | |
984 init = init->semantic(sc, type); | |
985 if (fd && isConst() && !isStatic()) | |
986 { // Make it static | |
987 storage_class |= STCstatic; | |
988 } | |
989 } | |
990 } | |
991 else if (isConst() || isFinal()) | |
992 { | |
993 /* Because we may need the results of a const declaration in a | |
994 * subsequent type, such as an array dimension, before semantic2() | |
995 * gets ordinarily run, try to run semantic2() now. | |
996 * Ignore failure. | |
997 */ | |
998 | |
999 if (!global.errors && !inferred) | |
1000 { | |
1001 unsigned errors = global.errors; | |
1002 global.gag++; | |
1003 //printf("+gag\n"); | |
1004 Expression *e; | |
1005 Initializer *i2 = init; | |
1006 inuse++; | |
1007 if (ei) | |
1008 { | |
1009 e = ei->exp->syntaxCopy(); | |
1010 e = e->semantic(sc); | |
1011 e = e->implicitCastTo(sc, type); | |
1012 } | |
1013 else if (si || ai) | |
1014 { i2 = init->syntaxCopy(); | |
1015 i2 = i2->semantic(sc, type); | |
1016 } | |
1017 inuse--; | |
1018 global.gag--; | |
1019 //printf("-gag\n"); | |
1020 if (errors != global.errors) // if errors happened | |
1021 { | |
1022 if (global.gag == 0) | |
1023 global.errors = errors; // act as if nothing happened | |
1024 } | |
1025 else if (ei) | |
1026 { | |
1027 e = e->optimize(WANTvalue | WANTinterpret); | |
1028 if (e->op == TOKint64 || e->op == TOKstring) | |
1029 { | |
1030 ei->exp = e; // no errors, keep result | |
1031 } | |
1032 } | |
1033 else | |
1034 init = i2; // no errors, keep result | |
1035 } | |
1036 } | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
1037 sc = sc->pop(); |
159 | 1038 } |
1039 } | |
1040 | |
1041 ExpInitializer *VarDeclaration::getExpInitializer() | |
1042 { | |
1043 ExpInitializer *ei; | |
1044 | |
1045 if (init) | |
1046 ei = init->isExpInitializer(); | |
1047 else | |
1048 { | |
336 | 1049 Expression *e = type->defaultInit(loc); |
159 | 1050 if (e) |
1051 ei = new ExpInitializer(loc, e); | |
1052 else | |
1053 ei = NULL; | |
1054 } | |
1055 return ei; | |
1056 } | |
1057 | |
1058 void VarDeclaration::semantic2(Scope *sc) | |
1059 { | |
1060 //printf("VarDeclaration::semantic2('%s')\n", toChars()); | |
1061 if (init && !toParent()->isFuncDeclaration()) | |
1062 { inuse++; | |
1063 #if 0 | |
1064 ExpInitializer *ei = init->isExpInitializer(); | |
1065 if (ei) | |
1066 { | |
1067 ei->exp->dump(0); | |
1068 printf("type = %p\n", ei->exp->type); | |
1069 } | |
1070 #endif | |
1071 init = init->semantic(sc, type); | |
1072 inuse--; | |
1073 } | |
1074 } | |
1075 | |
336 | 1076 const char *VarDeclaration::kind() |
159 | 1077 { |
1078 return "variable"; | |
1079 } | |
1080 | |
1081 Dsymbol *VarDeclaration::toAlias() | |
1082 { | |
1083 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); | |
1084 assert(this != aliassym); | |
1085 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | |
1086 return s; | |
1087 } | |
1088 | |
1089 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
1090 { | |
1091 if (storage_class & STCconst) | |
1092 buf->writestring("const "); | |
1093 if (storage_class & STCstatic) | |
1094 buf->writestring("static "); | |
336 | 1095 if (storage_class & STCauto) |
1096 buf->writestring("auto "); | |
1097 #if DMDV2 | |
1098 if (storage_class & STCmanifest) | |
1099 buf->writestring("manifest "); | |
1100 if (storage_class & STCinvariant) | |
1101 buf->writestring("invariant "); | |
1102 if (storage_class & STCtls) | |
1103 buf->writestring("__thread "); | |
1104 #endif | |
1105 | |
159 | 1106 if (type) |
1107 type->toCBuffer(buf, ident, hgs); | |
1108 else | |
1109 buf->writestring(ident->toChars()); | |
1110 if (init) | |
1111 { buf->writestring(" = "); | |
1112 init->toCBuffer(buf, hgs); | |
1113 } | |
1114 buf->writeByte(';'); | |
1115 buf->writenl(); | |
1116 } | |
1117 | |
1118 int VarDeclaration::needThis() | |
1119 { | |
1120 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); | |
1121 return storage_class & STCfield; | |
1122 } | |
1123 | |
1124 int VarDeclaration::isImportedSymbol() | |
1125 { | |
1126 if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) | |
1127 return TRUE; | |
1128 return FALSE; | |
1129 } | |
1130 | |
1131 void VarDeclaration::checkCtorConstInit() | |
1132 { | |
1133 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) | |
1134 error("missing initializer in static constructor for const variable"); | |
1135 } | |
1136 | |
1137 /************************************ | |
336 | 1138 * Check to see if this variable is actually in an enclosing function |
1139 * rather than the current one. | |
159 | 1140 */ |
1141 | |
1142 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) | |
1143 { | |
336 | 1144 //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); |
159 | 1145 if (parent && !isDataseg() && parent != sc->parent) |
1146 { | |
336 | 1147 // The function that this variable is in |
159 | 1148 FuncDeclaration *fdv = toParent()->isFuncDeclaration(); |
336 | 1149 // The current function |
159 | 1150 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); |
1151 | |
1152 if (fdv && fdthis) | |
1153 { | |
1154 if (loc.filename) | |
1155 fdthis->getLevel(loc, fdv); | |
1156 nestedref = 1; | |
1157 fdv->nestedFrameRef = 1; | |
1158 fdv->nestedVars.insert(this); | |
1159 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); | |
1160 } | |
1161 } | |
1162 } | |
1163 | |
1164 /******************************* | |
1165 * Does symbol go into data segment? | |
336 | 1166 * Includes extern variables. |
159 | 1167 */ |
1168 | |
1169 int VarDeclaration::isDataseg() | |
1170 { | |
1171 #if 0 | |
1172 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); | |
1173 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); | |
1174 printf("parent = '%s'\n", parent->toChars()); | |
1175 #endif | |
1176 Dsymbol *parent = this->toParent(); | |
1177 if (!parent && !(storage_class & (STCstatic | STCconst))) | |
1178 { error("forward referenced"); | |
1179 type = Type::terror; | |
1180 return 0; | |
1181 } | |
1182 return (storage_class & (STCstatic | STCconst) || | |
1183 parent->isModule() || | |
1184 parent->isTemplateInstance()); | |
1185 } | |
1186 | |
1187 int VarDeclaration::hasPointers() | |
1188 { | |
1189 return (!isDataseg() && type->hasPointers()); | |
1190 } | |
1191 | |
1192 /****************************************** | |
1193 * If a variable has an auto destructor call, return call for it. | |
1194 * Otherwise, return NULL. | |
1195 */ | |
1196 | |
1197 Expression *VarDeclaration::callAutoDtor() | |
1198 { Expression *e = NULL; | |
1199 | |
1200 //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); | |
1201 if (storage_class & (STCauto | STCscope) && !noauto) | |
1202 { | |
1203 for (ClassDeclaration *cd = type->isClassHandle(); | |
1204 cd; | |
1205 cd = cd->baseClass) | |
1206 { | |
1207 /* We can do better if there's a way with onstack | |
1208 * classes to determine if there's no way the monitor | |
1209 * could be set. | |
1210 */ | |
1211 //if (cd->isInterfaceDeclaration()) | |
1212 //error("interface %s cannot be scope", cd->toChars()); | |
1213 if (1 || onstack || cd->dtors.dim) // if any destructors | |
1214 { | |
1215 // delete this; | |
1216 Expression *ec; | |
1217 | |
1218 ec = new VarExp(loc, this); | |
1219 e = new DeleteExp(loc, ec); | |
1220 e->type = Type::tvoid; | |
1221 break; | |
1222 } | |
1223 } | |
1224 } | |
1225 return e; | |
1226 } | |
1227 | |
1228 | |
1229 /********************************* ClassInfoDeclaration ****************************/ | |
1230 | |
1231 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) | |
1232 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) | |
1233 { | |
1234 this->cd = cd; | |
1235 storage_class = STCstatic; | |
1236 } | |
1237 | |
1238 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1239 { | |
1240 assert(0); // should never be produced by syntax | |
1241 return NULL; | |
1242 } | |
1243 | |
1244 void ClassInfoDeclaration::semantic(Scope *sc) | |
1245 { | |
1246 } | |
1247 | |
1248 /********************************* ModuleInfoDeclaration ****************************/ | |
1249 | |
1250 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) | |
1251 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) | |
1252 { | |
1253 this->mod = mod; | |
1254 storage_class = STCstatic; | |
1255 } | |
1256 | |
1257 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1258 { | |
1259 assert(0); // should never be produced by syntax | |
1260 return NULL; | |
1261 } | |
1262 | |
1263 void ModuleInfoDeclaration::semantic(Scope *sc) | |
1264 { | |
1265 } | |
1266 | |
1267 /********************************* TypeInfoDeclaration ****************************/ | |
1268 | |
1269 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) | |
1270 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) | |
1271 { | |
1272 this->tinfo = tinfo; | |
1273 storage_class = STCstatic; | |
1274 protection = PROTpublic; | |
1275 linkage = LINKc; | |
1276 } | |
1277 | |
1278 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1279 { | |
1280 assert(0); // should never be produced by syntax | |
1281 return NULL; | |
1282 } | |
1283 | |
1284 void TypeInfoDeclaration::semantic(Scope *sc) | |
1285 { | |
1286 assert(linkage == LINKc); | |
1287 } | |
1288 | |
1289 /***************************** TypeInfoConstDeclaration **********************/ | |
1290 | |
336 | 1291 #if DMDV2 |
159 | 1292 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) |
1293 : TypeInfoDeclaration(tinfo, 0) | |
1294 { | |
1295 } | |
1296 #endif | |
1297 | |
1298 /***************************** TypeInfoInvariantDeclaration **********************/ | |
1299 | |
336 | 1300 #if DMDV2 |
159 | 1301 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) |
1302 : TypeInfoDeclaration(tinfo, 0) | |
1303 { | |
1304 } | |
1305 #endif | |
1306 | |
1307 /***************************** TypeInfoStructDeclaration **********************/ | |
1308 | |
1309 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) | |
1310 : TypeInfoDeclaration(tinfo, 0) | |
1311 { | |
1312 } | |
1313 | |
1314 /***************************** TypeInfoClassDeclaration ***********************/ | |
1315 | |
1316 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) | |
1317 : TypeInfoDeclaration(tinfo, 0) | |
1318 { | |
1319 } | |
1320 | |
1321 /***************************** TypeInfoInterfaceDeclaration *******************/ | |
1322 | |
1323 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) | |
1324 : TypeInfoDeclaration(tinfo, 0) | |
1325 { | |
1326 } | |
1327 | |
1328 /***************************** TypeInfoTypedefDeclaration *********************/ | |
1329 | |
1330 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) | |
1331 : TypeInfoDeclaration(tinfo, 0) | |
1332 { | |
1333 } | |
1334 | |
1335 /***************************** TypeInfoPointerDeclaration *********************/ | |
1336 | |
1337 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) | |
1338 : TypeInfoDeclaration(tinfo, 0) | |
1339 { | |
1340 } | |
1341 | |
1342 /***************************** TypeInfoArrayDeclaration ***********************/ | |
1343 | |
1344 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) | |
1345 : TypeInfoDeclaration(tinfo, 0) | |
1346 { | |
1347 } | |
1348 | |
1349 /***************************** TypeInfoStaticArrayDeclaration *****************/ | |
1350 | |
1351 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) | |
1352 : TypeInfoDeclaration(tinfo, 0) | |
1353 { | |
1354 } | |
1355 | |
1356 /***************************** TypeInfoAssociativeArrayDeclaration ************/ | |
1357 | |
1358 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) | |
1359 : TypeInfoDeclaration(tinfo, 0) | |
1360 { | |
1361 } | |
1362 | |
1363 /***************************** TypeInfoEnumDeclaration ***********************/ | |
1364 | |
1365 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) | |
1366 : TypeInfoDeclaration(tinfo, 0) | |
1367 { | |
1368 } | |
1369 | |
1370 /***************************** TypeInfoFunctionDeclaration ********************/ | |
1371 | |
1372 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) | |
1373 : TypeInfoDeclaration(tinfo, 0) | |
1374 { | |
1375 } | |
1376 | |
1377 /***************************** TypeInfoDelegateDeclaration ********************/ | |
1378 | |
1379 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) | |
1380 : TypeInfoDeclaration(tinfo, 0) | |
1381 { | |
1382 } | |
1383 | |
1384 /***************************** TypeInfoTupleDeclaration **********************/ | |
1385 | |
1386 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) | |
1387 : TypeInfoDeclaration(tinfo, 0) | |
1388 { | |
1389 } | |
1390 | |
1391 /********************************* ThisDeclaration ****************************/ | |
1392 | |
1393 // For the "this" parameter to member functions | |
1394 | |
1395 ThisDeclaration::ThisDeclaration(Type *t) | |
1396 : VarDeclaration(0, t, Id::This, NULL) | |
1397 { | |
1398 noauto = 1; | |
1399 } | |
1400 | |
1401 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) | |
1402 { | |
1403 assert(0); // should never be produced by syntax | |
1404 return NULL; | |
1405 } | |
1406 | |
1407 |