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