Mercurial > hg > CbC > CbC_gcc
comparison gcc/d/dmd/initsem.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
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 } |