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