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 "mars.h"
16: #include "init.h"
17: #include "expression.h"
18: #include "statement.h"
19: #include "identifier.h"
20: #include "declaration.h"
21: #include "aggregate.h"
22: #include "scope.h"
23: #include "mtype.h"
24: #include "hdrgen.h"
25:
26: /********************************** Initializer *******************************/
27:
28: Initializer::Initializer(Loc loc)
29: {
30: this->loc = loc;
31: }
32:
33: Initializer *Initializer::syntaxCopy()
34: {
35: return this;
36: }
37:
38: Initializer *Initializer::semantic(Scope *sc, Type *t, int needInterpret)
39: {
40: return this;
41: }
42:
43: Type *Initializer::inferType(Scope *sc)
44: {
45: error(loc, "cannot infer type from initializer");
46: return Type::terror;
47: }
48:
49: Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
50: { Initializers *a = NULL;
51:
52: if (ai)
53: {
54: a = new Initializers();
55: a->setDim(ai->dim);
56: for (int i = 0; i < a->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
57: { Initializer *e = ai->tdata()[i];
58:
59: e = e->syntaxCopy();
60: a->tdata()[i] = e;
61: }
62: }
63: return a;
64: }
65:
66: char *Initializer::toChars()
67: { OutBuffer *buf;
68: HdrGenState hgs;
69:
70: memset(&hgs, 0, sizeof(hgs));
71: buf = new OutBuffer();
72: toCBuffer(buf, &hgs);
73: return buf->toChars();
74: }
75:
76: /********************************** VoidInitializer ***************************/
77:
78: VoidInitializer::VoidInitializer(Loc loc)
79: : Initializer(loc)
80: {
81: type = NULL;
82: }
83:
84:
85: Initializer *VoidInitializer::syntaxCopy()
86: {
87: return new VoidInitializer(loc);
88: }
89:
90:
91: Initializer *VoidInitializer::semantic(Scope *sc, Type *t, int needInterpret)
92: {
93: //printf("VoidInitializer::semantic(t = %p)\n", t);
94: type = t;
95: return this;
96: }
97:
98:
99: Expression *VoidInitializer::toExpression()
100: {
101: error(loc, "void initializer has no value");
102: return new IntegerExp(0);
103: }
104:
105:
106: void VoidInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
107: {
108: buf->writestring("void");
109: }
110:
111:
112: /********************************** StructInitializer *************************/
113:
114: StructInitializer::StructInitializer(Loc loc)
115: : Initializer(loc)
116: {
117: ad = NULL;
118: }
119:
120: Initializer *StructInitializer::syntaxCopy()
121: {
122: StructInitializer *ai = new StructInitializer(loc);
123:
124: assert(field.dim == value.dim);
125: ai->field.setDim(field.dim);
126: ai->value.setDim(value.dim);
127: for (int i = 0; i < field.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
128: {
129: ai->field.tdata()[i] = field.tdata()[i];
130:
131: Initializer *init = value.tdata()[i];
132: init = init->syntaxCopy();
133: ai->value.tdata()[i] = init;
134: }
135: return ai;
136: }
137:
138: void StructInitializer::addInit(Identifier *field, Initializer *value)
139: {
140: //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
141: this->field.push(field);
142: this->value.push(value);
143: }
144:
145: Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
146: {
147: int errors = 0;
148:
149: //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
150: vars.setDim(field.dim);
151: t = t->toBasetype();
152: if (t->ty == Tstruct)
153: {
154: unsigned fieldi = 0;
155:
156: TypeStruct *ts = (TypeStruct *)t;
157: ad = ts->sym;
158: if (ad->ctor)
159: error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
160: ad->kind(), ad->toChars(), ad->toChars());
161: int nfields = ad->fields.dim;
162: if (((StructDeclaration *)ad)->isnested) nfields--;
163: for (size_t i = 0; i < field.dim; i++)
164: {
165: Identifier *id = field.tdata()[i];
166: Initializer *val = value.tdata()[i];
167: Dsymbol *s;
168: VarDeclaration *v;
169:
170: if (id == NULL)
171: {
172: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
173: { error(loc, "too many initializers for %s", ad->toChars());
174: errors = 1;
175: field.remove(i);
176: i--;
177: continue;
178: }
179: else
180: {
181: s = ad->fields.tdata()[fieldi];
182: }
183: }
184: else
185: {
186: //s = ad->symtab->lookup(id);
187: s = ad->search(loc, id, 0);
188: if (!s)
189: {
190: error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
191: errors = 1;
192: continue;
193: }
194:
195: // Find out which field index it is
196: for (fieldi = 0; 1; fieldi++)
197: {
198: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
199: {
200: error(loc, "%s.%s is not a per-instance initializable field",
201: t->toChars(), s->toChars());
202: errors = 1;
203: break;
204: }
205: if (s == ad->fields.tdata()[fieldi])
206: break;
207: }
208: }
209: if (s && (v = s->isVarDeclaration()) != NULL)
210: {
211: val = val->semantic(sc, v->type, needInterpret);
212: value.tdata()[i] = val;
213: vars.tdata()[i] = v;
214: }
215: else
216: { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
warning C6011: Dereferencing NULL pointer 's': Lines: 147, 150, 151, 152, 154, 156, 157, 158, 159, 161, 162, 163, 165, 166, 167, 168, 170, 187, 188, 190, 191, 163, 165, 166, 167, 168, 170, 172, 181, 209, 216
217: errors = 1;
218: }
219: fieldi++;
220: }
221: }
222: else if (t->ty == Tdelegate && value.dim == 0)
223: { /* Rewrite as empty delegate literal { }
224: */
225: Parameters *arguments = new Parameters;
226: Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
227: FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL);
228: fd->fbody = new CompoundStatement(loc, new Statements());
229: fd->endloc = loc;
230: Expression *e = new FuncExp(loc, fd);
231: ExpInitializer *ie = new ExpInitializer(loc, e);
232: return ie->semantic(sc, t, needInterpret);
233: }
234: else
235: {
236: error(loc, "a struct is not a valid initializer for a %s", t->toChars());
237: errors = 1;
238: }
239: if (errors)
240: {
241: field.setDim(0);
242: value.setDim(0);
243: vars.setDim(0);
244: }
245: return this;
246: }
247:
248: /***************************************
249: * This works by transforming a struct initializer into
250: * a struct literal. In the future, the two should be the
251: * same thing.
252: */
253: Expression *StructInitializer::toExpression()
254: { Expression *e;
255: size_t offset;
256:
257: //printf("StructInitializer::toExpression() %s\n", toChars());
258: if (!ad) // if fwd referenced
259: {
260: return NULL;
261: }
262: StructDeclaration *sd = ad->isStructDeclaration();
263: if (!sd)
264: return NULL;
265: Expressions *elements = new Expressions();
266: int nfields = ad->fields.dim;
267: if (sd->isnested) nfields--;
268: elements->setDim(nfields);
269: for (int i = 0; i < elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
270: {
271: elements->tdata()[i] = NULL;
272: }
273: unsigned fieldi = 0;
274: for (int i = 0; i < value.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
275: {
276: Identifier *id = field.tdata()[i];
277: if (id)
278: {
279: Dsymbol * s = ad->search(loc, id, 0);
280: if (!s)
281: {
282: error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
283: goto Lno;
284: }
285:
286: // Find out which field index it is
287: for (fieldi = 0; 1; fieldi++)
288: {
289: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
290: {
291: s->error("is not a per-instance initializable field");
292: goto Lno;
293: }
294: if (s == ad->fields.tdata()[fieldi])
295: break;
296: }
297: }
298: else if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
299: { error(loc, "too many initializers for '%s'", ad->toChars());
300: goto Lno;
301: }
302: Initializer *iz = value.tdata()[i];
303: if (!iz)
304: goto Lno;
305: Expression *ex = iz->toExpression();
306: if (!ex)
307: goto Lno;
308: if (elements->tdata()[fieldi])
309: { error(loc, "duplicate initializer for field '%s'",
310: ad->fields.tdata()[fieldi]->toChars());
311: goto Lno;
312: }
313: elements->tdata()[fieldi] = ex;
314: ++fieldi;
315: }
316: // Now, fill in any missing elements with default initializers.
317: // We also need to validate any anonymous unions
318: offset = 0;
319: for (int i = 0; i < elements->dim; )
warning C4018: '<' : signed/unsigned mismatch
320: {
321: VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration();
322:
323: //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
324: if (vd->offset < offset)
325: {
326: // Only the first field of a union can have an initializer
327: if (elements->tdata()[i])
328: goto Lno;
329: }
330: else
331: {
332: if (!elements->tdata()[i])
333: // Default initialize
334: elements->tdata()[i] = vd->type->defaultInit();
335: }
336: offset = vd->offset + vd->type->size();
warning C4244: '=' : conversion from 'd_uns64' to 'size_t', possible loss of data
337: i++;
338: #if 0
339: int unionSize = ad->numFieldsInUnion(i);
340: if (unionSize == 1)
341: { // Not a union -- default initialize if missing
342: if (!elements->tdata()[i])
343: elements->tdata()[i] = vd->type->defaultInit();
344: }
345: else
346: { // anonymous union -- check for errors
347: int found = -1; // index of the first field with an initializer
348: for (int j = i; j < i + unionSize; ++j)
349: {
350: if (!elements->tdata()[j])
351: continue;
352: if (found >= 0)
353: {
354: VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration();
355: VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration();
356: error(loc, "%s cannot have initializers for fields %s and %s in same union",
357: ad->toChars(),
358: v1->toChars(), v->toChars());
359: goto Lno;
360: }
361: found = j;
362: }
363: if (found == -1)
364: {
365: error(loc, "no initializer for union that contains field %s",
366: vd->toChars());
367: goto Lno;
368: }
369: }
370: i += unionSize;
371: #endif
372: }
373: e = new StructLiteralExp(loc, sd, elements);
374: e->type = sd->type;
375: return e;
376:
377: Lno:
378: delete elements;
379: return NULL;
380: }
381:
382:
383: void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
384: {
385: //printf("StructInitializer::toCBuffer()\n");
386: buf->writebyte('{');
387: for (int i = 0; i < field.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
388: {
389: if (i > 0)
390: buf->writebyte(',');
391: Identifier *id = field.tdata()[i];
392: if (id)
393: {
394: buf->writestring(id->toChars());
395: buf->writebyte(':');
396: }
397: Initializer *iz = value.tdata()[i];
398: if (iz)
399: iz->toCBuffer(buf, hgs);
400: }
401: buf->writebyte('}');
402: }
403:
404: /********************************** ArrayInitializer ************************************/
405:
406: ArrayInitializer::ArrayInitializer(Loc loc)
407: : Initializer(loc)
408: {
409: dim = 0;
410: type = NULL;
411: sem = 0;
412: }
413:
414: Initializer *ArrayInitializer::syntaxCopy()
415: {
416: //printf("ArrayInitializer::syntaxCopy()\n");
417:
418: ArrayInitializer *ai = new ArrayInitializer(loc);
419:
420: assert(index.dim == value.dim);
421: ai->index.setDim(index.dim);
422: ai->value.setDim(value.dim);
423: for (int i = 0; i < ai->value.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
424: { Expression *e = index.tdata()[i];
425: if (e)
426: e = e->syntaxCopy();
427: ai->index.tdata()[i] = e;
428:
429: Initializer *init = value.tdata()[i];
430: init = init->syntaxCopy();
431: ai->value.tdata()[i] = init;
432: }
433: return ai;
434: }
435:
436: void ArrayInitializer::addInit(Expression *index, Initializer *value)
437: {
438: this->index.push(index);
439: this->value.push(value);
440: dim = 0;
441: type = NULL;
442: }
443:
444: Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
445: { unsigned i;
446: unsigned length;
447: const unsigned amax = 0x80000000;
448:
449: //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
450: if (sem) // if semantic() already run
451: return this;
452: sem = 1;
453: type = t;
454: t = t->toBasetype();
455: switch (t->ty)
456: {
457: case Tpointer:
458: case Tsarray:
459: case Tarray:
460: break;
461:
462: default:
463: error(loc, "cannot use array to initialize %s", type->toChars());
464: goto Lerr;
465: }
466:
467: length = 0;
468: for (i = 0; i < index.dim; i++)
469: {
470: Expression *idx = index.tdata()[i];
471: if (idx)
472: { idx = idx->semantic(sc);
473: idx = idx->optimize(WANTvalue | WANTinterpret);
474: index.tdata()[i] = idx;
475: length = idx->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
476: }
477:
478: Initializer *val = value.tdata()[i];
479: val = val->semantic(sc, t->nextOf(), needInterpret);
480: value.tdata()[i] = val;
481: length++;
482: if (length == 0)
483: { error(loc, "array dimension overflow");
484: goto Lerr;
485: }
486: if (length > dim)
487: dim = length;
488: }
489: if (t->ty == Tsarray)
490: {
491: dinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
492: if (dim > edim)
493: {
494: error(loc, "array initializer has %u elements, but array length is %jd", dim, edim);
495: goto Lerr;
496: }
497: }
498:
499: if ((unsigned long) dim * t->nextOf()->size() >= amax)
500: { error(loc, "array dimension %u exceeds max of %u", dim, amax / t->nextOf()->size());
501: goto Lerr;
502: }
503: return this;
504:
505: Lerr:
506: return new ExpInitializer(loc, new ErrorExp());
507: }
508:
509: /********************************
510: * If possible, convert array initializer to array literal.
511: * Otherwise return NULL.
512: */
513:
514: Expression *ArrayInitializer::toExpression()
515: { Expressions *elements;
516: Expression *e;
warning C4101: 'e' : unreferenced local variable
517:
518: //printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
519: //static int i; if (++i == 2) halt();
520:
521: size_t edim;
522: Type *t = NULL;
523: if (type)
524: {
525: if (type == Type::terror)
526: return new ErrorExp();
527:
528: t = type->toBasetype();
529: switch (t->ty)
530: {
531: case Tsarray:
532: edim = ((TypeSArray *)t)->dim->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
533: break;
534:
535: case Tpointer:
536: case Tarray:
537: edim = dim;
538: break;
539:
540: default:
541: assert(0);
542: }
543: }
544: else
545: {
546: edim = value.dim;
547: for (size_t i = 0, j = 0; i < value.dim; i++, j++)
548: {
549: if (index.tdata()[i])
550: j = index.tdata()[i]->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
551: if (j >= edim)
552: edim = j + 1;
553: }
554: }
555:
556: elements = new Expressions();
557: elements->setDim(edim);
558: elements->zero();
559: for (size_t i = 0, j = 0; i < value.dim; i++, j++)
560: {
561: if (index.tdata()[i])
562: j = (index.tdata()[i])->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
563: assert(j < edim);
564: Initializer *iz = value.tdata()[i];
565: if (!iz)
566: goto Lno;
567: Expression *ex = iz->toExpression();
568: if (!ex)
569: {
570: goto Lno;
571: }
572: elements->tdata()[j] = ex;
573: }
574:
575: /* Fill in any missing elements with the default initializer
576: */
577: {
578: Expression *init = NULL;
579: for (size_t i = 0; i < edim; i++)
580: {
581: if (!elements->tdata()[i])
582: {
583: if (!type)
584: goto Lno;
585: if (!init)
586: init = ((TypeNext *)t)->next->defaultInit();
587: elements->tdata()[i] = init;
588: }
589: }
590:
591: Expression *e = new ArrayLiteralExp(loc, elements);
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '516' of 'c:\projects\extern\d\dmd\src\init.c': Lines: 516
592: e->type = type;
593: return e;
594: }
595:
596: Lno:
597: return NULL;
598: }
599:
600:
601: /********************************
602: * If possible, convert array initializer to associative array initializer.
603: */
604:
605: Expression *ArrayInitializer::toAssocArrayLiteral()
606: {
607: Expression *e;
608:
609: //printf("ArrayInitializer::toAssocArrayInitializer()\n");
610: //static int i; if (++i == 2) halt();
611: Expressions *keys = new Expressions();
warning C6211: Leaking memory 'keys' due to an exception. Consider using a local catch block to clean up memory: Lines: 607, 611, 612, 613
612: keys->setDim(value.dim);
613: Expressions *values = new Expressions();
614: values->setDim(value.dim);
615:
616: for (size_t i = 0; i < value.dim; i++)
617: {
618: e = index.tdata()[i];
619: if (!e)
620: goto Lno;
621: keys->tdata()[i] = e;
622:
623: Initializer *iz = value.tdata()[i];
624: if (!iz)
625: goto Lno;
626: e = iz->toExpression();
627: if (!e)
628: goto Lno;
629: values->tdata()[i] = e;
630: }
631: e = new AssocArrayLiteralExp(loc, keys, values);
632: return e;
633:
634: Lno:
635: delete keys;
636: delete values;
637: error(loc, "not an associative array initializer");
638: return new ErrorExp();
639: }
640:
641: int ArrayInitializer::isAssociativeArray()
642: {
643: for (size_t i = 0; i < value.dim; i++)
644: {
645: if (index.tdata()[i])
646: return 1;
647: }
648: return 0;
649: }
650:
651: Type *ArrayInitializer::inferType(Scope *sc)
652: {
653: //printf("ArrayInitializer::inferType() %s\n", toChars());
654: assert(0);
655: return NULL;
656: #if 0
657: type = Type::terror;
658: for (size_t i = 0; i < value.dim; i++)
659: {
660: if (index.data[i])
661: goto Laa;
662: }
663: for (size_t i = 0; i < value.dim; i++)
664: {
665: Initializer *iz = (Initializer *)value.data[i];
666: if (iz)
667: { Type *t = iz->inferType(sc);
668: if (i == 0)
669: { /* BUG: This gets the type from the first element.
670: * Fix to use all the elements to figure out the type.
671: */
672: t = new TypeSArray(t, new IntegerExp(value.dim));
673: t = t->semantic(loc, sc);
674: type = t;
675: }
676: }
677: }
678: return type;
679:
680: Laa:
681: /* It's possibly an associative array initializer.
682: * BUG: inferring type from first member.
683: */
684: Initializer *iz = (Initializer *)value.data[0];
685: Expression *indexinit = (Expression *)index.data[0];
686: if (iz && indexinit)
687: { Type *t = iz->inferType(sc);
688: indexinit = indexinit->semantic(sc);
689: Type *indext = indexinit->type;
690: t = new TypeAArray(t, indext);
691: type = t->semantic(loc, sc);
692: }
693: else
694: error(loc, "cannot infer type from this array initializer");
695: return type;
696: #endif
697: }
698:
699:
700: void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
701: {
702: buf->writebyte('[');
703: for (int i = 0; i < index.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
704: {
705: if (i > 0)
706: buf->writebyte(',');
707: Expression *ex = index.tdata()[i];
708: if (ex)
709: {
710: ex->toCBuffer(buf, hgs);
711: buf->writebyte(':');
712: }
713: Initializer *iz = value.tdata()[i];
714: if (iz)
715: iz->toCBuffer(buf, hgs);
716: }
717: buf->writebyte(']');
718: }
719:
720:
721: /********************************** ExpInitializer ************************************/
722:
723: ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
724: : Initializer(loc)
725: {
726: this->exp = exp;
727: }
728:
729: Initializer *ExpInitializer::syntaxCopy()
730: {
731: return new ExpInitializer(loc, exp->syntaxCopy());
732: }
733:
734: bool arrayHasNonConstPointers(Expressions *elems);
735:
736: bool hasNonConstPointers(Expression *e)
737: {
738: if (e->op == TOKnull)
739: return false;
740: if (e->op == TOKstructliteral)
741: {
742: StructLiteralExp *se = (StructLiteralExp *)e;
743: return arrayHasNonConstPointers(se->elements);
744: }
745: if (e->op == TOKarrayliteral)
746: {
747: if (!e->type->nextOf()->hasPointers())
748: return false;
749: ArrayLiteralExp *ae = (ArrayLiteralExp *)e;
750: return arrayHasNonConstPointers(ae->elements);
751: }
752: if (e->op == TOKassocarrayliteral)
753: {
754: AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e;
755: if (ae->type->nextOf()->hasPointers() &&
756: arrayHasNonConstPointers(ae->values))
757: return true;
758: if (((TypeAArray *)ae->type)->index->hasPointers())
759: return arrayHasNonConstPointers(ae->keys);
760: return false;
761: }
762: if (e->type->ty== Tpointer && e->type->nextOf()->ty != Tfunction)
763: {
764: if (e->op == TOKsymoff) // address of a global is OK
765: return false;
766: if (e->op == TOKint64) // cast(void *)int is OK
767: return false;
768: if (e->op == TOKstring) // "abc".ptr is OK
769: return false;
770: return true;
771: }
772: return false;
773: }
774:
775: bool arrayHasNonConstPointers(Expressions *elems)
776: {
777: for (size_t i = 0; i < elems->dim; i++)
778: {
779: if (!elems->tdata()[i])
780: continue;
781: if (hasNonConstPointers(elems->tdata()[i]))
782: return true;
783: }
784: return false;
785: }
786:
787:
788:
789: Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
790: {
791: //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
792: exp = exp->semantic(sc);
793: exp = resolveProperties(sc, exp);
794: int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue;
795:
796: int olderrors = global.errors;
797: exp = exp->optimize(wantOptimize);
798: if (!global.gag && olderrors != global.errors)
799: return this; // Failed, suppress duplicate error messages
800:
801: // Make sure all pointers are constants
802: if (needInterpret && hasNonConstPointers(exp))
803: {
804: exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars());
805: return this;
806: }
807:
808: Type *tb = t->toBasetype();
809:
810: /* Look for case of initializing a static array with a too-short
811: * string literal, such as:
812: * char[5] foo = "abc";
813: * Allow this by doing an explicit cast, which will lengthen the string
814: * literal.
815: */
816: if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray)
817: { StringExp *se = (StringExp *)exp;
818:
819: if (!se->committed && se->type->ty == Tsarray &&
820: ((TypeSArray *)se->type)->dim->toInteger() <
821: ((TypeSArray *)t)->dim->toInteger())
822: {
823: exp = se->castTo(sc, t);
824: goto L1;
825: }
826: }
827:
828: // Look for the case of statically initializing an array
829: // with a single member.
830: if (tb->ty == Tsarray &&
831: !tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
832: exp->implicitConvTo(tb->nextOf())
833: )
834: {
835: t = tb->nextOf();
836: }
837:
838: exp = exp->implicitCastTo(sc, t);
839: L1:
840: exp = exp->optimize(wantOptimize);
841: //printf("-ExpInitializer::semantic(): "); exp->print();
842: return this;
843: }
844:
845: Type *ExpInitializer::inferType(Scope *sc)
846: {
847: //printf("ExpInitializer::inferType() %s\n", toChars());
848: exp = exp->semantic(sc);
849: exp = resolveProperties(sc, exp);
850:
851: // Give error for overloaded function addresses
852: if (exp->op == TOKsymoff)
853: { SymOffExp *se = (SymOffExp *)exp;
854: if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
855: exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
856: }
857:
858: // Give error for overloaded function addresses
859: if (exp->op == TOKdelegate)
860: { DelegateExp *se = (DelegateExp *)exp;
861: if (
862: se->func->isFuncDeclaration() &&
863: !se->func->isFuncDeclaration()->isUnique())
864: exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
865: }
866:
867: Type *t = exp->type;
868: if (!t)
869: t = Initializer::inferType(sc);
870: return t;
871: }
872:
873: Expression *ExpInitializer::toExpression()
874: {
875: return exp;
876: }
877:
878:
879: void ExpInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
880: {
881: exp->toCBuffer(buf, hgs);
882: }
883:
884:
885:
886: