root/trunk/src/declaration.c

Revision 781, 56.6 kB (checked in by walter, 1 year ago)

bugzilla 5110 Excess attribute propagation of structs and classes

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <assert.h>
12
13 #include "init.h"
14 #include "declaration.h"
15 #include "attrib.h"
16 #include "mtype.h"
17 #include "template.h"
18 #include "scope.h"
19 #include "aggregate.h"
20 #include "module.h"
21 #include "id.h"
22 #include "expression.h"
23 #include "hdrgen.h"
24
25 /********************************* Declaration ****************************/
26
27 Declaration::Declaration(Identifier *id)
28     : Dsymbol(id)
29 {
30     type = NULL;
31     originalType = NULL;
32     storage_class = STCundefined;
33     protection = PROTundefined;
34     linkage = LINKdefault;
35     inuse = 0;
36     sem = SemanticStart;
37 }
38
39 void Declaration::semantic(Scope *sc)
40 {
41 }
42
43 const char *Declaration::kind()
44 {
45     return "declaration";
46 }
47
48 unsigned Declaration::size(Loc loc)
49 {
50     assert(type);
51     return type->size();
52 }
53
54 int Declaration::isDelete()
55 {
56     return FALSE;
57 }
58
59 int Declaration::isDataseg()
60 {
61     return FALSE;
62 }
63
64 int Declaration::isThreadlocal()
65 {
66     return FALSE;
67 }
68
69 int Declaration::isCodeseg()
70 {
71     return FALSE;
72 }
73
74 enum PROT Declaration::prot()
75 {
76     return protection;
77 }
78
79 /*************************************
80  * Check to see if declaration can be modified in this context (sc).
81  * Issue error if not.
82  */
83
84 #if DMDV2
85 void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
86 {
87     if (sc->incontract && isParameter())
88         error(loc, "cannot modify parameter '%s' in contract", toChars());
89
90     if (sc->incontract && isResult())
91         error(loc, "cannot modify result '%s' in contract", toChars());
92
93     if (isCtorinit() && !t->isMutable())
94     {   // It's only modifiable if inside the right constructor
95         Dsymbol *s = sc->func;
96         while (1)
97         {
98             FuncDeclaration *fd = NULL;
99             if (s)
100                 fd = s->isFuncDeclaration();
101             if (fd &&
102                 ((fd->isCtorDeclaration() && storage_class & STCfield) ||
103                  (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
104                 fd->toParent() == toParent()
105                )
106             {
107                 VarDeclaration *v = isVarDeclaration();
108                 assert(v);
109                 v->ctorinit = 1;
110                 //printf("setting ctorinit\n");
111             }
112             else
113             {
114                 if (s)
115                 {   s = s->toParent2();
116                     continue;
117                 }
118                 else
119                 {
120                     const char *p = isStatic() ? "static " : "";
121                     error(loc, "can only initialize %sconst %s inside %sconstructor",
122                         p, toChars(), p);
123                 }
124             }
125             break;
126         }
127     }
128     else
129     {
130         VarDeclaration *v = isVarDeclaration();
131         if (v && v->canassign == 0)
132         {
133             const char *p = NULL;
134             if (isConst())
135                 p = "const";
136             else if (isImmutable())
137                 p = "immutable";
138             else if (storage_class & STCmanifest)
139                 p = "enum";
140             else if (!t->isAssignable())
141                 p = "struct with immutable members";
142             if (p)
143             {   error(loc, "cannot modify %s", p);
144             }
145         }
146     }
147 }
148 #endif
149
150
151 /********************************* TupleDeclaration ****************************/
152
153 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
154     : Declaration(id)
155 {
156     this->loc = loc;
157     this->type = NULL;
158     this->objects = objects;
159     this->isexp = 0;
160     this->tupletype = NULL;
161 }
162
163 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
164 {
165     assert(0);
166     return NULL;
167 }
168
169 const char *TupleDeclaration::kind()
170 {
171     return "tuple";
172 }
173
174 Type *TupleDeclaration::getType()
175 {
176     /* If this tuple represents a type, return that type
177      */
178
179     //printf("TupleDeclaration::getType() %s\n", toChars());
180     if (isexp)
181         return NULL;
182     if (!tupletype)
183     {
184         /* It's only a type tuple if all the Object's are types
185          */
186         for (size_t i = 0; i < objects->dim; i++)
187         {   Object *o = (Object *)objects->data[i];
188
189             if (o->dyncast() != DYNCAST_TYPE)
190             {
191                 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
192                 return NULL;
193             }
194         }
195
196         /* We know it's a type tuple, so build the TypeTuple
197          */
198         Parameters *args = new Parameters();
199         args->setDim(objects->dim);
200         OutBuffer buf;
201         int hasdeco = 1;
202         for (size_t i = 0; i < objects->dim; i++)
203         {   Type *t = (Type *)objects->data[i];
204
205             //printf("type = %s\n", t->toChars());
206 #if 0
207             buf.printf("_%s_%d", ident->toChars(), i);
208             char *name = (char *)buf.extractData();
209             Identifier *id = new Identifier(name, TOKidentifier);
210             Parameter *arg = new Parameter(STCin, t, id, NULL);
211 #else
212             Parameter *arg = new Parameter(0, t, NULL, NULL);
213 #endif
214             args->data[i] = (void *)arg;
215             if (!t->deco)
216                 hasdeco = 0;
217         }
218
219         tupletype = new TypeTuple(args);
220         if (hasdeco)
221             return tupletype->semantic(0, NULL);
222     }
223
224     return tupletype;
225 }
226
227 int TupleDeclaration::needThis()
228 {
229     //printf("TupleDeclaration::needThis(%s)\n", toChars());
230     for (size_t i = 0; i < objects->dim; i++)
231     {   Object *o = (Object *)objects->data[i];
232         if (o->dyncast() == DYNCAST_EXPRESSION)
233         {   Expression *e = (Expression *)o;
234             if (e->op == TOKdsymbol)
235             {   DsymbolExp *ve = (DsymbolExp *)e;
236                 Declaration *d = ve->s->isDeclaration();
237                 if (d && d->needThis())
238                 {
239                     return 1;
240                 }
241             }
242         }
243     }
244     return 0;
245 }
246
247 /********************************* TypedefDeclaration ****************************/
248
249 TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init)
250     : Declaration(id)
251 {
252     this->type = new TypeTypedef(this);
253     this->basetype = basetype->toBasetype();
254     this->init = init;
255 #ifdef _DH
256     this->htype = NULL;
257     this->hbasetype = NULL;
258 #endif
259     this->loc = loc;
260     this->sinit = NULL;
261 }
262
263 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
264 {
265     Type *basetype = this->basetype->syntaxCopy();
266
267     Initializer *init = NULL;
268     if (this->init)
269         init = this->init->syntaxCopy();
270
271     assert(!s);
272     TypedefDeclaration *st;
273     st = new TypedefDeclaration(loc, ident, basetype, init);
274 #ifdef _DH
275     // Syntax copy for header file
276     if (!htype)      // Don't overwrite original
277     {   if (type)    // Make copy for both old and new instances
278         {   htype = type->syntaxCopy();
279             st->htype = type->syntaxCopy();
280         }
281     }
282     else            // Make copy of original for new instance
283         st->htype = htype->syntaxCopy();
284     if (!hbasetype)
285     {   if (basetype)
286         {   hbasetype = basetype->syntaxCopy();
287             st->hbasetype = basetype->syntaxCopy();
288         }
289     }
290     else
291         st->hbasetype = hbasetype->syntaxCopy();
292 #endif
293     return st;
294 }
295
296 void TypedefDeclaration::semantic(Scope *sc)
297 {
298     //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
299     if (sem == SemanticStart)
300     {   sem = SemanticIn;
301         basetype = basetype->semantic(loc, sc);
302         sem = SemanticDone;
303 #if DMDV2
304         type = type->addStorageClass(storage_class);
305 #endif
306         type = type->semantic(loc, sc);
307         if (sc->parent->isFuncDeclaration() && init)
308             semantic2(sc);
309         storage_class |= sc->stc & STCdeprecated;
310     }
311     else if (sem == SemanticIn)
312     {
313         error("circular definition");
314     }
315 }
316
317 void TypedefDeclaration::semantic2(Scope *sc)
318 {
319     //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
320     if (sem == SemanticDone)
321     {   sem = Semantic2Done;
322         if (init)
323         {
324             init = init->semantic(sc, basetype);
325
326             ExpInitializer *ie = init->isExpInitializer();
327             if (ie)
328             {
329                 if (ie->exp->type == basetype)
330                     ie->exp->type = type;
331             }
332         }
333     }
334 }
335
336 const char *TypedefDeclaration::kind()
337 {
338     return "typedef";
339 }
340
341 Type *TypedefDeclaration::getType()
342 {
343     return type;
344 }
345
346 void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
347 {
348     buf->writestring("typedef ");
349     basetype->toCBuffer(buf, ident, hgs);
350     if (init)
351     {
352         buf->writestring(" = ");
353         init->toCBuffer(buf, hgs);
354     }
355     buf->writeByte(';');
356     buf->writenl();
357 }
358
359 /********************************* AliasDeclaration ****************************/
360
361 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
362     : Declaration(id)
363 {
364     //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
365     //printf("type = '%s'\n", type->toChars());
366     this->loc = loc;
367     this->type = type;
368     this->aliassym = NULL;
369 #ifdef _DH
370     this->htype = NULL;
371     this->haliassym = NULL;
372 #endif
373     this->overnext = NULL;
374     this->inSemantic = 0;
375     assert(type);
376 }
377
378 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
379     : Declaration(id)
380 {
381     //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
382     assert(s != this);
383     this->loc = loc;
384     this->type = NULL;
385     this->aliassym = s;
386 #ifdef _DH
387     this->htype = NULL;
388     this->haliassym = NULL;
389 #endif
390     this->overnext = NULL;
391     this->inSemantic = 0;
392     assert(s);
393 }
394
395 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
396 {
397     //printf("AliasDeclaration::syntaxCopy()\n");
398     assert(!s);
399     AliasDeclaration *sa;
400     if (type)
401         sa = new AliasDeclaration(loc, ident, type->syntaxCopy());
402     else
403         sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
404 #ifdef _DH
405     // Syntax copy for header file
406     if (!htype)     // Don't overwrite original
407     {   if (type)       // Make copy for both old and new instances
408         {   htype = type->syntaxCopy();
409             sa->htype = type->syntaxCopy();
410         }
411     }
412     else                        // Make copy of original for new instance
413         sa->htype = htype->syntaxCopy();
414     if (!haliassym)
415     {   if (aliassym)
416         {   haliassym = aliassym->syntaxCopy(s);
417             sa->haliassym = aliassym->syntaxCopy(s);
418         }
419     }
420     else
421         sa->haliassym = haliassym->syntaxCopy(s);
422 #endif
423     return sa;
424 }
425
426 void AliasDeclaration::semantic(Scope *sc)
427 {
428     //printf("AliasDeclaration::semantic() %s\n", toChars());
429     if (aliassym)
430     {
431         if (aliassym->isTemplateInstance())
432             aliassym->semantic(sc);
433         return;
434     }
435     this->inSemantic = 1;
436
437 #if DMDV1   // don't really know why this is here
438     if (storage_class & STCconst)
439         error("cannot be const");
440 #endif
441
442     storage_class |= sc->stc & STCdeprecated;
443
444     // Given:
445     //  alias foo.bar.abc def;
446     // it is not knowable from the syntax whether this is an alias
447     // for a type or an alias for a symbol. It is up to the semantic()
448     // pass to distinguish.
449     // If it is a type, then type is set and getType() will return that
450     // type. If it is a symbol, then aliassym is set and type is NULL -
451     // toAlias() will return aliasssym.
452
453     Dsymbol *s;
454     Type *t;
455     Expression *e;
456
457     /* This section is needed because resolve() will:
458      *   const x = 3;
459      *   alias x y;
460      * try to alias y to 3.
461      */
462     s = type->toDsymbol(sc);
463     if (s
464 #if DMDV2
465         && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
466 #endif
467         )
468         goto L2;                        // it's a symbolic alias
469
470 #if DMDV2
471     type = type->addStorageClass(storage_class);
472     if (storage_class & (STCref | STCnothrow | STCpure | STCdisable))
473     {   // For 'ref' to be attached to function types, and picked
474         // up by Type::resolve(), it has to go into sc.
475         sc = sc->push();
476         sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable);
477         type->resolve(loc, sc, &e, &t, &s);
478         sc = sc->pop();
479     }
480     else
481 #endif
482         type->resolve(loc, sc, &e, &t, &s);
483     if (s)
484     {
485         goto L2;
486     }
487     else if (e)
488     {
489         // Try to convert Expression to Dsymbol
490         s = getDsymbol(e);
491         if (s)
492             goto L2;
493
494         error("cannot alias an expression %s", e->toChars());
495         t = e->type;
496     }
497     else if (t)
498     {
499         type = t;
500         //printf("\talias resolved to type %s\n", type->toChars());
501     }
502     if (overnext)
503         ScopeDsymbol::multiplyDefined(0, this, overnext);
504     this->inSemantic = 0;
505     return;
506
507   L2:
508     //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
509     type = NULL;
510     VarDeclaration *v = s->isVarDeclaration();
511     if (0 && v && v->linkage == LINKdefault)
512     {
513         error("forward reference of %s", v->toChars());
514         s = NULL;
515     }
516     else
517     {
518         FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
519         if (f)
520         {
521             if (overnext)
522             {
523                 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
524                 if (!fa->overloadInsert(overnext))
525                     ScopeDsymbol::multiplyDefined(0, f, overnext);
526                 overnext = NULL;
527                 s = fa;
528                 s->parent = sc->parent;
529             }
530         }
531         if (overnext)
532             ScopeDsymbol::multiplyDefined(0, s, overnext);
533         if (s == this)
534         {
535             assert(global.errors);
536             s = NULL;
537         }
538     }
539     //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars());
540     aliassym = s;
541     this->inSemantic = 0;
542 }
543
544 int AliasDeclaration::overloadInsert(Dsymbol *s)
545 {
546     /* Don't know yet what the aliased symbol is, so assume it can
547      * be overloaded and check later for correctness.
548      */
549
550     //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
551     if (aliassym) // see test/test56.d
552     {
553         Dsymbol *a = aliassym->toAlias();
554         FuncDeclaration *f = a->isFuncDeclaration();
555         if (f)  // BUG: what if it's a template?
556         {
557             FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
558             aliassym = fa;
559             return fa->overloadInsert(s);
560         }
561     }
562
563     if (overnext == NULL)
564     {
565         if (s == this)
566         {
567             return TRUE;
568         }
569         overnext = s;
570         return TRUE;
571     }
572     else
573     {
574         return overnext->overloadInsert(s);
575     }
576 }
577
578 const char *AliasDeclaration::kind()
579 {
580     return "alias";
581 }
582
583 Type *AliasDeclaration::getType()
584 {
585     return type;
586 }
587
588 Dsymbol *AliasDeclaration::toAlias()
589 {
590     //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
591     assert(this != aliassym);
592     //static int count; if (++count == 10) *(char*)0=0;
593     if (inSemantic)
594     {   error("recursive alias declaration");
595         aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
596     }
597     else if (!aliassym && scope)
598         semantic(scope);
599     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
600     return s;
601 }
602
603 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
604 {
605     buf->writestring("alias ");
606 #if 0 && _DH
607     if (hgs->hdrgen)
608     {
609         if (haliassym)
610         {
611             haliassym->toCBuffer(buf, hgs);
612             buf->writeByte(' ');
613             buf->writestring(ident->toChars());
614         }
615         else
616             htype->toCBuffer(buf, ident, hgs);
617     }
618     else
619 #endif
620     {
621         if (aliassym)
622         {
623             aliassym->toCBuffer(buf, hgs);
624             buf->writeByte(' ');
625             buf->writestring(ident->toChars());
626         }
627         else
628             type->toCBuffer(buf, ident, hgs);
629     }
630     buf->writeByte(';');
631     buf->writenl();
632 }
633
634 /********************************* VarDeclaration ****************************/
635
636 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
637     : Declaration(id)
638 {
639     //printf("VarDeclaration('%s')\n", id->toChars());
640 #ifdef DEBUG
641     if (!type && !init)
642     {   printf("VarDeclaration('%s')\n", id->toChars());
643         //*(char*)0=0;
644     }
645 #endif
646     assert(type || init);
647     this->type = type;
648     this->init = init;
649 #ifdef _DH
650     this->htype = NULL;
651     this->hinit = NULL;
652 #endif
653     this->loc = loc;
654     offset = 0;
655     noscope = 0;
656 #if DMDV2
657     isargptr = FALSE;
658 #endif
659 #if DMDV1
660     nestedref = 0;
661 #endif
662     ctorinit = 0;
663     aliassym = NULL;
664     onstack = 0;
665     canassign = 0;
666     value = NULL;
667     rundtor = NULL;
668 }
669
670 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
671 {
672     //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
673
674     VarDeclaration *sv;
675     if (s)
676     {   sv = (VarDeclaration *)s;
677     }
678     else
679     {
680         Initializer *init = NULL;
681         if (this->init)
682         {   init = this->init->syntaxCopy();
683             //init->isExpInitializer()->exp->print();
684             //init->isExpInitializer()->exp->dump(0);
685         }
686
687         sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
688         sv->storage_class = storage_class;
689     }
690 #ifdef _DH
691     // Syntax copy for header file
692     if (!htype)      // Don't overwrite original
693     {   if (type)    // Make copy for both old and new instances
694         {   htype = type->syntaxCopy();
695             sv->htype = type->syntaxCopy();
696         }
697     }
698     else            // Make copy of original for new instance
699         sv->htype = htype->syntaxCopy();
700     if (!hinit)
701     {   if (init)
702         {   hinit = init->syntaxCopy();
703             sv->hinit = init->syntaxCopy();
704         }
705     }
706     else
707         sv->hinit = hinit->syntaxCopy();
708 #endif
709     return sv;
710 }
711
712 void VarDeclaration::semantic(Scope *sc)
713 {
714 #if 0
715     printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
716     printf(" type = %s\n", type ? type->toChars() : "null");
717     printf(" stc = x%x\n", sc->stc);
718     printf(" storage_class = x%x\n", storage_class);
719     printf("linkage = %d\n", sc->linkage);
720     //if (strcmp(toChars(), "mul") == 0) halt();
721 #endif
722
723 //    if (sem > SemanticStart)
724 //      return;
725 //    sem = SemanticIn;
726
727     if (scope)
728     {   sc = scope;
729         scope = NULL;
730     }
731
732     /* Pick up storage classes from context, but skip synchronized
733      */
734     storage_class |= (sc->stc & ~STCsynchronized);
735     if (storage_class & STCextern && init)
736         error("extern symbols cannot have initializers");
737
738     AggregateDeclaration *ad = isThis();
739     if (ad)
740         storage_class |= ad->storage_class & STC_TYPECTOR;
741
742     /* If auto type inference, do the inference
743      */
744     int inferred = 0;
745     if (!type)
746     {   inuse++;
747
748         ArrayInitializer *ai = init->isArrayInitializer();
749         if (ai)
750         {   Expression *e;
751             if (ai->isAssociativeArray())
752                 e = ai->toAssocArrayLiteral();
753             else
754                 e = init->toExpression();
755             if (!e)
756             {
757                 error("cannot infer type from initializer");
758                 e = new ErrorExp();
759             }
760             init = new ExpInitializer(e->loc, e);
761             type = init->inferType(sc);
762             if (type->ty == Tsarray)
763                 type = type->nextOf()->arrayOf();
764         }
765         else
766             type = init->inferType(sc);
767
768 //printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco);
769 //      type = type->semantic(loc, sc);
770
771         inuse--;
772         inferred = 1;
773
774         if (init->isArrayInitializer() && type->toBasetype()->ty == Tsarray)
775         {   // Prefer array literals to give a T[] type rather than a T[dim]
776             type = type->toBasetype()->nextOf()->arrayOf();
777         }
778
779         /* This is a kludge to support the existing syntax for RAII
780          * declarations.
781          */
782         storage_class &= ~STCauto;
783         originalType = type;
784     }
785     else
786     {   if (!originalType)
787             originalType = type;
788         type = type->semantic(loc, sc);
789     }
790     //printf(" semantic type = %s\n", type ? type->toChars() : "null");
791
792     type->checkDeprecated(loc, sc);
793     linkage = sc->linkage;
794     this->parent = sc->parent;
795     //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
796     protection = sc->protection;
797     //printf("sc->stc = %x\n", sc->stc);
798     //printf("storage_class = x%x\n", storage_class);
799
800 #if DMDV2
801 #if 1
802     if (storage_class & STCgshared && sc->func && sc->func->isSafe())
803     {
804         error("__gshared not allowed in safe functions; use shared");
805     }
806 #else
807     if (storage_class & STCgshared && global.params.safe && !sc->module->safe)
808     {
809         error("__gshared not allowed in safe mode; use shared");
810     }
811 #endif
812 #endif
813
814     Dsymbol *parent = toParent();
815     FuncDeclaration *fd = parent->isFuncDeclaration();
816
817     Type *tb = type->toBasetype();
818     if (tb->ty == Tvoid && !(storage_class & STClazy))
819     {   error("voids have no value");
820         type = Type::terror;
821         tb = type;
822     }
823     if (tb->ty == Tfunction)
824     {   error("cannot be declared to be a function");
825         type = Type::terror;
826         tb = type;
827     }
828     if (tb->ty == Tstruct)
829     {   TypeStruct *ts = (TypeStruct *)tb;
830
831         if (!ts->sym->members)
832         {
833             error("no definition of struct %s", ts->toChars());
834         }
835     }
836     if ((storage_class & STCauto) && !inferred)
837        error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?");
838
839     if (tb->ty == Ttuple)
840     {   /* Instead, declare variables for each of the tuple elements
841          * and add those.
842          */
843         TypeTuple *tt = (TypeTuple *)tb;
844         size_t nelems = Parameter::dim(tt->arguments);
845         Objects *exps = new Objects();
846         exps->setDim(nelems);
847         Expression *ie = init ? init->toExpression() : NULL;
848
849         for (size_t i = 0; i < nelems; i++)
850         {   Parameter *arg = Parameter::getNth(tt->arguments, i);
851
852             OutBuffer buf;
853             buf.printf("_%s_field_%zu", ident->toChars(), i);
854             buf.writeByte(0);
855             const char *name = (const char *)buf.extractData();
856             Identifier *id = Lexer::idPool(name);
857
858             Expression *einit = ie;
859             if (ie && ie->op == TOKtuple)
860             {   einit = (Expression *)((TupleExp *)ie)->exps->data[i];
861             }
862             Initializer *ti = init;
863             if (einit)
864             {   ti = new ExpInitializer(einit->loc, einit);
865             }
866
867             VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
868             //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
869             v->semantic(sc);
870
871             if (sc->scopesym)
872             {   //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
873                 if (sc->scopesym->members)
874                     sc->scopesym->members->push(v);
875             }
876
877             Expression *e = new DsymbolExp(loc, v);
878             exps->data[i] = e;
879         }
880         TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
881         v2->isexp = 1;
882         aliassym = v2;
883         return;
884     }
885
886 Lagain:
887     /* Storage class can modify the type
888      */
889     type = type->addStorageClass(storage_class);
890
891     /* Adjust storage class to reflect type
892      */
893     if (type->isConst())
894     {   storage_class |= STCconst;
895         if (type->isShared())
896             storage_class |= STCshared;
897     }
898     else if (type->isImmutable())
899         storage_class |= STCimmutable;
900     else if (type->isShared())
901         storage_class |= STCshared;
902     else if (type->isWild())
903         storage_class |= STCwild;
904
905     if (isSynchronized())
906     {
907         error("variable %s cannot be synchronized", toChars());
908     }
909     else if (isOverride())
910     {
911         error("override cannot be applied to variable");
912     }
913     else if (isAbstract())
914     {
915         error("abstract cannot be applied to variable");
916     }
917     else if (storage_class & STCfinal)
918     {
919         error("final cannot be applied to variable");
920     }
921
922     if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
923     {
924     }
925     else
926     {
927         AggregateDeclaration *aad = sc->anonAgg;
928         if (!aad)
929             aad = parent->isAggregateDeclaration();
930         if (aad)
931         {
932 #if DMDV2
933             assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared)));
934
935             if (storage_class & (STCconst | STCimmutable) && init)
936             {
937                 if (!type->toBasetype()->isTypeBasic())
938                     storage_class |= STCstatic;
939             }
940             else
941 #endif
942                 aad->addField(sc, this);
943         }
944
945         InterfaceDeclaration *id = parent->isInterfaceDeclaration();
946         if (id)
947         {
948             error("field not allowed in interface");
949         }
950
951         /* Templates cannot add fields to aggregates
952          */
953         TemplateInstance *ti = parent->isTemplateInstance();
954         if (ti)
955         {
956             // Take care of nested templates
957             while (1)
958             {
959                 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
960                 if (!ti2)
961                     break;
962                 ti = ti2;
963             }
964
965             // If it's a member template
966             AggregateDeclaration *ad = ti->tempdecl->isMember();
967             if (ad && storage_class != STCundefined)
968             {
969                 error("cannot use template to add field to aggregate '%s'", ad->toChars());
970             }
971         }
972     }
973
974 #if DMDV2
975     if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref &&
976         ident != Id::This)
977     {
978         error("only parameters or foreach declarations can be ref");
979     }
980
981     if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) ||
982         isDataseg()) &&
983         type->hasWild())
984     {
985         error("only fields, parameters or stack based variables can be inout");
986     }
987 #endif
988
989     if (type->isscope() && !noscope)
990     {
991         if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd)
992         {
993             error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope");
994         }
995
996         if (!(storage_class & STCscope))
997         {
998             if (!(storage_class & STCparameter) && ident != Id::withSym)
999                 error("reference to scope class must be scope");
1000         }
1001     }
1002
1003     if (!init && !fd)
1004     {   // If not mutable, initializable by constructor only
1005         storage_class |= STCctorinit;
1006     }
1007
1008     if (init)
1009         storage_class |= STCinit;     // remember we had an explicit initializer
1010     else if (storage_class & STCmanifest)
1011         error("manifest constants must have initializers");
1012
1013     enum TOK op = TOKconstruct;
1014     if (!init && !sc->inunion && !isStatic() && fd &&
1015         (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult))
1016          || (storage_class & STCout)) &&
1017         type->size() != 0)
1018     {
1019         // Provide a default initializer
1020         //printf("Providing default initializer for '%s'\n", toChars());
1021         if (type->ty == Tstruct &&
1022             ((TypeStruct *)type)->sym->zeroInit == 1)
1023         {   /* If a struct is all zeros, as a special case
1024              * set it's initializer to the integer 0.
1025              * In AssignExp::toElem(), we check for this and issue
1026              * a memset() to initialize the struct.
1027              * Must do same check in interpreter.
1028              */
1029             Expression *e = new IntegerExp(loc, 0, Type::tint32);
1030             Expression *e1;
1031             e1 = new VarExp(loc, this);
1032             e = new ConstructExp(loc, e1, e);
1033             e->type = e1->type;         // don't type check this, it would fail
1034             init = new ExpInitializer(loc, e);
1035             return;
1036         }
1037         else if (type->ty == Ttypedef)
1038         {   TypeTypedef *td = (TypeTypedef *)type;
1039             if (td->sym->init)
1040             {   init = td->sym->init;
1041                 ExpInitializer *ie = init->isExpInitializer();
1042                 if (ie)
1043                     // Make copy so we can modify it
1044                     init = new ExpInitializer(ie->loc, ie->exp);
1045             }
1046             else
1047                 init = getExpInitializer();
1048         }
1049         else
1050         {
1051             init = getExpInitializer();
1052         }
1053         // Default initializer is always a blit
1054         op = TOKblit;
1055     }
1056
1057     if (init)
1058     {
1059         sc = sc->push();
1060         sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref | STCdisable);
1061
1062         ArrayInitializer *ai = init->isArrayInitializer();
1063         if (ai && tb->ty == Taarray)
1064         {
1065             Expression *e = ai->toAssocArrayLiteral();
1066             init = new ExpInitializer(e->loc, e);
1067         }
1068
1069         StructInitializer *si = init->isStructInitializer();
1070         ExpInitializer *ei = init->isExpInitializer();
1071
1072         // See if initializer is a NewExp that can be allocated on the stack
1073         if (ei && isScope() && ei->exp->op == TOKnew)
1074         {   NewExp *ne = (NewExp *)ei->exp;
1075             if (!(ne->newargs && ne->newargs->dim))
1076             {   ne->onstack = 1;
1077                 onstack = 1;
1078                 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
1079                     onstack = 2;
1080             }
1081         }
1082
1083         // If inside function, there is no semantic3() call
1084         if (sc->func)
1085         {
1086             // If local variable, use AssignExp to handle all the various
1087             // possibilities.
1088             if (fd &&
1089                 !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) &&
1090                 !init->isVoidInitializer())
1091             {
1092                 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
1093                 if (!ei)
1094                 {
1095                     Expression *e = init->toExpression();
1096                     if (!e)
1097                     {
1098                         init = init->semantic(sc, type);
1099                         e = init->toExpression();
1100                         if (!e)
1101                         {   error("is not a static and cannot have static initializer");
1102                             return;
1103                         }
1104                     }
1105                     ei = new ExpInitializer(init->loc, e);
1106                     init = ei;
1107                 }
1108
1109                 Expression *e1 = new VarExp(loc, this);
1110
1111                 Type *t = type->toBasetype();
1112                 if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
1113                 {
1114                     ei->exp = ei->exp->semantic(sc);
1115                     if (!ei->exp->implicitConvTo(type))
1116                     {
1117                         int dim = ((TypeSArray *)t)->dim->toInteger();
1118                         // If multidimensional static array, treat as one large array
1119                         while (1)
1120                         {
1121                             t = t->nextOf()->toBasetype();
1122                             if (t->ty != Tsarray)
1123                                 break;
1124                             dim *= ((TypeSArray *)t)->dim->toInteger();
1125                             e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
1126                         }
1127                     }
1128                     e1 = new SliceExp(loc, e1, NULL, NULL);
1129                 }
1130                 else if (t->ty == Tstruct)
1131                 {
1132                     ei->exp = ei->exp->semantic(sc);
1133                     ei->exp = resolveProperties(sc, ei->exp);
1134                     StructDeclaration *sd = ((TypeStruct *)t)->sym;
1135 #if DMDV2
1136                     /* Look to see if initializer is a call to the constructor
1137                      */
1138                     if (sd->ctor &&             // there are constructors
1139                         ei->exp->type->ty == Tstruct && // rvalue is the same struct
1140                         ((TypeStruct *)ei->exp->type)->sym == sd &&
1141                         ei->exp->op == TOKstar)
1142                     {
1143                         /* Look for form of constructor call which is:
1144                          *    *__ctmp.ctor(arguments...)
1145                          */
1146                         PtrExp *pe = (PtrExp *)ei->exp;
1147                         if (pe->e1->op == TOKcall)
1148                         {   CallExp *ce = (CallExp *)pe->e1;
1149                             if (ce->e1->op == TOKdotvar)
1150                             {   DotVarExp *dve = (DotVarExp *)ce->e1;
1151                                 if (dve->var->isCtorDeclaration())
1152                                 {   /* It's a constructor call, currently constructing
1153                                      * a temporary __ctmp.
1154                                      */
1155                                     /* Before calling the constructor, initialize
1156                                      * variable with a bit copy of the default
1157                                      * initializer
1158                                      */
1159                                     Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
1160                                     e->op = TOKblit;
1161                                     e->type = t;
1162                                     ei->exp = new CommaExp(loc, e, ei->exp);
1163
1164                                     /* Replace __ctmp being constructed with e1
1165                                      */
1166                                     dve->e1 = e1;
1167                                     return;
1168                                 }
1169                             }
1170                         }
1171                     }
1172 #endif
1173                     if (!ei->exp->implicitConvTo(type))
1174                     {
1175                         Type *ti = ei->exp->type->toBasetype();
1176                         // Look for constructor first
1177                         if (sd->ctor &&
1178                             /* Initializing with the same type is done differently
1179                              */
1180                             !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1181                         {
1182                            // Rewrite as e1.ctor(arguments)
1183                             Expression *ector = new DotIdExp(loc, e1, Id::ctor);
1184                             ei->exp = new CallExp(loc, ector, ei->exp);
1185                             /* Before calling the constructor, initialize
1186                              * variable with a bit copy of the default
1187                              * initializer
1188                              */
1189                             Expression *e = new AssignExp(loc, e1, t->defaultInit(loc));
1190                             e->op = TOKblit;
1191                             e->type = t;
1192                             ei->exp = new CommaExp(loc, e, ei->exp);
1193                         }
1194                         else
1195                         /* Look for opCall
1196                          * See bugzilla 2702 for more discussion
1197                          */
1198                         // Don't cast away invariant or mutability in initializer
1199                         if (search_function(sd, Id::call) &&
1200                             /* Initializing with the same type is done differently
1201                              */
1202                             !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1203                         {   // Rewrite as e1.call(arguments)
1204                             Expression * eCall = new DotIdExp(loc, e1, Id::call);
1205                             ei->exp = new CallExp(loc, eCall, ei->exp);
1206                         }
1207                     }
1208                 }
1209                 ei->exp = new AssignExp(loc, e1, ei->exp);
1210                 ei->exp->op = op;
1211                 canassign++;
1212                 ei->exp = ei->exp->semantic(sc);
1213                 canassign--;
1214                 ei->exp->optimize(WANTvalue);
1215             }
1216             else
1217             {
1218                 init = init->semantic(sc, type);
1219             }
1220         }
1221         else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
1222                  type->isConst() || type->isImmutable() ||
1223                  parent->isAggregateDeclaration())
1224         {
1225             /* Because we may need the results of a const declaration in a
1226              * subsequent type, such as an array dimension, before semantic2()
1227              * gets ordinarily run, try to run semantic2() now.
1228              * Ignore failure.
1229              */
1230
1231             if (!global.errors && !inferred)
1232             {
1233                 unsigned errors = global.errors;
1234                 global.gag++;
1235                 //printf("+gag\n");
1236                 Expression *e;
1237                 Initializer *i2 = init;
1238                 inuse++;
1239                 if (ei)
1240                 {
1241                     e = ei->exp->syntaxCopy();
1242                     e = e->semantic(sc);
1243                     e = resolveProperties(sc, e);
1244 #if DMDV2
1245                     /* The problem is the following code:
1246                      *  struct CopyTest {
1247                      *     double x;
1248                      *     this(double a) { x = a * 10.0;}
1249                      *     this(this) { x += 2.0; }
1250                      *  }
1251                      *  const CopyTest z = CopyTest(5.3);  // ok
1252                      *  const CopyTest w = z;              // not ok, postblit not run
1253                      *  static assert(w.x == 55.0);
1254                      * because the postblit doesn't get run on the initialization of w.
1255                      */
1256
1257                     Type *tb = e->type->toBasetype();
1258                     if (tb->ty == Tstruct)
1259                     {   StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1260                         Type *typeb = type->toBasetype();
1261                         /* Look to see if initializer involves a copy constructor
1262                          * (which implies a postblit)
1263                          */
1264                         if (sd->cpctor &&               // there is a copy constructor
1265                             typeb->equals(tb))          // rvalue is the same struct
1266                         {
1267                             // The only allowable initializer is a (non-copy) constructor
1268                             if (e->op == TOKcall)
1269                             {
1270                                 CallExp *ce = (CallExp *)e;
1271                                 if (ce->e1->op == TOKdotvar)
1272                                 {
1273                                     DotVarExp *dve = (DotVarExp *)ce->e1;
1274                                     if (dve->var->isCtorDeclaration())
1275                                         goto LNoCopyConstruction;
1276                                 }
1277                             }
1278                             global.gag--;
1279                             error("of type struct %s uses this(this), which is not allowed in static initialization", typeb->toChars());
1280                             global.gag++;
1281
1282                           LNoCopyConstruction:
1283                             ;
1284                         }
1285                     }
1286 #endif
1287                     e = e->implicitCastTo(sc, type);
1288                 }
1289                 else if (si || ai)
1290                 {   i2 = init->syntaxCopy();
1291                     i2 = i2->semantic(sc, type);
1292                 }
1293                 inuse--;
1294                 global.gag--;
1295                 //printf("-gag\n");
1296                 if (errors != global.errors)    // if errors happened
1297                 {
1298                     if (global.gag == 0)
1299                         global.errors = errors; // act as if nothing happened
1300 #if DMDV2
1301                     /* Save scope for later use, to try again
1302                      */
1303                     scope = new Scope(*sc);
1304                     scope->setNoFree();
1305 #endif
1306                 }
1307                 else if (ei)
1308                 {
1309                     if (isDataseg() || (storage_class & STCmanifest))
1310                         e = e->optimize(WANTvalue | WANTinterpret);
1311                     else
1312                         e = e->optimize(WANTvalue);
1313                     switch (e->op)
1314                     {
1315                         case TOKint64:
1316                         case TOKfloat64:
1317                         case TOKstring:
1318                         case TOKarrayliteral:
1319                         case TOKassocarrayliteral:
1320                         case TOKstructliteral:
1321                         case TOKnull:
1322                             ei->exp = e;            // no errors, keep result
1323                             break;
1324
1325                         default:
1326 #if DMDV2
1327                             /* Save scope for later use, to try again
1328                              */
1329                             scope = new Scope(*sc);
1330                             scope->setNoFree();
1331 #endif
1332                             break;
1333                     }
1334                 }
1335                 else
1336                     init = i2;          // no errors, keep result
1337             }
1338         }
1339         sc = sc->pop();
1340     }
1341     sem = SemanticDone;
1342 }
1343
1344 void VarDeclaration::semantic2(Scope *sc)
1345 {
1346     //printf("VarDeclaration::semantic2('%s')\n", toChars());
1347     if (init && !toParent()->isFuncDeclaration())
1348     {   inuse++;
1349 #if 0
1350         ExpInitializer *ei = init->isExpInitializer();
1351         if (ei)
1352         {
1353             ei->exp->dump(0);
1354             printf("type = %p\n", ei->exp->type);
1355         }
1356 #endif
1357         init = init->semantic(sc, type);
1358         inuse--;
1359     }
1360     sem = Semantic2Done;
1361 }
1362
1363 const char *VarDeclaration::kind()
1364 {
1365     return "variable";
1366 }
1367
1368 Dsymbol *VarDeclaration::toAlias()
1369 {
1370     //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1371     assert(this != aliassym);
1372     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1373     return s;
1374 }
1375
1376 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1377 {
1378     StorageClassDeclaration::stcToCBuffer(buf, storage_class);
1379
1380     /* If changing, be sure and fix CompoundDeclarationStatement::toCBuffer()
1381      * too.
1382      */
1383     if (type)
1384         type->toCBuffer(buf, ident, hgs);
1385     else
1386         buf->writestring(ident->toChars());
1387     if (init)
1388     {   buf->writestring(" = ");
1389 #if DMDV2
1390         ExpInitializer *ie = init->isExpInitializer();
1391         if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1392             ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
1393         else
1394 #endif
1395             init->toCBuffer(buf, hgs);
1396     }
1397     buf->writeByte(';');
1398     buf->writenl();
1399 }
1400
1401 AggregateDeclaration *VarDeclaration::isThis()
1402 {
1403     AggregateDeclaration *ad = NULL;
1404
1405     if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter |
1406                            STCtls | STCgshared | STCctfe)))
1407     {
1408         if ((storage_class & (STCconst | STCimmutable | STCwild)) && init)
1409             return NULL;
1410
1411         for (Dsymbol *s = this; s; s = s->parent)
1412         {
1413             ad = s->isMember();
1414             if (ad)
1415                 break;
1416             if (!s->parent || !s->parent->isTemplateMixin()) break;
1417         }
1418     }
1419     return ad;
1420 }
1421
1422 int VarDeclaration::needThis()
1423 {
1424     //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1425     return storage_class & STCfield;
1426 }
1427
1428 int VarDeclaration::isImportedSymbol()
1429 {
1430     if (protection == PROTexport && !init &&
1431         (storage_class & STCstatic || parent->isModule()))
1432         return TRUE;
1433     return FALSE;
1434 }
1435
1436 void VarDeclaration::checkCtorConstInit()
1437 {
1438 #if 0 /* doesn't work if more than one static ctor */
1439     if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
1440         error("missing initializer in static constructor for const variable");
1441 #endif
1442 }
1443
1444 /************************************
1445  * Check to see if this variable is actually in an enclosing function
1446  * rather than the current one.
1447  */
1448
1449 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1450 {
1451     //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
1452     if (parent && !isDataseg() && parent != sc->parent &&
1453         !(storage_class & STCmanifest))
1454     {
1455         // The function that this variable is in
1456         FuncDeclaration *fdv = toParent()->isFuncDeclaration();
1457         // The current function
1458         FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1459
1460         if (fdv && fdthis && fdv != fdthis)
1461         {
1462             if (loc.filename)
1463                 fdthis->getLevel(loc, fdv);
1464
1465             for (int i = 0; i < nestedrefs.dim; i++)
1466             {   FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i];
1467                 if (f == fdthis)
1468                     goto L1;
1469             }
1470             nestedrefs.push(fdthis);
1471           L1: ;
1472
1473
1474             for (int i = 0; i < fdv->closureVars.dim; i++)
1475             {   Dsymbol *s = (Dsymbol *)fdv->closureVars.data[i];
1476                 if (s == this)
1477                     goto L2;
1478             }
1479
1480             fdv->closureVars.push(this);
1481           L2: ;
1482
1483             //printf("fdthis is %s\n", fdthis->toChars());
1484             //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1485             // __dollar creates problems because it isn't a real variable Bugzilla 3326
1486             if (ident == Id::dollar)
1487                 ::error(loc, "cannnot use $ inside a function literal");
1488         }
1489     }
1490 }
1491
1492 /****************************
1493  * Get ExpInitializer for a variable, if there is one.
1494  */
1495
1496 ExpInitializer *VarDeclaration::getExpInitializer()
1497 {
1498     ExpInitializer *ei;
1499
1500     if (init)
1501         ei = init->isExpInitializer();
1502     else
1503     {
1504         Expression *e = type->defaultInit(loc);
1505         if (e)
1506             ei = new ExpInitializer(loc, e);
1507         else
1508             ei = NULL;
1509     }
1510     return ei;
1511 }
1512
1513 /*******************************************
1514  * If variable has a constant expression initializer, get it.
1515  * Otherwise, return NULL.
1516  */
1517
1518 Expression *VarDeclaration::getConstInitializer()
1519 {
1520     if ((isConst() || isImmutable() || storage_class & STCmanifest) &&
1521         storage_class & STCinit)
1522     {
1523         ExpInitializer *ei = getExpInitializer();
1524         if (ei)
1525             return ei->exp;
1526     }
1527
1528     return NULL;
1529 }
1530
1531 /*************************************
1532  * Return !=0 if we can take the address of this variable.
1533  */
1534
1535 int VarDeclaration::canTakeAddressOf()
1536 {
1537 #if 0
1538     /* Global variables and struct/class fields of the form:
1539      *  const int x = 3;
1540      * are not stored and hence cannot have their address taken.
1541      */
1542     if ((isConst() || isImmutable()) &&
1543         storage_class & STCinit &&
1544         (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) &&
1545         (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) &&
1546         type->toBasetype()->isTypeBasic()
1547        )
1548     {
1549         return 0;
1550     }
1551 #else
1552     if (storage_class & STCmanifest)
1553         return 0;
1554 #endif
1555     return 1;
1556 }
1557
1558 /*******************************
1559  * Does symbol go into data segment?
1560  * Includes extern variables.
1561  */
1562
1563 int VarDeclaration::isDataseg()
1564 {
1565 #if 0
1566     printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1567     printf("%llx, isModule: %p, isTemplateInstance: %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
1568     printf("parent = '%s'\n", parent->toChars());
1569 #endif
1570     if (storage_class & STCmanifest)
1571         return 0;
1572     Dsymbol *parent = this->toParent();
1573     if (!parent && !(storage_class & STCstatic))
1574     {   error("forward referenced");
1575         type = Type::terror;
1576         return 0;
1577     }
1578     return canTakeAddressOf() &&
1579         (storage_class & (STCstatic | STCextern | STCtls | STCgshared) ||
1580          toParent()->isModule() ||
1581          toParent()->isTemplateInstance());
1582 }
1583
1584 /************************************
1585  * Does symbol go into thread local storage?
1586  */
1587
1588 int VarDeclaration::isThreadlocal()
1589 {
1590     //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars());
1591 #if 0 //|| TARGET_OSX
1592     /* To be thread-local, must use the __thread storage class.
1593      * BUG: OSX doesn't support thread local yet.
1594      */
1595     return isDataseg() &&
1596         (storage_class & (STCtls | STCconst | STCimmutable | STCshared | STCgshared)) == STCtls;
1597 #else
1598     /* Data defaults to being thread-local. It is not thread-local
1599      * if it is immutable, const or shared.
1600      */
1601     int i = isDataseg() &&
1602         !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared));
1603     //printf("\treturn %d\n", i);
1604     return i;
1605 #endif
1606 }
1607
1608 /********************************************
1609  * Can variable be read and written by CTFE?
1610  */
1611
1612 int VarDeclaration::isCTFE()
1613 {
1614     return (storage_class & STCctfe) != 0; // || !isDataseg();
1615 }
1616
1617 int VarDeclaration::hasPointers()
1618 {
1619     //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1620     return (!isDataseg() && type->hasPointers());
1621 }
1622
1623 /******************************************
1624  * Return TRUE if variable needs to call the destructor.
1625  */
1626
1627 int VarDeclaration::needsAutoDtor()
1628 {
1629     //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1630
1631     if (noscope || storage_class & STCnodtor)
1632         return FALSE;
1633
1634     // Destructors for structs and arrays of structs
1635     Type *tv = type->toBasetype();
1636     while (tv->ty == Tsarray)
1637     {   TypeSArray *ta = (TypeSArray *)tv;
1638         tv = tv->nextOf()->toBasetype();
1639     }
1640     if (tv->ty == Tstruct)
1641     {   TypeStruct *ts = (TypeStruct *)tv;
1642         StructDeclaration *sd = ts->sym;
1643         if (sd->dtor)
1644             return TRUE;
1645     }
1646
1647     // Destructors for classes
1648     if (storage_class & (STCauto | STCscope))
1649     {
1650         if (type->isClassHandle())
1651             return TRUE;
1652     }
1653     return FALSE;
1654 }
1655
1656
1657 /******************************************
1658  * If a variable has a scope destructor call, return call for it.
1659  * Otherwise, return NULL.
1660  */
1661
1662 Expression *VarDeclaration::callScopeDtor(Scope *sc)
1663 {   Expression *e = NULL;
1664
1665     //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
1666
1667     if (noscope || storage_class & STCnodtor)
1668         return NULL;
1669
1670     // Destructors for structs and arrays of structs
1671     bool array = false;
1672     Type *tv = type->toBasetype();
1673     while (tv->ty == Tsarray)
1674     {   TypeSArray *ta = (TypeSArray *)tv;
1675         array = true;
1676         tv = tv->nextOf()->toBasetype();
1677     }
1678     if (tv->ty == Tstruct)
1679     {   TypeStruct *ts = (TypeStruct *)tv;
1680         StructDeclaration *sd = ts->sym;
1681         if (sd->dtor)
1682         {
1683             if (array)
1684             {
1685                 // Typeinfo.destroy(cast(void*)&v);
1686                 Expression *ea = new SymOffExp(loc, this, 0, 0);
1687                 ea = new CastExp(loc, ea, Type::tvoid->pointerTo());
1688                 Expressions *args = new Expressions();
1689                 args->push(ea);
1690
1691                 Expression *et = type->getTypeInfo(sc);
1692                 et = new DotIdExp(loc, et, Id::destroy);
1693
1694                 e = new CallExp(loc, et, args);
1695             }
1696             else
1697             {
1698                 e = new VarExp(loc, this);
1699                 e = new DotVarExp(loc, e, sd->dtor, 0);
1700                 e = new CallExp(loc, e);
1701             }
1702             return e;
1703         }
1704     }
1705
1706     // Destructors for classes
1707     if (storage_class & (STCauto | STCscope))
1708     {
1709         for (ClassDeclaration *cd = type->isClassHandle();
1710              cd;
1711              cd = cd->baseClass)
1712         {
1713             /* We can do better if there's a way with onstack
1714              * classes to determine if there's no way the monitor
1715              * could be set.
1716              */
1717             //if (cd->isInterfaceDeclaration())
1718                 //error("interface %s cannot be scope", cd->toChars());
1719             if (1 || onstack || cd->dtors.dim)  // if any destructors
1720             {
1721                 // delete this;
1722                 Expression *ec;
1723
1724                 ec = new VarExp(loc, this);
1725                 e = new DeleteExp(loc, ec);
1726                 e->type = Type::tvoid;
1727                 break;
1728             }
1729         }
1730     }
1731     return e;
1732 }
1733
1734
1735 /********************************* ClassInfoDeclaration ****************************/
1736
1737 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
1738     : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
1739 {
1740     this->cd = cd;
1741     storage_class = STCstatic | STCgshared;
1742 }
1743
1744 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
1745 {
1746     assert(0);          // should never be produced by syntax
1747     return NULL;
1748 }
1749
1750 void ClassInfoDeclaration::semantic(Scope *sc)
1751 {
1752 }
1753
1754 /********************************* ModuleInfoDeclaration ****************************/
1755
1756 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
1757     : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
1758 {
1759     this->mod = mod;
1760     storage_class = STCstatic | STCgshared;
1761 }
1762
1763 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
1764 {
1765     assert(0);          // should never be produced by syntax
1766     return NULL;
1767 }
1768
1769 void ModuleInfoDeclaration::semantic(Scope *sc)
1770 {
1771 }
1772
1773 /********************************* TypeInfoDeclaration ****************************/
1774
1775 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
1776     : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
1777 {
1778     this->tinfo = tinfo;
1779     storage_class = STCstatic | STCgshared;
1780     protection = PROTpublic;
1781     linkage = LINKc;
1782 }
1783
1784 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
1785 {
1786     assert(0);          // should never be produced by syntax
1787     return NULL;
1788 }
1789
1790 void TypeInfoDeclaration::semantic(Scope *sc)
1791 {
1792     assert(linkage == LINKc);
1793 }
1794
1795 /***************************** TypeInfoConstDeclaration **********************/
1796
1797 #if DMDV2
1798 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1799     : TypeInfoDeclaration(tinfo, 0)
1800 {
1801     type = Type::typeinfoconst->type;
1802 }
1803 #endif
1804
1805 /***************************** TypeInfoInvariantDeclaration **********************/
1806
1807 #if DMDV2
1808 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1809     : TypeInfoDeclaration(tinfo, 0)
1810 {
1811     type = Type::typeinfoinvariant->type;
1812 }
1813 #endif
1814
1815 /***************************** TypeInfoSharedDeclaration **********************/
1816
1817 #if DMDV2
1818 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
1819     : TypeInfoDeclaration(tinfo, 0)
1820 {
1821     type = Type::typeinfoshared->type;
1822 }
1823 #endif
1824
1825 /***************************** TypeInfoWildDeclaration **********************/
1826
1827 #if DMDV2
1828 TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
1829     : TypeInfoDeclaration(tinfo, 0)
1830 {
1831     type = Type::typeinfowild->type;
1832 }
1833 #endif
1834
1835 /***************************** TypeInfoStructDeclaration **********************/
1836
1837 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1838     : TypeInfoDeclaration(tinfo, 0)
1839 {
1840     type = Type::typeinfostruct->type;
1841 }
1842
1843 /***************************** TypeInfoClassDeclaration ***********************/
1844
1845 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1846     : TypeInfoDeclaration(tinfo, 0)
1847 {
1848     type = Type::typeinfoclass->type;
1849 }
1850
1851 /***************************** TypeInfoInterfaceDeclaration *******************/
1852
1853 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1854     : TypeInfoDeclaration(tinfo, 0)
1855 {
1856     type = Type::typeinfointerface->type;
1857 }
1858
1859 /***************************** TypeInfoTypedefDeclaration *********************/
1860
1861 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
1862     : TypeInfoDeclaration(tinfo, 0)
1863 {
1864     type = Type::typeinfotypedef->type;
1865 }
1866
1867 /***************************** TypeInfoPointerDeclaration *********************/
1868
1869 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1870     : TypeInfoDeclaration(tinfo, 0)
1871 {
1872     type = Type::typeinfopointer->type;
1873 }
1874
1875 /***************************** TypeInfoArrayDeclaration ***********************/
1876
1877 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1878     : TypeInfoDeclaration(tinfo, 0)
1879 {
1880     type = Type::typeinfoarray->type;
1881 }
1882
1883 /***************************** TypeInfoStaticArrayDeclaration *****************/
1884
1885 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1886     : TypeInfoDeclaration(tinfo, 0)
1887 {
1888     type = Type::typeinfostaticarray->type;
1889 }
1890
1891 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1892
1893 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1894     : TypeInfoDeclaration(tinfo, 0)
1895 {
1896     type = Type::typeinfoassociativearray->type;
1897 }
1898
1899 /***************************** TypeInfoEnumDeclaration ***********************/
1900
1901 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1902     : TypeInfoDeclaration(tinfo, 0)
1903 {
1904     type = Type::typeinfoenum->type;
1905 }
1906
1907 /***************************** TypeInfoFunctionDeclaration ********************/
1908
1909 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1910     : TypeInfoDeclaration(tinfo, 0)
1911 {
1912     type = Type::typeinfofunction->type;
1913 }
1914
1915 /***************************** TypeInfoDelegateDeclaration ********************/
1916
1917 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1918     : TypeInfoDeclaration(tinfo, 0)
1919 {
1920     type = Type::typeinfodelegate->type;
1921 }
1922
1923 /***************************** TypeInfoTupleDeclaration **********************/
1924
1925 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1926     : TypeInfoDeclaration(tinfo, 0)
1927 {
1928     type = Type::typeinfotypelist->type;
1929 }
1930
1931 /********************************* ThisDeclaration ****************************/
1932
1933 // For the "this" parameter to member functions
1934
1935 ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
1936    : VarDeclaration(loc, t, Id::This, NULL)
1937 {
1938     noscope = 1;
1939 }
1940
1941 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
1942 {
1943     assert(0);          // should never be produced by syntax
1944     return NULL;
1945 }
Note: See TracBrowser for help on using the browser.