Merged Delight changes to D1 into D2
[delight/core.git] / dmd2 / declaration.c
blob5da40744c678aa6257ce70f4e54ad0c5cd5196e5
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 skipnullcheck = 0;
620 dltNormalMode = 0;
621 inuse = 0;
622 ctorinit = 0;
623 aliassym = NULL;
624 onstack = 0;
625 canassign = 0;
626 value = NULL;
627 scope = NULL;
630 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
632 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
634 VarDeclaration *sv;
635 if (s)
636 { sv = (VarDeclaration *)s;
638 else
640 Initializer *init = NULL;
641 if (this->init)
642 { init = this->init->syntaxCopy();
643 //init->isExpInitializer()->exp->print();
644 //init->isExpInitializer()->exp->dump(0);
647 sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
648 sv->storage_class = storage_class;
650 sv->skipnullcheck = skipnullcheck;
651 #ifdef _DH
652 // Syntax copy for header file
653 if (!htype) // Don't overwrite original
654 { if (type) // Make copy for both old and new instances
655 { htype = type->syntaxCopy();
656 sv->htype = type->syntaxCopy();
659 else // Make copy of original for new instance
660 sv->htype = htype->syntaxCopy();
661 if (!hinit)
662 { if (init)
663 { hinit = init->syntaxCopy();
664 sv->hinit = init->syntaxCopy();
667 else
668 sv->hinit = hinit->syntaxCopy();
669 #endif
670 return sv;
673 void VarDeclaration::semantic(Scope *sc)
675 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
676 //printf(" type = %s\n", type ? type->toChars() : "null");
677 //printf(" stc = x%x\n", sc->stc);
678 //printf(" storage_class = x%x\n", storage_class);
679 //printf("linkage = %d\n", sc->linkage);
680 //if (strcmp(toChars(), "mul") == 0) halt();
682 storage_class |= sc->stc;
683 if (storage_class & STCextern && init)
684 error("extern symbols cannot have initializers");
686 if (dltNormalMode && (storage_class & STCstatic))
687 error("no static variables in Delight");
689 /* If auto type inference, do the inference
691 int inferred = 0;
692 if (!type)
693 { inuse++;
694 type = init->inferType(sc);
695 inuse--;
696 inferred = 1;
698 /* This is a kludge to support the existing syntax for RAII
699 * declarations.
701 storage_class &= ~STCauto;
702 originalType = type;
704 else
705 { if (!originalType)
706 originalType = type;
707 type = type->semantic(loc, sc);
709 //printf(" semantic type = %s\n", type ? type->toChars() : "null");
711 type->checkDeprecated(loc, sc);
712 linkage = sc->linkage;
713 this->parent = sc->parent;
714 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
715 protection = sc->protection;
716 if (attributes)
717 attributes->append(sc->attributes);
718 else
719 attributes = sc->attributes;
720 //printf("sc->stc = %x\n", sc->stc);
721 //printf("storage_class = x%x\n", storage_class);
723 Dsymbol *parent = toParent();
724 FuncDeclaration *fd = parent->isFuncDeclaration();
726 Type *tb = type->toBasetype();
727 if (tb->ty == Tvoid && !(storage_class & STClazy))
728 { error("voids have no value");
729 type = Type::terror;
730 tb = type;
732 if (tb->ty == Tfunction)
733 { error("cannot be declared to be a function");
734 type = Type::terror;
735 tb = type;
737 if (tb->ty == Tstruct)
738 { TypeStruct *ts = (TypeStruct *)tb;
740 if (!ts->sym->members)
742 error("no definition of struct %s", ts->toChars());
746 if (tb->ty == Ttuple)
747 { /* Instead, declare variables for each of the tuple elements
748 * and add those.
750 TypeTuple *tt = (TypeTuple *)tb;
751 size_t nelems = Argument::dim(tt->arguments);
752 Objects *exps = new Objects();
753 exps->setDim(nelems);
754 Expression *ie = init ? init->toExpression() : NULL;
756 for (size_t i = 0; i < nelems; i++)
757 { Argument *arg = Argument::getNth(tt->arguments, i);
759 OutBuffer buf;
760 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i);
761 buf.writeByte(0);
762 char *name = (char *)buf.extractData();
763 Identifier *id = new Identifier(name, TOKidentifier);
765 Expression *einit = ie;
766 if (ie && ie->op == TOKtuple)
767 { einit = (Expression *)((TupleExp *)ie)->exps->data[i];
769 Initializer *ti = init;
770 if (einit)
771 { ti = new ExpInitializer(einit->loc, einit);
774 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
775 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
776 v->semantic(sc);
778 if (sc->scopesym)
779 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
780 if (sc->scopesym->members)
781 sc->scopesym->members->push(v);
784 Expression *e = new DsymbolExp(loc, v);
785 exps->data[i] = e;
787 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
788 v2->isexp = 1;
789 aliassym = v2;
790 return;
793 Lagain:
794 if (storage_class & STCinvariant)
796 type = type->invariantOf();
798 else if (storage_class & (STCconst | STCin))
800 if (!type->isInvariant())
801 type = type->constOf();
803 else if (type->isConst())
804 storage_class |= STCconst;
805 else if (type->isInvariant())
806 storage_class |= STCinvariant;
808 if (isSynchronized())
810 error("variable %s cannot be synchronized", toChars());
812 else if (isOverride())
814 error("override cannot be applied to variable");
816 else if (isAbstract())
818 error("abstract cannot be applied to variable");
820 else if (storage_class & STCfinal)
822 error("final cannot be applied to variable");
825 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls))
828 else
830 AggregateDeclaration *aad = sc->anonAgg;
831 if (!aad)
832 aad = parent->isAggregateDeclaration();
833 if (aad)
834 { assert(!(storage_class & (STCextern | STCstatic | STCtls)));
836 if (storage_class & (STCconst | STCinvariant) && init)
838 if (!type->toBasetype()->isTypeBasic())
839 storage_class |= STCstatic;
841 else
842 aad->addField(sc, this);
845 InterfaceDeclaration *id = parent->isInterfaceDeclaration();
846 if (id)
848 error("field not allowed in interface");
851 /* Templates cannot add fields to aggregates
853 TemplateInstance *ti = parent->isTemplateInstance();
854 if (ti)
856 // Take care of nested templates
857 while (1)
859 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
860 if (!ti2)
861 break;
862 ti = ti2;
865 // If it's a member template
866 AggregateDeclaration *ad = ti->tempdecl->isMember();
867 if (ad && storage_class != STCundefined)
869 error("cannot use template to add field to aggregate '%s'", ad->toChars());
874 if (type->isauto() && !noauto)
876 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd)
878 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto");
881 if (!(storage_class & (STCauto | STCscope)))
883 if (!(storage_class & STCparameter) && ident != Id::withSym)
884 error("reference to scope class must be scope");
888 if ((isConst() || isInvariant()) && !init && !fd)
889 { // Initialize by constructor only
890 storage_class |= STCctorinit;
893 if (init)
894 storage_class |= STCinit; // remember we had an explicit initializer
895 else if (storage_class & STCmanifest)
896 error("manifest constants must have initializers");
898 enum TOK op = TOKconstruct;
899 if (!init && !sc->inunion && !isStatic() && fd &&
900 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) &&
901 type->size() != 0)
903 // Provide a default initializer
904 //printf("Providing default initializer for '%s'\n", toChars());
905 if (type->ty == Tstruct &&
906 ((TypeStruct *)type)->sym->zeroInit == 1)
907 { /* If a struct is all zeros, as a special case
908 * set it's initializer to the integer 0.
909 * In AssignExp::toElem(), we check for this and issue
910 * a memset() to initialize the struct.
911 * Must do same check in interpreter.
913 Expression *e = new IntegerExp(loc, 0, Type::tint32);
914 Expression *e1;
915 e1 = new VarExp(loc, this);
916 e = new AssignExp(loc, e1, e);
917 e->type = e1->type; // don't type check this, it would fail
918 init = new ExpInitializer(loc, e);
919 return;
921 else if (type->ty == Ttypedef)
922 { TypeTypedef *td = (TypeTypedef *)type;
923 if (td->sym->init)
924 { init = td->sym->init;
925 ExpInitializer *ie = init->isExpInitializer();
926 if (ie)
927 // Make copy so we can modify it
928 init = new ExpInitializer(ie->loc, ie->exp);
930 else
931 init = getExpInitializer();
933 else
935 init = getExpInitializer();
937 // Default initializer is always a blit
938 op = TOKblit;
941 if (init)
943 ArrayInitializer *ai = init->isArrayInitializer();
944 if (ai && tb->ty == Taarray)
946 init = ai->toAssocArrayInitializer();
949 StructInitializer *si = init->isStructInitializer();
950 ExpInitializer *ei = init->isExpInitializer();
952 // See if we can allocate on the stack
953 if (ei && isScope() && ei->exp->op == TOKnew)
954 { NewExp *ne = (NewExp *)ei->exp;
955 if (!(ne->newargs && ne->newargs->dim))
956 { ne->onstack = 1;
957 onstack = 1;
958 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
959 onstack = 2;
963 // If inside function, there is no semantic3() call
964 if (sc->func)
966 // If local variable, use AssignExp to handle all the various
967 // possibilities.
968 if (fd && !isStatic() && !(storage_class & STCmanifest) &&
969 !init->isVoidInitializer())
971 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
972 if (!ei)
974 Expression *e = init->toExpression();
975 if (!e)
977 init = init->semantic(sc, type);
978 e = init->toExpression();
979 if (!e)
980 { error("is not a static and cannot have static initializer");
981 return;
984 ei = new ExpInitializer(init->loc, e);
985 init = ei;
988 Expression *e1 = new VarExp(loc, this);
990 Type *t = type->toBasetype();
991 if (t->ty == Tsarray)
993 ei->exp = ei->exp->semantic(sc);
994 if (!ei->exp->implicitConvTo(type))
996 sinteger_t dim = ((TypeSArray *)t)->dim->toInteger();
997 // If multidimensional static array, treat as one large array
998 while (1)
1000 t = t->nextOf()->toBasetype();
1001 if (t->ty != Tsarray)
1002 break;
1003 dim *= ((TypeSArray *)t)->dim->toInteger();
1004 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
1007 e1 = new SliceExp(loc, e1, NULL, NULL);
1009 else if (t->ty == Tstruct)
1011 ei->exp = ei->exp->semantic(sc);
1012 if (!ei->exp->implicitConvTo(type))
1013 { Type *ti = ei->exp->type->toBasetype();
1014 // Don't cast away invariant or mutability in initializer
1015 if (!(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1016 ei->exp = new CastExp(loc, ei->exp, type);
1019 ei->exp = new AssignExp(loc, e1, ei->exp);
1020 ei->exp->op = op;
1021 canassign++;
1022 ei->exp = ei->exp->semantic(sc);
1023 canassign--;
1024 ei->exp->optimize(WANTvalue);
1026 else
1028 init = init->semantic(sc, type);
1031 else if (storage_class & (STCconst | STCinvariant | STCmanifest) ||
1032 type->isConst() || type->isInvariant())
1034 /* Because we may need the results of a const declaration in a
1035 * subsequent type, such as an array dimension, before semantic2()
1036 * gets ordinarily run, try to run semantic2() now.
1037 * Ignore failure.
1040 if (!global.errors && !inferred)
1042 unsigned errors = global.errors;
1043 global.gag++;
1044 //printf("+gag\n");
1045 Expression *e;
1046 Initializer *i2 = init;
1047 inuse++;
1048 if (ei)
1050 e = ei->exp->syntaxCopy();
1051 e = e->semantic(sc);
1052 e = e->implicitCastTo(sc, type);
1054 else if (si || ai)
1055 { i2 = init->syntaxCopy();
1056 i2 = i2->semantic(sc, type);
1058 inuse--;
1059 global.gag--;
1060 //printf("-gag\n");
1061 if (errors != global.errors) // if errors happened
1063 if (global.gag == 0)
1064 global.errors = errors; // act as if nothing happened
1066 /* Save scope for later use, to try again
1068 scope = new Scope(*sc);
1069 scope->setNoFree();
1071 else if (ei)
1073 if (isDataseg())
1074 /* static const/invariant does CTFE
1076 e = e->optimize(WANTvalue | WANTinterpret);
1077 else
1078 e = e->optimize(WANTvalue);
1079 if (e->op == TOKint64 || e->op == TOKstring)
1081 ei->exp = e; // no errors, keep result
1083 else
1085 /* Save scope for later use, to try again
1087 scope = new Scope(*sc);
1088 scope->setNoFree();
1091 else
1092 init = i2; // no errors, keep result
1098 void VarDeclaration::semantic2(Scope *sc)
1100 //printf("VarDeclaration::semantic2('%s')\n", toChars());
1101 if (init && !toParent()->isFuncDeclaration())
1102 { inuse++;
1103 #if 0
1104 ExpInitializer *ei = init->isExpInitializer();
1105 if (ei)
1107 ei->exp->dump(0);
1108 printf("type = %p\n", ei->exp->type);
1110 #endif
1111 init = init->semantic(sc, type);
1112 inuse--;
1116 char *VarDeclaration::kind()
1118 return "variable";
1121 Dsymbol *VarDeclaration::toAlias()
1123 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1124 assert(this != aliassym);
1125 Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1126 return s;
1129 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1131 if (storage_class & STCmanifest)
1132 buf->writestring("manifest ");
1133 if (storage_class & STCstatic)
1134 buf->writestring("static ");
1135 if (storage_class & STCtls)
1136 buf->writestring("__tls ");
1137 if (storage_class & STCconst)
1138 buf->writestring("const ");
1139 if (storage_class & STCinvariant)
1140 buf->writestring("invariant ");
1142 if (type)
1143 type->toCBuffer(buf, ident, hgs);
1144 else
1145 buf->writestring(ident->toChars());
1146 if (init)
1147 { buf->writestring(" = ");
1148 ExpInitializer *ie = init->isExpInitializer();
1149 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1150 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
1151 else
1152 init->toCBuffer(buf, hgs);
1154 buf->writeByte(';');
1155 buf->writenl();
1158 int VarDeclaration::needThis()
1160 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1161 return storage_class & STCfield;
1164 int VarDeclaration::isImportedSymbol()
1166 if (protection == PROTexport && !init &&
1167 (storage_class & STCstatic || parent->isModule()))
1168 return TRUE;
1169 return FALSE;
1172 void VarDeclaration::checkCtorConstInit()
1174 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
1175 error("missing initializer in static constructor for const variable");
1178 /************************************
1179 * Check to see if this variable is actually in an enclosing function
1180 * rather than the current one.
1183 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1185 if (parent && !isDataseg() && parent != sc->parent &&
1186 !(storage_class & STCmanifest))
1188 // The function that this variable is in
1189 FuncDeclaration *fdv = toParent()->isFuncDeclaration();
1190 // The current function
1191 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1193 if (fdv && fdthis && fdv != fdthis)
1195 if (loc.filename)
1196 fdthis->getLevel(loc, fdv);
1198 for (int i = 0; i < nestedrefs.dim; i++)
1199 { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i];
1200 if (f == fdthis)
1201 goto L1;
1203 nestedrefs.push(fdthis);
1204 L1: ;
1207 for (int i = 0; i < fdv->closureVars.dim; i++)
1208 { Dsymbol *s = (Dsymbol *)fdv->closureVars.data[i];
1209 if (s == this)
1210 goto L2;
1213 fdv->closureVars.push(this);
1214 L2: ;
1216 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1221 /****************************
1222 * Get ExpInitializer for a variable, if there is one.
1225 ExpInitializer *VarDeclaration::getExpInitializer()
1227 ExpInitializer *ei;
1229 if (init)
1230 ei = init->isExpInitializer();
1231 else
1233 if ((type->ty == Tclass || type->ty == Tpointer) && !skipnullcheck)
1234 error("non-null, but missing initialiser");
1236 Expression *e = type->defaultInit();
1237 if (e)
1238 ei = new ExpInitializer(loc, e);
1239 else
1240 ei = NULL;
1242 return ei;
1246 /*******************************************
1247 * If variable has a constant expression initializer, get it.
1248 * Otherwise, return NULL.
1251 Expression *VarDeclaration::getConstInitializer()
1253 if ((isConst() || isInvariant() || storage_class & STCmanifest) &&
1254 storage_class & STCinit)
1256 ExpInitializer *ei = getExpInitializer();
1257 if (ei)
1258 return ei->exp;
1261 return NULL;
1264 /*************************************
1265 * Return !=0 if we can take the address of this variable.
1268 int VarDeclaration::canTakeAddressOf()
1270 #if 0
1271 /* Global variables and struct/class fields of the form:
1272 * const int x = 3;
1273 * are not stored and hence cannot have their address taken.
1275 if ((isConst() || isInvariant()) &&
1276 storage_class & STCinit &&
1277 (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) &&
1278 (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) &&
1279 type->toBasetype()->isTypeBasic()
1282 return 0;
1284 #else
1285 if (storage_class & STCmanifest)
1286 return 0;
1287 #endif
1288 return 1;
1291 /*******************************
1292 * Does symbol go into data segment?
1293 * Includes extern variables.
1296 int VarDeclaration::isDataseg()
1298 #if 0
1299 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1300 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
1301 printf("parent = '%s'\n", parent->toChars());
1302 #endif
1303 if (storage_class & STCmanifest)
1304 return 0;
1305 Dsymbol *parent = this->toParent();
1306 if (!parent && !(storage_class & STCstatic))
1307 { error("forward referenced");
1308 type = Type::terror;
1309 return 0;
1311 return canTakeAddressOf() &&
1312 (storage_class & (STCstatic | STCextern | STCtls) ||
1313 toParent()->isModule() ||
1314 toParent()->isTemplateInstance());
1317 int VarDeclaration::hasPointers()
1319 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1320 return (!isDataseg() && type->hasPointers());
1323 /******************************************
1324 * Return TRUE if variable needs to call the destructor.
1327 int VarDeclaration::needsAutoDtor()
1329 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1331 if (noauto || storage_class & STCnodtor)
1332 return FALSE;
1334 // Destructors for structs and arrays of structs
1335 Type *tv = type->toBasetype();
1336 while (tv->ty == Tsarray)
1337 { TypeSArray *ta = (TypeSArray *)tv;
1338 tv = tv->nextOf()->toBasetype();
1340 if (tv->ty == Tstruct)
1341 { TypeStruct *ts = (TypeStruct *)tv;
1342 StructDeclaration *sd = ts->sym;
1343 if (sd->dtor)
1344 return TRUE;
1347 // Destructors for classes
1348 if (storage_class & (STCauto | STCscope))
1350 if (type->isClassHandle())
1351 return TRUE;
1353 return FALSE;
1357 /******************************************
1358 * If a variable has an auto destructor call, return call for it.
1359 * Otherwise, return NULL.
1362 Expression *VarDeclaration::callAutoDtor(Scope *sc)
1363 { Expression *e = NULL;
1365 //printf("VarDeclaration::callAutoDtor() %s\n", toChars());
1367 if (noauto || storage_class & STCnodtor)
1368 return NULL;
1370 // Destructors for structs and arrays of structs
1371 bool array = false;
1372 Type *tv = type->toBasetype();
1373 while (tv->ty == Tsarray)
1374 { TypeSArray *ta = (TypeSArray *)tv;
1375 array = true;
1376 tv = tv->nextOf()->toBasetype();
1378 if (tv->ty == Tstruct)
1379 { TypeStruct *ts = (TypeStruct *)tv;
1380 StructDeclaration *sd = ts->sym;
1381 if (sd->dtor)
1383 if (array)
1385 // Typeinfo.destroy(cast(void*)&v);
1386 Expression *ea = new SymOffExp(loc, this, 0, 0);
1387 ea = new CastExp(loc, ea, Type::tvoid->pointerTo());
1388 Expressions *args = new Expressions();
1389 args->push(ea);
1391 Expression *et = type->getTypeInfo(sc);
1392 et = new DotIdExp(loc, et, Id::destroy);
1394 e = new CallExp(loc, et, args);
1396 else
1398 e = new VarExp(loc, this);
1399 e = new DotVarExp(loc, e, sd->dtor, 0);
1400 e = new CallExp(loc, e);
1402 return e;
1406 // Destructors for classes
1407 if (storage_class & (STCauto | STCscope))
1409 for (ClassDeclaration *cd = type->isClassHandle();
1411 cd = cd->baseClass)
1413 /* We can do better if there's a way with onstack
1414 * classes to determine if there's no way the monitor
1415 * could be set.
1417 //if (cd->isInterfaceDeclaration())
1418 //error("interface %s cannot be scope", cd->toChars());
1419 if (1 || onstack || cd->dtors.dim) // if any destructors
1421 // delete this;
1422 Expression *ec;
1424 ec = new VarExp(loc, this);
1425 e = new DeleteExp(loc, ec);
1426 e->type = Type::tvoid;
1427 break;
1431 return e;
1435 /********************************* ClassInfoDeclaration ****************************/
1437 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
1438 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
1440 this->cd = cd;
1441 storage_class = STCstatic;
1444 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
1446 assert(0); // should never be produced by syntax
1447 return NULL;
1450 void ClassInfoDeclaration::semantic(Scope *sc)
1454 /********************************* ModuleInfoDeclaration ****************************/
1456 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
1457 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
1459 this->mod = mod;
1460 storage_class = STCstatic;
1463 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
1465 assert(0); // should never be produced by syntax
1466 return NULL;
1469 void ModuleInfoDeclaration::semantic(Scope *sc)
1473 /********************************* TypeInfoDeclaration ****************************/
1475 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
1476 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
1478 this->tinfo = tinfo;
1479 storage_class = STCstatic;
1480 protection = PROTpublic;
1481 linkage = LINKc;
1484 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
1486 assert(0); // should never be produced by syntax
1487 return NULL;
1490 void TypeInfoDeclaration::semantic(Scope *sc)
1492 assert(linkage == LINKc);
1495 /***************************** TypeInfoConstDeclaration **********************/
1497 #if V2
1498 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1499 : TypeInfoDeclaration(tinfo, 0)
1502 #endif
1504 /***************************** TypeInfoInvariantDeclaration **********************/
1506 #if V2
1507 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1508 : TypeInfoDeclaration(tinfo, 0)
1511 #endif
1513 /***************************** TypeInfoStructDeclaration **********************/
1515 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1516 : TypeInfoDeclaration(tinfo, 0)
1520 /***************************** TypeInfoClassDeclaration ***********************/
1522 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1523 : TypeInfoDeclaration(tinfo, 0)
1527 /***************************** TypeInfoInterfaceDeclaration *******************/
1529 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1530 : TypeInfoDeclaration(tinfo, 0)
1534 /***************************** TypeInfoTypedefDeclaration *********************/
1536 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
1537 : TypeInfoDeclaration(tinfo, 0)
1541 /***************************** TypeInfoPointerDeclaration *********************/
1543 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1544 : TypeInfoDeclaration(tinfo, 0)
1548 /***************************** TypeInfoMaybeDeclaration *********************/
1550 TypeInfoMaybeDeclaration::TypeInfoMaybeDeclaration(Type *tinfo)
1551 : TypeInfoDeclaration(tinfo, 0)
1555 /***************************** TypeInfoArrayDeclaration ***********************/
1557 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1558 : TypeInfoDeclaration(tinfo, 0)
1562 /***************************** TypeInfoStaticArrayDeclaration *****************/
1564 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1565 : TypeInfoDeclaration(tinfo, 0)
1569 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1571 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1572 : TypeInfoDeclaration(tinfo, 0)
1576 /***************************** TypeInfoEnumDeclaration ***********************/
1578 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1579 : TypeInfoDeclaration(tinfo, 0)
1583 /***************************** TypeInfoFunctionDeclaration ********************/
1585 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1586 : TypeInfoDeclaration(tinfo, 0)
1590 /***************************** TypeInfoDelegateDeclaration ********************/
1592 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1593 : TypeInfoDeclaration(tinfo, 0)
1597 /***************************** TypeInfoTupleDeclaration **********************/
1599 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1600 : TypeInfoDeclaration(tinfo, 0)
1604 /********************************* ThisDeclaration ****************************/
1606 // For the "this" parameter to member functions
1608 ThisDeclaration::ThisDeclaration(Type *t)
1609 : VarDeclaration(0, t, Id::This, NULL)
1611 noauto = 1;
1612 skipnullcheck = true;
1615 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
1617 assert(0); // should never be produced by syntax
1618 return NULL;