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