xref: /netbsd/external/gpl3/gcc/dist/gcc/d/dmd/initsem.c (revision 81418a27)
1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  */
9 
10 #include "root/checkedint.h"
11 #include "mars.h"
12 #include "init.h"
13 #include "expression.h"
14 #include "statement.h"
15 #include "declaration.h"
16 #include "aggregate.h"
17 #include "scope.h"
18 #include "mtype.h"
19 #include "template.h"
20 #include "id.h"
21 
22 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
23 Expression *semantic(Expression *e, Scope *sc);
24 Initializer *inferType(Initializer *init, Scope *sc);
25 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
26 bool hasNonConstPointers(Expression *e);
27 
28 class InitializerSemanticVisitor : public Visitor
29 {
30 public:
31     Initializer *result;
32     Scope *sc;
33     Type *t;
34     NeedInterpret needInterpret;
35 
InitializerSemanticVisitor(Scope * sc,Type * t,NeedInterpret needInterpret)36     InitializerSemanticVisitor(Scope *sc, Type *t, NeedInterpret needInterpret)
37     {
38         this->result = NULL;
39         this->sc = sc;
40         this->t = t;
41         this->needInterpret = needInterpret;
42     }
43 
visit(ErrorInitializer * i)44     void visit(ErrorInitializer *i)
45     {
46         //printf("ErrorInitializer::semantic(t = %p)\n", t);
47         result = i;
48     }
49 
visit(VoidInitializer * i)50     void visit(VoidInitializer *i)
51     {
52         //printf("VoidInitializer::semantic(t = %p)\n", t);
53         i->type = t;
54         result = i;
55     }
56 
visit(StructInitializer * i)57     void visit(StructInitializer *i)
58     {
59         //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
60         t = t->toBasetype();
61         if (t->ty == Tsarray && t->nextOf()->toBasetype()->ty == Tstruct)
62             t = t->nextOf()->toBasetype();
63         if (t->ty == Tstruct)
64         {
65             StructDeclaration *sd = ((TypeStruct *)t)->sym;
66             if (sd->ctor)
67             {
68                 error(i->loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
69                       sd->kind(), sd->toChars(), sd->toChars());
70                 result = new ErrorInitializer();
71                 return;
72             }
73             sd->size(i->loc);
74             if (sd->sizeok != SIZEOKdone)
75             {
76                 result = new ErrorInitializer();
77                 return;
78             }
79             size_t nfields = sd->fields.dim - sd->isNested();
80 
81             //expandTuples for non-identity arguments?
82 
83             Expressions *elements = new Expressions();
84             elements->setDim(nfields);
85             for (size_t j = 0; j < elements->dim; j++)
86                 (*elements)[j] = NULL;
87 
88             // Run semantic for explicitly given initializers
89             // TODO: this part is slightly different from StructLiteralExp::semantic.
90             bool errors = false;
91             for (size_t fieldi = 0, j = 0; j < i->field.dim; j++)
92             {
93                 if (Identifier *id = i->field[j])
94                 {
95                     Dsymbol *s = sd->search(i->loc, id);
96                     if (!s)
97                     {
98                         s = sd->search_correct(id);
99                         if (s)
100                             error(i->loc, "'%s' is not a member of '%s', did you mean %s '%s'?",
101                                   id->toChars(), sd->toChars(), s->kind(), s->toChars());
102                         else
103                             error(i->loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
104                         result = new ErrorInitializer();
105                         return;
106                     }
107                     s = s->toAlias();
108 
109                     // Find out which field index it is
110                     for (fieldi = 0; 1; fieldi++)
111                     {
112                         if (fieldi >= nfields)
113                         {
114                             error(i->loc, "%s.%s is not a per-instance initializable field",
115                                   sd->toChars(), s->toChars());
116                             result = new ErrorInitializer();
117                             return;
118                         }
119                         if (s == sd->fields[fieldi])
120                             break;
121                     }
122                 }
123                 else if (fieldi >= nfields)
124                 {
125                     error(i->loc, "too many initializers for %s", sd->toChars());
126                     result = new ErrorInitializer();
127                     return;
128                 }
129 
130                 VarDeclaration *vd = sd->fields[fieldi];
131                 if ((*elements)[fieldi])
132                 {
133                     error(i->loc, "duplicate initializer for field '%s'", vd->toChars());
134                     errors = true;
135                     continue;
136                 }
137                 for (size_t k = 0; k < nfields; k++)
138                 {
139                     VarDeclaration *v2 = sd->fields[k];
140                     if (vd->isOverlappedWith(v2) && (*elements)[k])
141                     {
142                         error(i->loc, "overlapping initialization for field %s and %s",
143                               v2->toChars(), vd->toChars());
144                         errors = true;
145                         continue;
146                     }
147                 }
148 
149                 assert(sc);
150                 Initializer *iz = i->value[j];
151                 iz = ::semantic(iz, sc, vd->type->addMod(t->mod), needInterpret);
152                 Expression *ex = initializerToExpression(iz);
153                 if (ex->op == TOKerror)
154                 {
155                     errors = true;
156                     continue;
157                 }
158                 i->value[j] = iz;
159                 (*elements)[fieldi] = doCopyOrMove(sc, ex);
160                 ++fieldi;
161             }
162             if (errors)
163             {
164                 result = new ErrorInitializer();
165                 return;
166             }
167 
168             StructLiteralExp *sle = new StructLiteralExp(i->loc, sd, elements, t);
169             if (!sd->fill(i->loc, elements, false))
170             {
171                 result = new ErrorInitializer();
172                 return;
173             }
174             sle->type = t;
175 
176             ExpInitializer *ie = new ExpInitializer(i->loc, sle);
177             result = ::semantic(ie, sc, t, needInterpret);
178             return;
179         }
180         else if ((t->ty == Tdelegate || (t->ty == Tpointer && t->nextOf()->ty == Tfunction)) && i->value.dim == 0)
181         {
182             TOK tok = (t->ty == Tdelegate) ? TOKdelegate : TOKfunction;
183             /* Rewrite as empty delegate literal { }
184             */
185             Parameters *parameters = new Parameters;
186             Type *tf = new TypeFunction(parameters, NULL, 0, LINKd);
187             FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(i->loc, Loc(), tf, tok, NULL);
188             fd->fbody = new CompoundStatement(i->loc, new Statements());
189             fd->endloc = i->loc;
190             Expression *e = new FuncExp(i->loc, fd);
191             ExpInitializer *ie = new ExpInitializer(i->loc, e);
192             result = ::semantic(ie, sc, t, needInterpret);
193             return;
194         }
195 
196         error(i->loc, "a struct is not a valid initializer for a %s", t->toChars());
197         result = new ErrorInitializer();
198     }
199 
visit(ArrayInitializer * i)200     void visit(ArrayInitializer *i)
201     {
202         unsigned length;
203         const unsigned amax = 0x80000000;
204         bool errors = false;
205 
206         //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
207         if (i->sem)                            // if semantic() already run
208         {
209             result = i;
210             return;
211         }
212         i->sem = true;
213         t = t->toBasetype();
214         switch (t->ty)
215         {
216             case Tsarray:
217             case Tarray:
218                 break;
219 
220             case Tvector:
221                 t = ((TypeVector *)t)->basetype;
222                 break;
223 
224             case Taarray:
225             case Tstruct:   // consider implicit constructor call
226                 {
227                     Expression *e;
228                     // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])
229                     if (t->ty == Taarray || i->isAssociativeArray())
230                         e = i->toAssocArrayLiteral();
231                     else
232                         e = initializerToExpression(i);
233                     if (!e) // Bugzilla 13987
234                     {
235                         error(i->loc, "cannot use array to initialize %s", t->toChars());
236                         goto Lerr;
237                     }
238                     ExpInitializer *ei = new ExpInitializer(e->loc, e);
239                     result = ::semantic(ei, sc, t, needInterpret);
240                     return;
241                 }
242             case Tpointer:
243                 if (t->nextOf()->ty != Tfunction)
244                     break;
245                 /* fall through */
246 
247             default:
248                 error(i->loc, "cannot use array to initialize %s", t->toChars());
249                 goto Lerr;
250         }
251 
252         i->type = t;
253 
254         length = 0;
255         for (size_t j = 0; j < i->index.dim; j++)
256         {
257             Expression *idx = i->index[j];
258             if (idx)
259             {
260                 sc = sc->startCTFE();
261                 idx = ::semantic(idx, sc);
262                 sc = sc->endCTFE();
263                 idx = idx->ctfeInterpret();
264                 i->index[j] = idx;
265                 const uinteger_t idxvalue = idx->toInteger();
266                 if (idxvalue >= amax)
267                 {
268                     error(i->loc, "array index %llu overflow", (ulonglong)idxvalue);
269                     errors = true;
270                 }
271                 length = (unsigned)idx->toInteger();
272                 if (idx->op == TOKerror)
273                     errors = true;
274             }
275 
276             Initializer *val = i->value[j];
277             ExpInitializer *ei = val->isExpInitializer();
278             if (ei && !idx)
279                 ei->expandTuples = true;
280             val = ::semantic(val, sc, t->nextOf(), needInterpret);
281             if (val->isErrorInitializer())
282                 errors = true;
283 
284             ei = val->isExpInitializer();
285             // found a tuple, expand it
286             if (ei && ei->exp->op == TOKtuple)
287             {
288                 TupleExp *te = (TupleExp *)ei->exp;
289                 i->index.remove(j);
290                 i->value.remove(j);
291 
292                 for (size_t k = 0; k < te->exps->dim; ++k)
293                 {
294                     Expression *e = (*te->exps)[k];
295                     i->index.insert(j + k, (Expression *)NULL);
296                     i->value.insert(j + k, new ExpInitializer(e->loc, e));
297                 }
298                 j--;
299                 continue;
300             }
301             else
302             {
303                 i->value[j] = val;
304             }
305 
306             length++;
307             if (length == 0)
308             {
309                 error(i->loc, "array dimension overflow");
310                 goto Lerr;
311             }
312             if (length > i->dim)
313                 i->dim = length;
314         }
315         if (t->ty == Tsarray)
316         {
317             uinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
318             if (i->dim > edim)
319             {
320                 error(i->loc, "array initializer has %u elements, but array length is %llu", i->dim, (ulonglong)edim);
321                 goto Lerr;
322             }
323         }
324         if (errors)
325             goto Lerr;
326         else
327         {
328             d_uns64 sz = t->nextOf()->size();
329             bool overflow = false;
330             const d_uns64 max = mulu((d_uns64)i->dim, sz, overflow);
331             if (overflow || max > amax)
332             {
333                 error(i->loc, "array dimension %llu exceeds max of %llu", (ulonglong)i->dim, (ulonglong)(amax / sz));
334                 goto Lerr;
335             }
336             result = i;
337             return;
338         }
339 
340     Lerr:
341         result = new ErrorInitializer();
342     }
343 
visit(ExpInitializer * i)344     void visit(ExpInitializer *i)
345     {
346         //printf("ExpInitializer::semantic(%s), type = %s\n", i->exp->toChars(), t->toChars());
347         if (needInterpret) sc = sc->startCTFE();
348         i->exp = ::semantic(i->exp, sc);
349         i->exp = resolveProperties(sc, i->exp);
350         if (needInterpret) sc = sc->endCTFE();
351         if (i->exp->op == TOKerror)
352         {
353             result = new ErrorInitializer();
354             return;
355         }
356 
357         unsigned int olderrors = global.errors;
358         if (needInterpret)
359         {
360             // If the result will be implicitly cast, move the cast into CTFE
361             // to avoid premature truncation of polysemous types.
362             // eg real [] x = [1.1, 2.2]; should use real precision.
363             if (i->exp->implicitConvTo(t))
364             {
365                 i->exp = i->exp->implicitCastTo(sc, t);
366             }
367             if (!global.gag && olderrors != global.errors)
368             {
369                 result = i;
370                 return;
371             }
372             i->exp = i->exp->ctfeInterpret();
373         }
374         else
375         {
376             i->exp = i->exp->optimize(WANTvalue);
377         }
378         if (!global.gag && olderrors != global.errors)
379         {
380             result = i; // Failed, suppress duplicate error messages
381             return;
382         }
383 
384         if (i->exp->type->ty == Ttuple && ((TypeTuple *)i->exp->type)->arguments->dim == 0)
385         {
386             Type *et = i->exp->type;
387             i->exp = new TupleExp(i->exp->loc, new Expressions());
388             i->exp->type = et;
389         }
390         if (i->exp->op == TOKtype)
391         {
392             i->exp->error("initializer must be an expression, not '%s'", i->exp->toChars());
393             result = new ErrorInitializer();
394             return;
395         }
396 
397         // Make sure all pointers are constants
398         if (needInterpret && hasNonConstPointers(i->exp))
399         {
400             i->exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", i->exp->toChars());
401             result = new ErrorInitializer();
402             return;
403         }
404 
405         Type *tb = t->toBasetype();
406         Type *ti = i->exp->type->toBasetype();
407 
408         if (i->exp->op == TOKtuple && i->expandTuples && !i->exp->implicitConvTo(t))
409         {
410             result = new ExpInitializer(i->loc, i->exp);
411             return;
412         }
413 
414         /* Look for case of initializing a static array with a too-short
415          * string literal, such as:
416          *  char[5] foo = "abc";
417          * Allow this by doing an explicit cast, which will lengthen the string
418          * literal.
419          */
420         if (i->exp->op == TOKstring && tb->ty == Tsarray)
421         {
422             StringExp *se = (StringExp *)i->exp;
423             Type *typeb = se->type->toBasetype();
424             TY tynto = tb->nextOf()->ty;
425             if (!se->committed &&
426                 (typeb->ty == Tarray || typeb->ty == Tsarray) &&
427                 (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
428                 se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger())
429             {
430                 i->exp = se->castTo(sc, t);
431                 goto L1;
432             }
433         }
434 
435         // Look for implicit constructor call
436         if (tb->ty == Tstruct &&
437             !(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
438             !i->exp->implicitConvTo(t))
439         {
440             StructDeclaration *sd = ((TypeStruct *)tb)->sym;
441             if (sd->ctor)
442             {
443                 // Rewrite as S().ctor(exp)
444                 Expression *e;
445                 e = new StructLiteralExp(i->loc, sd, NULL);
446                 e = new DotIdExp(i->loc, e, Id::ctor);
447                 e = new CallExp(i->loc, e, i->exp);
448                 e = ::semantic(e, sc);
449                 if (needInterpret)
450                     i->exp = e->ctfeInterpret();
451                 else
452                     i->exp = e->optimize(WANTvalue);
453             }
454         }
455 
456         // Look for the case of statically initializing an array
457         // with a single member.
458         if (tb->ty == Tsarray &&
459             !tb->nextOf()->equals(ti->toBasetype()->nextOf()) &&
460             i->exp->implicitConvTo(tb->nextOf())
461            )
462         {
463             /* If the variable is not actually used in compile time, array creation is
464              * redundant. So delay it until invocation of toExpression() or toDt().
465              */
466             t = tb->nextOf();
467         }
468 
469         if (i->exp->implicitConvTo(t))
470         {
471             i->exp = i->exp->implicitCastTo(sc, t);
472         }
473         else
474         {
475             // Look for mismatch of compile-time known length to emit
476             // better diagnostic message, as same as AssignExp::semantic.
477             if (tb->ty == Tsarray &&
478                 i->exp->implicitConvTo(tb->nextOf()->arrayOf()) > MATCHnomatch)
479             {
480                 uinteger_t dim1 = ((TypeSArray *)tb)->dim->toInteger();
481                 uinteger_t dim2 = dim1;
482                 if (i->exp->op == TOKarrayliteral)
483                 {
484                     ArrayLiteralExp *ale = (ArrayLiteralExp *)i->exp;
485                     dim2 = ale->elements ? ale->elements->dim : 0;
486                 }
487                 else if (i->exp->op == TOKslice)
488                 {
489                     Type *tx = toStaticArrayType((SliceExp *)i->exp);
490                     if (tx)
491                         dim2 = ((TypeSArray *)tx)->dim->toInteger();
492                 }
493                 if (dim1 != dim2)
494                 {
495                     i->exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);
496                     i->exp = new ErrorExp();
497                 }
498             }
499             i->exp = i->exp->implicitCastTo(sc, t);
500         }
501     L1:
502         if (i->exp->op == TOKerror)
503         {
504             result = i;
505             return;
506         }
507         if (needInterpret)
508             i->exp = i->exp->ctfeInterpret();
509         else
510             i->exp = i->exp->optimize(WANTvalue);
511         //printf("-ExpInitializer::semantic(): "); i->exp->print();
512         result = i;
513     }
514 };
515 
516 // Performs semantic analisys on Initializer AST nodes
semantic(Initializer * init,Scope * sc,Type * t,NeedInterpret needInterpret)517 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret)
518 {
519     InitializerSemanticVisitor v = InitializerSemanticVisitor(sc, t, needInterpret);
520     init->accept(&v);
521     return v.result;
522 }
523 
524 class InferTypeVisitor : public Visitor
525 {
526 public:
527     Initializer *result;
528     Scope *sc;
529 
InferTypeVisitor(Scope * sc)530     InferTypeVisitor(Scope *sc)
531     {
532         this->result = NULL;
533         this->sc = sc;
534     }
535 
visit(ErrorInitializer * i)536     void visit(ErrorInitializer *i)
537     {
538         result = i;
539     }
540 
visit(VoidInitializer * i)541     void visit(VoidInitializer *i)
542     {
543         error(i->loc, "cannot infer type from void initializer");
544         result = new ErrorInitializer();
545     }
546 
visit(StructInitializer * i)547     void visit(StructInitializer *i)
548     {
549         error(i->loc, "cannot infer type from struct initializer");
550         result = new ErrorInitializer();
551     }
552 
visit(ArrayInitializer * init)553     void visit(ArrayInitializer *init)
554     {
555         //printf("ArrayInitializer::inferType() %s\n", init->toChars());
556         Expressions *keys = NULL;
557         Expressions *values;
558         if (init->isAssociativeArray())
559         {
560             keys = new Expressions();
561             keys->setDim(init->value.dim);
562             values = new Expressions();
563             values->setDim(init->value.dim);
564 
565             for (size_t i = 0; i < init->value.dim; i++)
566             {
567                 Expression *e = init->index[i];
568                 if (!e)
569                     goto Lno;
570                 (*keys)[i] = e;
571 
572                 Initializer *iz = init->value[i];
573                 if (!iz)
574                     goto Lno;
575                 iz = inferType(iz, sc);
576                 if (iz->isErrorInitializer())
577                 {
578                     result = iz;
579                     return;
580                 }
581                 assert(iz->isExpInitializer());
582                 (*values)[i] = ((ExpInitializer *)iz)->exp;
583                 assert((*values)[i]->op != TOKerror);
584             }
585 
586             Expression *e = new AssocArrayLiteralExp(init->loc, keys, values);
587             ExpInitializer *ei = new ExpInitializer(init->loc, e);
588             result = inferType(ei, sc);
589             return;
590         }
591         else
592         {
593             Expressions *elements = new Expressions();
594             elements->setDim(init->value.dim);
595             elements->zero();
596 
597             for (size_t i = 0; i < init->value.dim; i++)
598             {
599                 assert(!init->index[i]);  // already asserted by isAssociativeArray()
600 
601                 Initializer *iz = init->value[i];
602                 if (!iz)
603                     goto Lno;
604                 iz = inferType(iz, sc);
605                 if (iz->isErrorInitializer())
606                 {
607                     result = iz;
608                     return;
609                 }
610                 assert(iz->isExpInitializer());
611                 (*elements)[i] = ((ExpInitializer *)iz)->exp;
612                 assert((*elements)[i]->op != TOKerror);
613             }
614 
615             Expression *e = new ArrayLiteralExp(init->loc, NULL, elements);
616             ExpInitializer *ei = new ExpInitializer(init->loc, e);
617             result = inferType(ei, sc);
618             return;
619         }
620     Lno:
621         if (keys)
622         {
623             delete keys;
624             delete values;
625             error(init->loc, "not an associative array initializer");
626         }
627         else
628         {
629             error(init->loc, "cannot infer type from array initializer");
630         }
631         result = new ErrorInitializer();
632     }
633 
visit(ExpInitializer * init)634     void visit(ExpInitializer *init)
635     {
636         //printf("ExpInitializer::inferType() %s\n", init->toChars());
637         init->exp = ::semantic(init->exp, sc);
638         init->exp = resolveProperties(sc, init->exp);
639 
640         if (init->exp->op == TOKscope)
641         {
642             ScopeExp *se = (ScopeExp *)init->exp;
643             TemplateInstance *ti = se->sds->isTemplateInstance();
644             if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
645                 se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
646             else
647                 se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
648             result = new ErrorInitializer();
649             return;
650         }
651 
652         // Give error for overloaded function addresses
653         bool hasOverloads = false;
654         if (FuncDeclaration *f = isFuncAddress(init->exp, &hasOverloads))
655         {
656             if (f->checkForwardRef(init->loc))
657             {
658                 result = new ErrorInitializer();
659                 return;
660             }
661 
662             if (hasOverloads && !f->isUnique())
663             {
664                 init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
665                 result = new ErrorInitializer();
666                 return;
667             }
668         }
669         if (init->exp->op == TOKaddress)
670         {
671             AddrExp *ae = (AddrExp *)init->exp;
672             if (ae->e1->op == TOKoverloadset)
673             {
674                 init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
675                 result = new ErrorInitializer();
676                 return;
677             }
678         }
679 
680         if (init->exp->op == TOKerror)
681         {
682             result = new ErrorInitializer();
683             return;
684         }
685         if (!init->exp->type)
686         {
687             result = new ErrorInitializer();
688             return;
689         }
690         result = init;
691     }
692 };
693 
694 /* Translates to an expression to infer type.
695  * Returns ExpInitializer or ErrorInitializer.
696  */
inferType(Initializer * init,Scope * sc)697 Initializer *inferType(Initializer *init, Scope *sc)
698 {
699     InferTypeVisitor v = InferTypeVisitor(sc);
700     init->accept(&v);
701     return v.result;
702 }
703 
704 class InitToExpressionVisitor : public Visitor
705 {
706 public:
707     Expression *result;
708     Type *itype;
709 
InitToExpressionVisitor(Type * itype)710     InitToExpressionVisitor(Type *itype)
711     {
712         this->result = NULL;
713         this->itype = itype;
714     }
715 
visit(ErrorInitializer *)716     void visit(ErrorInitializer *)
717     {
718         result = new ErrorExp();
719     }
720 
visit(VoidInitializer *)721     void visit(VoidInitializer *)
722     {
723         result = NULL;
724     }
725 
726     /***************************************
727      * This works by transforming a struct initializer into
728      * a struct literal. In the future, the two should be the
729      * same thing.
730      */
visit(StructInitializer *)731     void visit(StructInitializer *)
732     {
733         // cannot convert to an expression without target 'ad'
734         result = NULL;
735     }
736 
737     /********************************
738      * If possible, convert array initializer to array literal.
739      * Otherwise return NULL.
740      */
741 
visit(ArrayInitializer * init)742     void visit(ArrayInitializer *init)
743     {
744         //printf("ArrayInitializer::toExpression(), dim = %d\n", init->dim);
745         //static int i; if (++i == 2) halt();
746 
747         Expressions *elements;
748         unsigned edim;
749         const unsigned amax = 0x80000000;
750         Type *t = NULL;
751         if (init->type)
752         {
753             if (init->type == Type::terror)
754             {
755                 result = new ErrorExp();
756                 return;
757             }
758 
759             t = init->type->toBasetype();
760             switch (t->ty)
761             {
762                 case Tvector:
763                     t = ((TypeVector *)t)->basetype;
764                     /* fall through */
765 
766                 case Tsarray:
767                     {
768                         uinteger_t adim = ((TypeSArray *)t)->dim->toInteger();
769                         if (adim >= amax)
770                             goto Lno;
771                         edim = (unsigned)adim;
772                         break;
773                     }
774 
775                 case Tpointer:
776                 case Tarray:
777                     edim = init->dim;
778                     break;
779 
780                 default:
781                     assert(0);
782             }
783         }
784         else
785         {
786             edim = (unsigned)init->value.dim;
787             for (size_t i = 0, j = 0; i < init->value.dim; i++, j++)
788             {
789                 if (init->index[i])
790                 {
791                     if (init->index[i]->op == TOKint64)
792                     {
793                         const uinteger_t idxval = init->index[i]->toInteger();
794                         if (idxval >= amax)
795                             goto Lno;
796                         j = (size_t)idxval;
797                     }
798                     else
799                         goto Lno;
800                 }
801                 if (j >= edim)
802                     edim = (unsigned)(j + 1);
803             }
804         }
805 
806         elements = new Expressions();
807         elements->setDim(edim);
808         elements->zero();
809         for (size_t i = 0, j = 0; i < init->value.dim; i++, j++)
810         {
811             if (init->index[i])
812                 j = (size_t)(init->index[i])->toInteger();
813             assert(j < edim);
814             Initializer *iz = init->value[i];
815             if (!iz)
816                 goto Lno;
817             Expression *ex = initializerToExpression(iz);
818             if (!ex)
819             {
820                 goto Lno;
821             }
822             (*elements)[j] = ex;
823         }
824 
825         /* Fill in any missing elements with the default initializer
826          */
827         {
828             Expression *_init = NULL;
829             for (size_t i = 0; i < edim; i++)
830             {
831                 if (!(*elements)[i])
832                 {
833                     if (!init->type)
834                         goto Lno;
835                     if (!_init)
836                         _init = ((TypeNext *)t)->next->defaultInit();
837                     (*elements)[i] = _init;
838                 }
839             }
840 
841             /* Expand any static array initializers that are a single expression
842              * into an array of them
843              */
844             if (t)
845             {
846                 Type *tn = t->nextOf()->toBasetype();
847                 if (tn->ty == Tsarray)
848                 {
849                     size_t dim = ((TypeSArray *)tn)->dim->toInteger();
850                     Type *te = tn->nextOf()->toBasetype();
851                     for (size_t i = 0; i < elements->dim; i++)
852                     {
853                         Expression *e = (*elements)[i];
854                         if (te->equals(e->type))
855                         {
856                             Expressions *elements2 = new Expressions();
857                             elements2->setDim(dim);
858                             for (size_t j = 0; j < dim; j++)
859                                 (*elements2)[j] = e;
860                             e = new ArrayLiteralExp(e->loc, tn, elements2);
861                             (*elements)[i] = e;
862                         }
863                     }
864                 }
865             }
866 
867             /* If any elements are errors, then the whole thing is an error
868              */
869             for (size_t i = 0; i < edim; i++)
870             {
871                 Expression *e = (*elements)[i];
872                 if (e->op == TOKerror)
873                 {
874                     result = e;
875                     return;
876                 }
877             }
878 
879             Expression *e = new ArrayLiteralExp(init->loc, init->type, elements);
880             result = e;
881             return;
882         }
883 
884     Lno:
885         result = NULL;
886     }
887 
visit(ExpInitializer * i)888     void visit(ExpInitializer *i)
889     {
890         if (itype)
891         {
892             //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", itype->toChars(), i->exp->toChars());
893             Type *tb = itype->toBasetype();
894             Expression *e = (i->exp->op == TOKconstruct || i->exp->op == TOKblit) ? ((AssignExp *)i->exp)->e2 : i->exp;
895             if (tb->ty == Tsarray && e->implicitConvTo(tb->nextOf()))
896             {
897                 TypeSArray *tsa = (TypeSArray *)tb;
898                 size_t d = (size_t)tsa->dim->toInteger();
899                 Expressions *elements = new Expressions();
900                 elements->setDim(d);
901                 for (size_t i = 0; i < d; i++)
902                     (*elements)[i] = e;
903                 ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, itype, elements);
904                 result = ae;
905                 return;
906             }
907         }
908         result = i->exp;
909     }
910 };
911 
initializerToExpression(Initializer * i,Type * t)912 Expression *initializerToExpression(Initializer *i, Type *t)
913 {
914     InitToExpressionVisitor v = InitToExpressionVisitor(t);
915     i->accept(&v);
916     return v.result;
917 }
918