1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2021 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 
33 /************************************
34  * Check to see the aggregate type is nested and its context pointer is
35  * accessible from the current scope.
36  * Returns true if error occurs.
37  */
38 bool checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad, size_t iStart = 0)
39 {
40     Dsymbol *sparent = ad->toParent2();
41     Dsymbol *s = sc->func;
42     if (ad->isNested() && s)
43     {
44         //printf("ad = %p %s [%s], parent:%p\n", ad, ad->toChars(), ad->loc.toChars(), ad->parent);
45         //printf("sparent = %p %s [%s], parent: %s\n", sparent, sparent->toChars(), sparent->loc.toChars(), sparent->parent->toChars());
46         if (checkNestedRef(s, sparent))
47         {
48             error(loc, "cannot access frame pointer of %s", ad->toPrettyChars());
49             return true;
50         }
51     }
52 
53     bool result = false;
54     for (size_t i = iStart; i < ad->fields.length; i++)
55     {
56         VarDeclaration *vd = ad->fields[i];
57         Type *tb = vd->type->baseElemOf();
58         if (tb->ty == Tstruct)
59         {
60             result |= checkFrameAccess(loc, sc, ((TypeStruct *)tb)->sym);
61         }
62     }
63     return result;
64 }
65 
66 /********************************* Declaration ****************************/
67 
Declaration(Identifier * id)68 Declaration::Declaration(Identifier *id)
69     : Dsymbol(id)
70 {
71     type = NULL;
72     originalType = NULL;
73     storage_class = STCundefined;
74     protection = Prot(Prot::undefined);
75     linkage = LINKdefault;
76     inuse = 0;
77     mangleOverride = NULL;
78 }
79 
kind()80 const char *Declaration::kind() const
81 {
82     return "declaration";
83 }
84 
size(Loc)85 d_uns64 Declaration::size(Loc)
86 {
87     assert(type);
88     return type->size();
89 }
90 
isDelete()91 bool Declaration::isDelete()
92 {
93     return false;
94 }
95 
isDataseg()96 bool Declaration::isDataseg()
97 {
98     return false;
99 }
100 
isThreadlocal()101 bool Declaration::isThreadlocal()
102 {
103     return false;
104 }
105 
isCodeseg()106 bool Declaration::isCodeseg() const
107 {
108     return false;
109 }
110 
prot()111 Prot Declaration::prot()
112 {
113     return protection;
114 }
115 
116 /*************************************
117  * Check to see if declaration can be modified in this context (sc).
118  * Issue error if not.
119  */
120 
checkModify(Loc loc,Scope * sc,Type *,Expression * e1,int flag)121 int Declaration::checkModify(Loc loc, Scope *sc, Type *, Expression *e1, int flag)
122 {
123     VarDeclaration *v = isVarDeclaration();
124     if (v && v->canassign)
125         return 2;
126 
127     if (isParameter() || isResult())
128     {
129         for (Scope *scx = sc; scx; scx = scx->enclosing)
130         {
131             if (scx->func == parent && (scx->flags & SCOPEcontract))
132             {
133                 const char *s = isParameter() && parent->ident != Id::ensure ? "parameter" : "result";
134                 if (!flag) error(loc, "cannot modify %s `%s` in contract", s, toChars());
135                 return 2;   // do not report type related errors
136             }
137         }
138     }
139 
140     if (e1 && e1->op == TOKthis && isField())
141     {
142         VarDeclaration *vthis = e1->isThisExp()->var;
143         for (Scope *scx = sc; scx; scx = scx->enclosing)
144         {
145             if (scx->func == vthis->parent && (scx->flags & SCOPEcontract))
146             {
147                 if (!flag)
148                     error(loc, "cannot modify parameter `this` in contract");
149                 return 2;   // do not report type related errors
150             }
151         }
152     }
153 
154     if (v && (isCtorinit() || isField()))
155     {
156         // It's only modifiable if inside the right constructor
157         if ((storage_class & (STCforeach | STCref)) == (STCforeach | STCref))
158             return 2;
159         return modifyFieldVar(loc, sc, v, e1) ? 2 : 1;
160     }
161     return 1;
162 }
163 
164 /**
165  * Issue an error if an attempt to call a disabled method is made
166  *
167  * If the declaration is disabled but inside a disabled function,
168  * returns `true` but do not issue an error message.
169  *
170  * Params:
171  *   loc = Location information of the call
172  *   sc  = Scope in which the call occurs
173  *   isAliasedDeclaration = if `true` searches overload set
174  *
175  * Returns:
176  *   `true` if this `Declaration` is `@disable`d, `false` otherwise.
177  */
checkDisabled(Loc loc,Scope * sc,bool isAliasedDeclaration)178 bool Declaration::checkDisabled(Loc loc, Scope *sc, bool isAliasedDeclaration)
179 {
180     if (!(storage_class & STCdisable))
181         return false;
182 
183     if (sc->func && (sc->func->storage_class & STCdisable))
184         return true;
185 
186     Dsymbol *p = toParent();
187     if (p && isPostBlitDeclaration())
188     {
189         p->error(loc, "is not copyable because it is annotated with `@disable`");
190         return true;
191     }
192 
193     // if the function is @disabled, maybe there
194     // is an overload in the overload set that isn't
195     if (isAliasedDeclaration)
196     {
197         FuncDeclaration *fd = isFuncDeclaration();
198         if (fd)
199         {
200             for (FuncDeclaration *ovl = fd; ovl; ovl = (FuncDeclaration *)ovl->overnext)
201                 if (!(ovl->storage_class & STCdisable))
202                     return false;
203         }
204     }
205     error(loc, "cannot be used because it is annotated with `@disable`");
206     return true;
207 }
208 
search(const Loc & loc,Identifier * ident,int flags)209 Dsymbol *Declaration::search(const Loc &loc, Identifier *ident, int flags)
210 {
211     Dsymbol *s = Dsymbol::search(loc, ident, flags);
212     if (!s && type)
213     {
214         s = type->toDsymbol(_scope);
215         if (s)
216             s = s->search(loc, ident, flags);
217     }
218     return s;
219 }
220 
221 
222 /********************************* TupleDeclaration ****************************/
223 
TupleDeclaration(Loc loc,Identifier * id,Objects * objects)224 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
225     : Declaration(id)
226 {
227     this->loc = loc;
228     this->type = NULL;
229     this->objects = objects;
230     this->isexp = false;
231     this->tupletype = NULL;
232 }
233 
syntaxCopy(Dsymbol *)234 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *)
235 {
236     assert(0);
237     return NULL;
238 }
239 
kind()240 const char *TupleDeclaration::kind() const
241 {
242     return "tuple";
243 }
244 
getType()245 Type *TupleDeclaration::getType()
246 {
247     /* If this tuple represents a type, return that type
248      */
249 
250     //printf("TupleDeclaration::getType() %s\n", toChars());
251     if (isexp)
252         return NULL;
253     if (!tupletype)
254     {
255         /* It's only a type tuple if all the Object's are types
256          */
257         for (size_t i = 0; i < objects->length; i++)
258         {
259             RootObject *o = (*objects)[i];
260             if (o->dyncast() != DYNCAST_TYPE)
261             {
262                 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
263                 return NULL;
264             }
265         }
266 
267         /* We know it's a type tuple, so build the TypeTuple
268          */
269         Types *types = (Types *)objects;
270         Parameters *args = new Parameters();
271         args->setDim(objects->length);
272         OutBuffer buf;
273         int hasdeco = 1;
274         for (size_t i = 0; i < types->length; i++)
275         {
276             Type *t = (*types)[i];
277             //printf("type = %s\n", t->toChars());
278             Parameter *arg = new Parameter(0, t, NULL, NULL, NULL);
279             (*args)[i] = arg;
280             if (!t->deco)
281                 hasdeco = 0;
282         }
283 
284         tupletype = new TypeTuple(args);
285         if (hasdeco)
286             return typeSemantic(tupletype, Loc(), NULL);
287     }
288 
289     return tupletype;
290 }
291 
toAlias2()292 Dsymbol *TupleDeclaration::toAlias2()
293 {
294     //printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects->toChars());
295 
296     for (size_t i = 0; i < objects->length; i++)
297     {
298         RootObject *o = (*objects)[i];
299         if (Dsymbol *s = isDsymbol(o))
300         {
301             s = s->toAlias2();
302             (*objects)[i] = s;
303         }
304     }
305     return this;
306 }
307 
needThis()308 bool TupleDeclaration::needThis()
309 {
310     //printf("TupleDeclaration::needThis(%s)\n", toChars());
311     for (size_t i = 0; i < objects->length; i++)
312     {
313         RootObject *o = (*objects)[i];
314         if (o->dyncast() == DYNCAST_EXPRESSION)
315         {
316             Expression *e = (Expression *)o;
317             if (e->op == TOKdsymbol)
318             {
319                 DsymbolExp *ve = (DsymbolExp *)e;
320                 Declaration *d = ve->s->isDeclaration();
321                 if (d && d->needThis())
322                 {
323                     return true;
324                 }
325             }
326         }
327     }
328     return false;
329 }
330 
331 /********************************* AliasDeclaration ****************************/
332 
AliasDeclaration(Loc loc,Identifier * id,Type * type)333 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
334     : Declaration(id)
335 {
336     //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
337     //printf("type = '%s'\n", type->toChars());
338     this->loc = loc;
339     this->type = type;
340     this->aliassym = NULL;
341     this->_import = NULL;
342     this->overnext = NULL;
343     assert(type);
344 }
345 
AliasDeclaration(Loc loc,Identifier * id,Dsymbol * s)346 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
347     : Declaration(id)
348 {
349     //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
350     assert(s != this);
351     this->loc = loc;
352     this->type = NULL;
353     this->aliassym = s;
354     this->_import = NULL;
355     this->overnext = NULL;
356     assert(s);
357 }
358 
create(Loc loc,Identifier * id,Type * type)359 AliasDeclaration *AliasDeclaration::create(Loc loc, Identifier *id, Type *type)
360 {
361     return new AliasDeclaration(loc, id, type);
362 }
363 
syntaxCopy(Dsymbol * s)364 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
365 {
366     //printf("AliasDeclaration::syntaxCopy()\n");
367     assert(!s);
368     AliasDeclaration *sa =
369         type ? new AliasDeclaration(loc, ident, type->syntaxCopy())
370              : new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
371     sa->storage_class = storage_class;
372     return sa;
373 }
374 
overloadInsert(Dsymbol * s)375 bool AliasDeclaration::overloadInsert(Dsymbol *s)
376 {
377     //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n",
378     //    loc.toChars(), toChars(), s->kind(), s->toChars(), s->loc.toChars());
379 
380     /** Aliases aren't overloadable themselves, but if their Aliasee is
381      *  overloadable they are converted to an overloadable Alias (either
382      *  FuncAliasDeclaration or OverDeclaration).
383      *
384      *  This is done by moving the Aliasee into such an overloadable alias
385      *  which is then used to replace the existing Aliasee. The original
386      *  Alias (_this_) remains a useless shell.
387      *
388      *  This is a horrible mess. It was probably done to avoid replacing
389      *  existing AST nodes and references, but it needs a major
390      *  simplification b/c it's too complex to maintain.
391      *
392      *  A simpler approach might be to merge any colliding symbols into a
393      *  simple Overload class (an array) and then later have that resolve
394      *  all collisions.
395      */
396     if (semanticRun >= PASSsemanticdone)
397     {
398         /* Semantic analysis is already finished, and the aliased entity
399          * is not overloadable.
400          */
401         if (type)
402             return false;
403 
404         /* When s is added in member scope by static if, mixin("code") or others,
405          * aliassym is determined already. See the case in: test/compilable/test61.d
406          */
407         Dsymbol *sa = aliassym->toAlias();
408         if (FuncDeclaration *fd = sa->isFuncDeclaration())
409         {
410             FuncAliasDeclaration *fa = new FuncAliasDeclaration(ident, fd);
411             fa->protection = protection;
412             fa->parent = parent;
413             aliassym = fa;
414             return aliassym->overloadInsert(s);
415         }
416         if (TemplateDeclaration *td = sa->isTemplateDeclaration())
417         {
418             OverDeclaration *od = new OverDeclaration(ident, td);
419             od->protection = protection;
420             od->parent = parent;
421             aliassym = od;
422             return aliassym->overloadInsert(s);
423         }
424         if (OverDeclaration *od = sa->isOverDeclaration())
425         {
426             if (sa->ident != ident || sa->parent != parent)
427             {
428                 od = new OverDeclaration(ident, od);
429                 od->protection = protection;
430                 od->parent = parent;
431                 aliassym = od;
432             }
433             return od->overloadInsert(s);
434         }
435         if (OverloadSet *os = sa->isOverloadSet())
436         {
437             if (sa->ident != ident || sa->parent != parent)
438             {
439                 os = new OverloadSet(ident, os);
440                 // TODO: protection is lost here b/c OverloadSets have no protection attribute
441                 // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow.
442                 // ----
443                 // module os1;
444                 // import a, b;
445                 // private alias merged = foo; // private alias to overload set of a.foo and b.foo
446                 // ----
447                 // module os2;
448                 // import a, b;
449                 // public alias merged = bar; // public alias to overload set of a.bar and b.bar
450                 // ----
451                 // module bug;
452                 // import os1, os2;
453                 // void test() { merged(123); } // should only look at os2.merged
454                 //
455                 // os.protection = protection;
456                 os->parent = parent;
457                 aliassym = os;
458             }
459             os->push(s);
460             return true;
461         }
462         return false;
463     }
464 
465     /* Don't know yet what the aliased symbol is, so assume it can
466      * be overloaded and check later for correctness.
467      */
468     if (overnext)
469         return overnext->overloadInsert(s);
470     if (s == this)
471         return true;
472     overnext = s;
473     return true;
474 }
475 
kind()476 const char *AliasDeclaration::kind() const
477 {
478     return "alias";
479 }
480 
getType()481 Type *AliasDeclaration::getType()
482 {
483     if (type)
484         return type;
485     return toAlias()->getType();
486 }
487 
toAlias()488 Dsymbol *AliasDeclaration::toAlias()
489 {
490     //printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\n",
491     //    loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym->kind() : "", inuse);
492     assert(this != aliassym);
493     //static int count; if (++count == 10) *(char*)0=0;
494     if (inuse == 1 && type && _scope)
495     {
496         inuse = 2;
497         unsigned olderrors = global.errors;
498         Dsymbol *s = type->toDsymbol(_scope);
499         //printf("[%s] type = %s, s = %p, this = %p\n", loc.toChars(), type->toChars(), s, this);
500         if (global.errors != olderrors)
501             goto Lerr;
502         if (s)
503         {
504             s = s->toAlias();
505             if (global.errors != olderrors)
506                 goto Lerr;
507             aliassym = s;
508             inuse = 0;
509         }
510         else
511         {
512             Type *t = typeSemantic(type, loc, _scope);
513             if (t->ty == Terror)
514                 goto Lerr;
515             if (global.errors != olderrors)
516                 goto Lerr;
517             //printf("t = %s\n", t->toChars());
518             inuse = 0;
519         }
520     }
521     if (inuse)
522     {
523         error("recursive alias declaration");
524 
525     Lerr:
526         // Avoid breaking "recursive alias" state during errors gagged
527         if (global.gag)
528             return this;
529 
530         aliassym = new AliasDeclaration(loc, ident, Type::terror);
531         type = Type::terror;
532         return aliassym;
533     }
534 
535     if (semanticRun >= PASSsemanticdone)
536     {
537         // semantic is already done.
538 
539         // Do not see aliassym !is null, because of lambda aliases.
540 
541         // Do not see type.deco !is null, even so "alias T = const int;` needs
542         // semantic analysis to take the storage class `const` as type qualifier.
543     }
544     else
545     {
546         if (_import && _import->_scope)
547         {
548             /* If this is an internal alias for selective/renamed import,
549              * load the module first.
550              */
551             dsymbolSemantic(_import, NULL);
552         }
553         if (_scope)
554         {
555             aliasSemantic(this, _scope);
556         }
557     }
558 
559     inuse = 1;
560     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
561     inuse = 0;
562     return s;
563 }
564 
toAlias2()565 Dsymbol *AliasDeclaration::toAlias2()
566 {
567     if (inuse)
568     {
569         error("recursive alias declaration");
570         return this;
571     }
572     inuse = 1;
573     Dsymbol *s  = aliassym ? aliassym->toAlias2() : this;
574     inuse = 0;
575     return s;
576 }
577 
isOverloadable()578 bool AliasDeclaration::isOverloadable()
579 {
580     // assume overloadable until alias is resolved
581     return semanticRun < PASSsemanticdone ||
582         (aliassym && aliassym->isOverloadable());
583 }
584 
585 /****************************** OverDeclaration **************************/
586 
OverDeclaration(Identifier * ident,Dsymbol * s,bool hasOverloads)587 OverDeclaration::OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads)
588     : Declaration(ident)
589 {
590     this->overnext = NULL;
591     this->aliassym = s;
592 
593     this->hasOverloads = hasOverloads;
594     if (hasOverloads)
595     {
596         if (OverDeclaration *od = aliassym->isOverDeclaration())
597             this->hasOverloads = od->hasOverloads;
598     }
599     else
600     {
601         // for internal use
602         assert(!aliassym->isOverDeclaration());
603     }
604 }
605 
kind()606 const char *OverDeclaration::kind() const
607 {
608     return "overload alias";    // todo
609 }
610 
equals(RootObject * o)611 bool OverDeclaration::equals(RootObject *o)
612 {
613     if (this == o)
614         return true;
615 
616     Dsymbol *s = isDsymbol(o);
617     if (!s)
618         return false;
619 
620     OverDeclaration *od1 = this;
621     if (OverDeclaration *od2 = s->isOverDeclaration())
622     {
623         return od1->aliassym->equals(od2->aliassym) &&
624                od1->hasOverloads == od2->hasOverloads;
625     }
626     if (aliassym == s)
627     {
628         if (hasOverloads)
629             return true;
630         if (FuncDeclaration *fd = s->isFuncDeclaration())
631         {
632             return fd->isUnique() != NULL;
633         }
634         if (TemplateDeclaration *td = s->isTemplateDeclaration())
635         {
636             return td->overnext == NULL;
637         }
638     }
639     return false;
640 }
641 
overloadInsert(Dsymbol * s)642 bool OverDeclaration::overloadInsert(Dsymbol *s)
643 {
644     //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s->toChars(), aliassym, overnext);
645     if (overnext)
646         return overnext->overloadInsert(s);
647     if (s == this)
648         return true;
649     overnext = s;
650     return true;
651 }
652 
toAlias()653 Dsymbol *OverDeclaration::toAlias()
654 {
655     return this;
656 }
657 
isOverloadable()658 bool OverDeclaration::isOverloadable()
659 {
660     return true;
661 }
662 
isUnique()663 Dsymbol *OverDeclaration::isUnique()
664 {
665     if (!hasOverloads)
666     {
667         if (aliassym->isFuncDeclaration() ||
668             aliassym->isTemplateDeclaration())
669         {
670             return aliassym;
671         }
672     }
673 
674   struct ParamUniqueSym
675   {
676     static int fp(void *param, Dsymbol *s)
677     {
678         Dsymbol **ps = (Dsymbol **)param;
679         if (*ps)
680         {
681             *ps = NULL;
682             return 1;   // ambiguous, done
683         }
684         else
685         {
686             *ps = s;
687             return 0;
688         }
689     }
690   };
691     Dsymbol *result = NULL;
692     overloadApply(aliassym, &result, &ParamUniqueSym::fp);
693     return result;
694 }
695 
696 /********************************* VarDeclaration ****************************/
697 
VarDeclaration(Loc loc,Type * type,Identifier * id,Initializer * init)698 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
699     : Declaration(id)
700 {
701     //printf("VarDeclaration('%s')\n", id->toChars());
702     assert(id);
703     assert(type || init);
704     this->type = type;
705     this->_init = init;
706     this->loc = loc;
707     offset = 0;
708     isargptr = false;
709     alignment = 0;
710     ctorinit = 0;
711     aliassym = NULL;
712     onstack = false;
713     mynew = false;
714     canassign = 0;
715     overlapped = false;
716     overlapUnsafe = false;
717     doNotInferScope = false;
718     isdataseg = 0;
719     lastVar = NULL;
720     endlinnum = 0;
721     ctfeAdrOnStack = -1;
722     edtor = NULL;
723     range = NULL;
724 
725     static unsigned nextSequenceNumber = 0;
726     this->sequenceNumber = ++nextSequenceNumber;
727 }
728 
create(Loc loc,Type * type,Identifier * id,Initializer * init)729 VarDeclaration *VarDeclaration::create(Loc loc, Type *type, Identifier *id, Initializer *init)
730 {
731     return new VarDeclaration(loc, type, id, init);
732 }
733 
syntaxCopy(Dsymbol * s)734 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
735 {
736     //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
737     assert(!s);
738     VarDeclaration *v = new VarDeclaration(loc,
739             type ? type->syntaxCopy() : NULL,
740             ident,
741             _init ? _init->syntaxCopy() : NULL);
742     v->storage_class = storage_class;
743     return v;
744 }
745 
setFieldOffset(AggregateDeclaration * ad,unsigned * poffset,bool isunion)746 void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion)
747 {
748     //printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
749 
750     if (aliassym)
751     {
752         // If this variable was really a tuple, set the offsets for the tuple fields
753         TupleDeclaration *v2 = aliassym->isTupleDeclaration();
754         assert(v2);
755         for (size_t i = 0; i < v2->objects->length; i++)
756         {
757             RootObject *o = (*v2->objects)[i];
758             assert(o->dyncast() == DYNCAST_EXPRESSION);
759             Expression *e = (Expression *)o;
760             assert(e->op == TOKdsymbol);
761             DsymbolExp *se = (DsymbolExp *)e;
762             se->s->setFieldOffset(ad, poffset, isunion);
763         }
764         return;
765     }
766 
767     if (!isField())
768         return;
769     assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls)));
770 
771     //printf("+VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars());
772 
773     /* Fields that are tuples appear both as part of TupleDeclarations and
774      * as members. That means ignore them if they are already a field.
775      */
776     if (offset)
777     {
778         // already a field
779         *poffset = ad->structsize;  // Bugzilla 13613
780         return;
781     }
782     for (size_t i = 0; i < ad->fields.length; i++)
783     {
784         if (ad->fields[i] == this)
785         {
786             // already a field
787             *poffset = ad->structsize;  // Bugzilla 13613
788             return;
789         }
790     }
791 
792     // Check for forward referenced types which will fail the size() call
793     Type *t = type->toBasetype();
794     if (storage_class & STCref)
795     {
796         // References are the size of a pointer
797         t = Type::tvoidptr;
798     }
799     Type *tv = t->baseElemOf();
800     if (tv->ty == Tstruct)
801     {
802         TypeStruct *ts = (TypeStruct *)tv;
803         assert(ts->sym != ad);   // already checked in ad->determineFields()
804         if (!ts->sym->determineSize(loc))
805         {
806             type = Type::terror;
807             errors = true;
808             return;
809         }
810     }
811 
812     // List in ad->fields. Even if the type is error, it's necessary to avoid
813     // pointless error diagnostic "more initializers than fields" on struct literal.
814     ad->fields.push(this);
815 
816     if (t->ty == Terror)
817         return;
818 
819     const d_uns64 sz = t->size(loc);
820     assert(sz != SIZE_INVALID && sz < UINT32_MAX);
821     unsigned memsize = (unsigned)sz;                 // size of member
822     unsigned memalignsize = target.fieldalign(t);   // size of member for alignment purposes
823 
824     offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
825                 &ad->structsize, &ad->alignsize, isunion);
826 
827     //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize);
828 
829     //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad->toChars(), offset, memsize);
830 }
831 
kind()832 const char *VarDeclaration::kind() const
833 {
834     return "variable";
835 }
836 
toAlias()837 Dsymbol *VarDeclaration::toAlias()
838 {
839     //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
840     if ((!type || !type->deco) && _scope)
841         dsymbolSemantic(this, _scope);
842 
843     assert(this != aliassym);
844     Dsymbol *s = aliassym ? aliassym->toAlias() : this;
845     return s;
846 }
847 
isThis()848 AggregateDeclaration *VarDeclaration::isThis()
849 {
850     AggregateDeclaration *ad = NULL;
851 
852     if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter |
853                            STCtls | STCgshared | STCctfe)))
854     {
855         for (Dsymbol *s = this; s; s = s->parent)
856         {
857             ad = s->isMember();
858             if (ad)
859                 break;
860             if (!s->parent || !s->parent->isTemplateMixin()) break;
861         }
862     }
863     return ad;
864 }
865 
needThis()866 bool VarDeclaration::needThis()
867 {
868     //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
869     return isField();
870 }
871 
isExport()872 bool VarDeclaration::isExport() const
873 {
874     return protection.kind == Prot::export_;
875 }
876 
isImportedSymbol()877 bool VarDeclaration::isImportedSymbol() const
878 {
879     if (protection.kind == Prot::export_ && !_init &&
880         (storage_class & STCstatic || parent->isModule()))
881         return true;
882     return false;
883 }
884 
885 /*******************************************
886  * Helper function for the expansion of manifest constant.
887  */
expandInitializer(Loc loc)888 Expression *VarDeclaration::expandInitializer(Loc loc)
889 {
890     assert((storage_class & STCmanifest) && _init);
891 
892     Expression *e = getConstInitializer();
893     if (!e)
894     {
895         ::error(loc, "cannot make expression out of initializer for %s", toChars());
896         return new ErrorExp();
897     }
898 
899     e = e->copy();
900     e->loc = loc;    // for better error message
901     return e;
902 }
903 
checkCtorConstInit()904 void VarDeclaration::checkCtorConstInit()
905 {
906 #if 0 /* doesn't work if more than one static ctor */
907     if (ctorinit == 0 && isCtorinit() && !isField())
908         error("missing initializer in static constructor for const variable");
909 #endif
910 }
911 
912 bool lambdaCheckForNestedRef(Expression *e, Scope *sc);
913 
914 /************************************
915  * Check to see if this variable is actually in an enclosing function
916  * rather than the current one.
917  * Returns true if error occurs.
918  */
checkNestedReference(Scope * sc,Loc loc)919 bool VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
920 {
921     //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
922     if (sc->intypeof == 1 || (sc->flags & SCOPEctfe))
923         return false;
924     if (!parent || parent == sc->parent)
925         return false;
926     if (isDataseg() || (storage_class & STCmanifest))
927         return false;
928 
929     // The current function
930     FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
931     if (!fdthis)
932         return false;   // out of function scope
933 
934     Dsymbol *p = toParent2();
935 
936     // Function literals from fdthis to p must be delegates
937     checkNestedRef(fdthis, p);
938 
939     // The function that this variable is in
940     FuncDeclaration *fdv = p->isFuncDeclaration();
941     if (!fdv || fdv == fdthis)
942         return false;
943 
944     // Add fdthis to nestedrefs[] if not already there
945     if (!nestedrefs.contains(fdthis))
946         nestedrefs.push(fdthis);
947 
948     /* __require and __ensure will always get called directly,
949      * so they never make outer functions closure.
950      */
951     if (fdthis->ident == Id::require || fdthis->ident == Id::ensure)
952         return false;
953 
954     //printf("\tfdv = %s\n", fdv->toChars());
955     //printf("\tfdthis = %s\n", fdthis->toChars());
956     if (loc.filename)
957     {
958         int lv = fdthis->getLevel(loc, sc, fdv);
959         if (lv == -2)   // error
960             return true;
961     }
962 
963     // Add this to fdv->closureVars[] if not already there
964     if (!sc->intypeof && !(sc->flags & SCOPEcompile))
965     {
966         if (!fdv->closureVars.contains(this))
967             fdv->closureVars.push(this);
968     }
969 
970     //printf("fdthis is %s\n", fdthis->toChars());
971     //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
972     // __dollar creates problems because it isn't a real variable Bugzilla 3326
973     if (ident == Id::dollar)
974     {
975         ::error(loc, "cannnot use $ inside a function literal");
976         return true;
977     }
978 
979     if (ident == Id::withSym)       // Bugzilla 1759
980     {
981         ExpInitializer *ez = _init->isExpInitializer();
982         assert(ez);
983         Expression *e = ez->exp;
984         if (e->op == TOKconstruct || e->op == TOKblit)
985             e = ((AssignExp *)e)->e2;
986         return lambdaCheckForNestedRef(e, sc);
987     }
988 
989     return false;
990 }
991 
992 /*******************************************
993  * If variable has a constant expression initializer, get it.
994  * Otherwise, return NULL.
995  */
996 
getConstInitializer(bool needFullType)997 Expression *VarDeclaration::getConstInitializer(bool needFullType)
998 {
999     assert(type && _init);
1000 
1001     // Ungag errors when not speculative
1002     unsigned oldgag = global.gag;
1003     if (global.gag)
1004     {
1005         Dsymbol *sym = toParent()->isAggregateDeclaration();
1006         if (sym && !sym->isSpeculative())
1007             global.gag = 0;
1008     }
1009 
1010     if (_scope)
1011     {
1012         inuse++;
1013         _init = initializerSemantic(_init, _scope, type, INITinterpret);
1014         _scope = NULL;
1015         inuse--;
1016     }
1017     Expression *e = initializerToExpression(_init, needFullType ? type : NULL);
1018 
1019     global.gag = oldgag;
1020     return e;
1021 }
1022 
1023 /*************************************
1024  * Return true if we can take the address of this variable.
1025  */
1026 
canTakeAddressOf()1027 bool VarDeclaration::canTakeAddressOf()
1028 {
1029     return !(storage_class & STCmanifest);
1030 }
1031 
1032 
1033 /*******************************
1034  * Does symbol go into data segment?
1035  * Includes extern variables.
1036  */
1037 
isDataseg()1038 bool VarDeclaration::isDataseg()
1039 {
1040     if (isdataseg == 0) // the value is not cached
1041     {
1042         isdataseg = 2; // The Variables does not go into the datasegment
1043 
1044         if (!canTakeAddressOf())
1045         {
1046             return false;
1047         }
1048 
1049         Dsymbol *parent = toParent();
1050         if (!parent && !(storage_class & STCstatic))
1051         {
1052             error("forward referenced");
1053             type = Type::terror;
1054         }
1055         else if (storage_class & (STCstatic | STCextern | STCtls | STCgshared) ||
1056                  parent->isModule() || parent->isTemplateInstance() || parent->isNspace())
1057         {
1058             assert(!isParameter() && !isResult());
1059             isdataseg = 1; // It is in the DataSegment
1060         }
1061     }
1062 
1063     return (isdataseg == 1);
1064 }
1065 
1066 /************************************
1067  * Does symbol go into thread local storage?
1068  */
1069 
isThreadlocal()1070 bool VarDeclaration::isThreadlocal()
1071 {
1072     //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars());
1073     /* Data defaults to being thread-local. It is not thread-local
1074      * if it is immutable, const or shared.
1075      */
1076     bool i = isDataseg() &&
1077         !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared));
1078     //printf("\treturn %d\n", i);
1079     return i;
1080 }
1081 
1082 /********************************************
1083  * Can variable be read and written by CTFE?
1084  */
1085 
isCTFE()1086 bool VarDeclaration::isCTFE()
1087 {
1088     return (storage_class & STCctfe) != 0; // || !isDataseg();
1089 }
1090 
isOverlappedWith(VarDeclaration * v)1091 bool VarDeclaration::isOverlappedWith(VarDeclaration *v)
1092 {
1093     const d_uns64 vsz = v->type->size();
1094     const d_uns64 tsz = type->size();
1095     assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);
1096     return offset < v->offset + vsz &&
1097         v->offset < offset + tsz;
1098 }
1099 
hasPointers()1100 bool VarDeclaration::hasPointers()
1101 {
1102     //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1103     return (!isDataseg() && type->hasPointers());
1104 }
1105 
1106 /******************************************
1107  * Return true if variable needs to call the destructor.
1108  */
1109 
needsScopeDtor()1110 bool VarDeclaration::needsScopeDtor()
1111 {
1112     //printf("VarDeclaration::needsScopeDtor() %s\n", toChars());
1113     return edtor && !(storage_class & STCnodtor);
1114 }
1115 
1116 
1117 /******************************************
1118  * If a variable has a scope destructor call, return call for it.
1119  * Otherwise, return NULL.
1120  */
1121 
callScopeDtor(Scope *)1122 Expression *VarDeclaration::callScopeDtor(Scope *)
1123 {
1124     //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
1125 
1126     // Destruction of STCfield's is handled by buildDtor()
1127     if (storage_class & (STCnodtor | STCref | STCout | STCfield))
1128     {
1129         return NULL;
1130     }
1131 
1132     Expression *e = NULL;
1133 
1134     // Destructors for structs and arrays of structs
1135     Type *tv = type->baseElemOf();
1136     if (tv->ty == Tstruct)
1137     {
1138         StructDeclaration *sd = ((TypeStruct *)tv)->sym;
1139         if (!sd->dtor || sd->errors)
1140            return NULL;
1141 
1142         const d_uns64 sz = type->size();
1143         assert(sz != SIZE_INVALID);
1144         if (!sz)
1145             return NULL;
1146 
1147         if (type->toBasetype()->ty == Tstruct)
1148         {
1149             // v.__xdtor()
1150             e = new VarExp(loc, this);
1151 
1152             /* This is a hack so we can call destructors on const/immutable objects.
1153              * Need to add things like "const ~this()" and "immutable ~this()" to
1154              * fix properly.
1155              */
1156             e->type = e->type->mutableOf();
1157 
1158             // Enable calling destructors on shared objects.
1159             // The destructor is always a single, non-overloaded function,
1160             // and must serve both shared and non-shared objects.
1161             e->type = e->type->unSharedOf();
1162 
1163             e = new DotVarExp(loc, e, sd->dtor, false);
1164             e = new CallExp(loc, e);
1165         }
1166         else
1167         {
1168             // __ArrayDtor(v[0 .. n])
1169             e = new VarExp(loc, this);
1170 
1171             const d_uns64 sdsz = sd->type->size();
1172             assert(sdsz != SIZE_INVALID && sdsz != 0);
1173             const d_uns64 n = sz / sdsz;
1174             e = new SliceExp(loc, e, new IntegerExp(loc, 0, Type::tsize_t),
1175                                      new IntegerExp(loc, n, Type::tsize_t));
1176             // Prevent redundant bounds check
1177             ((SliceExp *)e)->upperIsInBounds = true;
1178             ((SliceExp *)e)->lowerIsLessThanUpper = true;
1179 
1180             // This is a hack so we can call destructors on const/immutable objects.
1181             e->type = sd->type->arrayOf();
1182 
1183             e = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayDtor), e);
1184         }
1185         return e;
1186     }
1187 
1188     // Destructors for classes
1189     if (storage_class & (STCauto | STCscope) && !(storage_class & STCparameter))
1190     {
1191         for (ClassDeclaration *cd = type->isClassHandle();
1192              cd;
1193              cd = cd->baseClass)
1194         {
1195             /* We can do better if there's a way with onstack
1196              * classes to determine if there's no way the monitor
1197              * could be set.
1198              */
1199             //if (cd->isInterfaceDeclaration())
1200                 //error("interface %s cannot be scope", cd->toChars());
1201 
1202             // Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them.
1203             // See https://issues.dlang.org/show_bug.cgi?id=13182
1204             if (cd->isCPPclass())
1205             {
1206                 break;
1207             }
1208             if (mynew || onstack) // if any destructors
1209             {
1210                 // delete this;
1211                 Expression *ec;
1212 
1213                 ec = new VarExp(loc, this);
1214                 e = new DeleteExp(loc, ec, true);
1215                 e->type = Type::tvoid;
1216                 break;
1217             }
1218         }
1219     }
1220     return e;
1221 }
1222 
1223 /**********************************
1224  * Determine if `this` has a lifetime that lasts past
1225  * the destruction of `v`
1226  * Params:
1227  *  v = variable to test against
1228  * Returns:
1229  *  true if it does
1230  */
enclosesLifetimeOf(VarDeclaration * v)1231 bool VarDeclaration::enclosesLifetimeOf(VarDeclaration *v) const
1232 {
1233     return sequenceNumber < v->sequenceNumber;
1234 }
1235 
1236 /******************************************
1237  */
1238 
ObjectNotFound(Identifier * id)1239 void ObjectNotFound(Identifier *id)
1240 {
1241     Type::error(Loc(), "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars());
1242     fatal();
1243 }
1244 
1245 /******************************** SymbolDeclaration ********************************/
1246 
SymbolDeclaration(Loc loc,StructDeclaration * dsym)1247 SymbolDeclaration::SymbolDeclaration(Loc loc, StructDeclaration *dsym)
1248         : Declaration(dsym->ident)
1249 {
1250     this->loc = loc;
1251     this->dsym = dsym;
1252     storage_class |= STCconst;
1253 }
1254 
1255 /********************************* TypeInfoDeclaration ****************************/
1256 
TypeInfoDeclaration(Type * tinfo)1257 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo)
1258     : VarDeclaration(Loc(), Type::dtypeinfo->type, tinfo->getTypeInfoIdent(), NULL)
1259 {
1260     this->tinfo = tinfo;
1261     storage_class = STCstatic | STCgshared;
1262     protection = Prot(Prot::public_);
1263     linkage = LINKc;
1264     alignment = target.ptrsize;
1265 }
1266 
create(Type * tinfo)1267 TypeInfoDeclaration *TypeInfoDeclaration::create(Type *tinfo)
1268 {
1269     return new TypeInfoDeclaration(tinfo);
1270 }
1271 
syntaxCopy(Dsymbol *)1272 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *)
1273 {
1274     assert(0);          // should never be produced by syntax
1275     return NULL;
1276 }
1277 
toChars()1278 const char *TypeInfoDeclaration::toChars()
1279 {
1280     //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo->toChars());
1281     OutBuffer buf;
1282     buf.writestring("typeid(");
1283     buf.writestring(tinfo->toChars());
1284     buf.writeByte(')');
1285     return buf.extractChars();
1286 }
1287 
1288 /***************************** TypeInfoConstDeclaration **********************/
1289 
TypeInfoConstDeclaration(Type * tinfo)1290 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1291     : TypeInfoDeclaration(tinfo)
1292 {
1293     if (!Type::typeinfoconst)
1294     {
1295         ObjectNotFound(Id::TypeInfo_Const);
1296     }
1297     type = Type::typeinfoconst->type;
1298 }
1299 
create(Type * tinfo)1300 TypeInfoConstDeclaration *TypeInfoConstDeclaration::create(Type *tinfo)
1301 {
1302     return new TypeInfoConstDeclaration(tinfo);
1303 }
1304 
1305 /***************************** TypeInfoInvariantDeclaration **********************/
1306 
TypeInfoInvariantDeclaration(Type * tinfo)1307 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1308     : TypeInfoDeclaration(tinfo)
1309 {
1310     if (!Type::typeinfoinvariant)
1311     {
1312         ObjectNotFound(Id::TypeInfo_Invariant);
1313     }
1314     type = Type::typeinfoinvariant->type;
1315 }
1316 
create(Type * tinfo)1317 TypeInfoInvariantDeclaration *TypeInfoInvariantDeclaration::create(Type *tinfo)
1318 {
1319     return new TypeInfoInvariantDeclaration(tinfo);
1320 }
1321 
1322 /***************************** TypeInfoSharedDeclaration **********************/
1323 
TypeInfoSharedDeclaration(Type * tinfo)1324 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
1325     : TypeInfoDeclaration(tinfo)
1326 {
1327     if (!Type::typeinfoshared)
1328     {
1329         ObjectNotFound(Id::TypeInfo_Shared);
1330     }
1331     type = Type::typeinfoshared->type;
1332 }
1333 
create(Type * tinfo)1334 TypeInfoSharedDeclaration *TypeInfoSharedDeclaration::create(Type *tinfo)
1335 {
1336     return new TypeInfoSharedDeclaration(tinfo);
1337 }
1338 
1339 /***************************** TypeInfoWildDeclaration **********************/
1340 
TypeInfoWildDeclaration(Type * tinfo)1341 TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
1342     : TypeInfoDeclaration(tinfo)
1343 {
1344     if (!Type::typeinfowild)
1345     {
1346         ObjectNotFound(Id::TypeInfo_Wild);
1347     }
1348     type = Type::typeinfowild->type;
1349 }
1350 
create(Type * tinfo)1351 TypeInfoWildDeclaration *TypeInfoWildDeclaration::create(Type *tinfo)
1352 {
1353     return new TypeInfoWildDeclaration(tinfo);
1354 }
1355 
1356 /***************************** TypeInfoStructDeclaration **********************/
1357 
TypeInfoStructDeclaration(Type * tinfo)1358 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1359     : TypeInfoDeclaration(tinfo)
1360 {
1361     if (!Type::typeinfostruct)
1362     {
1363         ObjectNotFound(Id::TypeInfo_Struct);
1364     }
1365     type = Type::typeinfostruct->type;
1366 }
1367 
create(Type * tinfo)1368 TypeInfoStructDeclaration *TypeInfoStructDeclaration::create(Type *tinfo)
1369 {
1370     return new TypeInfoStructDeclaration(tinfo);
1371 }
1372 
1373 /***************************** TypeInfoClassDeclaration ***********************/
1374 
TypeInfoClassDeclaration(Type * tinfo)1375 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1376     : TypeInfoDeclaration(tinfo)
1377 {
1378     if (!Type::typeinfoclass)
1379     {
1380         ObjectNotFound(Id::TypeInfo_Class);
1381     }
1382     type = Type::typeinfoclass->type;
1383 }
1384 
create(Type * tinfo)1385 TypeInfoClassDeclaration *TypeInfoClassDeclaration::create(Type *tinfo)
1386 {
1387     return new TypeInfoClassDeclaration(tinfo);
1388 }
1389 
1390 /***************************** TypeInfoInterfaceDeclaration *******************/
1391 
TypeInfoInterfaceDeclaration(Type * tinfo)1392 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1393     : TypeInfoDeclaration(tinfo)
1394 {
1395     if (!Type::typeinfointerface)
1396     {
1397         ObjectNotFound(Id::TypeInfo_Interface);
1398     }
1399     type = Type::typeinfointerface->type;
1400 }
1401 
create(Type * tinfo)1402 TypeInfoInterfaceDeclaration *TypeInfoInterfaceDeclaration::create(Type *tinfo)
1403 {
1404     return new TypeInfoInterfaceDeclaration(tinfo);
1405 }
1406 
1407 /***************************** TypeInfoPointerDeclaration *********************/
1408 
TypeInfoPointerDeclaration(Type * tinfo)1409 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1410     : TypeInfoDeclaration(tinfo)
1411 {
1412     if (!Type::typeinfopointer)
1413     {
1414         ObjectNotFound(Id::TypeInfo_Pointer);
1415     }
1416     type = Type::typeinfopointer->type;
1417 }
1418 
create(Type * tinfo)1419 TypeInfoPointerDeclaration *TypeInfoPointerDeclaration::create(Type *tinfo)
1420 {
1421     return new TypeInfoPointerDeclaration(tinfo);
1422 }
1423 
1424 /***************************** TypeInfoArrayDeclaration ***********************/
1425 
TypeInfoArrayDeclaration(Type * tinfo)1426 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1427     : TypeInfoDeclaration(tinfo)
1428 {
1429     if (!Type::typeinfoarray)
1430     {
1431         ObjectNotFound(Id::TypeInfo_Array);
1432     }
1433     type = Type::typeinfoarray->type;
1434 }
1435 
create(Type * tinfo)1436 TypeInfoArrayDeclaration *TypeInfoArrayDeclaration::create(Type *tinfo)
1437 {
1438     return new TypeInfoArrayDeclaration(tinfo);
1439 }
1440 
1441 /***************************** TypeInfoStaticArrayDeclaration *****************/
1442 
TypeInfoStaticArrayDeclaration(Type * tinfo)1443 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1444     : TypeInfoDeclaration(tinfo)
1445 {
1446     if (!Type::typeinfostaticarray)
1447     {
1448         ObjectNotFound(Id::TypeInfo_StaticArray);
1449     }
1450     type = Type::typeinfostaticarray->type;
1451 }
1452 
create(Type * tinfo)1453 TypeInfoStaticArrayDeclaration *TypeInfoStaticArrayDeclaration::create(Type *tinfo)
1454 {
1455     return new TypeInfoStaticArrayDeclaration(tinfo);
1456 }
1457 
1458 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1459 
TypeInfoAssociativeArrayDeclaration(Type * tinfo)1460 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1461     : TypeInfoDeclaration(tinfo)
1462 {
1463     if (!Type::typeinfoassociativearray)
1464     {
1465         ObjectNotFound(Id::TypeInfo_AssociativeArray);
1466     }
1467     type = Type::typeinfoassociativearray->type;
1468 }
1469 
create(Type * tinfo)1470 TypeInfoAssociativeArrayDeclaration *TypeInfoAssociativeArrayDeclaration::create(Type *tinfo)
1471 {
1472     return new TypeInfoAssociativeArrayDeclaration(tinfo);
1473 }
1474 
1475 /***************************** TypeInfoVectorDeclaration ***********************/
1476 
TypeInfoVectorDeclaration(Type * tinfo)1477 TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
1478     : TypeInfoDeclaration(tinfo)
1479 {
1480     if (!Type::typeinfovector)
1481     {
1482         ObjectNotFound(Id::TypeInfo_Vector);
1483     }
1484     type = Type::typeinfovector->type;
1485 }
1486 
create(Type * tinfo)1487 TypeInfoVectorDeclaration *TypeInfoVectorDeclaration::create(Type *tinfo)
1488 {
1489     return new TypeInfoVectorDeclaration(tinfo);
1490 }
1491 
1492 /***************************** TypeInfoEnumDeclaration ***********************/
1493 
TypeInfoEnumDeclaration(Type * tinfo)1494 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1495     : TypeInfoDeclaration(tinfo)
1496 {
1497     if (!Type::typeinfoenum)
1498     {
1499         ObjectNotFound(Id::TypeInfo_Enum);
1500     }
1501     type = Type::typeinfoenum->type;
1502 }
1503 
create(Type * tinfo)1504 TypeInfoEnumDeclaration *TypeInfoEnumDeclaration::create(Type *tinfo)
1505 {
1506     return new TypeInfoEnumDeclaration(tinfo);
1507 }
1508 
1509 /***************************** TypeInfoFunctionDeclaration ********************/
1510 
TypeInfoFunctionDeclaration(Type * tinfo)1511 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1512     : TypeInfoDeclaration(tinfo)
1513 {
1514     if (!Type::typeinfofunction)
1515     {
1516         ObjectNotFound(Id::TypeInfo_Function);
1517     }
1518     type = Type::typeinfofunction->type;
1519 }
1520 
create(Type * tinfo)1521 TypeInfoFunctionDeclaration *TypeInfoFunctionDeclaration::create(Type *tinfo)
1522 {
1523     return new TypeInfoFunctionDeclaration(tinfo);
1524 }
1525 
1526 /***************************** TypeInfoDelegateDeclaration ********************/
1527 
TypeInfoDelegateDeclaration(Type * tinfo)1528 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1529     : TypeInfoDeclaration(tinfo)
1530 {
1531     if (!Type::typeinfodelegate)
1532     {
1533         ObjectNotFound(Id::TypeInfo_Delegate);
1534     }
1535     type = Type::typeinfodelegate->type;
1536 }
1537 
create(Type * tinfo)1538 TypeInfoDelegateDeclaration *TypeInfoDelegateDeclaration::create(Type *tinfo)
1539 {
1540     return new TypeInfoDelegateDeclaration(tinfo);
1541 }
1542 
1543 /***************************** TypeInfoTupleDeclaration **********************/
1544 
TypeInfoTupleDeclaration(Type * tinfo)1545 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1546     : TypeInfoDeclaration(tinfo)
1547 {
1548     if (!Type::typeinfotypelist)
1549     {
1550         ObjectNotFound(Id::TypeInfo_Tuple);
1551     }
1552     type = Type::typeinfotypelist->type;
1553 }
1554 
create(Type * tinfo)1555 TypeInfoTupleDeclaration *TypeInfoTupleDeclaration::create(Type *tinfo)
1556 {
1557     return new TypeInfoTupleDeclaration(tinfo);
1558 }
1559 
1560 /********************************* ThisDeclaration ****************************/
1561 
1562 // For the "this" parameter to member functions
1563 
ThisDeclaration(Loc loc,Type * t)1564 ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
1565    : VarDeclaration(loc, t, Id::This, NULL)
1566 {
1567     storage_class |= STCnodtor;
1568 }
1569 
syntaxCopy(Dsymbol *)1570 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *)
1571 {
1572     assert(0);          // should never be produced by syntax
1573     return NULL;
1574 }
1575 
1576