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