comparison dmd2/declaration.c @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents
children 340acf1535d0
comparison
equal deleted inserted replaced
757:2c730d530c98 758:f04dde6e882c
1
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
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
42 const char *Declaration::kind()
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
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 const 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
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
170 const char *TupleDeclaration::kind()
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(0, 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);
304 storage_class |= sc->stc & STCdeprecated;
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
331 const char *TypedefDeclaration::kind()
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 {
392 //printf("AliasDeclaration::syntaxCopy()\n");
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 && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()))
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 s = getDsymbol(e);
469 if (s)
470 goto L2;
471
472 error("cannot alias an expression %s", e->toChars());
473 t = e->type;
474 }
475 else if (t)
476 type = t;
477 if (overnext)
478 ScopeDsymbol::multiplyDefined(0, this, overnext);
479 this->inSemantic = 0;
480 return;
481
482 L2:
483 //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
484 type = NULL;
485 VarDeclaration *v = s->isVarDeclaration();
486 if (v && v->linkage == LINKdefault)
487 {
488 error("forward reference of %s", v->toChars());
489 s = NULL;
490 }
491 else
492 {
493 FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
494 if (f)
495 {
496 if (overnext)
497 {
498 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
499 if (!fa->overloadInsert(overnext))
500 ScopeDsymbol::multiplyDefined(0, f, overnext);
501 overnext = NULL;
502 s = fa;
503 s->parent = sc->parent;
504 }
505 }
506 if (overnext)
507 ScopeDsymbol::multiplyDefined(0, s, overnext);
508 if (s == this)
509 {
510 assert(global.errors);
511 s = NULL;
512 }
513 }
514 aliassym = s;
515 this->inSemantic = 0;
516 }
517
518 int AliasDeclaration::overloadInsert(Dsymbol *s)
519 {
520 /* Don't know yet what the aliased symbol is, so assume it can
521 * be overloaded and check later for correctness.
522 */
523
524 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
525 if (overnext == NULL)
526 { overnext = s;
527 return TRUE;
528 }
529 else
530 {
531 return overnext->overloadInsert(s);
532 }
533 }
534
535 const char *AliasDeclaration::kind()
536 {
537 return "alias";
538 }
539
540 Type *AliasDeclaration::getType()
541 {
542 return type;
543 }
544
545 Dsymbol *AliasDeclaration::toAlias()
546 {
547 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
548 assert(this != aliassym);
549 //static int count; if (++count == 10) *(char*)0=0;
550 if (inSemantic)
551 { error("recursive alias declaration");
552 // return this;
553 }
554 Dsymbol *s = aliassym ? aliassym->toAlias() : this;
555 return s;
556 }
557
558 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
559 {
560 buf->writestring("alias ");
561 #if 0 && _DH
562 if (hgs->hdrgen)
563 {
564 if (haliassym)
565 {
566 haliassym->toCBuffer(buf, hgs);
567 buf->writeByte(' ');
568 buf->writestring(ident->toChars());
569 }
570 else
571 htype->toCBuffer(buf, ident, hgs);
572 }
573 else
574 #endif
575 {
576 if (aliassym)
577 {
578 aliassym->toCBuffer(buf, hgs);
579 buf->writeByte(' ');
580 buf->writestring(ident->toChars());
581 }
582 else
583 type->toCBuffer(buf, ident, hgs);
584 }
585 buf->writeByte(';');
586 buf->writenl();
587 }
588
589 /********************************* VarDeclaration ****************************/
590
591 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
592 : Declaration(id)
593 {
594 //printf("VarDeclaration('%s')\n", id->toChars());
595 #ifdef DEBUG
596 if (!type && !init)
597 { printf("VarDeclaration('%s')\n", id->toChars());
598 //*(char*)0=0;
599 }
600 #endif
601 assert(type || init);
602 this->type = type;
603 this->init = init;
604 #ifdef _DH
605 this->htype = NULL;
606 this->hinit = NULL;
607 #endif
608 this->loc = loc;
609 offset = 0;
610 noauto = 0;
611 inuse = 0;
612 ctorinit = 0;
613 aliassym = NULL;
614 onstack = 0;
615 canassign = 0;
616 value = NULL;
617 scope = NULL;
618
619 // LDC
620 anonDecl = NULL;
621 }
622
623 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
624 {
625 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
626
627 VarDeclaration *sv;
628 if (s)
629 { sv = (VarDeclaration *)s;
630 }
631 else
632 {
633 Initializer *init = NULL;
634 if (this->init)
635 { init = this->init->syntaxCopy();
636 //init->isExpInitializer()->exp->print();
637 //init->isExpInitializer()->exp->dump(0);
638 }
639
640 sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
641 sv->storage_class = storage_class;
642 }
643 #ifdef _DH
644 // Syntax copy for header file
645 if (!htype) // Don't overwrite original
646 { if (type) // Make copy for both old and new instances
647 { htype = type->syntaxCopy();
648 sv->htype = type->syntaxCopy();
649 }
650 }
651 else // Make copy of original for new instance
652 sv->htype = htype->syntaxCopy();
653 if (!hinit)
654 { if (init)
655 { hinit = init->syntaxCopy();
656 sv->hinit = init->syntaxCopy();
657 }
658 }
659 else
660 sv->hinit = hinit->syntaxCopy();
661 #endif
662 return sv;
663 }
664
665 void VarDeclaration::semantic(Scope *sc)
666 {
667 #if 0
668 printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
669 printf(" type = %s\n", type ? type->toChars() : "null");
670 printf(" stc = x%x\n", sc->stc);
671 printf(" storage_class = x%x\n", storage_class);
672 printf("linkage = %d\n", sc->linkage);
673 //if (strcmp(toChars(), "mul") == 0) halt();
674 #endif
675
676 storage_class |= sc->stc;
677 if (storage_class & STCextern && init)
678 error("extern symbols cannot have initializers");
679
680 /* If auto type inference, do the inference
681 */
682 int inferred = 0;
683 if (!type)
684 { inuse++;
685 type = init->inferType(sc);
686 inuse--;
687 inferred = 1;
688
689 /* This is a kludge to support the existing syntax for RAII
690 * declarations.
691 */
692 storage_class &= ~STCauto;
693 originalType = type;
694 }
695 else
696 { if (!originalType)
697 originalType = type;
698 type = type->semantic(loc, sc);
699 }
700 //printf(" semantic type = %s\n", type ? type->toChars() : "null");
701
702 type->checkDeprecated(loc, sc);
703 linkage = sc->linkage;
704 this->parent = sc->parent;
705 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
706 protection = sc->protection;
707 //printf("sc->stc = %x\n", sc->stc);
708 //printf("storage_class = x%x\n", storage_class);
709
710 Dsymbol *parent = toParent();
711 FuncDeclaration *fd = parent->isFuncDeclaration();
712
713 Type *tb = type->toBasetype();
714 if (tb->ty == Tvoid && !(storage_class & STClazy))
715 { error("voids have no value");
716 type = Type::terror;
717 tb = type;
718 }
719 if (tb->ty == Tfunction)
720 { error("cannot be declared to be a function");
721 type = Type::terror;
722 tb = type;
723 }
724 if (tb->ty == Tstruct)
725 { TypeStruct *ts = (TypeStruct *)tb;
726
727 if (!ts->sym->members)
728 {
729 error("no definition of struct %s", ts->toChars());
730 }
731 }
732
733 if (tb->ty == Ttuple)
734 { /* Instead, declare variables for each of the tuple elements
735 * and add those.
736 */
737 TypeTuple *tt = (TypeTuple *)tb;
738 size_t nelems = Argument::dim(tt->arguments);
739 Objects *exps = new Objects();
740 exps->setDim(nelems);
741 Expression *ie = init ? init->toExpression() : NULL;
742
743 for (size_t i = 0; i < nelems; i++)
744 { Argument *arg = Argument::getNth(tt->arguments, i);
745
746 OutBuffer buf;
747 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i);
748 buf.writeByte(0);
749 char *name = (char *)buf.extractData();
750 Identifier *id = new Identifier(name, TOKidentifier);
751
752 Expression *einit = ie;
753 if (ie && ie->op == TOKtuple)
754 { einit = (Expression *)((TupleExp *)ie)->exps->data[i];
755 }
756 Initializer *ti = init;
757 if (einit)
758 { ti = new ExpInitializer(einit->loc, einit);
759 }
760
761 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
762 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
763 v->semantic(sc);
764
765 if (sc->scopesym)
766 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
767 if (sc->scopesym->members)
768 sc->scopesym->members->push(v);
769 }
770
771 Expression *e = new DsymbolExp(loc, v);
772 exps->data[i] = e;
773 }
774 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
775 v2->isexp = 1;
776 aliassym = v2;
777 return;
778 }
779
780 Lagain:
781 if (storage_class & STCinvariant)
782 {
783 type = type->invariantOf();
784 }
785 else if (storage_class & (STCconst | STCin))
786 {
787 if (!type->isInvariant())
788 type = type->constOf();
789 }
790 else if (type->isConst())
791 storage_class |= STCconst;
792 else if (type->isInvariant())
793 storage_class |= STCinvariant;
794
795 if (isSynchronized())
796 {
797 error("variable %s cannot be synchronized", toChars());
798 }
799 else if (isOverride())
800 {
801 error("override cannot be applied to variable");
802 }
803 else if (isAbstract())
804 {
805 error("abstract cannot be applied to variable");
806 }
807 else if (storage_class & STCfinal)
808 {
809 error("final cannot be applied to variable");
810 }
811
812 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls))
813 {
814 }
815 else
816 {
817 AggregateDeclaration *aad = sc->anonAgg;
818 if (!aad)
819 aad = parent->isAggregateDeclaration();
820 if (aad)
821 { assert(!(storage_class & (STCextern | STCstatic | STCtls)));
822
823 if (storage_class & (STCconst | STCinvariant) && init)
824 {
825 if (!type->toBasetype()->isTypeBasic())
826 storage_class |= STCstatic;
827 }
828 else
829 aad->addField(sc, this);
830 }
831
832 InterfaceDeclaration *id = parent->isInterfaceDeclaration();
833 if (id)
834 {
835 error("field not allowed in interface");
836 }
837
838 /* Templates cannot add fields to aggregates
839 */
840 TemplateInstance *ti = parent->isTemplateInstance();
841 if (ti)
842 {
843 // Take care of nested templates
844 while (1)
845 {
846 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
847 if (!ti2)
848 break;
849 ti = ti2;
850 }
851
852 // If it's a member template
853 AggregateDeclaration *ad = ti->tempdecl->isMember();
854 if (ad && storage_class != STCundefined)
855 {
856 error("cannot use template to add field to aggregate '%s'", ad->toChars());
857 }
858 }
859 }
860
861 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref)
862 error("only parameters or foreach declarations can be ref");
863
864 if (type->isauto() && !noauto)
865 {
866 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd)
867 {
868 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto");
869 }
870
871 if (!(storage_class & (STCauto | STCscope)))
872 {
873 if (!(storage_class & STCparameter) && ident != Id::withSym)
874 error("reference to scope class must be scope");
875 }
876 }
877
878 if ((isConst() || isInvariant()) && !init && !fd)
879 { // Initialize by constructor only
880 storage_class |= STCctorinit;
881 }
882
883 if (init)
884 storage_class |= STCinit; // remember we had an explicit initializer
885 else if (storage_class & STCmanifest)
886 error("manifest constants must have initializers");
887
888 enum TOK op = TOKconstruct;
889 if (!init && !sc->inunion && !isStatic() && fd &&
890 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) &&
891 type->size() != 0)
892 {
893 // Provide a default initializer
894 //printf("Providing default initializer for '%s'\n", toChars());
895 if (type->ty == Tstruct &&
896 ((TypeStruct *)type)->sym->zeroInit == 1)
897 { /* If a struct is all zeros, as a special case
898 * set it's initializer to the integer 0.
899 * In AssignExp::toElem(), we check for this and issue
900 * a memset() to initialize the struct.
901 * Must do same check in interpreter.
902 */
903 Expression *e = new IntegerExp(loc, 0, Type::tint32);
904 Expression *e1;
905 e1 = new VarExp(loc, this);
906 e = new AssignExp(loc, e1, e);
907 e->type = e1->type; // don't type check this, it would fail
908 init = new ExpInitializer(loc, e);
909 return;
910 }
911 else if (type->ty == Ttypedef)
912 { TypeTypedef *td = (TypeTypedef *)type;
913 if (td->sym->init)
914 { init = td->sym->init;
915 ExpInitializer *ie = init->isExpInitializer();
916 if (ie)
917 // Make copy so we can modify it
918 init = new ExpInitializer(ie->loc, ie->exp);
919 }
920 else
921 init = getExpInitializer();
922 }
923 else
924 {
925 init = getExpInitializer();
926 }
927 // Default initializer is always a blit
928 op = TOKblit;
929 }
930
931 if (init)
932 {
933 sc = sc->push();
934 sc->stc &= ~(STCconst | STCinvariant | STCpure | STCnothrow | STCref | STCshared);
935
936 ArrayInitializer *ai = init->isArrayInitializer();
937 if (ai && tb->ty == Taarray)
938 {
939 init = ai->toAssocArrayInitializer();
940 }
941
942 StructInitializer *si = init->isStructInitializer();
943 ExpInitializer *ei = init->isExpInitializer();
944
945 // See if initializer is a NewExp that can be allocated on the stack
946 if (ei && isScope() && ei->exp->op == TOKnew)
947 { NewExp *ne = (NewExp *)ei->exp;
948 if (!(ne->newargs && ne->newargs->dim))
949 { ne->onstack = 1;
950 onstack = 1;
951 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
952 onstack = 2;
953 }
954 }
955
956 // If inside function, there is no semantic3() call
957 if (sc->func)
958 {
959 // If local variable, use AssignExp to handle all the various
960 // possibilities.
961 if (fd && !isStatic() && !(storage_class & STCmanifest) &&
962 !init->isVoidInitializer())
963 {
964 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
965 if (!ei)
966 {
967 Expression *e = init->toExpression();
968 if (!e)
969 {
970 init = init->semantic(sc, type);
971 e = init->toExpression();
972 if (!e)
973 { error("is not a static and cannot have static initializer");
974 return;
975 }
976 }
977 ei = new ExpInitializer(init->loc, e);
978 init = ei;
979 }
980
981 Expression *e1 = new VarExp(loc, this);
982
983 Type *t = type->toBasetype();
984 if (t->ty == Tsarray)
985 {
986 ei->exp = ei->exp->semantic(sc);
987 if (!ei->exp->implicitConvTo(type))
988 {
989 int dim = ((TypeSArray *)t)->dim->toInteger();
990 // If multidimensional static array, treat as one large array
991 while (1)
992 {
993 t = t->nextOf()->toBasetype();
994 if (t->ty != Tsarray)
995 break;
996 dim *= ((TypeSArray *)t)->dim->toInteger();
997 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
998 }
999 }
1000 e1 = new SliceExp(loc, e1, NULL, NULL);
1001 }
1002 else if (t->ty == Tstruct)
1003 {
1004 ei->exp = ei->exp->semantic(sc);
1005
1006 /* Look to see if initializer is a call to the constructor
1007 */
1008 StructDeclaration *sd = ((TypeStruct *)t)->sym;
1009 if (sd->ctor && // there are constructors
1010 ei->exp->type->ty == Tstruct && // rvalue is the same struct
1011 ((TypeStruct *)ei->exp->type)->sym == sd &&
1012 ei->exp->op == TOKstar)
1013 {
1014 /* Look for form of constructor call which is:
1015 * *__ctmp.ctor(arguments...)
1016 */
1017 PtrExp *pe = (PtrExp *)ei->exp;
1018 if (pe->e1->op == TOKcall)
1019 { CallExp *ce = (CallExp *)pe->e1;
1020 if (ce->e1->op == TOKdotvar)
1021 { DotVarExp *dve = (DotVarExp *)ce->e1;
1022 if (dve->var->isCtorDeclaration())
1023 { /* It's a constructor call, currently constructing
1024 * a temporary __ctmp.
1025 */
1026 /* Before calling the constructor, initialize
1027 * variable with a bit copy of the default
1028 * initializer
1029 */
1030 Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
1031 e->op = TOKblit;
1032 e->type = t;
1033 ei->exp = new CommaExp(loc, e, ei->exp);
1034
1035 /* Replace __ctmp being constructed with e1
1036 */
1037 dve->e1 = e1;
1038 return;
1039 }
1040 }
1041 }
1042 }
1043
1044 if (!ei->exp->implicitConvTo(type))
1045 { Type *ti = ei->exp->type->toBasetype();
1046 // Don't cast away invariant or mutability in initializer
1047 if (!(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1048 ei->exp = new CastExp(loc, ei->exp, type);
1049 }
1050 }
1051 ei->exp = new AssignExp(loc, e1, ei->exp);
1052 ei->exp->op = op;
1053 canassign++;
1054 ei->exp = ei->exp->semantic(sc);
1055 canassign--;
1056 ei->exp->optimize(WANTvalue);
1057 }
1058 else
1059 {
1060 init = init->semantic(sc, type);
1061 }
1062 }
1063 else if (storage_class & (STCconst | STCinvariant | STCmanifest) ||
1064 type->isConst() || type->isInvariant())
1065 {
1066 /* Because we may need the results of a const declaration in a
1067 * subsequent type, such as an array dimension, before semantic2()
1068 * gets ordinarily run, try to run semantic2() now.
1069 * Ignore failure.
1070 */
1071
1072 if (!global.errors && !inferred)
1073 {
1074 unsigned errors = global.errors;
1075 global.gag++;
1076 //printf("+gag\n");
1077 Expression *e;
1078 Initializer *i2 = init;
1079 inuse++;
1080 if (ei)
1081 {
1082 e = ei->exp->syntaxCopy();
1083 e = e->semantic(sc);
1084 e = e->implicitCastTo(sc, type);
1085 }
1086 else if (si || ai)
1087 { i2 = init->syntaxCopy();
1088 i2 = i2->semantic(sc, type);
1089 }
1090 inuse--;
1091 global.gag--;
1092 //printf("-gag\n");
1093 if (errors != global.errors) // if errors happened
1094 {
1095 if (global.gag == 0)
1096 global.errors = errors; // act as if nothing happened
1097
1098 /* Save scope for later use, to try again
1099 */
1100 scope = new Scope(*sc);
1101 scope->setNoFree();
1102 }
1103 else if (ei)
1104 {
1105 if (isDataseg())
1106 /* static const/invariant does CTFE
1107 */
1108 e = e->optimize(WANTvalue | WANTinterpret);
1109 else
1110 e = e->optimize(WANTvalue);
1111 if (e->op == TOKint64 || e->op == TOKstring)
1112 {
1113 ei->exp = e; // no errors, keep result
1114 }
1115 else
1116 {
1117 /* Save scope for later use, to try again
1118 */
1119 scope = new Scope(*sc);
1120 scope->setNoFree();
1121 }
1122 }
1123 else
1124 init = i2; // no errors, keep result
1125 }
1126 }
1127 sc = sc->pop();
1128 }
1129 }
1130
1131 void VarDeclaration::semantic2(Scope *sc)
1132 {
1133 //printf("VarDeclaration::semantic2('%s')\n", toChars());
1134 if (init && !toParent()->isFuncDeclaration())
1135 { inuse++;
1136 #if 0
1137 ExpInitializer *ei = init->isExpInitializer();
1138 if (ei)
1139 {
1140 ei->exp->dump(0);
1141 printf("type = %p\n", ei->exp->type);
1142 }
1143 #endif
1144 init = init->semantic(sc, type);
1145 inuse--;
1146 }
1147 }
1148
1149 const char *VarDeclaration::kind()
1150 {
1151 return "variable";
1152 }
1153
1154 Dsymbol *VarDeclaration::toAlias()
1155 {
1156 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1157 assert(this != aliassym);
1158 Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1159 return s;
1160 }
1161
1162 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1163 {
1164 if (storage_class & STCconst)
1165 buf->writestring("const ");
1166 if (storage_class & STCstatic)
1167 buf->writestring("static ");
1168 if (storage_class & STCauto)
1169 buf->writestring("auto ");
1170 #if DMDV2
1171 if (storage_class & STCmanifest)
1172 buf->writestring("manifest ");
1173 if (storage_class & STCinvariant)
1174 buf->writestring("invariant ");
1175 if (storage_class & STCtls)
1176 buf->writestring("__thread ");
1177 #endif
1178
1179 if (type)
1180 type->toCBuffer(buf, ident, hgs);
1181 else
1182 buf->writestring(ident->toChars());
1183 if (init)
1184 { buf->writestring(" = ");
1185 ExpInitializer *ie = init->isExpInitializer();
1186 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1187 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
1188 else
1189 init->toCBuffer(buf, hgs);
1190 }
1191 buf->writeByte(';');
1192 buf->writenl();
1193 }
1194
1195 int VarDeclaration::needThis()
1196 {
1197 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1198 return storage_class & STCfield;
1199 }
1200
1201 int VarDeclaration::isImportedSymbol()
1202 {
1203 if (protection == PROTexport && !init &&
1204 (storage_class & STCstatic || parent->isModule()))
1205 return TRUE;
1206 return FALSE;
1207 }
1208
1209 void VarDeclaration::checkCtorConstInit()
1210 {
1211 #if 0 /* doesn't work if more than one static ctor */
1212 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
1213 error("missing initializer in static constructor for const variable");
1214 #endif
1215 }
1216
1217 /************************************
1218 * Check to see if this variable is actually in an enclosing function
1219 * rather than the current one.
1220 */
1221
1222 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1223 {
1224 if (parent && !isDataseg() && parent != sc->parent &&
1225 !(storage_class & STCmanifest))
1226 {
1227 // The function that this variable is in
1228 FuncDeclaration *fdv = toParent()->isFuncDeclaration();
1229 // The current function
1230 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1231
1232 if (fdv && fdthis && fdv != fdthis)
1233 {
1234 if (loc.filename)
1235 fdthis->getLevel(loc, fdv);
1236
1237 for (int i = 0; i < nestedrefs.dim; i++)
1238 { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i];
1239 if (f == fdthis)
1240 goto L1;
1241 }
1242 fdv->nestedVars.insert(this);
1243 nestedrefs.push(fdthis);
1244 L1: ;
1245
1246
1247 for (int i = 0; i < fdv->closureVars.dim; i++)
1248 { Dsymbol *s = (Dsymbol *)fdv->closureVars.data[i];
1249 if (s == this)
1250 goto L2;
1251 }
1252
1253 fdv->closureVars.push(this);
1254 L2: ;
1255
1256 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1257 }
1258 }
1259 }
1260
1261 /****************************
1262 * Get ExpInitializer for a variable, if there is one.
1263 */
1264
1265 ExpInitializer *VarDeclaration::getExpInitializer()
1266 {
1267 ExpInitializer *ei;
1268
1269 if (init)
1270 ei = init->isExpInitializer();
1271 else
1272 {
1273 Expression *e = type->defaultInit(loc);
1274 if (e)
1275 ei = new ExpInitializer(loc, e);
1276 else
1277 ei = NULL;
1278 }
1279 return ei;
1280 }
1281
1282 /*******************************************
1283 * If variable has a constant expression initializer, get it.
1284 * Otherwise, return NULL.
1285 */
1286
1287 Expression *VarDeclaration::getConstInitializer()
1288 {
1289 if ((isConst() || isInvariant() || storage_class & STCmanifest) &&
1290 storage_class & STCinit)
1291 {
1292 ExpInitializer *ei = getExpInitializer();
1293 if (ei)
1294 return ei->exp;
1295 }
1296
1297 return NULL;
1298 }
1299
1300 /*************************************
1301 * Return !=0 if we can take the address of this variable.
1302 */
1303
1304 int VarDeclaration::canTakeAddressOf()
1305 {
1306 #if 0
1307 /* Global variables and struct/class fields of the form:
1308 * const int x = 3;
1309 * are not stored and hence cannot have their address taken.
1310 */
1311 if ((isConst() || isInvariant()) &&
1312 storage_class & STCinit &&
1313 (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) &&
1314 (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) &&
1315 type->toBasetype()->isTypeBasic()
1316 )
1317 {
1318 return 0;
1319 }
1320 #else
1321 if (storage_class & STCmanifest)
1322 return 0;
1323 #endif
1324 return 1;
1325 }
1326
1327 /*******************************
1328 * Does symbol go into data segment?
1329 * Includes extern variables.
1330 */
1331
1332 int VarDeclaration::isDataseg()
1333 {
1334 #if 0
1335 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1336 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
1337 printf("parent = '%s'\n", parent->toChars());
1338 #endif
1339 if (storage_class & STCmanifest)
1340 return 0;
1341 Dsymbol *parent = this->toParent();
1342 if (!parent && !(storage_class & STCstatic))
1343 { error("forward referenced");
1344 type = Type::terror;
1345 return 0;
1346 }
1347 return canTakeAddressOf() &&
1348 (storage_class & (STCstatic | STCextern | STCtls) ||
1349 toParent()->isModule() ||
1350 toParent()->isTemplateInstance());
1351 }
1352
1353 int VarDeclaration::hasPointers()
1354 {
1355 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1356 return (!isDataseg() && type->hasPointers());
1357 }
1358
1359 /******************************************
1360 * Return TRUE if variable needs to call the destructor.
1361 */
1362
1363 int VarDeclaration::needsAutoDtor()
1364 {
1365 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1366
1367 if (noauto || storage_class & STCnodtor)
1368 return FALSE;
1369
1370 // Destructors for structs and arrays of structs
1371 Type *tv = type->toBasetype();
1372 while (tv->ty == Tsarray)
1373 { TypeSArray *ta = (TypeSArray *)tv;
1374 tv = tv->nextOf()->toBasetype();
1375 }
1376 if (tv->ty == Tstruct)
1377 { TypeStruct *ts = (TypeStruct *)tv;
1378 StructDeclaration *sd = ts->sym;
1379 if (sd->dtor)
1380 return TRUE;
1381 }
1382
1383 // Destructors for classes
1384 if (storage_class & (STCauto | STCscope))
1385 {
1386 if (type->isClassHandle())
1387 return TRUE;
1388 }
1389 return FALSE;
1390 }
1391
1392
1393 /******************************************
1394 * If a variable has an auto destructor call, return call for it.
1395 * Otherwise, return NULL.
1396 */
1397
1398 Expression *VarDeclaration::callAutoDtor(Scope *sc)
1399 { Expression *e = NULL;
1400
1401 //printf("VarDeclaration::callAutoDtor() %s\n", toChars());
1402
1403 if (noauto || storage_class & STCnodtor)
1404 return NULL;
1405
1406 // Destructors for structs and arrays of structs
1407 bool array = false;
1408 Type *tv = type->toBasetype();
1409 while (tv->ty == Tsarray)
1410 { TypeSArray *ta = (TypeSArray *)tv;
1411 array = true;
1412 tv = tv->nextOf()->toBasetype();
1413 }
1414 if (tv->ty == Tstruct)
1415 { TypeStruct *ts = (TypeStruct *)tv;
1416 StructDeclaration *sd = ts->sym;
1417 if (sd->dtor)
1418 {
1419 if (array)
1420 {
1421 // Typeinfo.destroy(cast(void*)&v);
1422 Expression *ea = new SymOffExp(loc, this, 0, 0);
1423 ea = new CastExp(loc, ea, Type::tvoid->pointerTo());
1424 Expressions *args = new Expressions();
1425 args->push(ea);
1426
1427 Expression *et = type->getTypeInfo(sc);
1428 et = new DotIdExp(loc, et, Id::destroy);
1429
1430 e = new CallExp(loc, et, args);
1431 }
1432 else
1433 {
1434 e = new VarExp(loc, this);
1435 e = new DotVarExp(loc, e, sd->dtor, 0);
1436 e = new CallExp(loc, e);
1437 }
1438 return e;
1439 }
1440 }
1441
1442 // Destructors for classes
1443 if (storage_class & (STCauto | STCscope))
1444 {
1445 for (ClassDeclaration *cd = type->isClassHandle();
1446 cd;
1447 cd = cd->baseClass)
1448 {
1449 /* We can do better if there's a way with onstack
1450 * classes to determine if there's no way the monitor
1451 * could be set.
1452 */
1453 //if (cd->isInterfaceDeclaration())
1454 //error("interface %s cannot be scope", cd->toChars());
1455 if (1 || onstack || cd->dtors.dim) // if any destructors
1456 {
1457 // delete this;
1458 Expression *ec;
1459
1460 ec = new VarExp(loc, this);
1461 e = new DeleteExp(loc, ec);
1462 e->type = Type::tvoid;
1463 break;
1464 }
1465 }
1466 }
1467 return e;
1468 }
1469
1470
1471 /********************************* ClassInfoDeclaration ****************************/
1472
1473 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
1474 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
1475 {
1476 this->cd = cd;
1477 storage_class = STCstatic;
1478 }
1479
1480 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
1481 {
1482 assert(0); // should never be produced by syntax
1483 return NULL;
1484 }
1485
1486 void ClassInfoDeclaration::semantic(Scope *sc)
1487 {
1488 }
1489
1490 /********************************* ModuleInfoDeclaration ****************************/
1491
1492 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
1493 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
1494 {
1495 this->mod = mod;
1496 storage_class = STCstatic;
1497 }
1498
1499 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
1500 {
1501 assert(0); // should never be produced by syntax
1502 return NULL;
1503 }
1504
1505 void ModuleInfoDeclaration::semantic(Scope *sc)
1506 {
1507 }
1508
1509 /********************************* TypeInfoDeclaration ****************************/
1510
1511 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
1512 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
1513 {
1514 this->tinfo = tinfo;
1515 storage_class = STCstatic;
1516 protection = PROTpublic;
1517 linkage = LINKc;
1518 }
1519
1520 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
1521 {
1522 assert(0); // should never be produced by syntax
1523 return NULL;
1524 }
1525
1526 void TypeInfoDeclaration::semantic(Scope *sc)
1527 {
1528 assert(linkage == LINKc);
1529 }
1530
1531 /***************************** TypeInfoConstDeclaration **********************/
1532
1533 #if DMDV2
1534 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1535 : TypeInfoDeclaration(tinfo, 0)
1536 {
1537 }
1538 #endif
1539
1540 /***************************** TypeInfoInvariantDeclaration **********************/
1541
1542 #if DMDV2
1543 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1544 : TypeInfoDeclaration(tinfo, 0)
1545 {
1546 }
1547 #endif
1548
1549 /***************************** TypeInfoStructDeclaration **********************/
1550
1551 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1552 : TypeInfoDeclaration(tinfo, 0)
1553 {
1554 }
1555
1556 /***************************** TypeInfoClassDeclaration ***********************/
1557
1558 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1559 : TypeInfoDeclaration(tinfo, 0)
1560 {
1561 }
1562
1563 /***************************** TypeInfoInterfaceDeclaration *******************/
1564
1565 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1566 : TypeInfoDeclaration(tinfo, 0)
1567 {
1568 }
1569
1570 /***************************** TypeInfoTypedefDeclaration *********************/
1571
1572 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
1573 : TypeInfoDeclaration(tinfo, 0)
1574 {
1575 }
1576
1577 /***************************** TypeInfoPointerDeclaration *********************/
1578
1579 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1580 : TypeInfoDeclaration(tinfo, 0)
1581 {
1582 }
1583
1584 /***************************** TypeInfoArrayDeclaration ***********************/
1585
1586 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1587 : TypeInfoDeclaration(tinfo, 0)
1588 {
1589 }
1590
1591 /***************************** TypeInfoStaticArrayDeclaration *****************/
1592
1593 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1594 : TypeInfoDeclaration(tinfo, 0)
1595 {
1596 }
1597
1598 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1599
1600 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1601 : TypeInfoDeclaration(tinfo, 0)
1602 {
1603 }
1604
1605 /***************************** TypeInfoEnumDeclaration ***********************/
1606
1607 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1608 : TypeInfoDeclaration(tinfo, 0)
1609 {
1610 }
1611
1612 /***************************** TypeInfoFunctionDeclaration ********************/
1613
1614 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1615 : TypeInfoDeclaration(tinfo, 0)
1616 {
1617 }
1618
1619 /***************************** TypeInfoDelegateDeclaration ********************/
1620
1621 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1622 : TypeInfoDeclaration(tinfo, 0)
1623 {
1624 }
1625
1626 /***************************** TypeInfoTupleDeclaration **********************/
1627
1628 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1629 : TypeInfoDeclaration(tinfo, 0)
1630 {
1631 }
1632
1633 /********************************* ThisDeclaration ****************************/
1634
1635 // For the "this" parameter to member functions
1636
1637 ThisDeclaration::ThisDeclaration(Type *t)
1638 : VarDeclaration(0, t, Id::This, NULL)
1639 {
1640 noauto = 1;
1641 }
1642
1643 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
1644 {
1645 assert(0); // should never be produced by syntax
1646 return NULL;
1647 }
1648
1649