Mercurial > projects > ddmd
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() |