1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/D-Programming-Language/dmd/blob/master/src/declaration.c
9  */
10 
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
13 
14 #include "errors.h"
15 #include "init.h"
16 #include "declaration.h"
17 #include "attrib.h"
18 #include "mtype.h"
19 #include "template.h"
20 #include "scope.h"
21 #include "aggregate.h"
22 #include "module.h"
23 #include "import.h"
24 #include "id.h"
25 #include "expression.h"
26 #include "statement.h"
27 #include "ctfe.h"
28 #include "target.h"
29 #include "hdrgen.h"
30 
31 bool checkNestedRef(Dsymbol *s, Dsymbol *p);
32 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
33 Expression *semantic(Expression *e, Scope *sc);
34 Initializer *inferType(Initializer *init, Scope *sc);
35 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
36 
37 /************************************
38  * Check to see the aggregate type is nested and its context pointer is
39  * accessible from the current scope.
40  * Returns true if error occurs.
41  */
42 bool checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad, size_t iStart = 0)
43 {
44     Dsymbol *sparent = ad->toParent2();
45     Dsymbol *s = sc->func;
46     if (ad->isNested() && s)
47     {
48         //printf("ad = %p %s [%s], parent:%p\n", ad, ad->toChars(), ad->loc.toChars(), ad->parent);
49         //printf("sparent = %p %s [%s], parent: %s\n", sparent, sparent->toChars(), sparent->loc.toChars(), sparent->parent->toChars());
50         if (checkNestedRef(s, sparent))
51         {
52             error(loc, "cannot access frame pointer of %s", ad->toPrettyChars());
53             return true;
54         }
55     }
56 
57     bool result = false;
58     for (size_t i = iStart; i < ad->fields.dim; i++)
59     {
60         VarDeclaration *vd = ad->fields[i];
61         Type *tb = vd->type->baseElemOf();
62         if (tb->ty == Tstruct)
63         {
64             result |= checkFrameAccess(loc, sc, ((TypeStruct *)tb)->sym);
65         }
66     }
67     return result;
68 }
69 
70 /********************************* Declaration ****************************/
71 
Declaration(Identifier * id)72 Declaration::Declaration(Identifier *id)
73     : Dsymbol(id)
74 {
75     type = NULL;
76     originalType = NULL;
77     storage_class = STCundefined;
78     protection = Prot(PROTundefined);
79     linkage = LINKdefault;
80     inuse = 0;
81     mangleOverride = NULL;
82 }
83 
semantic(Scope *)84 void Declaration::semantic(Scope *)
85 {
86 }
87 
kind()88 const char *Declaration::kind() const
89 {
90     return "declaration";
91 }
92 
size(Loc)93 d_uns64 Declaration::size(Loc)
94 {
95     assert(type);
96     return type->size();
97 }
98 
isDelete()99 bool Declaration::isDelete()
100 {
101     return false;
102 }
103 
isDataseg()104 bool Declaration::isDataseg()
105 {
106     return false;
107 }
108 
isThreadlocal()109 bool Declaration::isThreadlocal()
110 {
111     return false;
112 }
113 
isCodeseg()114 bool Declaration::isCodeseg() const
115 {
116     return false;
117 }
118 
prot()119 Prot Declaration::prot()
120 {
121     return protection;
122 }
123 
124 /*************************************
125  * Check to see if declaration can be modified in this context (sc).
126  * Issue error if not.
127  */
128 
checkModify(Loc loc,Scope * sc,Type *,Expression * e1,int flag)129 int Declaration::checkModify(Loc loc, Scope *sc, Type *, Expression *e1, int flag)
130 {
131     VarDeclaration *v = isVarDeclaration();
132     if (v && v->canassign)
133         return 2;
134 
135     if (isParameter() || isResult())
136     {
137         for (Scope *scx = sc; scx; scx = scx->enclosing)
138         {
139             if (scx->func == parent && (scx->flags & SCOPEcontract))
140             {
141                 const char *s = isParameter() && parent->ident != Id::ensure ? "parameter" : "result";
142                 if (!flag) error(loc, "cannot modify %s '%s' in contract", s, toChars());
143                 return 2;   // do not report type related errors
144             }
145         }
146     }
147 
148     if (v && (isCtorinit() || isField()))
149     {
150         // It's only modifiable if inside the right constructor
151         if ((storage_class & (STCforeach | STCref)) == (STCforeach | STCref))
152             return 2;
153         return modifyFieldVar(loc, sc, v, e1) ? 2 : 1;
154     }
155     return 1;
156 }
157 
search(const Loc & loc,Identifier * ident,int flags)158 Dsymbol *Declaration::search(const Loc &loc, Identifier *ident, int flags)
159 {
160     Dsymbol *s = Dsymbol::search(loc, ident, flags);
161     if (!s && type)
162     {
163         s = type->toDsymbol(_scope);
164         if (s)
165             s = s->search(loc, ident, flags);
166     }
167     return s;
168 }
169 
170 
171 /********************************* TupleDeclaration ****************************/
172 
TupleDeclaration(Loc loc,Identifier * id,Objects * objects)173 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
174     : Declaration(id)
175 {
176     this->loc = loc;
177     this->type = NULL;
178     this->objects = objects;
179     this->isexp = false;
180     this->tupletype = NULL;
181 }
182 
syntaxCopy(Dsymbol *)183 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *)
184 {
185     assert(0);
186     return NULL;
187 }
188 
kind()189 const char *TupleDeclaration::kind() const
190 {
191     return "tuple";
192 }
193 
getType()194 Type *TupleDeclaration::getType()
195 {
196     /* If this tuple represents a type, return that type
197      */
198 
199     //printf("TupleDeclaration::getType() %s\n", toChars());
200     if (isexp)
201         return NULL;
202     if (!tupletype)
203     {
204         /* It's only a type tuple if all the Object's are types
205          */
206         for (size_t i = 0; i < objects->dim; i++)
207         {
208             RootObject *o = (*objects)[i];
209             if (o->dyncast() != DYNCAST_TYPE)
210             {
211                 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
212                 return NULL;
213             }
214         }
215 
216         /* We know it's a type tuple, so build the TypeTuple
217          */
218         Types *types = (Types *)objects;
219         Parameters *args = new Parameters();
220         args->setDim(objects->dim);
221         OutBuffer buf;
222         int hasdeco = 1;
223         for (size_t i = 0; i < types->dim; i++)
224         {
225             Type *t = (*types)[i];
226             //printf("type = %s\n", t->toChars());
227             Parameter *arg = new Parameter(0, t, NULL, NULL);
228             (*args)[i] = arg;
229             if (!t->deco)
230                 hasdeco = 0;
231         }
232 
233         tupletype = new TypeTuple(args);
234         if (hasdeco)
235             return tupletype->semantic(Loc(), NULL);
236     }
237 
238     return tupletype;
239 }
240 
toAlias2()241 Dsymbol *TupleDeclaration::toAlias2()
242 {
243     //printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects->toChars());
244 
245     for (size_t i = 0; i < objects->dim; i++)
246     {
247         RootObject *o = (*objects)[i];
248         if (Dsymbol *s = isDsymbol(o))
249         {
250             s = s->toAlias2();
251             (*objects)[i] = s;
252         }
253     }
254     return this;
255 }
256 
needThis()257 bool TupleDeclaration::needThis()
258 {
259     //printf("TupleDeclaration::needThis(%s)\n", toChars());
260     for (size_t i = 0; i < objects->dim; i++)
261     {
262         RootObject *o = (*objects)[i];
263         if (o->dyncast() == DYNCAST_EXPRESSION)
264         {
265             Expression *e = (Expression *)o;
266             if (e->op == TOKdsymbol)
267             {
268                 DsymbolExp *ve = (DsymbolExp *)e;
269                 Declaration *d = ve->s->isDeclaration();
270                 if (d && d->needThis())
271                 {
272                     return true;
273                 }
274             }
275         }
276     }
277     return false;
278 }
279 
280 /********************************* AliasDeclaration ****************************/
281 
AliasDeclaration(Loc loc,Identifier * id,Type * type)282 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
283     : Declaration(id)
284 {
285     //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
286     //printf("type = '%s'\n", type->toChars());
287     this->loc = loc;
288     this->type = type;
289     this->aliassym = NULL;
290     this->_import = NULL;
291     this->overnext = NULL;
292     assert(type);
293 }
294 
AliasDeclaration(Loc loc,Identifier * id,Dsymbol * s)295 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
296     : Declaration(id)
297 {
298     //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
299     assert(s != this);
300     this->loc = loc;
301     this->type = NULL;
302     this->aliassym = s;
303     this->_import = NULL;
304     this->overnext = NULL;
305     assert(s);
306 }
307 
create(Loc loc,Identifier * id,Type * type)308 AliasDeclaration *AliasDeclaration::create(Loc loc, Identifier *id, Type *type)
309 {
310     return new AliasDeclaration(loc, id, type);
311 }
312 
syntaxCopy(Dsymbol * s)313 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
314 {
315     //printf("AliasDeclaration::syntaxCopy()\n");
316     assert(!s);
317     AliasDeclaration *sa =
318         type ? new AliasDeclaration(loc, ident, type->syntaxCopy())
319              : new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
320     sa->storage_class = storage_class;
321     return sa;
322 }
323 
semantic(Scope * sc)324 void AliasDeclaration::semantic(Scope *sc)
325 {
326     if (semanticRun >= PASSsemanticdone)
327         return;
328     assert(semanticRun <= PASSsemantic);
329 
330     storage_class |= sc->stc & STCdeprecated;
331     protection = sc->protection;
332     userAttribDecl = sc->userAttribDecl;
333 
334     if (!sc->func && inNonRoot())
335         return;
336 
337     aliasSemantic(sc);
338 }
339 
aliasSemantic(Scope * sc)340 void AliasDeclaration::aliasSemantic(Scope *sc)
341 {
342     //printf("AliasDeclaration::semantic() %s\n", toChars());
343     if (aliassym)
344     {
345         FuncDeclaration *fd = aliassym->isFuncLiteralDeclaration();
346         TemplateDeclaration *td = aliassym->isTemplateDeclaration();
347         if (fd || (td && td->literal))
348         {
349             if (fd && fd->semanticRun >= PASSsemanticdone)
350                 return;
351 
352             Expression *e = new FuncExp(loc, aliassym);
353             e = ::semantic(e, sc);
354             if (e->op == TOKfunction)
355             {
356                 FuncExp *fe = (FuncExp *)e;
357                 aliassym = fe->td ? (Dsymbol *)fe->td : fe->fd;
358             }
359             else
360             {
361                 aliassym = NULL;
362                 type = Type::terror;
363             }
364             return;
365         }
366 
367         if (aliassym->isTemplateInstance())
368             aliassym->semantic(sc);
369         return;
370     }
371     inuse = 1;
372 
373     // Given:
374     //  alias foo.bar.abc def;
375     // it is not knowable from the syntax whether this is an alias
376     // for a type or an alias for a symbol. It is up to the semantic()
377     // pass to distinguish.
378     // If it is a type, then type is set and getType() will return that
379     // type. If it is a symbol, then aliassym is set and type is NULL -
380     // toAlias() will return aliasssym.
381 
382     unsigned int errors = global.errors;
383     Type *oldtype = type;
384 
385     // Ungag errors when not instantiated DeclDefs scope alias
386     Ungag ungag(global.gag);
387     //printf("%s parent = %s, gag = %d, instantiated = %d\n", toChars(), parent, global.gag, isInstantiated());
388     if (parent && global.gag && !isInstantiated() && !toParent2()->isFuncDeclaration())
389     {
390         //printf("%s type = %s\n", toPrettyChars(), type->toChars());
391         global.gag = 0;
392     }
393 
394     /* This section is needed because Type::resolve() will:
395      *   const x = 3;
396      *   alias y = x;
397      * try to convert identifier x to 3.
398      */
399     Dsymbol *s = type->toDsymbol(sc);
400     if (errors != global.errors)
401     {
402         s = NULL;
403         type = Type::terror;
404     }
405     if (s && s == this)
406     {
407         error("cannot resolve");
408         s = NULL;
409         type = Type::terror;
410     }
411     if (!s || !s->isEnumMember())
412     {
413         Type *t;
414         Expression *e;
415         Scope *sc2 = sc;
416         if (storage_class & (STCref | STCnothrow | STCnogc | STCpure | STCdisable))
417         {
418             // For 'ref' to be attached to function types, and picked
419             // up by Type::resolve(), it has to go into sc.
420             sc2 = sc->push();
421             sc2->stc |= storage_class & (STCref | STCnothrow | STCnogc | STCpure | STCshared | STCdisable);
422         }
423         type = type->addSTC(storage_class);
424         type->resolve(loc, sc2, &e, &t, &s);
425         if (sc2 != sc)
426             sc2->pop();
427 
428         if (e)  // Try to convert Expression to Dsymbol
429         {
430             s = getDsymbol(e);
431             if (!s)
432             {
433                 if (e->op != TOKerror)
434                     error("cannot alias an expression %s", e->toChars());
435                 t = Type::terror;
436             }
437         }
438         type = t;
439     }
440     if (s == this)
441     {
442         assert(global.errors);
443         type = Type::terror;
444         s = NULL;
445     }
446     if (!s) // it's a type alias
447     {
448         //printf("alias %s resolved to type %s\n", toChars(), type->toChars());
449         type = type->semantic(loc, sc);
450         aliassym = NULL;
451     }
452     else    // it's a symbolic alias
453     {
454         //printf("alias %s resolved to %s %s\n", toChars(), s->kind(), s->toChars());
455         type = NULL;
456         aliassym = s;
457     }
458     if (global.gag && errors != global.errors)
459     {
460         type = oldtype;
461         aliassym = NULL;
462     }
463     inuse = 0;
464     semanticRun = PASSsemanticdone;
465 
466     if (Dsymbol *sx = overnext)
467     {
468         overnext = NULL;
469 
470         if (!overloadInsert(sx))
471             ScopeDsymbol::multiplyDefined(Loc(), sx, this);
472     }
473 }
474 
overloadInsert(Dsymbol * s)475 bool AliasDeclaration::overloadInsert(Dsymbol *s)
476 {
477     //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n",
478     //    loc.toChars(), toChars(), s->kind(), s->toChars(), s->loc.toChars());
479 
480     /** Aliases aren't overloadable themselves, but if their Aliasee is
481      *  overloadable they are converted to an overloadable Alias (either
482      *  FuncAliasDeclaration or OverDeclaration).
483      *
484      *  This is done by moving the Aliasee into such an overloadable alias
485      *  which is then used to replace the existing Aliasee. The original
486      *  Alias (_this_) remains a useless shell.
487      *
488      *  This is a horrible mess. It was probably done to avoid replacing
489      *  existing AST nodes and references, but it needs a major
490      *  simplification b/c it's too complex to maintain.
491      *
492      *  A simpler approach might be to merge any colliding symbols into a
493      *  simple Overload class (an array) and then later have that resolve
494      *  all collisions.
495      */
496     if (semanticRun >= PASSsemanticdone)
497     {
498         /* Semantic analysis is already finished, and the aliased entity
499          * is not overloadable.
500          */
501         if (type)
502             return false;
503 
504         /* When s is added in member scope by static if, mixin("code") or others,
505          * aliassym is determined already. See the case in: test/compilable/test61.d
506          */
507         Dsymbol *sa = aliassym->toAlias();
508         if (FuncDeclaration *fd = sa->isFuncDeclaration())
509         {
510             FuncAliasDeclaration *fa = new FuncAliasDeclaration(ident, fd);
511             fa->protection = protection;
512             fa->parent = parent;
513             aliassym = fa;
514             return aliassym->overloadInsert(s);
515         }
516         if (TemplateDeclaration *td = sa->isTemplateDeclaration())
517         {
518             OverDeclaration *od = new OverDeclaration(ident, td);
519             od->protection = protection;
520             od->parent = parent;
521             aliassym = od;
522             return aliassym->overloadInsert(s);
523         }
524         if (OverDeclaration *od = sa->isOverDeclaration())
525         {
526             if (sa->ident != ident || sa->parent != parent)
527             {
528                 od = new OverDeclaration(ident, od);
529                 od->protection = protection;
530                 od->parent = parent;
531                 aliassym = od;
532             }
533             return od->overloadInsert(s);
534         }
535         if (OverloadSet *os = sa->isOverloadSet())
536         {
537             if (sa->ident != ident || sa->parent != parent)
538             {
539                 os = new OverloadSet(ident, os);
540                 // TODO: protection is lost here b/c OverloadSets have no protection attribute
541                 // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow.
542                 // ----
543                 // module os1;
544                 // import a, b;
545                 // private alias merged = foo; // private alias to overload set of a.foo and b.foo
546                 // ----
547                 // module os2;
548                 // import a, b;
549                 // public alias merged = bar; // public alias to overload set of a.bar and b.bar
550                 // ----
551                 // module bug;
552                 // import os1, os2;
553                 // void test() { merged(123); } // should only look at os2.merged
554                 //
555                 // os.protection = protection;
556                 os->parent = parent;
557                 aliassym = os;
558             }
559             os->push(s);
560             return true;
561         }
562         return false;
563     }
564 
565     /* Don't know yet what the aliased symbol is, so assume it can
566      * be overloaded and check later for correctness.
567      */
568     if (overnext)
569         return overnext->overloadInsert(s);
570     if (s == this)
571         return true;
572     overnext = s;
573     return true;
574 }
575 
kind()576 const char *AliasDeclaration::kind() const
577 {
578     return "alias";
579 }
580 
getType()581 Type *AliasDeclaration::getType()
582 {
583     if (type)
584         return type;
585     return toAlias()->getType();
586 }
587 
toAlias()588 Dsymbol *AliasDeclaration::toAlias()
589 {
590     //printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\n",
591     //    loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym->kind() : "", inuse);
592     assert(this != aliassym);
593     //static int count; if (++count == 10) *(char*)0=0;
594     if (inuse == 1 && type && _scope)
595     {
596         inuse = 2;
597         unsigned olderrors = global.errors;
598         Dsymbol *s = type->toDsymbol(_scope);
599         //printf("[%s] type = %s, s = %p, this = %p\n", loc.toChars(), type->toChars(), s, this);
600         if (global.errors != olderrors)
601             goto Lerr;
602         if (s)
603         {
604             s = s->toAlias();
605             if (global.errors != olderrors)
606                 goto Lerr;
607             aliassym = s;
608             inuse = 0;
609         }
610         else
611         {
612             Type *t = type->semantic(loc, _scope);
613             if (t->ty == Terror)
614                 goto Lerr;
615             if (global.errors != olderrors)
616                 goto Lerr;
617             //printf("t = %s\n", t->toChars());
618             inuse = 0;
619         }
620     }
621     if (inuse)
622     {
623         error("recursive alias declaration");
624 
625     Lerr:
626         // Avoid breaking "recursive alias" state during errors gagged
627         if (global.gag)
628             return this;
629 
630         aliassym = new AliasDeclaration(loc, ident, Type::terror);
631         type = Type::terror;
632         return aliassym;
633     }
634 
635     if (semanticRun >= PASSsemanticdone)
636     {
637         // semantic is already done.
638 
639         // Do not see aliassym !is null, because of lambda aliases.
640 
641         // Do not see type.deco !is null, even so "alias T = const int;` needs
642         // semantic analysis to take the storage class `const` as type qualifier.
643     }
644     else
645     {
646         if (_import && _import->_scope)
647         {
648             /* If this is an internal alias for selective/renamed import,
649              * load the module first.
650              */
651             _import->semantic(NULL);
652         }
653         if (_scope)
654         {
655             aliasSemantic(_scope);
656         }
657     }
658 
659     inuse = 1;
660     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
661     inuse = 0;
662     return s;
663 }
664 
toAlias2()665 Dsymbol *AliasDeclaration::toAlias2()
666 {
667     if (inuse)
668     {
669         error("recursive alias declaration");
670         return this;
671     }
672     inuse = 1;
673     Dsymbol *s  = aliassym ? aliassym->toAlias2() : this;
674     inuse = 0;
675     return s;
676 }
677 
isOverloadable()678 bool AliasDeclaration::isOverloadable()
679 {
680     // assume overloadable until alias is resolved
681     return semanticRun < PASSsemanticdone ||
682         (aliassym && aliassym->isOverloadable());
683 }
684 
685 /****************************** OverDeclaration **************************/
686 
OverDeclaration(Identifier * ident,Dsymbol * s,bool hasOverloads)687 OverDeclaration::OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads)
688     : Declaration(ident)
689 {
690     this->overnext = NULL;
691     this->aliassym = s;
692 
693     this->hasOverloads = hasOverloads;
694     if (hasOverloads)
695     {
696         if (OverDeclaration *od = aliassym->isOverDeclaration())
697             this->hasOverloads = od->hasOverloads;
698     }
699     else
700     {
701         // for internal use
702         assert(!aliassym->isOverDeclaration());
703     }
704 }
705 
kind()706 const char *OverDeclaration::kind() const
707 {
708     return "overload alias";    // todo
709 }
710 
semantic(Scope *)711 void OverDeclaration::semantic(Scope *)
712 {
713 }
714 
equals(RootObject * o)715 bool OverDeclaration::equals(RootObject *o)
716 {
717     if (this == o)
718         return true;
719 
720     Dsymbol *s = isDsymbol(o);
721     if (!s)
722         return false;
723 
724     OverDeclaration *od1 = this;
725     if (OverDeclaration *od2 = s->isOverDeclaration())
726     {
727         return od1->aliassym->equals(od2->aliassym) &&
728                od1->hasOverloads == od2->hasOverloads;
729     }
730     if (aliassym == s)
731     {
732         if (hasOverloads)
733             return true;
734         if (FuncDeclaration *fd = s->isFuncDeclaration())
735         {
736             return fd->isUnique() != NULL;
737         }
738         if (TemplateDeclaration *td = s->isTemplateDeclaration())
739         {
740             return td->overnext == NULL;
741         }
742     }
743     return false;
744 }
745 
overloadInsert(Dsymbol * s)746 bool OverDeclaration::overloadInsert(Dsymbol *s)
747 {
748     //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s->toChars(), aliassym, overnext);
749     if (overnext)
750         return overnext->overloadInsert(s);
751     if (s == this)
752         return true;
753     overnext = s;
754     return true;
755 }
756 
toAlias()757 Dsymbol *OverDeclaration::toAlias()
758 {
759     return this;
760 }
761 
isOverloadable()762 bool OverDeclaration::isOverloadable()
763 {
764     return true;
765 }
766 
isUnique()767 Dsymbol *OverDeclaration::isUnique()
768 {
769     if (!hasOverloads)
770     {
771         if (aliassym->isFuncDeclaration() ||
772             aliassym->isTemplateDeclaration())
773         {
774             return aliassym;
775         }
776     }
777 
778   struct ParamUniqueSym
779   {
780     static int fp(void *param, Dsymbol *s)
781     {
782         Dsymbol **ps = (Dsymbol **)param;
783         if (*ps)
784         {
785             *ps = NULL;
786             return 1;   // ambiguous, done
787         }
788         else
789         {
790             *ps = s;
791             return 0;
792         }
793     }
794   };
795     Dsymbol *result = NULL;
796     overloadApply(aliassym, &result, &ParamUniqueSym::fp);
797     return result;
798 }
799 
800 /********************************* VarDeclaration ****************************/
801 
VarDeclaration(Loc loc,Type * type,Identifier * id,Initializer * init)802 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
803     : Declaration(id)
804 {
805     //printf("VarDeclaration('%s')\n", id->toChars());
806     assert(id);
807     assert(type || init);
808     this->type = type;
809     this->_init = init;
810     this->loc = loc;
811     offset = 0;
812     isargptr = false;
813     alignment = 0;
814     ctorinit = 0;
815     aliassym = NULL;
816     onstack = false;
817     mynew = false;
818     canassign = 0;
819     overlapped = false;
820     overlapUnsafe = false;
821     doNotInferScope = false;
822     isdataseg = 0;
823     lastVar = NULL;
824     endlinnum = 0;
825     ctfeAdrOnStack = -1;
826     edtor = NULL;
827     range = NULL;
828 
829     static unsigned nextSequenceNumber = 0;
830     this->sequenceNumber = ++nextSequenceNumber;
831 }
832 
syntaxCopy(Dsymbol * s)833 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
834 {
835     //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
836     assert(!s);
837     VarDeclaration *v = new VarDeclaration(loc,
838             type ? type->syntaxCopy() : NULL,
839             ident,
840             _init ? _init->syntaxCopy() : NULL);
841     v->storage_class = storage_class;
842     return v;
843 }
844 
845 
semantic(Scope * sc)846 void VarDeclaration::semantic(Scope *sc)
847 {
848 //    if (semanticRun > PASSinit)
849 //      return;
850 //    semanticRun = PASSsemantic;
851 
852     if (semanticRun >= PASSsemanticdone)
853         return;
854 
855     Scope *scx = NULL;
856     if (_scope)
857     {
858         sc = _scope;
859         scx = sc;
860         _scope = NULL;
861     }
862 
863     /* Pick up storage classes from context, but except synchronized,
864      * override, abstract, and final.
865      */
866     storage_class |= (sc->stc & ~(STCsynchronized | STCoverride | STCabstract | STCfinal));
867     if (storage_class & STCextern && _init)
868         error("extern symbols cannot have initializers");
869 
870     userAttribDecl = sc->userAttribDecl;
871 
872     AggregateDeclaration *ad = isThis();
873     if (ad)
874         storage_class |= ad->storage_class & STC_TYPECTOR;
875 
876     /* If auto type inference, do the inference
877      */
878     int inferred = 0;
879     if (!type)
880     {
881         inuse++;
882 
883         // Infering the type requires running semantic,
884         // so mark the scope as ctfe if required
885         bool needctfe = (storage_class & (STCmanifest | STCstatic)) != 0;
886         if (needctfe) sc = sc->startCTFE();
887 
888         //printf("inferring type for %s with init %s\n", toChars(), _init->toChars());
889         _init = inferType(_init, sc);
890         type = initializerToExpression(_init)->type;
891 
892         if (needctfe) sc = sc->endCTFE();
893 
894         inuse--;
895         inferred = 1;
896 
897         /* This is a kludge to support the existing syntax for RAII
898          * declarations.
899          */
900         storage_class &= ~STCauto;
901         originalType = type->syntaxCopy();
902     }
903     else
904     {
905         if (!originalType)
906             originalType = type->syntaxCopy();
907 
908         /* Prefix function attributes of variable declaration can affect
909          * its type:
910          *      pure nothrow void function() fp;
911          *      static assert(is(typeof(fp) == void function() pure nothrow));
912          */
913         Scope *sc2 = sc->push();
914         sc2->stc |= (storage_class & STC_FUNCATTR);
915         inuse++;
916         type = type->semantic(loc, sc2);
917         inuse--;
918         sc2->pop();
919     }
920     //printf(" semantic type = %s\n", type ? type->toChars() : "null");
921     if (type->ty == Terror)
922         errors = true;
923 
924     type->checkDeprecated(loc, sc);
925     linkage = sc->linkage;
926     this->parent = sc->parent;
927     //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
928     protection = sc->protection;
929 
930     /* If scope's alignment is the default, use the type's alignment,
931      * otherwise the scope overrrides.
932      */
933     alignment = sc->alignment();
934     if (alignment == STRUCTALIGN_DEFAULT)
935         alignment = type->alignment();          // use type's alignment
936 
937     //printf("sc->stc = %x\n", sc->stc);
938     //printf("storage_class = x%x\n", storage_class);
939 
940     if (global.params.vcomplex)
941         type->checkComplexTransition(loc);
942 
943     // Calculate type size + safety checks
944     if (sc->func && !sc->intypeof)
945     {
946         if ((storage_class & STCgshared) && !isMember())
947         {
948             if (sc->func->setUnsafe())
949                 error("__gshared not allowed in safe functions; use shared");
950         }
951     }
952 
953     Dsymbol *parent = toParent();
954 
955     Type *tb = type->toBasetype();
956     Type *tbn = tb->baseElemOf();
957     if (tb->ty == Tvoid && !(storage_class & STClazy))
958     {
959         if (inferred)
960         {
961             error("type %s is inferred from initializer %s, and variables cannot be of type void",
962                 type->toChars(), _init->toChars());
963         }
964         else
965             error("variables cannot be of type void");
966         type = Type::terror;
967         tb = type;
968     }
969     if (tb->ty == Tfunction)
970     {
971         error("cannot be declared to be a function");
972         type = Type::terror;
973         tb = type;
974     }
975     if (tb->ty == Tstruct)
976     {
977         TypeStruct *ts = (TypeStruct *)tb;
978         if (!ts->sym->members)
979         {
980             error("no definition of struct %s", ts->toChars());
981         }
982     }
983     if ((storage_class & STCauto) && !inferred)
984         error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?");
985 
986     if (tb->ty == Ttuple)
987     {
988         /* Instead, declare variables for each of the tuple elements
989          * and add those.
990          */
991         TypeTuple *tt = (TypeTuple *)tb;
992         size_t nelems = Parameter::dim(tt->arguments);
993         Expression *ie = (_init && !_init->isVoidInitializer()) ? initializerToExpression(_init) : NULL;
994         if (ie)
995             ie = ::semantic(ie, sc);
996 
997         if (nelems > 0 && ie)
998         {
999             Expressions *iexps = new Expressions();
1000             iexps->push(ie);
1001 
1002             Expressions *exps = new Expressions();
1003 
1004             for (size_t pos = 0; pos < iexps->dim; pos++)
1005             {
1006             Lexpand1:
1007                 Expression *e = (*iexps)[pos];
1008                 Parameter *arg = Parameter::getNth(tt->arguments, pos);
1009                 arg->type = arg->type->semantic(loc, sc);
1010                 //printf("[%d] iexps->dim = %d, ", pos, iexps->dim);
1011                 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars());
1012                 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
1013 
1014                 if (e != ie)
1015                 {
1016                 if (iexps->dim > nelems)
1017                     goto Lnomatch;
1018                 if (e->type->implicitConvTo(arg->type))
1019                     continue;
1020                 }
1021 
1022                 if (e->op == TOKtuple)
1023                 {
1024                     TupleExp *te = (TupleExp *)e;
1025                     if (iexps->dim - 1 + te->exps->dim > nelems)
1026                         goto Lnomatch;
1027 
1028                     iexps->remove(pos);
1029                     iexps->insert(pos, te->exps);
1030                     (*iexps)[pos] = Expression::combine(te->e0, (*iexps)[pos]);
1031                     goto Lexpand1;
1032                 }
1033                 else if (isAliasThisTuple(e))
1034                 {
1035                     VarDeclaration *v = copyToTemp(0, "__tup", e);
1036                     VarExp *ve = new VarExp(loc, v);
1037                     ve->type = e->type;
1038 
1039                     exps->setDim(1);
1040                     (*exps)[0] = ve;
1041                     expandAliasThisTuples(exps, 0);
1042 
1043                     for (size_t u = 0; u < exps->dim ; u++)
1044                     {
1045                     Lexpand2:
1046                         Expression *ee = (*exps)[u];
1047                         arg = Parameter::getNth(tt->arguments, pos + u);
1048                         arg->type = arg->type->semantic(loc, sc);
1049                         //printf("[%d+%d] exps->dim = %d, ", pos, u, exps->dim);
1050                         //printf("ee = (%s %s, %s), ", Token::tochars[ee->op], ee->toChars(), ee->type->toChars());
1051                         //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
1052 
1053                         size_t iexps_dim = iexps->dim - 1 + exps->dim;
1054                         if (iexps_dim > nelems)
1055                             goto Lnomatch;
1056                         if (ee->type->implicitConvTo(arg->type))
1057                             continue;
1058 
1059                         if (expandAliasThisTuples(exps, u) != -1)
1060                             goto Lexpand2;
1061                     }
1062 
1063                     if ((*exps)[0] != ve)
1064                     {
1065                         Expression *e0 = (*exps)[0];
1066                         (*exps)[0] = new CommaExp(loc, new DeclarationExp(loc, v), e0);
1067                         (*exps)[0]->type = e0->type;
1068 
1069                         iexps->remove(pos);
1070                         iexps->insert(pos, exps);
1071                         goto Lexpand1;
1072                     }
1073                 }
1074             }
1075             if (iexps->dim < nelems)
1076                 goto Lnomatch;
1077 
1078             ie = new TupleExp(_init->loc, iexps);
1079         }
1080 Lnomatch:
1081 
1082         if (ie && ie->op == TOKtuple)
1083         {
1084             TupleExp *te = (TupleExp *)ie;
1085             size_t tedim = te->exps->dim;
1086             if (tedim != nelems)
1087             {
1088                 ::error(loc, "tuple of %d elements cannot be assigned to tuple of %d elements", (int)tedim, (int)nelems);
1089                 for (size_t u = tedim; u < nelems; u++) // fill dummy expression
1090                     te->exps->push(new ErrorExp());
1091             }
1092         }
1093 
1094         Objects *exps = new Objects();
1095         exps->setDim(nelems);
1096         for (size_t i = 0; i < nelems; i++)
1097         {
1098             Parameter *arg = Parameter::getNth(tt->arguments, i);
1099 
1100             OutBuffer buf;
1101             buf.printf("__%s_field_%llu", ident->toChars(), (ulonglong)i);
1102             const char *name = buf.extractString();
1103             Identifier *id = Identifier::idPool(name);
1104 
1105             Initializer *ti;
1106             if (ie)
1107             {
1108                 Expression *einit = ie;
1109                 if (ie->op == TOKtuple)
1110                 {
1111                     TupleExp *te = (TupleExp *)ie;
1112                     einit = (*te->exps)[i];
1113                     if (i == 0)
1114                         einit = Expression::combine(te->e0, einit);
1115                 }
1116                 ti = new ExpInitializer(einit->loc, einit);
1117             }
1118             else
1119                 ti = _init ? _init->syntaxCopy() : NULL;
1120 
1121             VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
1122             v->storage_class |= STCtemp | storage_class;
1123             if (arg->storageClass & STCparameter)
1124                 v->storage_class |= arg->storageClass;
1125             //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
1126             v->semantic(sc);
1127 
1128             if (sc->scopesym)
1129             {
1130                 //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
1131                 if (sc->scopesym->members)
1132                     sc->scopesym->members->push(v);
1133             }
1134 
1135             Expression *e = new DsymbolExp(loc, v);
1136             (*exps)[i] = e;
1137         }
1138         TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
1139         v2->parent = this->parent;
1140         v2->isexp = true;
1141         aliassym = v2;
1142         semanticRun = PASSsemanticdone;
1143         return;
1144     }
1145 
1146     /* Storage class can modify the type
1147      */
1148     type = type->addStorageClass(storage_class);
1149 
1150     /* Adjust storage class to reflect type
1151      */
1152     if (type->isConst())
1153     {
1154         storage_class |= STCconst;
1155         if (type->isShared())
1156             storage_class |= STCshared;
1157     }
1158     else if (type->isImmutable())
1159         storage_class |= STCimmutable;
1160     else if (type->isShared())
1161         storage_class |= STCshared;
1162     else if (type->isWild())
1163         storage_class |= STCwild;
1164 
1165     if (StorageClass stc = storage_class & (STCsynchronized | STCoverride | STCabstract | STCfinal))
1166     {
1167         if (stc == STCfinal)
1168             error("cannot be final, perhaps you meant const?");
1169         else
1170         {
1171             OutBuffer buf;
1172             stcToBuffer(&buf, stc);
1173             error("cannot be %s", buf.peekString());
1174         }
1175         storage_class &= ~stc;  // strip off
1176     }
1177 
1178     if (storage_class & STCscope)
1179     {
1180         StorageClass stc = storage_class & (STCstatic | STCextern | STCmanifest | STCtls | STCgshared);
1181         if (stc)
1182         {
1183             OutBuffer buf;
1184             stcToBuffer(&buf, stc);
1185             error("cannot be 'scope' and '%s'", buf.peekString());
1186         }
1187         else if (isMember())
1188         {
1189             error("field cannot be 'scope'");
1190         }
1191         else if (!type->hasPointers())
1192         {
1193             storage_class &= ~STCscope;     // silently ignore; may occur in generic code
1194         }
1195     }
1196 
1197     if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
1198     {
1199     }
1200     else
1201     {
1202         AggregateDeclaration *aad = parent->isAggregateDeclaration();
1203         if (aad)
1204         {
1205             if (global.params.vfield &&
1206                 storage_class & (STCconst | STCimmutable) && _init && !_init->isVoidInitializer())
1207             {
1208                 const char *s = (storage_class & STCimmutable) ? "immutable" : "const";
1209                 message(loc, "`%s.%s` is `%s` field", ad->toPrettyChars(), toChars(), s);
1210             }
1211             storage_class |= STCfield;
1212             if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor)
1213             {
1214                 if (!isThisDeclaration() && !_init)
1215                     aad->noDefaultCtor = true;
1216             }
1217         }
1218 
1219         InterfaceDeclaration *id = parent->isInterfaceDeclaration();
1220         if (id)
1221         {
1222             error("field not allowed in interface");
1223         }
1224         else if (aad && aad->sizeok == SIZEOKdone)
1225         {
1226             error("cannot be further field because it will change the determined %s size", aad->toChars());
1227         }
1228 
1229         /* Templates cannot add fields to aggregates
1230          */
1231         TemplateInstance *ti = parent->isTemplateInstance();
1232         if (ti)
1233         {
1234             // Take care of nested templates
1235             while (1)
1236             {
1237                 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
1238                 if (!ti2)
1239                     break;
1240                 ti = ti2;
1241             }
1242 
1243             // If it's a member template
1244             AggregateDeclaration *ad2 = ti->tempdecl->isMember();
1245             if (ad2 && storage_class != STCundefined)
1246             {
1247                 error("cannot use template to add field to aggregate '%s'", ad2->toChars());
1248             }
1249         }
1250     }
1251 
1252     if ((storage_class & (STCref | STCparameter | STCforeach | STCtemp | STCresult)) == STCref && ident != Id::This)
1253     {
1254         error("only parameters or foreach declarations can be ref");
1255     }
1256 
1257     if (type->hasWild())
1258     {
1259         if (storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCfield) ||
1260             isDataseg()
1261             )
1262         {
1263             error("only parameters or stack based variables can be inout");
1264         }
1265         FuncDeclaration *func = sc->func;
1266         if (func)
1267         {
1268             if (func->fes)
1269                 func = func->fes->func;
1270             bool isWild = false;
1271             for (FuncDeclaration *fd = func; fd; fd = fd->toParent2()->isFuncDeclaration())
1272             {
1273                 if (((TypeFunction *)fd->type)->iswild)
1274                 {
1275                     isWild = true;
1276                     break;
1277                 }
1278             }
1279             if (!isWild)
1280             {
1281                 error("inout variables can only be declared inside inout functions");
1282             }
1283         }
1284     }
1285 
1286     if (!(storage_class & (STCctfe | STCref | STCresult)) && tbn->ty == Tstruct &&
1287         ((TypeStruct *)tbn)->sym->noDefaultCtor)
1288     {
1289         if (!_init)
1290         {
1291             if (isField())
1292             {
1293                 /* For fields, we'll check the constructor later to make sure it is initialized
1294                  */
1295                 storage_class |= STCnodefaultctor;
1296             }
1297             else if (storage_class & STCparameter)
1298                 ;
1299             else
1300                 error("default construction is disabled for type %s", type->toChars());
1301         }
1302     }
1303 
1304     FuncDeclaration *fd = parent->isFuncDeclaration();
1305     if (type->isscope() && !(storage_class & STCnodtor))
1306     {
1307         if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd)
1308         {
1309             error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope");
1310         }
1311 
1312         if (!(storage_class & STCscope))
1313         {
1314             if (!(storage_class & STCparameter) && ident != Id::withSym)
1315                 error("reference to scope class must be scope");
1316         }
1317     }
1318 
1319     // Calculate type size + safety checks
1320     if (sc->func && !sc->intypeof)
1321     {
1322         if (_init && _init->isVoidInitializer() && type->hasPointers()) // get type size
1323         {
1324             if (sc->func->setUnsafe())
1325                 error("void initializers for pointers not allowed in safe functions");
1326         }
1327         else if (!_init &&
1328                  !(storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCfield | STCparameter)) &&
1329                  type->hasVoidInitPointers())
1330         {
1331             if (sc->func->setUnsafe())
1332                 error("void initializers for pointers not allowed in safe functions");
1333         }
1334     }
1335 
1336     if (!_init && !fd)
1337     {
1338         // If not mutable, initializable by constructor only
1339         storage_class |= STCctorinit;
1340     }
1341 
1342     if (_init)
1343         storage_class |= STCinit;     // remember we had an explicit initializer
1344     else if (storage_class & STCmanifest)
1345         error("manifest constants must have initializers");
1346 
1347     bool isBlit = false;
1348     d_uns64 sz = 0;
1349     if (!_init && !sc->inunion && !(storage_class & (STCstatic | STCgshared | STCextern)) && fd &&
1350         (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult))
1351          || (storage_class & STCout)) &&
1352         (sz = type->size()) != 0)
1353     {
1354         // Provide a default initializer
1355         //printf("Providing default initializer for '%s'\n", toChars());
1356         if (sz == SIZE_INVALID && type->ty != Terror)
1357             error("size of type %s is invalid", type->toChars());
1358 
1359         Type *tv = type;
1360         while (tv->ty == Tsarray)    // Don't skip Tenum
1361             tv = tv->nextOf();
1362         if (tv->needsNested())
1363         {
1364             /* Nested struct requires valid enclosing frame pointer.
1365              * In StructLiteralExp::toElem(), it's calculated.
1366              */
1367             assert(tv->toBasetype()->ty == Tstruct);
1368             checkFrameAccess(loc, sc, ((TypeStruct *)tbn)->sym);
1369 
1370             Expression *e = tv->defaultInitLiteral(loc);
1371             e = new BlitExp(loc, new VarExp(loc, this), e);
1372             e = ::semantic(e, sc);
1373             _init = new ExpInitializer(loc, e);
1374             goto Ldtor;
1375         }
1376         if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->zeroInit == 1)
1377         {
1378             /* If a struct is all zeros, as a special case
1379              * set it's initializer to the integer 0.
1380              * In AssignExp::toElem(), we check for this and issue
1381              * a memset() to initialize the struct.
1382              * Must do same check in interpreter.
1383              */
1384             Expression *e = new IntegerExp(loc, 0, Type::tint32);
1385             e = new BlitExp(loc, new VarExp(loc, this), e);
1386             e->type = type;         // don't type check this, it would fail
1387             _init = new ExpInitializer(loc, e);
1388             goto Ldtor;
1389         }
1390         if (type->baseElemOf()->ty == Tvoid)
1391         {
1392             error("%s does not have a default initializer", type->toChars());
1393         }
1394         else if (Expression *e = type->defaultInit(loc))
1395         {
1396             _init = new ExpInitializer(loc, e);
1397         }
1398         // Default initializer is always a blit
1399         isBlit = true;
1400     }
1401 
1402     if (_init)
1403     {
1404         sc = sc->push();
1405         sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCnogc | STCref | STCdisable);
1406 
1407         ExpInitializer *ei = _init->isExpInitializer();
1408         if (ei)     // Bugzilla 13424: Preset the required type to fail in FuncLiteralDeclaration::semantic3
1409             ei->exp = inferType(ei->exp, type);
1410 
1411         // If inside function, there is no semantic3() call
1412         if (sc->func || sc->intypeof == 1)
1413         {
1414             // If local variable, use AssignExp to handle all the various
1415             // possibilities.
1416             if (fd &&
1417                 !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) &&
1418                 !_init->isVoidInitializer())
1419             {
1420                 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
1421                 if (!ei)
1422                 {
1423                     ArrayInitializer *ai = _init->isArrayInitializer();
1424                     Expression *e;
1425                     if (ai && tb->ty == Taarray)
1426                         e = ai->toAssocArrayLiteral();
1427                     else
1428                         e = initializerToExpression(_init);
1429                     if (!e)
1430                     {
1431                         // Run semantic, but don't need to interpret
1432                         _init = ::semantic(_init, sc, type, INITnointerpret);
1433                         e = initializerToExpression(_init);
1434                         if (!e)
1435                         {
1436                             error("is not a static and cannot have static initializer");
1437                             return;
1438                         }
1439                     }
1440                     ei = new ExpInitializer(_init->loc, e);
1441                     _init = ei;
1442                 }
1443 
1444                 Expression *exp = ei->exp;
1445                 Expression *e1 = new VarExp(loc, this);
1446                 if (isBlit)
1447                     exp = new BlitExp(loc, e1, exp);
1448                 else
1449                     exp = new ConstructExp(loc, e1, exp);
1450                 canassign++;
1451                 exp = ::semantic(exp, sc);
1452                 canassign--;
1453                 exp = exp->optimize(WANTvalue);
1454 
1455                 if (exp->op == TOKerror)
1456                 {
1457                     _init = new ErrorInitializer();
1458                     ei = NULL;
1459                 }
1460                 else
1461                     ei->exp = exp;
1462 
1463                 if (ei && isScope())
1464                 {
1465                     Expression *ex = ei->exp;
1466                     while (ex->op == TOKcomma)
1467                         ex = ((CommaExp *)ex)->e2;
1468                     if (ex->op == TOKblit || ex->op == TOKconstruct)
1469                         ex = ((AssignExp *)ex)->e2;
1470                     if (ex->op == TOKnew)
1471                     {
1472                         // See if initializer is a NewExp that can be allocated on the stack
1473                         NewExp *ne = (NewExp *)ex;
1474                         if (type->toBasetype()->ty == Tclass)
1475                         {
1476                             if (ne->newargs && ne->newargs->dim > 1)
1477                             {
1478                                 mynew = true;
1479                             }
1480                             else
1481                             {
1482                                 ne->onstack = true;
1483                                 onstack = true;
1484                             }
1485                         }
1486                     }
1487                     else if (ex->op == TOKfunction)
1488                     {
1489                         // or a delegate that doesn't escape a reference to the function
1490                         FuncDeclaration *f = ((FuncExp *)ex)->fd;
1491                         f->tookAddressOf--;
1492                     }
1493                 }
1494             }
1495             else
1496             {
1497                 // Bugzilla 14166: Don't run CTFE for the temporary variables inside typeof
1498                 _init = ::semantic(_init, sc, type, sc->intypeof == 1 ? INITnointerpret : INITinterpret);
1499             }
1500         }
1501         else if (parent->isAggregateDeclaration())
1502         {
1503             _scope = scx ? scx : sc->copy();
1504             _scope->setNoFree();
1505         }
1506         else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
1507                  type->isConst() || type->isImmutable())
1508         {
1509             /* Because we may need the results of a const declaration in a
1510              * subsequent type, such as an array dimension, before semantic2()
1511              * gets ordinarily run, try to run semantic2() now.
1512              * Ignore failure.
1513              */
1514 
1515             if (!inferred)
1516             {
1517                 unsigned errors = global.errors;
1518                 inuse++;
1519                 if (ei)
1520                 {
1521                     Expression *exp = ei->exp->syntaxCopy();
1522 
1523                     bool needctfe = isDataseg() || (storage_class & STCmanifest);
1524                     if (needctfe) sc = sc->startCTFE();
1525                     exp = ::semantic(exp, sc);
1526                     exp = resolveProperties(sc, exp);
1527                     if (needctfe) sc = sc->endCTFE();
1528 
1529                     Type *tb2 = type->toBasetype();
1530                     Type *ti = exp->type->toBasetype();
1531 
1532                     /* The problem is the following code:
1533                      *  struct CopyTest {
1534                      *     double x;
1535                      *     this(double a) { x = a * 10.0;}
1536                      *     this(this) { x += 2.0; }
1537                      *  }
1538                      *  const CopyTest z = CopyTest(5.3);  // ok
1539                      *  const CopyTest w = z;              // not ok, postblit not run
1540                      *  static assert(w.x == 55.0);
1541                      * because the postblit doesn't get run on the initialization of w.
1542                      */
1543                     if (ti->ty == Tstruct)
1544                     {
1545                         StructDeclaration *sd = ((TypeStruct *)ti)->sym;
1546                         /* Look to see if initializer involves a copy constructor
1547                          * (which implies a postblit)
1548                          */
1549                          // there is a copy constructor
1550                          // and exp is the same struct
1551                         if (sd->postblit &&
1552                             tb2->toDsymbol(NULL) == sd)
1553                         {
1554                             // The only allowable initializer is a (non-copy) constructor
1555                             if (exp->isLvalue())
1556                                 error("of type struct %s uses this(this), which is not allowed in static initialization", tb2->toChars());
1557                         }
1558                     }
1559                     ei->exp = exp;
1560                 }
1561                 _init = ::semantic(_init, sc, type, INITinterpret);
1562                 inuse--;
1563                 if (global.errors > errors)
1564                 {
1565                     _init = new ErrorInitializer();
1566                     type = Type::terror;
1567                 }
1568             }
1569             else
1570             {
1571                 _scope = scx ? scx : sc->copy();
1572                 _scope->setNoFree();
1573             }
1574         }
1575         sc = sc->pop();
1576     }
1577 
1578 Ldtor:
1579     /* Build code to execute destruction, if necessary
1580      */
1581     edtor = callScopeDtor(sc);
1582     if (edtor)
1583     {
1584         if (sc->func && storage_class & (STCstatic | STCgshared))
1585             edtor = ::semantic(edtor, sc->_module->_scope);
1586         else
1587             edtor = ::semantic(edtor, sc);
1588 
1589 #if 0 // currently disabled because of std.stdio.stdin, stdout and stderr
1590         if (isDataseg() && !(storage_class & STCextern))
1591             error("static storage variables cannot have destructors");
1592 #endif
1593     }
1594 
1595     semanticRun = PASSsemanticdone;
1596 
1597     if (type->toBasetype()->ty == Terror)
1598         errors = true;
1599 
1600     if (sc->scopesym && !sc->scopesym->isAggregateDeclaration())
1601     {
1602         for (ScopeDsymbol *sym = sc->scopesym; sym && endlinnum == 0;
1603              sym = sym->parent ? sym->parent->isScopeDsymbol() : NULL)
1604             endlinnum = sym->endlinnum;
1605     }
1606 }
1607 
semantic2(Scope * sc)1608 void VarDeclaration::semantic2(Scope *sc)
1609 {
1610     if (semanticRun < PASSsemanticdone && inuse)
1611         return;
1612 
1613     //printf("VarDeclaration::semantic2('%s')\n", toChars());
1614 
1615     if (_init && !toParent()->isFuncDeclaration())
1616     {
1617         inuse++;
1618         // Bugzilla 14166: Don't run CTFE for the temporary variables inside typeof
1619         _init = ::semantic(_init, sc, type, sc->intypeof == 1 ? INITnointerpret : INITinterpret);
1620         inuse--;
1621     }
1622     if (_init && storage_class & STCmanifest)
1623     {
1624         /* Cannot initializer enums with CTFE classreferences and addresses of struct literals.
1625          * Scan initializer looking for them. Issue error if found.
1626          */
1627         if (ExpInitializer *ei = _init->isExpInitializer())
1628         {
1629             struct EnumInitializer
1630             {
1631                 static bool arrayHasInvalidEnumInitializer(Expressions *elems)
1632                 {
1633                     for (size_t i = 0; i < elems->dim; i++)
1634                     {
1635                         Expression *e = (*elems)[i];
1636                         if (e && hasInvalidEnumInitializer(e))
1637                             return true;
1638                     }
1639                     return false;
1640                 }
1641 
1642                 static bool hasInvalidEnumInitializer(Expression *e)
1643                 {
1644                     if (e->op == TOKclassreference)
1645                         return true;
1646                     if (e->op == TOKaddress && ((AddrExp *)e)->e1->op == TOKstructliteral)
1647                         return true;
1648                     if (e->op == TOKarrayliteral)
1649                         return arrayHasInvalidEnumInitializer(((ArrayLiteralExp *)e)->elements);
1650                     if (e->op == TOKstructliteral)
1651                         return arrayHasInvalidEnumInitializer(((StructLiteralExp *)e)->elements);
1652                     if (e->op == TOKassocarrayliteral)
1653                     {
1654                         AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e;
1655                         return arrayHasInvalidEnumInitializer(ae->values) ||
1656                             arrayHasInvalidEnumInitializer(ae->keys);
1657                     }
1658                     return false;
1659                 }
1660             };
1661             if (EnumInitializer::hasInvalidEnumInitializer(ei->exp))
1662                 error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead.");
1663         }
1664     }
1665     else if (_init && isThreadlocal())
1666     {
1667         if ((type->ty == Tclass) && type->isMutable() && !type->isShared())
1668         {
1669             ExpInitializer *ei = _init->isExpInitializer();
1670             if (ei && ei->exp->op == TOKclassreference)
1671                 error("is mutable. Only const or immutable class thread local variable are allowed, not %s", type->toChars());
1672         }
1673         else if (type->ty == Tpointer && type->nextOf()->ty == Tstruct && type->nextOf()->isMutable() &&!type->nextOf()->isShared())
1674         {
1675             ExpInitializer *ei = _init->isExpInitializer();
1676             if (ei && ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral)
1677             {
1678                 error("is a pointer to mutable struct. Only pointers to const, immutable or shared struct thread local variable are allowed, not %s", type->toChars());
1679             }
1680         }
1681     }
1682     semanticRun = PASSsemantic2done;
1683 }
1684 
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)1685 void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
1686 {
1687     //printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
1688 
1689     if (aliassym)
1690     {
1691         // If this variable was really a tuple, set the offsets for the tuple fields
1692         TupleDeclaration *v2 = aliassym->isTupleDeclaration();
1693         assert(v2);
1694         for (size_t i = 0; i < v2->objects->dim; i++)
1695         {
1696             RootObject *o = (*v2->objects)[i];
1697             assert(o->dyncast() == DYNCAST_EXPRESSION);
1698             Expression *e = (Expression *)o;
1699             assert(e->op == TOKdsymbol);
1700             DsymbolExp *se = (DsymbolExp *)e;
1701             se->s->setFieldOffset(ad, poffset, isunion);
1702         }
1703         return;
1704     }
1705 
1706     if (!isField())
1707         return;
1708     assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls)));
1709 
1710     //printf("+VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
1711 
1712     /* Fields that are tuples appear both as part of TupleDeclarations and
1713      * as members. That means ignore them if they are already a field.
1714      */
1715     if (offset)
1716     {
1717         // already a field
1718         *poffset = ad->structsize;  // Bugzilla 13613
1719         return;
1720     }
1721     for (size_t i = 0; i < ad->fields.dim; i++)
1722     {
1723         if (ad->fields[i] == this)
1724         {
1725             // already a field
1726             *poffset = ad->structsize;  // Bugzilla 13613
1727             return;
1728         }
1729     }
1730 
1731     // Check for forward referenced types which will fail the size() call
1732     Type *t = type->toBasetype();
1733     if (storage_class & STCref)
1734     {
1735         // References are the size of a pointer
1736         t = Type::tvoidptr;
1737     }
1738     Type *tv = t->baseElemOf();
1739     if (tv->ty == Tstruct)
1740     {
1741         TypeStruct *ts = (TypeStruct *)tv;
1742         assert(ts->sym != ad);   // already checked in ad->determineFields()
1743         if (!ts->sym->determineSize(loc))
1744         {
1745             type = Type::terror;
1746             errors = true;
1747             return;
1748         }
1749     }
1750 
1751     // List in ad->fields. Even if the type is error, it's necessary to avoid
1752     // pointless error diagnostic "more initializers than fields" on struct literal.
1753     ad->fields.push(this);
1754 
1755     if (t->ty == Terror)
1756         return;
1757 
1758     const d_uns64 sz = t->size(loc);
1759     assert(sz != SIZE_INVALID && sz < UINT32_MAX);
1760     unsigned memsize = (unsigned)sz;                 // size of member
1761     unsigned memalignsize = Target::fieldalign(t);   // size of member for alignment purposes
1762 
1763     offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
1764                 &ad->structsize, &ad->alignsize, isunion);
1765 
1766     //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize);
1767 
1768     //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad->toChars(), offset, memsize);
1769 }
1770 
kind()1771 const char *VarDeclaration::kind() const
1772 {
1773     return "variable";
1774 }
1775 
toAlias()1776 Dsymbol *VarDeclaration::toAlias()
1777 {
1778     //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1779     if ((!type || !type->deco) && _scope)
1780         semantic(_scope);
1781 
1782     assert(this != aliassym);
1783     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1784     return s;
1785 }
1786 
isThis()1787 AggregateDeclaration *VarDeclaration::isThis()
1788 {
1789     AggregateDeclaration *ad = NULL;
1790 
1791     if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter |
1792                            STCtls | STCgshared | STCctfe)))
1793     {
1794         for (Dsymbol *s = this; s; s = s->parent)
1795         {
1796             ad = s->isMember();
1797             if (ad)
1798                 break;
1799             if (!s->parent || !s->parent->isTemplateMixin()) break;
1800         }
1801     }
1802     return ad;
1803 }
1804 
needThis()1805 bool VarDeclaration::needThis()
1806 {
1807     //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1808     return isField();
1809 }
1810 
isExport()1811 bool VarDeclaration::isExport() const
1812 {
1813     return protection.kind == PROTexport;
1814 }
1815 
isImportedSymbol()1816 bool VarDeclaration::isImportedSymbol() const
1817 {
1818     if (protection.kind == PROTexport && !_init &&
1819         (storage_class & STCstatic || parent->isModule()))
1820         return true;
1821     return false;
1822 }
1823 
1824 /*******************************************
1825  * Helper function for the expansion of manifest constant.
1826  */
expandInitializer(Loc loc)1827 Expression *VarDeclaration::expandInitializer(Loc loc)
1828 {
1829     assert((storage_class & STCmanifest) && _init);
1830 
1831     Expression *e = getConstInitializer();
1832     if (!e)
1833     {
1834         ::error(loc, "cannot make expression out of initializer for %s", toChars());
1835         return new ErrorExp();
1836     }
1837 
1838     e = e->copy();
1839     e->loc = loc;    // for better error message
1840     return e;
1841 }
1842 
checkCtorConstInit()1843 void VarDeclaration::checkCtorConstInit()
1844 {
1845 #if 0 /* doesn't work if more than one static ctor */
1846     if (ctorinit == 0 && isCtorinit() && !isField())
1847         error("missing initializer in static constructor for const variable");
1848 #endif
1849 }
1850 
1851 bool lambdaCheckForNestedRef(Expression *e, Scope *sc);
1852 
1853 /************************************
1854  * Check to see if this variable is actually in an enclosing function
1855  * rather than the current one.
1856  * Returns true if error occurs.
1857  */
checkNestedReference(Scope * sc,Loc loc)1858 bool VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1859 {
1860     //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
1861     if (sc->intypeof == 1 || (sc->flags & SCOPEctfe))
1862         return false;
1863     if (!parent || parent == sc->parent)
1864         return false;
1865     if (isDataseg() || (storage_class & STCmanifest))
1866         return false;
1867 
1868     // The current function
1869     FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1870     if (!fdthis)
1871         return false;   // out of function scope
1872 
1873     Dsymbol *p = toParent2();
1874 
1875     // Function literals from fdthis to p must be delegates
1876     checkNestedRef(fdthis, p);
1877 
1878     // The function that this variable is in
1879     FuncDeclaration *fdv = p->isFuncDeclaration();
1880     if (!fdv || fdv == fdthis)
1881         return false;
1882 
1883     // Add fdthis to nestedrefs[] if not already there
1884     for (size_t i = 0; 1; i++)
1885     {
1886         if (i == nestedrefs.dim)
1887         {
1888             nestedrefs.push(fdthis);
1889             break;
1890         }
1891         if (nestedrefs[i] == fdthis)
1892             break;
1893     }
1894 
1895     /* __require and __ensure will always get called directly,
1896      * so they never make outer functions closure.
1897      */
1898     if (fdthis->ident == Id::require || fdthis->ident == Id::ensure)
1899         return false;
1900 
1901     //printf("\tfdv = %s\n", fdv->toChars());
1902     //printf("\tfdthis = %s\n", fdthis->toChars());
1903     if (loc.filename)
1904     {
1905         int lv = fdthis->getLevel(loc, sc, fdv);
1906         if (lv == -2)   // error
1907             return true;
1908     }
1909 
1910     // Add this to fdv->closureVars[] if not already there
1911     for (size_t i = 0; 1; i++)
1912     {
1913         if (i == fdv->closureVars.dim)
1914         {
1915             if (!sc->intypeof && !(sc->flags & SCOPEcompile))
1916                 fdv->closureVars.push(this);
1917             break;
1918         }
1919         if (fdv->closureVars[i] == this)
1920             break;
1921     }
1922 
1923     //printf("fdthis is %s\n", fdthis->toChars());
1924     //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1925     // __dollar creates problems because it isn't a real variable Bugzilla 3326
1926     if (ident == Id::dollar)
1927     {
1928         ::error(loc, "cannnot use $ inside a function literal");
1929         return true;
1930     }
1931 
1932     if (ident == Id::withSym)       // Bugzilla 1759
1933     {
1934         ExpInitializer *ez = _init->isExpInitializer();
1935         assert(ez);
1936         Expression *e = ez->exp;
1937         if (e->op == TOKconstruct || e->op == TOKblit)
1938             e = ((AssignExp *)e)->e2;
1939         return lambdaCheckForNestedRef(e, sc);
1940     }
1941 
1942     return false;
1943 }
1944 
1945 /*******************************************
1946  * If variable has a constant expression initializer, get it.
1947  * Otherwise, return NULL.
1948  */
1949 
getConstInitializer(bool needFullType)1950 Expression *VarDeclaration::getConstInitializer(bool needFullType)
1951 {
1952     assert(type && _init);
1953 
1954     // Ungag errors when not speculative
1955     unsigned oldgag = global.gag;
1956     if (global.gag)
1957     {
1958         Dsymbol *sym = toParent()->isAggregateDeclaration();
1959         if (sym && !sym->isSpeculative())
1960             global.gag = 0;
1961     }
1962 
1963     if (_scope)
1964     {
1965         inuse++;
1966         _init = ::semantic(_init, _scope, type, INITinterpret);
1967         _scope = NULL;
1968         inuse--;
1969     }
1970     Expression *e = initializerToExpression(_init, needFullType ? type : NULL);
1971 
1972     global.gag = oldgag;
1973     return e;
1974 }
1975 
1976 /*************************************
1977  * Return true if we can take the address of this variable.
1978  */
1979 
canTakeAddressOf()1980 bool VarDeclaration::canTakeAddressOf()
1981 {
1982     return !(storage_class & STCmanifest);
1983 }
1984 
1985 
1986 /*******************************
1987  * Does symbol go into data segment?
1988  * Includes extern variables.
1989  */
1990 
isDataseg()1991 bool VarDeclaration::isDataseg()
1992 {
1993     if (isdataseg == 0) // the value is not cached
1994     {
1995         isdataseg = 2; // The Variables does not go into the datasegment
1996 
1997         if (!canTakeAddressOf())
1998         {
1999             return false;
2000         }
2001 
2002         Dsymbol *parent = toParent();
2003         if (!parent && !(storage_class & STCstatic))
2004         {
2005             error("forward referenced");
2006             type = Type::terror;
2007         }
2008         else if (storage_class & (STCstatic | STCextern | STCtls | STCgshared) ||
2009                  parent->isModule() || parent->isTemplateInstance() || parent->isNspace())
2010         {
2011             assert(!isParameter() && !isResult());
2012             isdataseg = 1; // It is in the DataSegment
2013         }
2014     }
2015 
2016     return (isdataseg == 1);
2017 }
2018 
2019 /************************************
2020  * Does symbol go into thread local storage?
2021  */
2022 
isThreadlocal()2023 bool VarDeclaration::isThreadlocal()
2024 {
2025     //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars());
2026     /* Data defaults to being thread-local. It is not thread-local
2027      * if it is immutable, const or shared.
2028      */
2029     bool i = isDataseg() &&
2030         !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared));
2031     //printf("\treturn %d\n", i);
2032     return i;
2033 }
2034 
2035 /********************************************
2036  * Can variable be read and written by CTFE?
2037  */
2038 
isCTFE()2039 bool VarDeclaration::isCTFE()
2040 {
2041     return (storage_class & STCctfe) != 0; // || !isDataseg();
2042 }
2043 
isOverlappedWith(VarDeclaration * v)2044 bool VarDeclaration::isOverlappedWith(VarDeclaration *v)
2045 {
2046     const d_uns64 vsz = v->type->size();
2047     const d_uns64 tsz = type->size();
2048     assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);
2049     return offset < v->offset + vsz &&
2050         v->offset < offset + tsz;
2051 }
2052 
hasPointers()2053 bool VarDeclaration::hasPointers()
2054 {
2055     //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
2056     return (!isDataseg() && type->hasPointers());
2057 }
2058 
2059 /******************************************
2060  * Return true if variable needs to call the destructor.
2061  */
2062 
needsScopeDtor()2063 bool VarDeclaration::needsScopeDtor()
2064 {
2065     //printf("VarDeclaration::needsScopeDtor() %s\n", toChars());
2066     return edtor && !(storage_class & STCnodtor);
2067 }
2068 
2069 
2070 /******************************************
2071  * If a variable has a scope destructor call, return call for it.
2072  * Otherwise, return NULL.
2073  */
2074 
callScopeDtor(Scope *)2075 Expression *VarDeclaration::callScopeDtor(Scope *)
2076 {
2077     //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
2078 
2079     // Destruction of STCfield's is handled by buildDtor()
2080     if (storage_class & (STCnodtor | STCref | STCout | STCfield))
2081     {
2082         return NULL;
2083     }
2084 
2085     Expression *e = NULL;
2086 
2087     // Destructors for structs and arrays of structs
2088     Type *tv = type->baseElemOf();
2089     if (tv->ty == Tstruct)
2090     {
2091         StructDeclaration *sd = ((TypeStruct *)tv)->sym;
2092         if (!sd->dtor || sd->errors)
2093            return NULL;
2094 
2095         const d_uns64 sz = type->size();
2096         assert(sz != SIZE_INVALID);
2097         if (!sz)
2098             return NULL;
2099 
2100         if (type->toBasetype()->ty == Tstruct)
2101         {
2102             // v.__xdtor()
2103             e = new VarExp(loc, this);
2104 
2105             /* This is a hack so we can call destructors on const/immutable objects.
2106              * Need to add things like "const ~this()" and "immutable ~this()" to
2107              * fix properly.
2108              */
2109             e->type = e->type->mutableOf();
2110 
2111             // Enable calling destructors on shared objects.
2112             // The destructor is always a single, non-overloaded function,
2113             // and must serve both shared and non-shared objects.
2114             e->type = e->type->unSharedOf();
2115 
2116             e = new DotVarExp(loc, e, sd->dtor, false);
2117             e = new CallExp(loc, e);
2118         }
2119         else
2120         {
2121             // __ArrayDtor(v[0 .. n])
2122             e = new VarExp(loc, this);
2123 
2124             const d_uns64 sdsz = sd->type->size();
2125             assert(sdsz != SIZE_INVALID && sdsz != 0);
2126             const d_uns64 n = sz / sdsz;
2127             e = new SliceExp(loc, e, new IntegerExp(loc, 0, Type::tsize_t),
2128                                      new IntegerExp(loc, n, Type::tsize_t));
2129             // Prevent redundant bounds check
2130             ((SliceExp *)e)->upperIsInBounds = true;
2131             ((SliceExp *)e)->lowerIsLessThanUpper = true;
2132 
2133             // This is a hack so we can call destructors on const/immutable objects.
2134             e->type = sd->type->arrayOf();
2135 
2136             e = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayDtor), e);
2137         }
2138         return e;
2139     }
2140 
2141     // Destructors for classes
2142     if (storage_class & (STCauto | STCscope) && !(storage_class & STCparameter))
2143     {
2144         for (ClassDeclaration *cd = type->isClassHandle();
2145              cd;
2146              cd = cd->baseClass)
2147         {
2148             /* We can do better if there's a way with onstack
2149              * classes to determine if there's no way the monitor
2150              * could be set.
2151              */
2152             //if (cd->isInterfaceDeclaration())
2153                 //error("interface %s cannot be scope", cd->toChars());
2154 
2155             // Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.
2156             // See https://issues.dlang.org/show_bug.cgi?id=13182
2157             if (cd->cpp)
2158             {
2159                 break;
2160             }
2161             if (mynew || onstack) // if any destructors
2162             {
2163                 // delete this;
2164                 Expression *ec;
2165 
2166                 ec = new VarExp(loc, this);
2167                 e = new DeleteExp(loc, ec, true);
2168                 e->type = Type::tvoid;
2169                 break;
2170             }
2171         }
2172     }
2173     return e;
2174 }
2175 
2176 /**********************************
2177  * Determine if `this` has a lifetime that lasts past
2178  * the destruction of `v`
2179  * Params:
2180  *  v = variable to test against
2181  * Returns:
2182  *  true if it does
2183  */
enclosesLifetimeOf(VarDeclaration * v)2184 bool VarDeclaration::enclosesLifetimeOf(VarDeclaration *v) const
2185 {
2186     return sequenceNumber < v->sequenceNumber;
2187 }
2188 
2189 /******************************************
2190  */
2191 
ObjectNotFound(Identifier * id)2192 void ObjectNotFound(Identifier *id)
2193 {
2194     Type::error(Loc(), "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars());
2195     fatal();
2196 }
2197 
2198 /******************************** SymbolDeclaration ********************************/
2199 
SymbolDeclaration(Loc loc,StructDeclaration * dsym)2200 SymbolDeclaration::SymbolDeclaration(Loc loc, StructDeclaration *dsym)
2201         : Declaration(dsym->ident)
2202 {
2203     this->loc = loc;
2204     this->dsym = dsym;
2205     storage_class |= STCconst;
2206 }
2207 
2208 /********************************* TypeInfoDeclaration ****************************/
2209 
TypeInfoDeclaration(Type * tinfo)2210 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo)
2211     : VarDeclaration(Loc(), Type::dtypeinfo->type, tinfo->getTypeInfoIdent(), NULL)
2212 {
2213     this->tinfo = tinfo;
2214     storage_class = STCstatic | STCgshared;
2215     protection = Prot(PROTpublic);
2216     linkage = LINKc;
2217     alignment = Target::ptrsize;
2218 }
2219 
create(Type * tinfo)2220 TypeInfoDeclaration *TypeInfoDeclaration::create(Type *tinfo)
2221 {
2222     return new TypeInfoDeclaration(tinfo);
2223 }
2224 
syntaxCopy(Dsymbol *)2225 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *)
2226 {
2227     assert(0);          // should never be produced by syntax
2228     return NULL;
2229 }
2230 
semantic(Scope *)2231 void TypeInfoDeclaration::semantic(Scope *)
2232 {
2233     assert(linkage == LINKc);
2234 }
2235 
toChars()2236 const char *TypeInfoDeclaration::toChars()
2237 {
2238     //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo->toChars());
2239     OutBuffer buf;
2240     buf.writestring("typeid(");
2241     buf.writestring(tinfo->toChars());
2242     buf.writeByte(')');
2243     return buf.extractString();
2244 }
2245 
2246 /***************************** TypeInfoConstDeclaration **********************/
2247 
TypeInfoConstDeclaration(Type * tinfo)2248 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
2249     : TypeInfoDeclaration(tinfo)
2250 {
2251     if (!Type::typeinfoconst)
2252     {
2253         ObjectNotFound(Id::TypeInfo_Const);
2254     }
2255     type = Type::typeinfoconst->type;
2256 }
2257 
create(Type * tinfo)2258 TypeInfoConstDeclaration *TypeInfoConstDeclaration::create(Type *tinfo)
2259 {
2260     return new TypeInfoConstDeclaration(tinfo);
2261 }
2262 
2263 /***************************** TypeInfoInvariantDeclaration **********************/
2264 
TypeInfoInvariantDeclaration(Type * tinfo)2265 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
2266     : TypeInfoDeclaration(tinfo)
2267 {
2268     if (!Type::typeinfoinvariant)
2269     {
2270         ObjectNotFound(Id::TypeInfo_Invariant);
2271     }
2272     type = Type::typeinfoinvariant->type;
2273 }
2274 
create(Type * tinfo)2275 TypeInfoInvariantDeclaration *TypeInfoInvariantDeclaration::create(Type *tinfo)
2276 {
2277     return new TypeInfoInvariantDeclaration(tinfo);
2278 }
2279 
2280 /***************************** TypeInfoSharedDeclaration **********************/
2281 
TypeInfoSharedDeclaration(Type * tinfo)2282 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
2283     : TypeInfoDeclaration(tinfo)
2284 {
2285     if (!Type::typeinfoshared)
2286     {
2287         ObjectNotFound(Id::TypeInfo_Shared);
2288     }
2289     type = Type::typeinfoshared->type;
2290 }
2291 
create(Type * tinfo)2292 TypeInfoSharedDeclaration *TypeInfoSharedDeclaration::create(Type *tinfo)
2293 {
2294     return new TypeInfoSharedDeclaration(tinfo);
2295 }
2296 
2297 /***************************** TypeInfoWildDeclaration **********************/
2298 
TypeInfoWildDeclaration(Type * tinfo)2299 TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
2300     : TypeInfoDeclaration(tinfo)
2301 {
2302     if (!Type::typeinfowild)
2303     {
2304         ObjectNotFound(Id::TypeInfo_Wild);
2305     }
2306     type = Type::typeinfowild->type;
2307 }
2308 
create(Type * tinfo)2309 TypeInfoWildDeclaration *TypeInfoWildDeclaration::create(Type *tinfo)
2310 {
2311     return new TypeInfoWildDeclaration(tinfo);
2312 }
2313 
2314 /***************************** TypeInfoStructDeclaration **********************/
2315 
TypeInfoStructDeclaration(Type * tinfo)2316 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
2317     : TypeInfoDeclaration(tinfo)
2318 {
2319     if (!Type::typeinfostruct)
2320     {
2321         ObjectNotFound(Id::TypeInfo_Struct);
2322     }
2323     type = Type::typeinfostruct->type;
2324 }
2325 
create(Type * tinfo)2326 TypeInfoStructDeclaration *TypeInfoStructDeclaration::create(Type *tinfo)
2327 {
2328     return new TypeInfoStructDeclaration(tinfo);
2329 }
2330 
2331 /***************************** TypeInfoClassDeclaration ***********************/
2332 
TypeInfoClassDeclaration(Type * tinfo)2333 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
2334     : TypeInfoDeclaration(tinfo)
2335 {
2336     if (!Type::typeinfoclass)
2337     {
2338         ObjectNotFound(Id::TypeInfo_Class);
2339     }
2340     type = Type::typeinfoclass->type;
2341 }
2342 
create(Type * tinfo)2343 TypeInfoClassDeclaration *TypeInfoClassDeclaration::create(Type *tinfo)
2344 {
2345     return new TypeInfoClassDeclaration(tinfo);
2346 }
2347 
2348 /***************************** TypeInfoInterfaceDeclaration *******************/
2349 
TypeInfoInterfaceDeclaration(Type * tinfo)2350 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
2351     : TypeInfoDeclaration(tinfo)
2352 {
2353     if (!Type::typeinfointerface)
2354     {
2355         ObjectNotFound(Id::TypeInfo_Interface);
2356     }
2357     type = Type::typeinfointerface->type;
2358 }
2359 
create(Type * tinfo)2360 TypeInfoInterfaceDeclaration *TypeInfoInterfaceDeclaration::create(Type *tinfo)
2361 {
2362     return new TypeInfoInterfaceDeclaration(tinfo);
2363 }
2364 
2365 /***************************** TypeInfoPointerDeclaration *********************/
2366 
TypeInfoPointerDeclaration(Type * tinfo)2367 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
2368     : TypeInfoDeclaration(tinfo)
2369 {
2370     if (!Type::typeinfopointer)
2371     {
2372         ObjectNotFound(Id::TypeInfo_Pointer);
2373     }
2374     type = Type::typeinfopointer->type;
2375 }
2376 
create(Type * tinfo)2377 TypeInfoPointerDeclaration *TypeInfoPointerDeclaration::create(Type *tinfo)
2378 {
2379     return new TypeInfoPointerDeclaration(tinfo);
2380 }
2381 
2382 /***************************** TypeInfoArrayDeclaration ***********************/
2383 
TypeInfoArrayDeclaration(Type * tinfo)2384 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
2385     : TypeInfoDeclaration(tinfo)
2386 {
2387     if (!Type::typeinfoarray)
2388     {
2389         ObjectNotFound(Id::TypeInfo_Array);
2390     }
2391     type = Type::typeinfoarray->type;
2392 }
2393 
create(Type * tinfo)2394 TypeInfoArrayDeclaration *TypeInfoArrayDeclaration::create(Type *tinfo)
2395 {
2396     return new TypeInfoArrayDeclaration(tinfo);
2397 }
2398 
2399 /***************************** TypeInfoStaticArrayDeclaration *****************/
2400 
TypeInfoStaticArrayDeclaration(Type * tinfo)2401 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
2402     : TypeInfoDeclaration(tinfo)
2403 {
2404     if (!Type::typeinfostaticarray)
2405     {
2406         ObjectNotFound(Id::TypeInfo_StaticArray);
2407     }
2408     type = Type::typeinfostaticarray->type;
2409 }
2410 
create(Type * tinfo)2411 TypeInfoStaticArrayDeclaration *TypeInfoStaticArrayDeclaration::create(Type *tinfo)
2412 {
2413     return new TypeInfoStaticArrayDeclaration(tinfo);
2414 }
2415 
2416 /***************************** TypeInfoAssociativeArrayDeclaration ************/
2417 
TypeInfoAssociativeArrayDeclaration(Type * tinfo)2418 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
2419     : TypeInfoDeclaration(tinfo)
2420 {
2421     if (!Type::typeinfoassociativearray)
2422     {
2423         ObjectNotFound(Id::TypeInfo_AssociativeArray);
2424     }
2425     type = Type::typeinfoassociativearray->type;
2426 }
2427 
create(Type * tinfo)2428 TypeInfoAssociativeArrayDeclaration *TypeInfoAssociativeArrayDeclaration::create(Type *tinfo)
2429 {
2430     return new TypeInfoAssociativeArrayDeclaration(tinfo);
2431 }
2432 
2433 /***************************** TypeInfoVectorDeclaration ***********************/
2434 
TypeInfoVectorDeclaration(Type * tinfo)2435 TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
2436     : TypeInfoDeclaration(tinfo)
2437 {
2438     if (!Type::typeinfovector)
2439     {
2440         ObjectNotFound(Id::TypeInfo_Vector);
2441     }
2442     type = Type::typeinfovector->type;
2443 }
2444 
create(Type * tinfo)2445 TypeInfoVectorDeclaration *TypeInfoVectorDeclaration::create(Type *tinfo)
2446 {
2447     return new TypeInfoVectorDeclaration(tinfo);
2448 }
2449 
2450 /***************************** TypeInfoEnumDeclaration ***********************/
2451 
TypeInfoEnumDeclaration(Type * tinfo)2452 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
2453     : TypeInfoDeclaration(tinfo)
2454 {
2455     if (!Type::typeinfoenum)
2456     {
2457         ObjectNotFound(Id::TypeInfo_Enum);
2458     }
2459     type = Type::typeinfoenum->type;
2460 }
2461 
create(Type * tinfo)2462 TypeInfoEnumDeclaration *TypeInfoEnumDeclaration::create(Type *tinfo)
2463 {
2464     return new TypeInfoEnumDeclaration(tinfo);
2465 }
2466 
2467 /***************************** TypeInfoFunctionDeclaration ********************/
2468 
TypeInfoFunctionDeclaration(Type * tinfo)2469 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
2470     : TypeInfoDeclaration(tinfo)
2471 {
2472     if (!Type::typeinfofunction)
2473     {
2474         ObjectNotFound(Id::TypeInfo_Function);
2475     }
2476     type = Type::typeinfofunction->type;
2477 }
2478 
create(Type * tinfo)2479 TypeInfoFunctionDeclaration *TypeInfoFunctionDeclaration::create(Type *tinfo)
2480 {
2481     return new TypeInfoFunctionDeclaration(tinfo);
2482 }
2483 
2484 /***************************** TypeInfoDelegateDeclaration ********************/
2485 
TypeInfoDelegateDeclaration(Type * tinfo)2486 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
2487     : TypeInfoDeclaration(tinfo)
2488 {
2489     if (!Type::typeinfodelegate)
2490     {
2491         ObjectNotFound(Id::TypeInfo_Delegate);
2492     }
2493     type = Type::typeinfodelegate->type;
2494 }
2495 
create(Type * tinfo)2496 TypeInfoDelegateDeclaration *TypeInfoDelegateDeclaration::create(Type *tinfo)
2497 {
2498     return new TypeInfoDelegateDeclaration(tinfo);
2499 }
2500 
2501 /***************************** TypeInfoTupleDeclaration **********************/
2502 
TypeInfoTupleDeclaration(Type * tinfo)2503 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
2504     : TypeInfoDeclaration(tinfo)
2505 {
2506     if (!Type::typeinfotypelist)
2507     {
2508         ObjectNotFound(Id::TypeInfo_Tuple);
2509     }
2510     type = Type::typeinfotypelist->type;
2511 }
2512 
create(Type * tinfo)2513 TypeInfoTupleDeclaration *TypeInfoTupleDeclaration::create(Type *tinfo)
2514 {
2515     return new TypeInfoTupleDeclaration(tinfo);
2516 }
2517 
2518 /********************************* ThisDeclaration ****************************/
2519 
2520 // For the "this" parameter to member functions
2521 
ThisDeclaration(Loc loc,Type * t)2522 ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
2523    : VarDeclaration(loc, t, Id::This, NULL)
2524 {
2525     storage_class |= STCnodtor;
2526 }
2527 
syntaxCopy(Dsymbol *)2528 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *)
2529 {
2530     assert(0);          // should never be produced by syntax
2531     return NULL;
2532 }
2533 
2534