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