1:
2: // Compiler implementation of the D programming language
3: // Copyright (c) 1999-2011 by Digital Mars
4: // All Rights Reserved
5: // written by Walter Bright
6: // http://www.digitalmars.com
7: // License for redistribution is by either the Artistic License
8: // in artistic.txt, or the GNU General Public License in gnu.txt.
9: // See the included readme.txt for details.
10:
11: #include <stdio.h>
12: static char __file__[] = __FILE__; /* for tassert.h */
13: #include "tassert.h"
14:
15: #include "cdef.h"
16: #include "init.h"
17: #include "declaration.h"
18: #include "attrib.h"
19: #include "mtype.h"
20: #include "template.h"
21: #include "scope.h"
22: #include "aggregate.h"
23: #include "module.h"
24: #include "id.h"
25: #include "expression.h"
26: #include "hdrgen.h"
27:
28: /********************************* Declaration ****************************/
29:
30: Declaration::Declaration(Identifier *id)
31: : Dsymbol(id)
32: {
33: type = NULL;
34: originalType = NULL;
35: storage_class = STCundefined;
36: protection = PROTundefined;
37: linkage = LINKdefault;
38: inuse = 0;
39: sem = SemanticStart;
40: }
41:
42: void Declaration::semantic(Scope *sc)
43: {
44: }
45:
46: const char *Declaration::kind()
47: {
48: return "declaration";
49: }
50:
51: unsigned Declaration::size(Loc loc)
52: {
53: assert(type);
54: return type->size();
warning C4244: 'return' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
55: }
56:
57: int Declaration::isDelete()
58: {
59: return FALSE;
60: }
61:
62: int Declaration::isDataseg()
63: {
64: return FALSE;
65: }
66:
67: int Declaration::isThreadlocal()
68: {
69: return FALSE;
70: }
71:
72: int Declaration::isCodeseg()
73: {
74: return FALSE;
75: }
76:
77: enum PROT Declaration::prot()
78: {
79: return protection;
80: }
81:
82: /*************************************
83: * Check to see if declaration can be modified in this context (sc).
84: * Issue error if not.
85: */
86:
87: #if DMDV2
88: void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
89: {
90: if (sc->incontract && isParameter())
91: error(loc, "cannot modify parameter '%s' in contract", toChars());
92:
93: if (sc->incontract && isResult())
94: error(loc, "cannot modify result '%s' in contract", toChars());
95:
96: if (isCtorinit() && !t->isMutable())
97: { // It's only modifiable if inside the right constructor
98: Dsymbol *s = sc->func;
99: while (1)
100: {
101: FuncDeclaration *fd = NULL;
102: if (s)
103: fd = s->isFuncDeclaration();
104: if (fd &&
105: ((fd->isCtorDeclaration() && storage_class & STCfield) ||
106: (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
107: fd->toParent2() == toParent()
108: )
109: {
110: VarDeclaration *v = isVarDeclaration();
111: assert(v);
112: v->ctorinit = 1;
113: //printf("setting ctorinit\n");
114: }
115: else
116: {
117: if (s)
118: { s = s->toParent2();
119: continue;
120: }
121: else
122: {
123: const char *p = isStatic() ? "static " : "";
124: error(loc, "can only initialize %sconst %s inside %sconstructor",
125: p, toChars(), p);
126: }
127: }
128: break;
129: }
130: }
131: else
132: {
133: VarDeclaration *v = isVarDeclaration();
134: if (v && v->canassign == 0)
135: {
136: const char *p = NULL;
137: if (isConst())
138: p = "const";
139: else if (isImmutable())
140: p = "immutable";
141: else if (storage_class & STCmanifest)
142: p = "enum";
143: else if (!t->isAssignable())
144: p = "struct with immutable members";
145: if (p)
146: { error(loc, "cannot modify %s", p);
147: }
148: }
149: }
150: }
151: #endif
152:
153:
154: /********************************* TupleDeclaration ****************************/
155:
156: TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
157: : Declaration(id)
158: {
159: this->loc = loc;
160: this->type = NULL;
161: this->objects = objects;
162: this->isexp = 0;
163: this->tupletype = NULL;
164: }
165:
166: Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
167: {
168: assert(0);
169: return NULL;
170: }
171:
172: const char *TupleDeclaration::kind()
173: {
174: return "tuple";
175: }
176:
177: Type *TupleDeclaration::getType()
178: {
179: /* If this tuple represents a type, return that type
180: */
181:
182: //printf("TupleDeclaration::getType() %s\n", toChars());
183: if (isexp)
184: return NULL;
185: if (!tupletype)
186: {
187: /* It's only a type tuple if all the Object's are types
188: */
189: for (size_t i = 0; i < objects->dim; i++)
190: { Object *o = objects->tdata()[i];
191:
192: if (o->dyncast() != DYNCAST_TYPE)
193: {
194: //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
195: return NULL;
196: }
197: }
198:
199: /* We know it's a type tuple, so build the TypeTuple
200: */
201: Types *types = (Types *)objects;
202: Parameters *args = new Parameters();
warning C6211: Leaking memory 'args' due to an exception. Consider using a local catch block to clean up memory: Lines: 183, 185, 189, 190, 192, 189, 190, 192, 189, 201, 202, 203, 204, 205, 206, 207, 216
203: args->setDim(objects->dim);
204: OutBuffer buf;
205: int hasdeco = 1;
206: for (size_t i = 0; i < types->dim; i++)
207: { Type *t = types->tdata()[i];
208:
209: //printf("type = %s\n", t->toChars());
210: #if 0
211: buf.printf("_%s_%d", ident->toChars(), i);
212: char *name = (char *)buf.extractData();
213: Identifier *id = new Identifier(name, TOKidentifier);
214: Parameter *arg = new Parameter(STCin, t, id, NULL);
215: #else
216: Parameter *arg = new Parameter(0, t, NULL, NULL);
217: #endif
218: args->tdata()[i] = arg;
219: if (!t->deco)
220: hasdeco = 0;
221: }
222:
223: tupletype = new TypeTuple(args);
224: if (hasdeco)
225: return tupletype->semantic(0, NULL);
226: }
227:
228: return tupletype;
229: }
230:
231: int TupleDeclaration::needThis()
232: {
233: //printf("TupleDeclaration::needThis(%s)\n", toChars());
234: for (size_t i = 0; i < objects->dim; i++)
235: { Object *o = objects->tdata()[i];
236: if (o->dyncast() == DYNCAST_EXPRESSION)
237: { Expression *e = (Expression *)o;
238: if (e->op == TOKdsymbol)
239: { DsymbolExp *ve = (DsymbolExp *)e;
240: Declaration *d = ve->s->isDeclaration();
241: if (d && d->needThis())
242: {
243: return 1;
244: }
245: }
246: }
247: }
248: return 0;
249: }
250:
251:
252: /********************************* TypedefDeclaration ****************************/
253:
254: TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init)
255: : Declaration(id)
256: {
257: this->type = new TypeTypedef(this);
258: this->basetype = basetype->toBasetype();
259: this->init = init;
260: this->htype = NULL;
261: this->hbasetype = NULL;
262: this->loc = loc;
263: this->sinit = NULL;
264: }
265:
266: Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
267: {
268: Type *basetype = this->basetype->syntaxCopy();
269:
270: Initializer *init = NULL;
271: if (this->init)
272: init = this->init->syntaxCopy();
273:
274: assert(!s);
275: TypedefDeclaration *st;
276: st = new TypedefDeclaration(loc, ident, basetype, init);
277:
278: // Syntax copy for header file
279: if (!htype) // Don't overwrite original
280: { if (type) // Make copy for both old and new instances
281: { htype = type->syntaxCopy();
282: st->htype = type->syntaxCopy();
283: }
284: }
285: else // Make copy of original for new instance
286: st->htype = htype->syntaxCopy();
287: if (!hbasetype)
288: { if (basetype)
289: { hbasetype = basetype->syntaxCopy();
290: st->hbasetype = basetype->syntaxCopy();
291: }
292: }
293: else
294: st->hbasetype = hbasetype->syntaxCopy();
295:
296: return st;
297: }
298:
299: void TypedefDeclaration::semantic(Scope *sc)
300: {
301: //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
302: if (sem == SemanticStart)
303: { sem = SemanticIn;
304: basetype = basetype->semantic(loc, sc);
305: sem = SemanticDone;
306: #if DMDV2
307: type = type->addStorageClass(storage_class);
308: #endif
309: type = type->semantic(loc, sc);
310: if (sc->parent->isFuncDeclaration() && init)
311: semantic2(sc);
312: storage_class |= sc->stc & STCdeprecated;
313: }
314: else if (sem == SemanticIn)
315: {
316: error("circular definition");
317: }
318: }
319:
320: void TypedefDeclaration::semantic2(Scope *sc)
321: {
322: //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
323: if (sem == SemanticDone)
324: { sem = Semantic2Done;
325: if (init)
326: {
327: init = init->semantic(sc, basetype, WANTinterpret);
328:
329: ExpInitializer *ie = init->isExpInitializer();
330: if (ie)
331: {
332: if (ie->exp->type == basetype)
333: ie->exp->type = type;
334: }
335: }
336: }
337: }
338:
339: const char *TypedefDeclaration::kind()
340: {
341: return "typedef";
342: }
343:
344: Type *TypedefDeclaration::getType()
345: {
346: return type;
347: }
348:
349: void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
350: {
351: buf->writestring("typedef ");
352: basetype->toCBuffer(buf, ident, hgs);
353: if (init)
354: {
355: buf->writestring(" = ");
356: init->toCBuffer(buf, hgs);
357: }
358: buf->writeByte(';');
359: buf->writenl();
360: }
361:
362: /********************************* AliasDeclaration ****************************/
363:
364: AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
365: : Declaration(id)
366: {
367: //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
368: //printf("type = '%s'\n", type->toChars());
369: this->loc = loc;
370: this->type = type;
371: this->aliassym = NULL;
372: this->htype = NULL;
373: this->haliassym = NULL;
374: this->overnext = NULL;
375: this->inSemantic = 0;
376: assert(type);
377: }
378:
379: AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
380: : Declaration(id)
381: {
382: //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
383: assert(s != this);
384: this->loc = loc;
385: this->type = NULL;
386: this->aliassym = s;
387: this->htype = NULL;
388: this->haliassym = NULL;
389: this->overnext = NULL;
390: this->inSemantic = 0;
391: assert(s);
392: }
393:
394: Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
395: {
396: //printf("AliasDeclaration::syntaxCopy()\n");
397: assert(!s);
398: AliasDeclaration *sa;
399: if (type)
400: sa = new AliasDeclaration(loc, ident, type->syntaxCopy());
401: else
402: sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
403:
404: // Syntax copy for header file
405: if (!htype) // Don't overwrite original
406: { if (type) // Make copy for both old and new instances
407: { htype = type->syntaxCopy();
408: sa->htype = type->syntaxCopy();
409: }
410: }
411: else // Make copy of original for new instance
412: sa->htype = htype->syntaxCopy();
413: if (!haliassym)
414: { if (aliassym)
415: { haliassym = aliassym->syntaxCopy(s);
416: sa->haliassym = aliassym->syntaxCopy(s);
417: }
418: }
419: else
420: sa->haliassym = haliassym->syntaxCopy(s);
421:
422: return sa;
423: }
424:
425: void AliasDeclaration::semantic(Scope *sc)
426: {
427: //printf("AliasDeclaration::semantic() %s\n", toChars());
428: if (aliassym)
429: {
430: if (aliassym->isTemplateInstance())
431: aliassym->semantic(sc);
432: return;
433: }
434: this->inSemantic = 1;
435:
436: #if DMDV1 // don't really know why this is here
437: if (storage_class & STCconst)
438: error("cannot be const");
439: #endif
440:
441: storage_class |= sc->stc & STCdeprecated;
442:
443: // Given:
444: // alias foo.bar.abc def;
445: // it is not knowable from the syntax whether this is an alias
446: // for a type or an alias for a symbol. It is up to the semantic()
447: // pass to distinguish.
448: // If it is a type, then type is set and getType() will return that
449: // type. If it is a symbol, then aliassym is set and type is NULL -
450: // toAlias() will return aliasssym.
451:
452: Dsymbol *s;
453: Type *t;
454: Expression *e;
455:
456: /* This section is needed because resolve() will:
457: * const x = 3;
458: * alias x y;
459: * try to alias y to 3.
460: */
461: s = type->toDsymbol(sc);
462: if (s
463: #if DMDV2
464: && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
465: #endif
466: )
467: goto L2; // it's a symbolic alias
468:
469: #if DMDV2
470: type = type->addStorageClass(storage_class);
471: if (storage_class & (STCref | STCnothrow | STCpure | STCdisable))
472: { // For 'ref' to be attached to function types, and picked
473: // up by Type::resolve(), it has to go into sc.
474: sc = sc->push();
475: sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable);
476: type->resolve(loc, sc, &e, &t, &s);
477: sc = sc->pop();
478: }
479: else
480: #endif
481: type->resolve(loc, sc, &e, &t, &s);
482: if (s)
483: {
484: goto L2;
485: }
486: else if (e)
487: {
488: // Try to convert Expression to Dsymbol
489: s = getDsymbol(e);
490: if (s)
491: goto L2;
492:
493: error("cannot alias an expression %s", e->toChars());
494: t = e->type;
495: }
496: else if (t)
497: {
498: type = t;
499: //printf("\talias resolved to type %s\n", type->toChars());
500: }
501: if (overnext)
502: ScopeDsymbol::multiplyDefined(0, this, overnext);
503: this->inSemantic = 0;
504: return;
505:
506: L2:
507: //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
508: type = NULL;
509: VarDeclaration *v = s->isVarDeclaration();
510: if (0 && v && v->linkage == LINKdefault)
511: {
512: error("forward reference of %s", v->toChars());
513: s = NULL;
514: }
515: else
516: {
517: FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
518: if (f)
519: {
520: if (overnext)
521: {
522: FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
523: if (!fa->overloadInsert(overnext))
524: ScopeDsymbol::multiplyDefined(0, f, overnext);
525: overnext = NULL;
526: s = fa;
527: s->parent = sc->parent;
528: }
529: }
530: if (overnext)
531: ScopeDsymbol::multiplyDefined(0, this, overnext);
532: if (s == this)
533: {
534: assert(global.errors);
535: s = NULL;
536: }
537: }
538: //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars());
539: aliassym = s;
540: this->inSemantic = 0;
541: }
542:
543: int AliasDeclaration::overloadInsert(Dsymbol *s)
544: {
545: /* Don't know yet what the aliased symbol is, so assume it can
546: * be overloaded and check later for correctness.
547: */
548:
549: //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
550: if (aliassym) // see test/test56.d
551: {
552: Dsymbol *a = aliassym->toAlias();
553: FuncDeclaration *f = a->isFuncDeclaration();
554: if (f) // BUG: what if it's a template?
555: {
556: FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
557: aliassym = fa;
558: return fa->overloadInsert(s);
559: }
560: }
561:
562: if (overnext == NULL)
563: {
564: if (s == this)
565: {
566: return TRUE;
567: }
568: overnext = s;
569: return TRUE;
570: }
571: else
572: {
573: return overnext->overloadInsert(s);
574: }
575: }
576:
577: const char *AliasDeclaration::kind()
578: {
579: return "alias";
580: }
581:
582: Type *AliasDeclaration::getType()
583: {
584: return type;
585: }
586:
587: Dsymbol *AliasDeclaration::toAlias()
588: {
589: //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
590: assert(this != aliassym);
591: //static int count; if (++count == 10) *(char*)0=0;
592: if (inSemantic)
593: { error("recursive alias declaration");
594: aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
595: type = Type::terror;
596: }
597: else if (!aliassym && scope)
598: semantic(scope);
599: Dsymbol *s = aliassym ? aliassym->toAlias() : this;
600: return s;
601: }
602:
603: void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
604: {
605: buf->writestring("alias ");
606: #if 0
607: if (hgs->hdrgen)
608: {
609: if (haliassym)
610: {
611: haliassym->toCBuffer(buf, hgs);
612: buf->writeByte(' ');
613: buf->writestring(ident->toChars());
614: }
615: else
616: htype->toCBuffer(buf, ident, hgs);
617: }
618: else
619: #endif
620: {
621: if (aliassym)
622: {
623: aliassym->toCBuffer(buf, hgs);
624: buf->writeByte(' ');
625: buf->writestring(ident->toChars());
626: }
627: else
628: type->toCBuffer(buf, ident, hgs);
629: }
630: buf->writeByte(';');
631: buf->writenl();
632: }
633:
634: /********************************* VarDeclaration ****************************/
635:
636: VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
637: : Declaration(id)
638: {
639: //printf("VarDeclaration('%s')\n", id->toChars());
640: #ifdef DEBUG
641: if (!type && !init)
642: { printf("VarDeclaration('%s')\n", id->toChars());
643: //*(char*)0=0;
644: }
645: #endif
646: assert(type || init);
647: this->type = type;
648: this->init = init;
649: this->htype = NULL;
650: this->hinit = NULL;
651: this->loc = loc;
652: offset = 0;
653: noscope = 0;
654: #if DMDV2
655: isargptr = FALSE;
656: #endif
657: #if DMDV1
658: nestedref = 0;
659: #endif
660: ctorinit = 0;
661: aliassym = NULL;
662: onstack = 0;
663: canassign = 0;
664: setValueNull();
665: #if DMDV2
666: rundtor = NULL;
667: edtor = NULL;
668: #endif
669: }
670:
671: Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
672: {
673: //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
674:
675: VarDeclaration *sv;
676: if (s)
677: { sv = (VarDeclaration *)s;
678: }
679: else
680: {
681: Initializer *init = NULL;
682: if (this->init)
683: { init = this->init->syntaxCopy();
684: //init->isExpInitializer()->exp->print();
685: //init->isExpInitializer()->exp->dump(0);
686: }
687:
688: sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
689: sv->storage_class = storage_class;
690: }
691:
692: // Syntax copy for header file
693: if (!htype) // Don't overwrite original
694: { if (type) // Make copy for both old and new instances
695: { htype = type->syntaxCopy();
696: sv->htype = type->syntaxCopy();
697: }
698: }
699: else // Make copy of original for new instance
700: sv->htype = htype->syntaxCopy();
701: if (!hinit)
702: { if (init)
703: { hinit = init->syntaxCopy();
704: sv->hinit = init->syntaxCopy();
705: }
706: }
707: else
708: sv->hinit = hinit->syntaxCopy();
709:
710: return sv;
711: }
712:
713: void VarDeclaration::semantic(Scope *sc)
714: {
715: #if 0
716: printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
717: printf(" type = %s\n", type ? type->toChars() : "null");
718: printf(" stc = x%x\n", sc->stc);
719: printf(" storage_class = x%x\n", storage_class);
720: printf("linkage = %d\n", sc->linkage);
721: //if (strcmp(toChars(), "mul") == 0) halt();
722: #endif
723:
724: // if (sem > SemanticStart)
725: // return;
726: // sem = SemanticIn;
727:
728: if (scope)
729: { sc = scope;
730: scope = NULL;
731: }
732:
733: /* Pick up storage classes from context, but skip synchronized
734: */
735: storage_class |= (sc->stc & ~STCsynchronized);
736: if (storage_class & STCextern && init)
737: error("extern symbols cannot have initializers");
738:
739: AggregateDeclaration *ad = isThis();
740: if (ad)
741: storage_class |= ad->storage_class & STC_TYPECTOR;
742:
743: /* If auto type inference, do the inference
744: */
745: int inferred = 0;
746: if (!type)
747: { inuse++;
748:
749: ArrayInitializer *ai = init->isArrayInitializer();
750: if (ai)
751: { Expression *e;
752: if (ai->isAssociativeArray())
753: e = ai->toAssocArrayLiteral();
754: else
755: e = init->toExpression();
756: if (!e)
757: {
758: error("cannot infer type from initializer");
759: e = new ErrorExp();
760: }
761: init = new ExpInitializer(e->loc, e);
762: type = init->inferType(sc);
763: if (type->ty == Tsarray)
764: type = type->nextOf()->arrayOf();
765: }
766: else
767: type = init->inferType(sc);
768:
769: //printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco);
770: // type = type->semantic(loc, sc);
771:
772: inuse--;
773: inferred = 1;
774:
775: if (init->isArrayInitializer() && type->toBasetype()->ty == Tsarray)
776: { // Prefer array literals to give a T[] type rather than a T[dim]
777: type = type->toBasetype()->nextOf()->arrayOf();
778: }
779:
780: /* This is a kludge to support the existing syntax for RAII
781: * declarations.
782: */
783: storage_class &= ~STCauto;
784: originalType = type;
785: }
786: else
787: { if (!originalType)
788: originalType = type;
789: type = type->semantic(loc, sc);
790: }
791: //printf(" semantic type = %s\n", type ? type->toChars() : "null");
792:
793: type->checkDeprecated(loc, sc);
794: linkage = sc->linkage;
795: this->parent = sc->parent;
796: //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
797: protection = sc->protection;
798: //printf("sc->stc = %x\n", sc->stc);
799: //printf("storage_class = x%x\n", storage_class);
800:
801: #if DMDV2
802: // Safety checks
803: if (sc->func && !sc->intypeof)
804: {
805: if (storage_class & STCgshared)
806: {
807: if (sc->func->setUnsafe())
808: error("__gshared not allowed in safe functions; use shared");
809: }
810: if (init && init->isVoidInitializer() && type->hasPointers())
811: {
812: if (sc->func->setUnsafe())
813: error("void initializers for pointers not allowed in safe functions");
814: }
815: if (type->hasPointers() && type->toDsymbol(sc))
816: {
817: Dsymbol *s = type->toDsymbol(sc);
818: if (s)
819: {
820: AggregateDeclaration *ad = s->isAggregateDeclaration();
warning C6246: Local declaration of 'ad' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '739' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 739
821: if (ad && ad->hasUnions)
822: {
823: if (sc->func->setUnsafe())
824: error("unions containing pointers are not allowed in @safe functions");
825: }
826: }
827: }
828: }
829: #endif
830:
831: Dsymbol *parent = toParent();
832: FuncDeclaration *fd = parent->isFuncDeclaration();
833:
834: Type *tb = type->toBasetype();
835: if (tb->ty == Tvoid && !(storage_class & STClazy))
836: { error("voids have no value");
837: type = Type::terror;
838: tb = type;
839: }
840: if (tb->ty == Tfunction)
841: { error("cannot be declared to be a function");
842: type = Type::terror;
843: tb = type;
844: }
845: if (tb->ty == Tstruct)
846: { TypeStruct *ts = (TypeStruct *)tb;
847:
848: if (!ts->sym->members)
849: {
850: error("no definition of struct %s", ts->toChars());
851: }
852: }
853: if ((storage_class & STCauto) && !inferred)
854: error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?");
855:
856: if (tb->ty == Ttuple)
857: { /* Instead, declare variables for each of the tuple elements
858: * and add those.
859: */
860: TypeTuple *tt = (TypeTuple *)tb;
861: size_t nelems = Parameter::dim(tt->arguments);
862: Objects *exps = new Objects();
863: exps->setDim(nelems);
864: Expression *ie = init ? init->toExpression() : NULL;
865:
866: for (size_t i = 0; i < nelems; i++)
867: { Parameter *arg = Parameter::getNth(tt->arguments, i);
868:
869: OutBuffer buf;
870: buf.printf("_%s_field_%"SIZE_T_FORMAT"u", ident->toChars(), i);
871: buf.writeByte(0);
872: const char *name = (const char *)buf.extractData();
873: Identifier *id = Lexer::idPool(name);
874:
875: Expression *einit = ie;
876: if (ie && ie->op == TOKtuple)
877: { einit = ((TupleExp *)ie)->exps->tdata()[i];
878: }
879: Initializer *ti = init;
880: if (einit)
881: { ti = new ExpInitializer(einit->loc, einit);
882: }
883:
884: VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
885: //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
886: v->semantic(sc);
887:
888: if (sc->scopesym)
889: { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
890: if (sc->scopesym->members)
891: sc->scopesym->members->push(v);
892: }
893:
894: Expression *e = new DsymbolExp(loc, v);
895: exps->tdata()[i] = e;
896: }
897: TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
898: v2->isexp = 1;
899: aliassym = v2;
900: return;
901: }
902:
903: Lagain:
warning C4102: 'Lagain' : unreferenced label
904: /* Storage class can modify the type
905: */
906: type = type->addStorageClass(storage_class);
907:
908: /* Adjust storage class to reflect type
909: */
910: if (type->isConst())
911: { storage_class |= STCconst;
912: if (type->isShared())
913: storage_class |= STCshared;
914: }
915: else if (type->isImmutable())
916: storage_class |= STCimmutable;
917: else if (type->isShared())
918: storage_class |= STCshared;
919: else if (type->isWild())
920: storage_class |= STCwild;
921:
922: if (isSynchronized())
923: {
924: error("variable %s cannot be synchronized", toChars());
925: }
926: else if (isOverride())
927: {
928: error("override cannot be applied to variable");
929: }
930: else if (isAbstract())
931: {
932: error("abstract cannot be applied to variable");
933: }
934: else if (storage_class & STCfinal)
935: {
936: error("final cannot be applied to variable");
937: }
938:
939: if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
940: {
941: }
942: else
943: {
944: AggregateDeclaration *aad = sc->anonAgg;
945: if (!aad)
946: aad = parent->isAggregateDeclaration();
947: if (aad)
948: {
949: #if DMDV2
950: assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared)));
951:
952: if (storage_class & (STCconst | STCimmutable) && init)
953: {
954: if (!tb->isTypeBasic())
955: storage_class |= STCstatic;
956: }
957: else
958: {
959: aad->addField(sc, this);
960: if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
961: tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
962: aad->noDefaultCtor = TRUE;
963: }
964: #else
965: aad->addField(sc, this);
966: #endif
967: }
968:
969: InterfaceDeclaration *id = parent->isInterfaceDeclaration();
970: if (id)
971: {
972: error("field not allowed in interface");
973: }
974:
975: /* Templates cannot add fields to aggregates
976: */
977: TemplateInstance *ti = parent->isTemplateInstance();
978: if (ti)
979: {
980: // Take care of nested templates
981: while (1)
982: {
983: TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
984: if (!ti2)
985: break;
986: ti = ti2;
987: }
988:
989: // If it's a member template
990: AggregateDeclaration *ad = ti->tempdecl->isMember();
warning C6246: Local declaration of 'ad' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '739' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 739
991: if (ad && storage_class != STCundefined)
992: {
993: error("cannot use template to add field to aggregate '%s'", ad->toChars());
994: }
995: }
996: }
997:
998: #if DMDV2
999: if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref &&
1000: ident != Id::This)
1001: {
1002: error("only parameters or foreach declarations can be ref");
1003: }
1004:
1005: if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) ||
1006: isDataseg()) &&
1007: type->hasWild())
1008: {
1009: error("only fields, parameters or stack based variables can be inout");
1010: }
1011:
1012: if (!(storage_class & (STCfield | STCctfe)) && tb->ty == Tstruct &&
1013: ((TypeStruct *)tb)->sym->noDefaultCtor)
1014: {
1015: if (!init)
1016: error("initializer required for type %s", type->toChars());
1017: }
1018: #endif
1019:
1020: if (type->isscope() && !noscope)
1021: {
1022: if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd)
1023: {
1024: error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope");
1025: }
1026:
1027: if (!(storage_class & STCscope))
1028: {
1029: if (!(storage_class & STCparameter) && ident != Id::withSym)
1030: error("reference to scope class must be scope");
1031: }
1032: }
1033:
1034: if (!init && !fd)
1035: { // If not mutable, initializable by constructor only
1036: storage_class |= STCctorinit;
1037: }
1038:
1039: if (init)
1040: storage_class |= STCinit; // remember we had an explicit initializer
1041: else if (storage_class & STCmanifest)
1042: error("manifest constants must have initializers");
1043:
1044: enum TOK op = TOKconstruct;
1045: if (!init && !sc->inunion && !isStatic() && fd &&
1046: (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult))
1047: || (storage_class & STCout)) &&
1048: type->size() != 0)
1049: {
1050: // Provide a default initializer
1051: //printf("Providing default initializer for '%s'\n", toChars());
1052: if (type->ty == Tstruct &&
1053: ((TypeStruct *)type)->sym->zeroInit == 1)
1054: { /* If a struct is all zeros, as a special case
1055: * set it's initializer to the integer 0.
1056: * In AssignExp::toElem(), we check for this and issue
1057: * a memset() to initialize the struct.
1058: * Must do same check in interpreter.
1059: */
1060: Expression *e = new IntegerExp(loc, 0, Type::tint32);
1061: Expression *e1;
1062: e1 = new VarExp(loc, this);
1063: e = new ConstructExp(loc, e1, e);
1064: e->type = e1->type; // don't type check this, it would fail
1065: init = new ExpInitializer(loc, e);
1066: goto Ldtor;
1067: }
1068: else if (type->ty == Ttypedef)
1069: { TypeTypedef *td = (TypeTypedef *)type;
1070: if (td->sym->init)
1071: { init = td->sym->init;
1072: ExpInitializer *ie = init->isExpInitializer();
1073: if (ie)
1074: // Make copy so we can modify it
1075: init = new ExpInitializer(ie->loc, ie->exp);
1076: }
1077: else
1078: init = getExpInitializer();
1079: }
1080: else
1081: {
1082: init = getExpInitializer();
1083: }
1084: // Default initializer is always a blit
1085: op = TOKblit;
1086: }
1087:
1088: if (init)
1089: {
1090: sc = sc->push();
1091: sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref | STCdisable);
1092:
1093: ArrayInitializer *ai = init->isArrayInitializer();
1094: if (ai && tb->ty == Taarray)
1095: {
1096: Expression *e = ai->toAssocArrayLiteral();
1097: init = new ExpInitializer(e->loc, e);
1098: }
1099:
1100: StructInitializer *si = init->isStructInitializer();
1101: ExpInitializer *ei = init->isExpInitializer();
1102:
1103: // See if initializer is a NewExp that can be allocated on the stack
1104: if (ei && isScope() && ei->exp->op == TOKnew)
1105: { NewExp *ne = (NewExp *)ei->exp;
1106: if (!(ne->newargs && ne->newargs->dim))
1107: { ne->onstack = 1;
1108: onstack = 1;
1109: if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
1110: onstack = 2;
1111: }
1112: }
1113:
1114: // If inside function, there is no semantic3() call
1115: if (sc->func)
1116: {
1117: // If local variable, use AssignExp to handle all the various
1118: // possibilities.
1119: if (fd &&
1120: !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) &&
1121: !init->isVoidInitializer())
1122: {
1123: //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
1124: if (!ei)
1125: {
1126: Expression *e = init->toExpression();
1127: if (!e)
1128: {
1129: init = init->semantic(sc, type, 0); // Don't need to interpret
1130: e = init->toExpression();
1131: if (!e)
1132: { error("is not a static and cannot have static initializer");
1133: return;
1134: }
1135: }
1136: ei = new ExpInitializer(init->loc, e);
1137: init = ei;
1138: }
1139:
1140: Expression *e1 = new VarExp(loc, this);
1141:
1142: Type *t = type->toBasetype();
1143:
1144: Linit2:
1145: if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
1146: {
1147: ei->exp = ei->exp->semantic(sc);
1148: if (!ei->exp->implicitConvTo(type))
1149: {
1150: int dim = ((TypeSArray *)t)->dim->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'int', possible loss of data
1151: // If multidimensional static array, treat as one large array
1152: while (1)
1153: {
1154: t = t->nextOf()->toBasetype();
1155: if (t->ty != Tsarray)
1156: break;
1157: dim *= ((TypeSArray *)t)->dim->toInteger();
warning C4244: '*=' : conversion from 'dinteger_t' to 'int', possible loss of data
1158: e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
1159: }
1160: }
1161: e1 = new SliceExp(loc, e1, NULL, NULL);
1162: }
1163: else if (t->ty == Tstruct)
1164: {
1165: ei->exp = ei->exp->semantic(sc);
1166: ei->exp = resolveProperties(sc, ei->exp);
1167: StructDeclaration *sd = ((TypeStruct *)t)->sym;
1168: #if DMDV2
1169: Expression** pinit = &ei->exp;
1170: while ((*pinit)->op == TOKcomma)
1171: {
1172: pinit = &((CommaExp *)*pinit)->e2;
1173: }
1174:
1175: /* Look to see if initializer is a call to the constructor
1176: */
1177: if (sd->ctor && // there are constructors
1178: (*pinit)->type->ty == Tstruct && // rvalue is the same struct
1179: ((TypeStruct *)(*pinit)->type)->sym == sd &&
1180: (*pinit)->op == TOKcall)
1181: {
1182: /* Look for form of constructor call which is:
1183: * *__ctmp.ctor(arguments...)
1184: */
1185: if (1)
1186: { CallExp *ce = (CallExp *)(*pinit);
1187: if (ce->e1->op == TOKdotvar)
1188: { DotVarExp *dve = (DotVarExp *)ce->e1;
1189: if (dve->var->isCtorDeclaration())
1190: { /* It's a constructor call, currently constructing
1191: * a temporary __ctmp.
1192: */
1193: /* Before calling the constructor, initialize
1194: * variable with a bit copy of the default
1195: * initializer
1196: */
1197: Expression *e;
1198: if (sd->zeroInit == 1)
1199: {
1200: e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32));
1201: }
1202: else
1203: { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
1204: e->op = TOKblit;
1205: }
1206: e->type = t;
1207: (*pinit) = new CommaExp(loc, e, (*pinit));
1208:
1209: /* Replace __ctmp being constructed with e1
1210: */
1211: dve->e1 = e1;
1212: (*pinit) = (*pinit)->semantic(sc);
1213: goto Ldtor;
1214: }
1215: }
1216: }
1217: }
1218:
1219: /* Look for ((S tmp = S()),tmp) and replace it with just S()
1220: */
1221: Expression *e2 = ei->exp->isTemp();
1222: if (e2)
1223: {
1224: ei->exp = e2;
1225: goto Linit2;
1226: }
1227: #endif
1228: if (!ei->exp->implicitConvTo(type))
1229: {
1230: Type *ti = ei->exp->type->toBasetype();
1231: // Look for constructor first
1232: if (sd->ctor &&
1233: /* Initializing with the same type is done differently
1234: */
1235: !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1236: {
1237: // Rewrite as e1.ctor(arguments)
1238: Expression *ector = new DotIdExp(loc, e1, Id::ctor);
1239: ei->exp = new CallExp(loc, ector, ei->exp);
1240: /* Before calling the constructor, initialize
1241: * variable with a bit copy of the default
1242: * initializer
1243: */
1244: Expression *e = new AssignExp(loc, e1, t->defaultInit(loc));
1245: e->op = TOKblit;
1246: e->type = t;
1247: ei->exp = new CommaExp(loc, e, ei->exp);
1248: }
1249: else
1250: /* Look for opCall
1251: * See bugzilla 2702 for more discussion
1252: */
1253: // Don't cast away invariant or mutability in initializer
1254: if (search_function(sd, Id::call) &&
1255: /* Initializing with the same type is done differently
1256: */
1257: !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
1258: { // Rewrite as e1.call(arguments)
1259: Expression * eCall = new DotIdExp(loc, e1, Id::call);
1260: ei->exp = new CallExp(loc, eCall, ei->exp);
1261: }
1262: }
1263: }
1264: ei->exp = new AssignExp(loc, e1, ei->exp);
1265: ei->exp->op = op;
1266: canassign++;
1267: ei->exp = ei->exp->semantic(sc);
1268: canassign--;
1269: ei->exp->optimize(WANTvalue);
1270: }
1271: else
1272: {
1273: init = init->semantic(sc, type, WANTinterpret);
1274: }
1275: }
1276: else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
1277: type->isConst() || type->isImmutable() ||
1278: parent->isAggregateDeclaration())
1279: {
1280: /* Because we may need the results of a const declaration in a
1281: * subsequent type, such as an array dimension, before semantic2()
1282: * gets ordinarily run, try to run semantic2() now.
1283: * Ignore failure.
1284: */
1285:
1286: if (!global.errors && !inferred)
1287: {
1288: unsigned errors = global.errors;
1289: global.gag++;
1290: //printf("+gag\n");
1291: Expression *e;
1292: Initializer *i2 = init;
1293: inuse++;
1294: if (ei)
1295: {
1296: e = ei->exp->syntaxCopy();
1297: e = e->semantic(sc);
1298: e = resolveProperties(sc, e);
1299: #if DMDV2
1300: /* The problem is the following code:
1301: * struct CopyTest {
1302: * double x;
1303: * this(double a) { x = a * 10.0;}
1304: * this(this) { x += 2.0; }
1305: * }
1306: * const CopyTest z = CopyTest(5.3); // ok
1307: * const CopyTest w = z; // not ok, postblit not run
1308: * static assert(w.x == 55.0);
1309: * because the postblit doesn't get run on the initialization of w.
1310: */
1311:
1312: Type *tb = e->type->toBasetype();
warning C6246: Local declaration of 'tb' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '834' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 834
1313: if (tb->ty == Tstruct)
1314: { StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1315: Type *typeb = type->toBasetype();
1316: /* Look to see if initializer involves a copy constructor
1317: * (which implies a postblit)
1318: */
1319: if (sd->cpctor && // there is a copy constructor
1320: typeb->equals(tb)) // rvalue is the same struct
1321: {
1322: // The only allowable initializer is a (non-copy) constructor
1323: if (e->op == TOKcall)
1324: {
1325: CallExp *ce = (CallExp *)e;
1326: if (ce->e1->op == TOKdotvar)
1327: {
1328: DotVarExp *dve = (DotVarExp *)ce->e1;
1329: if (dve->var->isCtorDeclaration())
1330: goto LNoCopyConstruction;
1331: }
1332: }
1333: global.gag--;
1334: error("of type struct %s uses this(this), which is not allowed in static initialization", typeb->toChars());
1335: global.gag++;
1336:
1337: LNoCopyConstruction:
1338: ;
1339: }
1340: }
1341: #endif
1342: e = e->implicitCastTo(sc, type);
1343: }
1344: else if (si || ai)
1345: { i2 = init->syntaxCopy();
1346: i2 = i2->semantic(sc, type, WANTinterpret);
1347: }
1348: inuse--;
1349: global.gag--;
1350: //printf("-gag\n");
1351: if (errors != global.errors) // if errors happened
1352: {
1353: if (global.gag == 0)
1354: global.errors = errors; // act as if nothing happened
1355: #if DMDV2
1356: /* Save scope for later use, to try again
1357: */
1358: scope = new Scope(*sc);
1359: scope->setNoFree();
1360: #endif
1361: }
1362: else if (ei)
1363: {
1364: if (isDataseg() || (storage_class & STCmanifest))
1365: e = e->optimize(WANTvalue | WANTinterpret);
1366: else
1367: e = e->optimize(WANTvalue);
1368: switch (e->op)
1369: {
1370: case TOKint64:
1371: case TOKfloat64:
1372: case TOKstring:
1373: case TOKarrayliteral:
1374: case TOKassocarrayliteral:
1375: case TOKstructliteral:
1376: case TOKnull:
1377: ei->exp = e; // no errors, keep result
1378: break;
1379:
1380: default:
1381: #if DMDV2
1382: /* Save scope for later use, to try again
1383: */
1384: scope = new Scope(*sc);
1385: scope->setNoFree();
1386: #endif
1387: break;
1388: }
1389: }
1390: else
1391: init = i2; // no errors, keep result
1392: }
1393: }
1394: sc = sc->pop();
1395: }
1396:
1397: Ldtor:
1398: /* Build code to execute destruction, if necessary
1399: */
1400: edtor = callScopeDtor(sc);
1401: if (edtor)
1402: {
1403: edtor = edtor->semantic(sc);
1404:
1405: #if 0 // currently disabled because of std.stdio.stdin, stdout and stderr
1406: if (isDataseg() && !(storage_class & STCextern))
1407: error("static storage variables cannot have destructors");
1408: #endif
1409: }
1410:
1411: sem = SemanticDone;
1412: }
1413:
1414: void VarDeclaration::semantic2(Scope *sc)
1415: {
1416: //printf("VarDeclaration::semantic2('%s')\n", toChars());
1417: if (init && !toParent()->isFuncDeclaration())
1418: { inuse++;
1419: #if 0
1420: ExpInitializer *ei = init->isExpInitializer();
1421: if (ei)
1422: {
1423: ei->exp->dump(0);
1424: printf("type = %p\n", ei->exp->type);
1425: }
1426: #endif
1427: init = init->semantic(sc, type, WANTinterpret);
1428: inuse--;
1429: }
1430: sem = Semantic2Done;
1431: }
1432:
1433: const char *VarDeclaration::kind()
1434: {
1435: return "variable";
1436: }
1437:
1438: Dsymbol *VarDeclaration::toAlias()
1439: {
1440: //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1441: assert(this != aliassym);
1442: Dsymbol *s = aliassym ? aliassym->toAlias() : this;
1443: return s;
1444: }
1445:
1446: void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1447: {
1448: StorageClassDeclaration::stcToCBuffer(buf, storage_class);
1449:
1450: /* If changing, be sure and fix CompoundDeclarationStatement::toCBuffer()
1451: * too.
1452: */
1453: if (type)
1454: type->toCBuffer(buf, ident, hgs);
1455: else
1456: buf->writestring(ident->toChars());
1457: if (init)
1458: { buf->writestring(" = ");
1459: #if DMDV2
1460: ExpInitializer *ie = init->isExpInitializer();
1461: if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1462: ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
1463: else
1464: #endif
1465: init->toCBuffer(buf, hgs);
1466: }
1467: buf->writeByte(';');
1468: buf->writenl();
1469: }
1470:
1471: AggregateDeclaration *VarDeclaration::isThis()
1472: {
1473: AggregateDeclaration *ad = NULL;
1474:
1475: if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter |
1476: STCtls | STCgshared | STCctfe)))
1477: {
1478: if ((storage_class & (STCconst | STCimmutable | STCwild)) && init)
1479: return NULL;
1480:
1481: for (Dsymbol *s = this; s; s = s->parent)
1482: {
1483: ad = s->isMember();
1484: if (ad)
1485: break;
1486: if (!s->parent || !s->parent->isTemplateMixin()) break;
1487: }
1488: }
1489: return ad;
1490: }
1491:
1492: int VarDeclaration::needThis()
1493: {
1494: //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1495: return storage_class & STCfield;
1496: }
1497:
1498: int VarDeclaration::isImportedSymbol()
1499: {
1500: if (protection == PROTexport && !init &&
1501: (storage_class & STCstatic || parent->isModule()))
1502: return TRUE;
1503: return FALSE;
1504: }
1505:
1506: void VarDeclaration::checkCtorConstInit()
1507: {
1508: #if 0 /* doesn't work if more than one static ctor */
1509: if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
1510: error("missing initializer in static constructor for const variable");
1511: #endif
1512: }
1513:
1514: /************************************
1515: * Check to see if this variable is actually in an enclosing function
1516: * rather than the current one.
1517: */
1518:
1519: void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
1520: {
1521: //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
1522: if (parent && !isDataseg() && parent != sc->parent &&
1523: !(storage_class & STCmanifest))
1524: {
1525: // The function that this variable is in
1526: FuncDeclaration *fdv = toParent()->isFuncDeclaration();
1527: // The current function
1528: FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
1529:
1530: if (fdv && fdthis && fdv != fdthis)
1531: {
1532: if (loc.filename)
1533: fdthis->getLevel(loc, fdv);
1534:
1535: for (int i = 0; i < nestedrefs.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1536: { FuncDeclaration *f = nestedrefs.tdata()[i];
1537: if (f == fdthis)
1538: goto L1;
1539: }
1540: nestedrefs.push(fdthis);
1541: L1: ;
1542:
1543:
1544: for (int i = 0; i < fdv->closureVars.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1545: { Dsymbol *s = fdv->closureVars.tdata()[i];
1546: if (s == this)
1547: goto L2;
1548: }
1549:
1550: fdv->closureVars.push(this);
1551: L2: ;
1552:
1553: //printf("fdthis is %s\n", fdthis->toChars());
1554: //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1555: // __dollar creates problems because it isn't a real variable Bugzilla 3326
1556: if (ident == Id::dollar)
1557: ::error(loc, "cannnot use $ inside a function literal");
1558: }
1559: }
1560: }
1561:
1562: /****************************
1563: * Get ExpInitializer for a variable, if there is one.
1564: */
1565:
1566: ExpInitializer *VarDeclaration::getExpInitializer()
1567: {
1568: ExpInitializer *ei;
1569:
1570: if (init)
1571: ei = init->isExpInitializer();
1572: else
1573: {
1574: Expression *e = type->defaultInit(loc);
1575: if (e)
1576: ei = new ExpInitializer(loc, e);
1577: else
1578: ei = NULL;
1579: }
1580: return ei;
1581: }
1582:
1583: /*******************************************
1584: * If variable has a constant expression initializer, get it.
1585: * Otherwise, return NULL.
1586: */
1587:
1588: Expression *VarDeclaration::getConstInitializer()
1589: {
1590: if ((isConst() || isImmutable() || storage_class & STCmanifest) &&
1591: storage_class & STCinit)
1592: {
1593: ExpInitializer *ei = getExpInitializer();
1594: if (ei)
1595: return ei->exp;
1596: }
1597:
1598: return NULL;
1599: }
1600:
1601: /*************************************
1602: * Return !=0 if we can take the address of this variable.
1603: */
1604:
1605: int VarDeclaration::canTakeAddressOf()
1606: {
1607: #if 0
1608: /* Global variables and struct/class fields of the form:
1609: * const int x = 3;
1610: * are not stored and hence cannot have their address taken.
1611: */
1612: if ((isConst() || isImmutable()) &&
1613: storage_class & STCinit &&
1614: (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) &&
1615: (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) &&
1616: type->toBasetype()->isTypeBasic()
1617: )
1618: {
1619: return 0;
1620: }
1621: #else
1622: if (storage_class & STCmanifest)
1623: return 0;
1624: #endif
1625: return 1;
1626: }
1627:
1628:
1629: /*******************************
1630: * Does symbol go into data segment?
1631: * Includes extern variables.
1632: */
1633:
1634: int VarDeclaration::isDataseg()
1635: {
1636: #if 0
1637: printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1638: printf("%llx, isModule: %p, isTemplateInstance: %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
1639: printf("parent = '%s'\n", parent->toChars());
1640: #endif
1641: if (storage_class & STCmanifest)
1642: return 0;
1643: Dsymbol *parent = this->toParent();
1644: if (!parent && !(storage_class & STCstatic))
1645: { error("forward referenced");
1646: type = Type::terror;
1647: return 0;
1648: }
1649: return canTakeAddressOf() &&
1650: (storage_class & (STCstatic | STCextern | STCtls | STCgshared) ||
1651: toParent()->isModule() ||
1652: toParent()->isTemplateInstance());
1653: }
1654:
1655: /************************************
1656: * Does symbol go into thread local storage?
1657: */
1658:
1659: int VarDeclaration::isThreadlocal()
1660: {
1661: //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars());
1662: #if 0 //|| TARGET_OSX
1663: /* To be thread-local, must use the __thread storage class.
1664: * BUG: OSX doesn't support thread local yet.
1665: */
1666: return isDataseg() &&
1667: (storage_class & (STCtls | STCconst | STCimmutable | STCshared | STCgshared)) == STCtls;
1668: #else
1669: /* Data defaults to being thread-local. It is not thread-local
1670: * if it is immutable, const or shared.
1671: */
1672: int i = isDataseg() &&
1673: !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared));
1674: //printf("\treturn %d\n", i);
1675: return i;
1676: #endif
1677: }
1678:
1679: /********************************************
1680: * Can variable be read and written by CTFE?
1681: */
1682:
1683: int VarDeclaration::isCTFE()
1684: {
1685: return (storage_class & STCctfe) != 0; // || !isDataseg();
1686: }
1687:
1688: int VarDeclaration::hasPointers()
1689: {
1690: //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1691: return (!isDataseg() && type->hasPointers());
1692: }
1693:
1694: /******************************************
1695: * Return TRUE if variable needs to call the destructor.
1696: */
1697:
1698: int VarDeclaration::needsAutoDtor()
1699: {
1700: //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1701:
1702: if (noscope || !edtor)
1703: return FALSE;
1704:
1705: return TRUE;
1706: }
1707:
1708:
1709: /******************************************
1710: * If a variable has a scope destructor call, return call for it.
1711: * Otherwise, return NULL.
1712: */
1713:
1714: Expression *VarDeclaration::callScopeDtor(Scope *sc)
1715: { Expression *e = NULL;
1716:
1717: //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
1718:
1719: // Destruction of STCfield's is handled by buildDtor()
1720: if (noscope || storage_class & (STCnodtor | STCref | STCout | STCfield))
1721: {
1722: return NULL;
1723: }
1724:
1725: // Destructors for structs and arrays of structs
1726: bool array = false;
1727: Type *tv = type->toBasetype();
1728: while (tv->ty == Tsarray)
1729: { TypeSArray *ta = (TypeSArray *)tv;
1730: array = true;
1731: tv = tv->nextOf()->toBasetype();
1732: }
1733: if (tv->ty == Tstruct)
1734: { TypeStruct *ts = (TypeStruct *)tv;
1735: StructDeclaration *sd = ts->sym;
1736: if (sd->dtor)
1737: {
1738: if (array)
1739: {
1740: // Typeinfo.destroy(cast(void*)&v);
1741: Expression *ea = new SymOffExp(loc, this, 0, 0);
1742: ea = new CastExp(loc, ea, Type::tvoid->pointerTo());
1743: Expressions *args = new Expressions();
1744: args->push(ea);
1745:
1746: Expression *et = type->getTypeInfo(sc);
1747: et = new DotIdExp(loc, et, Id::destroy);
1748:
1749: e = new CallExp(loc, et, args);
1750: }
1751: else
1752: {
1753: e = new VarExp(loc, this);
1754: /* This is a hack so we can call destructors on const/immutable objects.
1755: * Need to add things like "const ~this()" and "immutable ~this()" to
1756: * fix properly.
1757: */
1758: e->type = e->type->mutableOf();
1759: e = new DotVarExp(loc, e, sd->dtor, 0);
1760: e = new CallExp(loc, e);
1761: }
1762: return e;
1763: }
1764: }
1765:
1766: // Destructors for classes
1767: if (storage_class & (STCauto | STCscope))
1768: {
1769: for (ClassDeclaration *cd = type->isClassHandle();
1770: cd;
1771: cd = cd->baseClass)
1772: {
1773: /* We can do better if there's a way with onstack
1774: * classes to determine if there's no way the monitor
1775: * could be set.
1776: */
1777: //if (cd->isInterfaceDeclaration())
1778: //error("interface %s cannot be scope", cd->toChars());
1779: if (1 || onstack || cd->dtors.dim) // if any destructors
warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
1780: {
1781: // delete this;
1782: Expression *ec;
1783:
1784: ec = new VarExp(loc, this);
1785: e = new DeleteExp(loc, ec);
1786: e->type = Type::tvoid;
1787: break;
1788: }
1789: }
1790: }
1791: return e;
1792: }
1793:
1794:
1795: /********************************* ClassInfoDeclaration ****************************/
1796:
1797: ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
1798: : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
1799: {
1800: this->cd = cd;
1801: storage_class = STCstatic | STCgshared;
1802: }
1803:
1804: Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
1805: {
1806: assert(0); // should never be produced by syntax
1807: return NULL;
1808: }
1809:
1810: void ClassInfoDeclaration::semantic(Scope *sc)
1811: {
1812: }
1813:
1814: /********************************* ModuleInfoDeclaration ****************************/
1815:
1816: ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
1817: : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
1818: {
1819: this->mod = mod;
1820: storage_class = STCstatic | STCgshared;
1821: }
1822:
1823: Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
1824: {
1825: assert(0); // should never be produced by syntax
1826: return NULL;
1827: }
1828:
1829: void ModuleInfoDeclaration::semantic(Scope *sc)
1830: {
1831: }
1832:
1833: /********************************* TypeInfoDeclaration ****************************/
1834:
1835: TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
1836: : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
1837: {
1838: this->tinfo = tinfo;
1839: storage_class = STCstatic | STCgshared;
1840: protection = PROTpublic;
1841: linkage = LINKc;
1842: }
1843:
1844: Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
1845: {
1846: assert(0); // should never be produced by syntax
1847: return NULL;
1848: }
1849:
1850: void TypeInfoDeclaration::semantic(Scope *sc)
1851: {
1852: assert(linkage == LINKc);
1853: }
1854:
1855: /***************************** TypeInfoConstDeclaration **********************/
1856:
1857: #if DMDV2
1858: TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
1859: : TypeInfoDeclaration(tinfo, 0)
1860: {
1861: type = Type::typeinfoconst->type;
1862: }
1863: #endif
1864:
1865: /***************************** TypeInfoInvariantDeclaration **********************/
1866:
1867: #if DMDV2
1868: TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
1869: : TypeInfoDeclaration(tinfo, 0)
1870: {
1871: type = Type::typeinfoinvariant->type;
1872: }
1873: #endif
1874:
1875: /***************************** TypeInfoSharedDeclaration **********************/
1876:
1877: #if DMDV2
1878: TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
1879: : TypeInfoDeclaration(tinfo, 0)
1880: {
1881: type = Type::typeinfoshared->type;
1882: }
1883: #endif
1884:
1885: /***************************** TypeInfoWildDeclaration **********************/
1886:
1887: #if DMDV2
1888: TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo)
1889: : TypeInfoDeclaration(tinfo, 0)
1890: {
1891: type = Type::typeinfowild->type;
1892: }
1893: #endif
1894:
1895: /***************************** TypeInfoStructDeclaration **********************/
1896:
1897: TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
1898: : TypeInfoDeclaration(tinfo, 0)
1899: {
1900: type = Type::typeinfostruct->type;
1901: }
1902:
1903: /***************************** TypeInfoClassDeclaration ***********************/
1904:
1905: TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
1906: : TypeInfoDeclaration(tinfo, 0)
1907: {
1908: type = Type::typeinfoclass->type;
1909: }
1910:
1911: /***************************** TypeInfoInterfaceDeclaration *******************/
1912:
1913: TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
1914: : TypeInfoDeclaration(tinfo, 0)
1915: {
1916: type = Type::typeinfointerface->type;
1917: }
1918:
1919: /***************************** TypeInfoTypedefDeclaration *********************/
1920:
1921: TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
1922: : TypeInfoDeclaration(tinfo, 0)
1923: {
1924: type = Type::typeinfotypedef->type;
1925: }
1926:
1927: /***************************** TypeInfoPointerDeclaration *********************/
1928:
1929: TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
1930: : TypeInfoDeclaration(tinfo, 0)
1931: {
1932: type = Type::typeinfopointer->type;
1933: }
1934:
1935: /***************************** TypeInfoArrayDeclaration ***********************/
1936:
1937: TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
1938: : TypeInfoDeclaration(tinfo, 0)
1939: {
1940: type = Type::typeinfoarray->type;
1941: }
1942:
1943: /***************************** TypeInfoStaticArrayDeclaration *****************/
1944:
1945: TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
1946: : TypeInfoDeclaration(tinfo, 0)
1947: {
1948: type = Type::typeinfostaticarray->type;
1949: }
1950:
1951: /***************************** TypeInfoAssociativeArrayDeclaration ************/
1952:
1953: TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
1954: : TypeInfoDeclaration(tinfo, 0)
1955: {
1956: type = Type::typeinfoassociativearray->type;
1957: }
1958:
1959: /***************************** TypeInfoEnumDeclaration ***********************/
1960:
1961: TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
1962: : TypeInfoDeclaration(tinfo, 0)
1963: {
1964: type = Type::typeinfoenum->type;
1965: }
1966:
1967: /***************************** TypeInfoFunctionDeclaration ********************/
1968:
1969: TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
1970: : TypeInfoDeclaration(tinfo, 0)
1971: {
1972: type = Type::typeinfofunction->type;
1973: }
1974:
1975: /***************************** TypeInfoDelegateDeclaration ********************/
1976:
1977: TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
1978: : TypeInfoDeclaration(tinfo, 0)
1979: {
1980: type = Type::typeinfodelegate->type;
1981: }
1982:
1983: /***************************** TypeInfoTupleDeclaration **********************/
1984:
1985: TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
1986: : TypeInfoDeclaration(tinfo, 0)
1987: {
1988: type = Type::typeinfotypelist->type;
1989: }
1990:
1991: /********************************* ThisDeclaration ****************************/
1992:
1993: // For the "this" parameter to member functions
1994:
1995: ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
1996: : VarDeclaration(loc, t, Id::This, NULL)
1997: {
1998: noscope = 1;
1999: }
2000:
2001: Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
2002: {
2003: assert(0); // should never be produced by syntax
2004: return NULL;
2005: }
2006:
2007: