Fixed parsing of maybe types in statements
[delight/core.git] / dmd2 / declaration.c
blobd9d541da2cafbb8ec0f8457a4eabdf374ec2c7b9
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.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 #include <stdio.h>
18 #include <assert.h>
20 #include "init.h"
21 #include "declaration.h"
22 #include "attrib.h"
23 #include "mtype.h"
24 #include "template.h"
25 #include "scope.h"
26 #include "aggregate.h"
27 #include "module.h"
28 #include "id.h"
29 #include "expression.h"
30 #include "hdrgen.h"
32 /********************************* Declaration ****************************/
34 Declaration::Declaration(Identifier *id)
35 : Dsymbol(id)
37 type = NULL;
38 originalType = NULL;
39 storage_class = STCundefined;
40 protection = PROTundefined;
41 linkage = LINKdefault;
42 attributes = NULL;
45 void Declaration::semantic(Scope *sc)
49 char *Declaration::kind()
51 return "declaration";
54 target_size_t Declaration::size(Loc loc)
56 assert(type);
57 return type->size();
60 int Declaration::isStaticConstructor()
62 return FALSE;
65 int Declaration::isStaticDestructor()
67 return FALSE;
70 int Declaration::isDelete()
72 return FALSE;
75 int Declaration::isDataseg()
77 return FALSE;
80 int Declaration::isCodeseg()
82 return FALSE;
85 enum PROT Declaration::prot()
87 return protection;
90 /*************************************
91 * Check to see if declaration can be modified in this context (sc).
92 * Issue error if not.
95 void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
97 if (sc->incontract && isParameter())
98 error(loc, "cannot modify parameter '%s' in contract", toChars());
100 if (isCtorinit())
101 { // It's only modifiable if inside the right constructor
102 Dsymbol *s = sc->func;
103 while (1)
105 FuncDeclaration *fd = NULL;
106 if (s)
107 fd = s->isFuncDeclaration();
108 if (fd &&
109 ((fd->isCtorDeclaration() && storage_class & STCfield) ||
110 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
111 fd->toParent() == toParent()
114 VarDeclaration *v = isVarDeclaration();
115 assert(v);
116 v->ctorinit = 1;
117 //printf("setting ctorinit\n");
119 else
121 if (s)
122 { s = s->toParent2();
123 continue;
125 else
127 const char *p = isStatic() ? "static " : "";
128 error(loc, "can only initialize %sconst %s inside %sconstructor",
129 p, toChars(), p);
132 break;
135 else
137 VarDeclaration *v = isVarDeclaration();
138 if (v && v->canassign == 0)
140 char *p = NULL;
141 if (isConst())
142 p = "const";
143 else if (isInvariant())
144 p = "invariant";
145 else if (storage_class & STCmanifest)
146 p = "manifest constant";
147 else if (!t->isAssignable())
148 p = "struct with immutable members";
149 if (p)
150 { error(loc, "cannot modify %s", p);
151 halt();
158 /********************************* TupleDeclaration ****************************/
160 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
161 : Declaration(id)
163 this->type = NULL;
164 this->objects = objects;
165 this->isexp = 0;
166 this->tupletype = NULL;
169 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
171 assert(0);
172 return NULL;
175 char *TupleDeclaration::kind()
177 return "tuple";
180 Type *TupleDeclaration::getType()
182 /* If this tuple represents a type, return that type
185 //printf("TupleDeclaration::getType() %s\n", toChars());
186 if (isexp)
187 return NULL;
188 if (!tupletype)
190 /* It's only a type tuple if all the Object's are types
192 for (size_t i = 0; i < objects->dim; i++)
193 { Object *o = (Object *)objects->data[i];
195 if (o->dyncast() != DYNCAST_TYPE)
197 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
198 return NULL;
202 /* We know it's a type tuple, so build the TypeTuple
204 Arguments *args = new Arguments();
205 args->setDim(objects->dim);
206 OutBuffer buf;
207 for (size_t i = 0; i < objects->dim; i++)
208 { Type *t = (Type *)objects->data[i];
210 //printf("type = %s\n", t->toChars());
211 #if 0
212 buf.printf("_%s_%d", ident->toChars(), i);
213 char *name = (char *)buf.extractData();
214 Identifier *id = new Identifier(name, TOKidentifier);
215 Argument *arg = new Argument(STCin, t, id, NULL);
216 #else
217 Argument *arg = new Argument(0, t, NULL, NULL);
218 #endif
219 args->data[i] = (void *)arg;
222 tupletype = new TypeTuple(args);
225 return tupletype;
228 int TupleDeclaration::needThis()
230 //printf("TupleDeclaration::needThis(%s)\n", toChars());
231 for (size_t i = 0; i < objects->dim; i++)
232 { Object *o = (Object *)objects->data[i];
233 if (o->dyncast() == DYNCAST_EXPRESSION)
234 { Expression *e = (Expression *)o;
235 if (e->op == TOKdsymbol)
236 { DsymbolExp *ve = (DsymbolExp *)e;
237 Declaration *d = ve->s->isDeclaration();
238 if (d && d->needThis())
240 return 1;
245 return 0;
248 /********************************* TypedefDeclaration ****************************/
250 TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init)
251 : Declaration(id)
253 this->type = new TypeTypedef(this);
254 this->basetype = basetype->toBasetype();
255 this->init = init;
256 #ifdef _DH
257 this->htype = NULL;
258 this->hbasetype = NULL;
259 #endif
260 this->sem = 0;
261 this->inuse = 0;
262 this->loc = loc;
263 this->sinit = NULL;
266 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
268 Type *basetype = this->basetype->syntaxCopy();
270 Initializer *init = NULL;
271 if (this->init)
272 init = this->init->syntaxCopy();
274 assert(!s);
275 TypedefDeclaration *st;
276 st = new TypedefDeclaration(loc, ident, basetype, init);
277 #ifdef _DH
278 // Syntax copy for header file
279 if (!htype) // Don't overwrite original
280 { if (type) // Make copy for both old and new instances
281 { htype = type->syntaxCopy();
282 st->htype = type->syntaxCopy();
285 else // Make copy of original for new instance
286 st->htype = htype->syntaxCopy();
287 if (!hbasetype)
288 { if (basetype)
289 { hbasetype = basetype->syntaxCopy();
290 st->hbasetype = basetype->syntaxCopy();
293 else
294 st->hbasetype = hbasetype->syntaxCopy();
295 #endif
296 return st;
299 void TypedefDeclaration::semantic(Scope *sc)
301 //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
302 if (sem == 0)
303 { sem = 1;
304 basetype = basetype->semantic(loc, sc);
305 sem = 2;
306 type = type->semantic(loc, sc);
307 if (attributes)
308 attributes->append(sc->attributes);
309 else
310 attributes = sc->attributes;
311 if (sc->parent->isFuncDeclaration() && init)
312 semantic2(sc);
314 else if (sem == 1)
316 error("circular definition");
320 void TypedefDeclaration::semantic2(Scope *sc)
322 //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
323 if (sem == 2)
324 { sem = 3;
325 if (init)
327 init = init->semantic(sc, basetype);
329 ExpInitializer *ie = init->isExpInitializer();
330 if (ie)
332 if (ie->exp->type == basetype)
333 ie->exp->type = type;
339 char *TypedefDeclaration::kind()
341 return "typedef";
344 Type *TypedefDeclaration::getType()
346 return type;
349 void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
351 buf->writestring("typedef ");
352 basetype->toCBuffer(buf, ident, hgs);
353 if (init)
355 buf->writestring(" = ");
356 init->toCBuffer(buf, hgs);
358 buf->writeByte(';');
359 buf->writenl();
362 /********************************* AliasDeclaration ****************************/
364 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
365 : Declaration(id)
367 //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
368 //printf("type = '%s'\n", type->toChars());
369 this->loc = loc;
370 this->type = type;
371 this->aliassym = NULL;
372 #ifdef _DH
373 this->htype = NULL;
374 this->haliassym = NULL;
375 #endif
376 this->overnext = NULL;
377 this->inSemantic = 0;
378 assert(type);
381 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
382 : Declaration(id)
384 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
385 assert(s != this);
386 this->loc = loc;
387 this->type = NULL;
388 this->aliassym = s;
389 #ifdef _DH
390 this->htype = NULL;
391 this->haliassym = NULL;
392 #endif
393 this->overnext = NULL;
394 this->inSemantic = 0;
395 assert(s);
398 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
400 //printf("AliasDeclaration::syntaxCopy()\n");
401 assert(!s);
402 AliasDeclaration *sa;
403 if (type)
404 sa = new AliasDeclaration(loc, ident, type->syntaxCopy());
405 else
406 sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
407 #ifdef _DH
408 // Syntax copy for header file
409 if (!htype) // Don't overwrite original
410 { if (type) // Make copy for both old and new instances
411 { htype = type->syntaxCopy();
412 sa->htype = type->syntaxCopy();
415 else // Make copy of original for new instance
416 sa->htype = htype->syntaxCopy();
417 if (!haliassym)
418 { if (aliassym)
419 { haliassym = aliassym->syntaxCopy(s);
420 sa->haliassym = aliassym->syntaxCopy(s);
423 else
424 sa->haliassym = haliassym->syntaxCopy(s);
425 #endif
426 return sa;
429 void AliasDeclaration::semantic(Scope *sc)
431 //printf("AliasDeclaration::semantic() %s\n", toChars());
432 if (aliassym)
434 if (aliassym->isTemplateInstance())
435 aliassym->semantic(sc);
436 return;
438 this->inSemantic = 1;
440 if (storage_class & STCconst)
441 error("cannot be const");
443 storage_class |= sc->stc & STCdeprecated;
445 // Given:
446 // alias foo.bar.abc def;
447 // it is not knowable from the syntax whether this is an alias
448 // for a type or an alias for a symbol. It is up to the semantic()
449 // pass to distinguish.
450 // If it is a type, then type is set and getType() will return that
451 // type. If it is a symbol, then aliassym is set and type is NULL -
452 // toAlias() will return aliasssym.
454 Dsymbol *s;
455 Type *t;
456 Expression *e;
458 /* This section is needed because resolve() will:
459 * const x = 3;
460 * alias x y;
461 * try to alias y to 3.
463 s = type->toDsymbol(sc);
464 if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()))
465 goto L2; // it's a symbolic alias
467 //printf("alias type is %s\n", type->toChars());
468 type->resolve(loc, sc, &e, &t, &s);
469 if (s)
471 goto L2;
473 else if (e)
475 // Try to convert Expression to Dsymbol
476 s = getDsymbol(e);
477 if (s)
478 goto L2;
480 error("cannot alias an expression %s", e->toChars());
481 t = e->type;
483 else if (t)
484 type = t;
485 if (overnext)
486 ScopeDsymbol::multiplyDefined(0, this, overnext);
487 this->inSemantic = 0;
488 return;
491 //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
492 type = NULL;
493 VarDeclaration *v = s->isVarDeclaration();
494 if (v && v->linkage == LINKdefault)
496 error("forward reference of %s", v->toChars());
497 s = NULL;
499 else
501 FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
502 if (f)
504 if (overnext)
506 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
507 if (!fa->overloadInsert(overnext))
508 ScopeDsymbol::multiplyDefined(0, f, overnext);
509 overnext = NULL;
510 s = fa;
511 s->parent = sc->parent;
514 if (overnext)
515 ScopeDsymbol::multiplyDefined(0, s, overnext);
516 if (s == this)
518 assert(global.errors);
519 s = NULL;
522 aliassym = s;
523 this->inSemantic = 0;
526 int AliasDeclaration::overloadInsert(Dsymbol *s)
528 /* Don't know yet what the aliased symbol is, so assume it can
529 * be overloaded and check later for correctness.
532 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
533 if (overnext == NULL)
534 { overnext = s;
535 return TRUE;
537 else
539 return overnext->overloadInsert(s);
543 char *AliasDeclaration::kind()
545 return "alias";
548 Type *AliasDeclaration::getType()
550 return type;
553 Dsymbol *AliasDeclaration::toAlias()
555 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
556 assert(this != aliassym);
557 //static int count; if (++count == 10) *(char*)0=0;
558 if (inSemantic)
559 { error("recursive alias declaration");
560 // return this;
562 Dsymbol *s = aliassym ? aliassym->toAlias() : this;
563 return s;
566 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
568 buf->writestring("alias ");
569 #if 0 && _DH
570 if (hgs->hdrgen)
572 if (haliassym)
574 haliassym->toCBuffer(buf, hgs);
575 buf->writeByte(' ');
576 buf->writestring(ident->toChars());
578 else
579 htype->toCBuffer(buf, ident, hgs);
581 else
582 #endif
584 if (aliassym)
586 aliassym->toCBuffer(buf, hgs);
587 buf->writeByte(' ');
588 buf->writestring(ident->toChars());
590 else
591 type->toCBuffer(buf, ident, hgs);
593 buf->writeByte(';');
594 buf->writenl();
597 /********************************* VarDeclaration ****************************/
599 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
600 : Declaration(id)
602 //printf("VarDeclaration('%s')\n", id->toChars());
603 #ifdef DEBUG
604 if (!type && !init)
605 { printf("VarDeclaration('%s')\n", id->toChars());
606 //*(char*)0=0;
608 #endif
609 assert(type || init);
610 this->type = type;
611 this->init = init;
612 #ifdef _DH
613 this->htype = NULL;
614 this->hinit = NULL;
615 #endif
616 this->loc = loc;
617 offset = 0;
618 noauto = 0;
619 inuse = 0;
620 ctorinit = 0;
621 aliassym = NULL;
622 onstack = 0;
623 canassign = 0;
624 value = NULL;
625 scope = NULL;
628 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
630 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
632 VarDeclaration *sv;
633 if (s)
634 { sv = (VarDeclaration *)s;
636 else
638 Initializer *init = NULL;
639 if (this->init)
640 { init = this->init->syntaxCopy();
641 //init->isExpInitializer()->exp->print();
642 //init->isExpInitializer()->exp->dump(0);
645 sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
646 sv->storage_class = storage_class;
648 #ifdef _DH
649 // Syntax copy for header file
650 if (!htype) // Don't overwrite original
651 { if (type) // Make copy for both old and new instances
652 { htype = type->syntaxCopy();
653 sv->htype = type->syntaxCopy();
656 else // Make copy of original for new instance
657 sv->htype = htype->syntaxCopy();
658 if (!hinit)
659 { if (init)
660 { hinit = init->syntaxCopy();
661 sv->hinit = init->syntaxCopy();
664 else
665 sv->hinit = hinit->syntaxCopy();
666 #endif
667 return sv;
670 void VarDeclaration::semantic(Scope *sc)
672 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
673 //printf(" type = %s\n", type ? type->toChars() : "null");
674 //printf(" stc = x%x\n", sc->stc);
675 //printf(" storage_class = x%x\n", storage_class);
676 //printf("linkage = %d\n", sc->linkage);
677 //if (strcmp(toChars(), "mul") == 0) halt();
679 storage_class |= sc->stc;
680 if (storage_class & STCextern && init)
681 error("extern symbols cannot have initializers");
683 /* If auto type inference, do the inference
685 int inferred = 0;
686 if (!type)
687 { inuse++;
688 type = init->inferType(sc);
689 inuse--;
690 inferred = 1;
692 /* This is a kludge to support the existing syntax for RAII
693 * declarations.
695 storage_class &= ~STCauto;
696 originalType = type;
698 else
699 { if (!originalType)
700 originalType = type;
701 type = type->semantic(loc, sc);
703 //printf(" semantic type = %s\n", type ? type->toChars() : "null");
705 type->checkDeprecated(loc, sc);
706 linkage = sc->linkage;
707 this->parent = sc->parent;
708 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
709 protection = sc->protection;
710 if (attributes)
711 attributes->append(sc->attributes);
712 else
713 attributes = sc->attributes;
714 //printf("sc->stc = %x\n", sc->stc);
715 //printf("storage_class = x%x\n", storage_class);
717 Dsymbol *parent = toParent();
718 FuncDeclaration *fd = parent->isFuncDeclaration();
720 Type *tb = type->toBasetype();
721 if (tb->ty == Tvoid && !(storage_class & STClazy))
722 { error("voids have no value");
723 type = Type::terror;
724 tb = type;
726 if (tb->ty == Tfunction)
727 { error("cannot be declared to be a function");
728 type = Type::terror;
729 tb = type;
731 if (tb->ty == Tstruct)
732 { TypeStruct *ts = (TypeStruct *)tb;
734 if (!ts->sym->members)
736 error("no definition of struct %s", ts->toChars());
740 if (tb->ty == Ttuple)
741 { /* Instead, declare variables for each of the tuple elements
742 * and add those.
744 TypeTuple *tt = (TypeTuple *)tb;
745 size_t nelems = Argument::dim(tt->arguments);
746 Objects *exps = new Objects();
747 exps->setDim(nelems);
748 Expression *ie = init ? init->toExpression() : NULL;
750 for (size_t i = 0; i < nelems; i++)
751 { Argument *arg = Argument::getNth(tt->arguments, i);
753 OutBuffer buf;
754 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i);
755 buf.writeByte(0);
756 char *name = (char *)buf.extractData();
757 Identifier *id = new Identifier(name, TOKidentifier);
759 Expression *einit = ie;
760 if (ie && ie->op == TOKtuple)
761 { einit = (Expression *)((TupleExp *)ie)->exps->data[i];
763 Initializer *ti = init;
764 if (einit)
765 { ti = new ExpInitializer(einit->loc, einit);
768 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
769 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
770 v->semantic(sc);
772 if (sc->scopesym)
773 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
774 if (sc->scopesym->members)
775 sc->scopesym->members->push(v);
778 Expression *e = new DsymbolExp(loc, v);
779 exps->data[i] = e;
781 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
782 v2->isexp = 1;
783 aliassym = v2;
784 return;
787 Lagain:
788 if (storage_class & STCinvariant)
790 type = type->invariantOf();
792 else if (storage_class & (STCconst | STCin))
794 if (!type->isInvariant())
795 type = type->constOf();
797 else if (type->isConst())
798 storage_class |= STCconst;
799 else if (type->isInvariant())
800 storage_class |= STCinvariant;
802 if (isSynchronized())
804 error("variable %s cannot be synchronized", toChars());
806 else if (isOverride())
808 error("override cannot be applied to variable");
810 else if (isAbstract())
812 error("abstract cannot be applied to variable");
814 else if (storage_class & STCfinal)
816 error("final cannot be applied to variable");
819 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls))
822 else
824 AggregateDeclaration *aad = sc->anonAgg;
825 if (!aad)
826 aad = parent->isAggregateDeclaration();
827 if (aad)
828 { assert(!(storage_class & (STCextern | STCstatic | STCtls)));
830 if (storage_class & (STCconst | STCinvariant) && init)
832 if (!type->toBasetype()->isTypeBasic())
833 storage_class |= STCstatic;
835 else
836 aad->addField(sc, this);
839 InterfaceDeclaration *id = parent->isInterfaceDeclaration();
840 if (id)
842 error("field not allowed in interface");
845 /* Templates cannot add fields to aggregates
847 TemplateInstance *ti = parent->isTemplateInstance();
848 if (ti)
850 // Take care of nested templates
851 while (1)
853 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
854 if (!ti2)
855 break;
856 ti = ti2;
859 // If it's a member template
860 AggregateDeclaration *ad = ti->tempdecl->isMember();
861 if (ad && storage_class != STCundefined)
863 error("cannot use template to add field to aggregate '%s'", ad->toChars());
868 if (type->isauto() && !noauto)
870 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd)
872 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto");
875 if (!(storage_class & (STCauto | STCscope)))
877 if (!(storage_class & STCparameter) && ident != Id::withSym)
878 error("reference to scope class must be scope");
882 if ((isConst() || isInvariant()) && !init && !fd)
883 { // Initialize by constructor only
884 storage_class |= STCctorinit;
887 if (init)
888 storage_class |= STCinit; // remember we had an explicit initializer
889 else if (storage_class & STCmanifest)
890 error("manifest constants must have initializers");
892 enum TOK op = TOKconstruct;
893 if (!init && !sc->inunion && !isStatic() && fd &&
894 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) &&
895 type->size() != 0)
897 // Provide a default initializer
898 //printf("Providing default initializer for '%s'\n", toChars());
899 if (type->ty == Tstruct &&
900 ((TypeStruct *)type)->sym->zeroInit == 1)
901 { /* If a struct is all zeros, as a special case
902 * set it's initializer to the integer 0.
903 * In AssignExp::toElem(), we check for this and issue
904 * a memset() to initialize the struct.
905 * Must do same check in interpreter.
907 Expression *e = new IntegerExp(loc, 0, Type::tint32);
908 Expression *e1;
909 e1 = new VarExp(loc, this);
910 e = new AssignExp(loc, e1, e);
911 e->type = e1->type; // don't type check this, it would fail
912 init = new ExpInitializer(loc, e);
913 return;
915 else if (type->ty == Ttypedef)
916 { TypeTypedef *td = (TypeTypedef *)type;
917 if (td->sym->init)
918 { init = td->sym->init;
919 ExpInitializer *ie = init->isExpInitializer();
920 if (ie)
921 // Make copy so we can modify it
922 init = new ExpInitializer(ie->loc, ie->exp);
924 else
925 init = getExpInitializer();
927 else
929 init = getExpInitializer();
931 // Default initializer is always a blit
932 op = TOKblit;
935 if (init)
937 ArrayInitializer *ai = init->isArrayInitializer();
938 if (ai && tb->ty == Taarray)
940 init = ai->toAssocArrayInitializer();
943 StructInitializer *si = init->isStructInitializer();
944 ExpInitializer *ei = init->isExpInitializer();
946 // See if we can allocate on the stack
947 if (ei && isScope() && ei->exp->op == TOKnew)
948 { NewExp *ne = (NewExp *)ei->exp;
949 if (!(ne->newargs && ne->newargs->dim))
950 { ne->onstack = 1;
951 onstack = 1;
952 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
953 onstack = 2;
957 // If inside function, there is no semantic3() call
958 if (sc->func)
960 // If local variable, use AssignExp to handle all the various
961 // possibilities.
962 if (fd && !isStatic() && !(storage_class & STCmanifest) &&
963 !init->isVoidInitializer())
965 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
966 if (!ei)
968 Expression *e = init->toExpression();
969 if (!e)
971 init = init->semantic(sc, type);
972 e = init->toExpression();
973 if (!e)
974 { error("is not a static and cannot have static initializer");
975 return;
978 ei = new ExpInitializer(init->loc, e);
979 init = ei;
982 Expression *e1 = new VarExp(loc, this);
984 Type *t = type->toBasetype();
985 if (t->ty == Tsarray)
987 ei->exp = ei->exp->semantic(sc);
988 if (!ei->exp->implicitConvTo(type))
990 sinteger_t dim = ((TypeSArray *)t)->dim->toInteger();
991 // If multidimensional static array, treat as one large array
992 while (1)
994 t = t->nextOf()->toBasetype();
995 if (t->ty != Tsarray)
996 break;
997 dim *= ((TypeSArray *)t)->dim->toInteger();
998 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
1001 e1 = new SliceExp(loc, e1, NULL, NULL);
1003 else if (t->ty == Tstruct)
1005 ei->exp = ei->exp->semantic(sc);
1006 if (!ei->exp->implicitConvTo(type))
1007 { Type *ti = ei->exp->type->toBasetype();
1008 // Don't cast away invariant or mutability in initializer
1009 if (!(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1010 ei->exp = new CastExp(loc, ei->exp, type);
1013 ei->exp = new AssignExp(loc, e1, ei->exp);
1014 ei->exp->op = op;
1015 canassign++;
1016 ei->exp = ei->exp->semantic(sc);
1017 canassign--;
1018 ei->exp->optimize(WANTvalue);
1020 else
1022 init = init->semantic(sc, type);
1025 else if (storage_class & (STCconst | STCinvariant | STCmanifest) ||
1026 type->isConst() || type->isInvariant())
1028 /* Because we may need the results of a const declaration in a
1029 * subsequent type, such as an array dimension, before semantic2()
1030 * gets ordinarily run, try to run semantic2() now.
1031 * Ignore failure.
1034 if (!global.errors && !inferred)
1036 unsigned errors = global.errors;
1037 global.gag++;
1038 //printf("+gag\n");
1039 Expression *e;
1040 Initializer *i2 = init;
1041 inuse++;
1042 if (ei)
1044 e = ei->exp->syntaxCopy();
1045 e = e->semantic(sc);
1046 e = e->implicitCastTo(sc, type);
1048 else if (si || ai)
1049 { i2 = init->syntaxCopy();
1050 i2 = i2->semantic(sc, type);
1052 inuse--;
1053 global.gag--;
1054 //printf("-gag\n");
1055 if (errors != global.errors) // if errors happened
1057 if (global.gag == 0)
1058 global.errors = errors; // act as if nothing happened
1060 /* Save scope for later use, to try again
1062 scope = new Scope(*sc);
1063 scope->setNoFree();
1065 else if (ei)
1067 if (isDataseg())
1068 /* static const/invariant does CTFE
1070 e = e->optimize(WANTvalue | WANTinterpret);
1071 else
1072 e = e->optimize(WANTvalue);
1073 if (e->op == TOKint64 || e->op == TOKstring)
1075 ei->exp = e; // no errors, keep result
1077 else
1079 /* Save scope for later use, to try again
1081 scope = new Scope(*sc);
1082 scope->setNoFree();
1085 else
1086 init = i2; // no errors, keep result
1092 void VarDeclaration::semantic2(Scope *sc)
1094 //printf("VarDeclaration::semantic2('%s')\n", toChars());
1095 if (init && !toParent()->isFuncDeclaration())
1096 { inuse++;
1097 #if 0
1098 ExpInitializer *ei = init->isExpInitializer();
1099 if (ei)
1101 ei->exp->dump(0);
1102 printf("type = %p\n", ei->exp->type);
1104 #endif
1105 init = init->semantic(sc, type);
1106 inuse--;
1110 char *VarDeclaration::kind()
1112 return "variable";
1115 Dsymbol *VarDeclaration::toAlias()
1117 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1118 assert(this != aliassym);
1119 Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1120 return s;
1123 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1125 if (storage_class & STCmanifest)
1126 buf->writestring("manifest ");
1127 if (storage_class & STCstatic)
1128 buf->writestring("static ");
1129 if (storage_class & STCtls)
1130 buf->writestring("__tls ");
1131 if (storage_class & STCconst)
1132 buf->writestring("const ");
1133 if (storage_class & STCinvariant)
1134 buf->writestring("invariant ");
1136 if (type)
1137 type->toCBuffer(buf, ident, hgs);
1138 else
1139 buf->writestring(ident->toChars());
1140 if (init)
1141 { buf->writestring(" = ");
1142 ExpInitializer *ie = init->isExpInitializer();
1143 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1144 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
1145 else
1146 init->toCBuffer(buf, hgs);
1148 buf->writeByte(';');
1149 buf->writenl();
1152 int VarDeclaration::needThis()
1154 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1155 return storage_class & STCfield;
1158 int VarDeclaration::isImportedSymbol()
1160 if (protection == PROTexport && !init &&
1161 (storage_class & STCstatic || parent->isModule()))
1162 return TRUE;
1163 return FALSE;
1166 void VarDeclaration::checkCtorConstInit()
1168 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
1169 error("missing initializer in static constructor for const variable");
1172 /************************************
1173 * Check to see if this variable is actually in an enclosing function
1174 * rather than the current one.
1177 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1179 if (parent && !isDataseg() && parent != sc->parent &&
1180 !(storage_class & STCmanifest))
1182 // The function that this variable is in
1183 FuncDeclaration *fdv = toParent()->isFuncDeclaration();
1184 // The current function
1185 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1187 if (fdv && fdthis && fdv != fdthis)
1189 if (loc.filename)
1190 fdthis->getLevel(loc, fdv);
1192 for (int i = 0; i < nestedrefs.dim; i++)
1193 { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i];
1194 if (f == fdthis)
1195 goto L1;
1197 nestedrefs.push(fdthis);
1198 L1: ;
1201 for (int i = 0; i < fdv->closureVars.dim; i++)
1202 { Dsymbol *s = (Dsymbol *)fdv->closureVars.data[i];
1203 if (s == this)
1204 goto L2;
1207 fdv->closureVars.push(this);
1208 L2: ;
1210 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1215 /****************************
1216 * Get ExpInitializer for a variable, if there is one.
1219 ExpInitializer *VarDeclaration::getExpInitializer()
1221 ExpInitializer *ei;
1223 if (init)
1224 ei = init->isExpInitializer();
1225 else
1227 Expression *e = type->defaultInit();
1228 if (e)
1229 ei = new ExpInitializer(loc, e);
1230 else
1231 ei = NULL;
1233 return ei;
1236 /*******************************************
1237 * If variable has a constant expression initializer, get it.
1238 * Otherwise, return NULL.
1241 Expression *VarDeclaration::getConstInitializer()
1243 if ((isConst() || isInvariant() || storage_class & STCmanifest) &&
1244 storage_class & STCinit)
1246 ExpInitializer *ei = getExpInitializer();
1247 if (ei)
1248 return ei->exp;
1251 return NULL;
1254 /*************************************
1255 * Return !=0 if we can take the address of this variable.
1258 int VarDeclaration::canTakeAddressOf()
1260 #if 0
1261 /* Global variables and struct/class fields of the form:
1262 * const int x = 3;
1263 * are not stored and hence cannot have their address taken.
1265 if ((isConst() || isInvariant()) &&
1266 storage_class & STCinit &&
1267 (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) &&
1268 (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) &&
1269 type->toBasetype()->isTypeBasic()
1272 return 0;
1274 #else
1275 if (storage_class & STCmanifest)
1276 return 0;
1277 #endif
1278 return 1;
1281 /*******************************
1282 * Does symbol go into data segment?
1283 * Includes extern variables.
1286 int VarDeclaration::isDataseg()
1288 #if 0
1289 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1290 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
1291 printf("parent = '%s'\n", parent->toChars());
1292 #endif
1293 if (storage_class & STCmanifest)
1294 return 0;
1295 Dsymbol *parent = this->toParent();
1296 if (!parent && !(storage_class & STCstatic))
1297 { error("forward referenced");
1298 type = Type::terror;
1299 return 0;
1301 return canTakeAddressOf() &&
1302 (storage_class & (STCstatic | STCextern | STCtls) ||
1303 toParent()->isModule() ||
1304 toParent()->isTemplateInstance());
1307 int VarDeclaration::hasPointers()
1309 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1310 return (!isDataseg() && type->hasPointers());
1313 /******************************************
1314 * Return TRUE if variable needs to call the destructor.
1317 int VarDeclaration::needsAutoDtor()
1319 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1321 if (noauto || storage_class & STCnodtor)
1322 return FALSE;
1324 // Destructors for structs and arrays of structs
1325 Type *tv = type->toBasetype();
1326 while (tv->ty == Tsarray)
1327 { TypeSArray *ta = (TypeSArray *)tv;
1328 tv = tv->nextOf()->toBasetype();
1330 if (tv->ty == Tstruct)
1331 { TypeStruct *ts = (TypeStruct *)tv;
1332 StructDeclaration *sd = ts->sym;
1333 if (sd->dtor)
1334 return TRUE;
1337 // Destructors for classes
1338 if (storage_class & (STCauto | STCscope))
1340 if (type->isClassHandle())
1341 return TRUE;
1343 return FALSE;
1347 /******************************************
1348 * If a variable has an auto destructor call, return call for it.
1349 * Otherwise, return NULL.
1352 Expression *VarDeclaration::callAutoDtor(Scope *sc)
1353 { Expression *e = NULL;
1355 //printf("VarDeclaration::callAutoDtor() %s\n", toChars());
1357 if (noauto || storage_class & STCnodtor)
1358 return NULL;
1360 // Destructors for structs and arrays of structs
1361 bool array = false;
1362 Type *tv = type->toBasetype();
1363 while (tv->ty == Tsarray)
1364 { TypeSArray *ta = (TypeSArray *)tv;
1365 array = true;
1366 tv = tv->nextOf()->toBasetype();
1368 if (tv->ty == Tstruct)
1369 { TypeStruct *ts = (TypeStruct *)tv;
1370 StructDeclaration *sd = ts->sym;
1371 if (sd->dtor)
1373 if (array)
1375 // Typeinfo.destroy(cast(void*)&v);
1376 Expression *ea = new SymOffExp(loc, this, 0, 0);
1377 ea = new CastExp(loc, ea, Type::tvoid->pointerTo());
1378 Expressions *args = new Expressions();
1379 args->push(ea);
1381 Expression *et = type->getTypeInfo(sc);
1382 et = new DotIdExp(loc, et, Id::destroy);
1384 e = new CallExp(loc, et, args);
1386 else
1388 e = new VarExp(loc, this);
1389 e = new DotVarExp(loc, e, sd->dtor, 0);
1390 e = new CallExp(loc, e);
1392 return e;
1396 // Destructors for classes
1397 if (storage_class & (STCauto | STCscope))
1399 for (ClassDeclaration *cd = type->isClassHandle();
1401 cd = cd->baseClass)
1403 /* We can do better if there's a way with onstack
1404 * classes to determine if there's no way the monitor
1405 * could be set.
1407 //if (cd->isInterfaceDeclaration())
1408 //error("interface %s cannot be scope", cd->toChars());
1409 if (1 || onstack || cd->dtors.dim) // if any destructors
1411 // delete this;
1412 Expression *ec;
1414 ec = new VarExp(loc, this);
1415 e = new DeleteExp(loc, ec);
1416 e->type = Type::tvoid;
1417 break;
1421 return e;
1425 /********************************* ClassInfoDeclaration ****************************/
1427 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
1428 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
1430 this->cd = cd;
1431 storage_class = STCstatic;
1434 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
1436 assert(0); // should never be produced by syntax
1437 return NULL;
1440 void ClassInfoDeclaration::semantic(Scope *sc)
1444 /********************************* ModuleInfoDeclaration ****************************/
1446 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
1447 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
1449 this->mod = mod;
1450 storage_class = STCstatic;
1453 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
1455 assert(0); // should never be produced by syntax
1456 return NULL;
1459 void ModuleInfoDeclaration::semantic(Scope *sc)
1463 /********************************* TypeInfoDeclaration ****************************/
1465 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
1466 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
1468 this->tinfo = tinfo;
1469 storage_class = STCstatic;
1470 protection = PROTpublic;
1471 linkage = LINKc;
1474 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
1476 assert(0); // should never be produced by syntax
1477 return NULL;
1480 void TypeInfoDeclaration::semantic(Scope *sc)
1482 assert(linkage == LINKc);
1485 /***************************** TypeInfoConstDeclaration **********************/
1487 #if V2
1488 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1489 : TypeInfoDeclaration(tinfo, 0)
1492 #endif
1494 /***************************** TypeInfoInvariantDeclaration **********************/
1496 #if V2
1497 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1498 : TypeInfoDeclaration(tinfo, 0)
1501 #endif
1503 /***************************** TypeInfoStructDeclaration **********************/
1505 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1506 : TypeInfoDeclaration(tinfo, 0)
1510 /***************************** TypeInfoClassDeclaration ***********************/
1512 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1513 : TypeInfoDeclaration(tinfo, 0)
1517 /***************************** TypeInfoInterfaceDeclaration *******************/
1519 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1520 : TypeInfoDeclaration(tinfo, 0)
1524 /***************************** TypeInfoTypedefDeclaration *********************/
1526 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
1527 : TypeInfoDeclaration(tinfo, 0)
1531 /***************************** TypeInfoPointerDeclaration *********************/
1533 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1534 : TypeInfoDeclaration(tinfo, 0)
1538 /***************************** TypeInfoArrayDeclaration ***********************/
1540 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1541 : TypeInfoDeclaration(tinfo, 0)
1545 /***************************** TypeInfoStaticArrayDeclaration *****************/
1547 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1548 : TypeInfoDeclaration(tinfo, 0)
1552 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1554 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1555 : TypeInfoDeclaration(tinfo, 0)
1559 /***************************** TypeInfoEnumDeclaration ***********************/
1561 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1562 : TypeInfoDeclaration(tinfo, 0)
1566 /***************************** TypeInfoFunctionDeclaration ********************/
1568 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1569 : TypeInfoDeclaration(tinfo, 0)
1573 /***************************** TypeInfoDelegateDeclaration ********************/
1575 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1576 : TypeInfoDeclaration(tinfo, 0)
1580 /***************************** TypeInfoTupleDeclaration **********************/
1582 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1583 : TypeInfoDeclaration(tinfo, 0)
1587 /********************************* ThisDeclaration ****************************/
1589 // For the "this" parameter to member functions
1591 ThisDeclaration::ThisDeclaration(Type *t)
1592 : VarDeclaration(0, t, Id::This, NULL)
1594 noauto = 1;
1597 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
1599 assert(0); // should never be produced by syntax
1600 return NULL;