comparison dmd/StructLiteralExp.d @ 123:9e39c7de8438

Make dmd test suite compile
author korDen
date Fri, 03 Sep 2010 20:46:58 +0400
parents e28b18c23469
children af1bebfd96a4
comparison
equal deleted inserted replaced
122:c77e9f4f1793 123:9e39c7de8438
1 module dmd.StructLiteralExp; 1 module dmd.StructLiteralExp;
2 2
3 import dmd.common; 3 import dmd.common;
4 import dmd.Expression; 4 import dmd.Expression;
5 import dmd.GlobalExpressions;
5 import dmd.MOD; 6 import dmd.MOD;
6 import dmd.TypeStruct; 7 import dmd.TypeStruct;
7 import dmd.TypeSArray; 8 import dmd.TypeSArray;
8 import dmd.expression.Util; 9 import dmd.expression.Util;
9 import dmd.ErrorExp; 10 import dmd.ErrorExp;
11 import dmd.Array;
10 import dmd.Dsymbol; 12 import dmd.Dsymbol;
11 import dmd.VarDeclaration; 13 import dmd.VarDeclaration;
12 import dmd.StructDeclaration; 14 import dmd.StructDeclaration;
13 import dmd.FuncDeclaration; 15 import dmd.FuncDeclaration;
14 import dmd.ThisDeclaration; 16 import dmd.ThisDeclaration;
61 this.fillHoles = 1; 63 this.fillHoles = 1;
62 } 64 }
63 65
64 override Expression syntaxCopy() 66 override Expression syntaxCopy()
65 { 67 {
66 assert(false); 68 return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements));
67 } 69 }
68 70
69 override Expression semantic(Scope sc) 71 override Expression semantic(Scope sc)
70 { 72 {
71 Expression e; 73 Expression e;
457 return this; 459 return this;
458 } 460 }
459 461
460 override Expression interpret(InterState istate) 462 override Expression interpret(InterState istate)
461 { 463 {
462 assert(false); 464 Expressions expsx = null;
465
466 version (LOG) {
467 printf("StructLiteralExp.interpret() %.*s\n", toChars());
468 }
469 /* We don't know how to deal with overlapping fields
470 */
471 if (sd.hasUnions)
472 {
473 error("Unions with overlapping fields are not yet supported in CTFE");
474 return EXP_CANT_INTERPRET;
475 }
476
477 if (elements)
478 {
479 foreach (size_t i, Expression e; elements)
480 {
481 if (!e)
482 continue;
483
484 Expression ex = e.interpret(istate);
485 if (ex is EXP_CANT_INTERPRET)
486 {
487 delete expsx;
488 return EXP_CANT_INTERPRET;
489 }
490
491 /* If any changes, do Copy On Write
492 */
493 if (ex != e)
494 {
495 if (!expsx)
496 {
497 expsx = new Expressions();
498 expsx.setDim(elements.dim);
499 for (size_t j = 0; j < elements.dim; j++)
500 {
501 expsx[j] = elements[j];
502 }
503 }
504 expsx[i] = ex;
505 }
506 }
507 }
508 if (elements && expsx)
509 {
510 expandTuples(expsx);
511 if (expsx.dim != elements.dim)
512 {
513 delete expsx;
514 return EXP_CANT_INTERPRET;
515 }
516 StructLiteralExp se = new StructLiteralExp(loc, sd, expsx);
517 se.type = type;
518 return se;
519 }
520 return this;
463 } 521 }
464 522
465 override dt_t** toDt(dt_t** pdt) 523 override dt_t** toDt(dt_t** pdt)
466 { 524 {
467 assert(false); 525 Array dts;
526 dt_t *dt;
527 dt_t *d;
528 uint offset;
529
530 //printf("StructLiteralExp.toDt() %s)\n", toChars());
531 dts.setDim(sd.fields.dim);
532 dts.zero();
533 assert(elements.dim <= sd.fields.dim);
534
535 foreach (uint i, Expression e; elements)
536 {
537 if (!e)
538 continue;
539
540 dt = null;
541 e.toDt(&dt);
542 dts.data[i] = dt;
543 }
544
545 offset = 0;
546 foreach (uint j, VarDeclaration v; sd.fields)
547 {
548 d = cast(dt_t*)dts.data[j];
549 if (!d)
550 { // An instance specific initializer was not provided.
551 // Look to see if there's a default initializer from the
552 // struct definition
553 if (v.init)
554 {
555 d = v.init.toDt();
556 }
557 else if (v.offset >= offset)
558 {
559 uint k;
560 uint offset2 = v.offset + cast(uint)v.type.size();
561 // Make sure this field (v) does not overlap any explicitly
562 // initialized field.
563 for (k = j + 1; 1; k++)
564 {
565 if (k == dts.dim) // didn't find any overlap
566 {
567 v.type.toDt(&d);
568 break;
569 }
570 VarDeclaration v2 = sd.fields[k];
571
572 if (v2.offset < offset2 && dts.data[k])
573 break; // overlap
574 }
575 }
576 }
577 if (d)
578 {
579 if (v.offset < offset)
580 error("duplicate union initialization for %s", v.toChars());
581 else
582 {
583 uint sz = dt_size(d);
584 uint vsz = cast(uint)v.type.size();
585 uint voffset = v.offset;
586 assert(sz <= vsz);
587
588 uint dim = 1;
589 for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype())
590 {
591 TypeSArray tsa = cast(TypeSArray)vt;
592 dim *= tsa.dim.toInteger();
593 }
594
595 for (size_t i = 0; i < dim; i++)
596 {
597 if (offset < voffset)
598 pdt = dtnzeros(pdt, voffset - offset);
599 if (!d)
600 {
601 if (v.init)
602 d = v.init.toDt();
603 else
604 v.type.toDt(&d);
605 }
606 pdt = dtcat(pdt, d);
607 d = null;
608 offset = voffset + sz;
609 voffset += vsz / dim;
610 if (sz == vsz)
611 break;
612 }
613 }
614 }
615 }
616
617 if (offset < sd.structsize)
618 pdt = dtnzeros(pdt, sd.structsize - offset);
619
620 return pdt;
468 } 621 }
469 622
470 version(DMDV2) 623 version(DMDV2)
471 { 624 {
472 override int isLvalue() 625 override int isLvalue()