comparison dmd/declaration.c @ 1:c53b6e3fe49a trunk

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