145
|
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
|
|
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
|
|
44 void visit(ErrorInitializer *i)
|
|
45 {
|
|
46 //printf("ErrorInitializer::semantic(t = %p)\n", t);
|
|
47 result = i;
|
|
48 }
|
|
49
|
|
50 void visit(VoidInitializer *i)
|
|
51 {
|
|
52 //printf("VoidInitializer::semantic(t = %p)\n", t);
|
|
53 i->type = t;
|
|
54 result = i;
|
|
55 }
|
|
56
|
|
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
|
|
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
|
|
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
|
|
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
|
|
530 InferTypeVisitor(Scope *sc)
|
|
531 {
|
|
532 this->result = NULL;
|
|
533 this->sc = sc;
|
|
534 }
|
|
535
|
|
536 void visit(ErrorInitializer *i)
|
|
537 {
|
|
538 result = i;
|
|
539 }
|
|
540
|
|
541 void visit(VoidInitializer *i)
|
|
542 {
|
|
543 error(i->loc, "cannot infer type from void initializer");
|
|
544 result = new ErrorInitializer();
|
|
545 }
|
|
546
|
|
547 void visit(StructInitializer *i)
|
|
548 {
|
|
549 error(i->loc, "cannot infer type from struct initializer");
|
|
550 result = new ErrorInitializer();
|
|
551 }
|
|
552
|
|
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
|
|
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 */
|
|
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
|
|
710 InitToExpressionVisitor(Type *itype)
|
|
711 {
|
|
712 this->result = NULL;
|
|
713 this->itype = itype;
|
|
714 }
|
|
715
|
|
716 void visit(ErrorInitializer *)
|
|
717 {
|
|
718 result = new ErrorExp();
|
|
719 }
|
|
720
|
|
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 */
|
|
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
|
|
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
|
|
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
|
|
912 Expression *initializerToExpression(Initializer *i, Type *t)
|
|
913 {
|
|
914 InitToExpressionVisitor v = InitToExpressionVisitor(t);
|
|
915 i->accept(&v);
|
|
916 return v.result;
|
|
917 }
|