Mercurial > projects > ddmd
comparison dmd/NewExp.d @ 174:af724d3510d7
lot os toCBuffer methods implemented
moved shared Type.* stuff into Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 03:47:23 +0400 |
parents | 60bb0fe4563e |
children | e3afd1303184 |
comparison
equal
deleted
inserted
replaced
173:d237b38b5858 | 174:af724d3510d7 |
---|---|
5 import dmd.NewDeclaration; | 5 import dmd.NewDeclaration; |
6 import dmd.CtorDeclaration; | 6 import dmd.CtorDeclaration; |
7 import dmd.ClassDeclaration; | 7 import dmd.ClassDeclaration; |
8 import dmd.Type; | 8 import dmd.Type; |
9 import dmd.OutBuffer; | 9 import dmd.OutBuffer; |
10 import dmd.PREC; | |
10 import dmd.Loc; | 11 import dmd.Loc; |
11 import dmd.Scope; | 12 import dmd.Scope; |
12 import dmd.IRState; | 13 import dmd.IRState; |
13 import dmd.InlineDoState; | 14 import dmd.InlineDoState; |
14 import dmd.HdrGenState; | 15 import dmd.HdrGenState; |
90 if (type) // if semantic() already run | 91 if (type) // if semantic() already run |
91 return this; | 92 return this; |
92 | 93 |
93 Lagain: | 94 Lagain: |
94 if (thisexp) | 95 if (thisexp) |
95 { | 96 { |
96 thisexp = thisexp.semantic(sc); | 97 thisexp = thisexp.semantic(sc); |
97 cdthis = thisexp.type.isClassHandle(); | 98 cdthis = thisexp.type.isClassHandle(); |
98 if (cdthis) | 99 if (cdthis) |
99 { | 100 { |
100 sc = sc.push(cdthis); | 101 sc = sc.push(cdthis); |
120 | 121 |
121 if (thisexp && tb.ty != Tclass) | 122 if (thisexp && tb.ty != Tclass) |
122 error("e.new is only for allocating nested classes, not %s", tb.toChars()); | 123 error("e.new is only for allocating nested classes, not %s", tb.toChars()); |
123 | 124 |
124 if (tb.ty == Tclass) | 125 if (tb.ty == Tclass) |
125 { | 126 { |
126 TypeFunction tf; | 127 TypeFunction tf; |
127 | 128 |
128 TypeClass tc = cast(TypeClass)tb; | 129 TypeClass tc = cast(TypeClass)tb; |
129 ClassDeclaration cd = tc.sym.isClassDeclaration(); | 130 ClassDeclaration cd = tc.sym.isClassDeclaration(); |
130 if (cd.isInterfaceDeclaration()) | 131 if (cd.isInterfaceDeclaration()) |
131 error("cannot create instance of interface %s", cd.toChars()); | 132 error("cannot create instance of interface %s", cd.toChars()); |
132 else if (cd.isAbstract()) | 133 else if (cd.isAbstract()) |
133 { | 134 { |
134 error("cannot create instance of abstract class %s", cd.toChars()); | 135 error("cannot create instance of abstract class %s", cd.toChars()); |
135 for (int j = 0; j < cd.vtbl.dim; j++) | 136 for (int j = 0; j < cd.vtbl.dim; j++) |
136 { | 137 { |
137 FuncDeclaration fd = (cast(Dsymbol)cd.vtbl.data[j]).isFuncDeclaration(); | 138 FuncDeclaration fd = (cast(Dsymbol)cd.vtbl.data[j]).isFuncDeclaration(); |
138 if (fd && fd.isAbstract()) | 139 if (fd && fd.isAbstract()) |
139 error("function %s is abstract", fd.toChars()); | 140 error("function %s is abstract", fd.toChars()); |
140 } | 141 } |
141 } | 142 } |
154 if (!cdthis) | 155 if (!cdthis) |
155 { | 156 { |
156 // Supply an implicit 'this' and try again | 157 // Supply an implicit 'this' and try again |
157 thisexp = new ThisExp(loc); | 158 thisexp = new ThisExp(loc); |
158 for (Dsymbol sp = sc.parent; 1; sp = sp.parent) | 159 for (Dsymbol sp = sc.parent; 1; sp = sp.parent) |
159 { | 160 { |
160 if (!sp) | 161 if (!sp) |
161 { | 162 { |
162 error("outer class %s 'this' needed to 'new' nested class %s", cdn.toChars(), cd.toChars()); | 163 error("outer class %s 'this' needed to 'new' nested class %s", cdn.toChars(), cd.toChars()); |
163 break; | 164 break; |
164 } | 165 } |
215 } | 216 } |
216 } | 217 } |
217 } | 218 } |
218 ///} else { | 219 ///} else { |
219 /// else if (fdn) | 220 /// else if (fdn) |
220 /// { | 221 /// { |
221 /// /* The nested class cd is nested inside a function, | 222 /// /* The nested class cd is nested inside a function, |
222 /// * we'll let getEthis() look for errors. | 223 /// * we'll let getEthis() look for errors. |
223 /// */ | 224 /// */ |
224 /// //printf("nested class %s is nested inside function %s, we're in %s\n", cd.toChars(), fdn.toChars(), sc.func.toChars()); | 225 /// //printf("nested class %s is nested inside function %s, we're in %s\n", cd.toChars(), fdn.toChars(), sc.func.toChars()); |
225 /// if (thisexp) | 226 /// if (thisexp) |
340 else if (tb.ty == Tarray && (arguments && arguments.dim)) | 341 else if (tb.ty == Tarray && (arguments && arguments.dim)) |
341 { | 342 { |
342 for (size_t j = 0; j < arguments.dim; j++) | 343 for (size_t j = 0; j < arguments.dim; j++) |
343 { | 344 { |
344 if (tb.ty != Tarray) | 345 if (tb.ty != Tarray) |
345 { | 346 { |
346 error("too many arguments for array"); | 347 error("too many arguments for array"); |
347 arguments.dim = i; | 348 arguments.dim = i; |
348 break; | 349 break; |
349 } | 350 } |
350 | 351 |
384 | 385 |
385 // Optimize parameters | 386 // Optimize parameters |
386 if (newargs) | 387 if (newargs) |
387 { | 388 { |
388 foreach (ref Expression e; newargs) | 389 foreach (ref Expression e; newargs) |
389 { | 390 { |
390 e = e.optimize(WANTvalue); | 391 e = e.optimize(WANTvalue); |
391 } | 392 } |
392 } | 393 } |
393 | 394 |
394 if (arguments) | 395 if (arguments) |
395 { | 396 { |
396 foreach (ref Expression e; arguments) | 397 foreach (ref Expression e; arguments) |
397 { | 398 { |
398 e = e.optimize(WANTvalue); | 399 e = e.optimize(WANTvalue); |
399 } | 400 } |
400 } | 401 } |
401 return this; | 402 return this; |
402 } | 403 } |
430 elem *ex = null; | 431 elem *ex = null; |
431 elem *ey = null; | 432 elem *ey = null; |
432 elem *ez = null; | 433 elem *ez = null; |
433 | 434 |
434 if (allocator || onstack) | 435 if (allocator || onstack) |
435 { | 436 { |
436 elem *ei; | 437 elem *ei; |
437 Symbol *si; | 438 Symbol *si; |
438 | 439 |
439 if (onstack) | 440 if (onstack) |
440 { | 441 { |
499 //elem_print(ey); | 500 //elem_print(ey); |
500 //elem_print(ez); | 501 //elem_print(ez); |
501 } | 502 } |
502 | 503 |
503 if (thisexp) | 504 if (thisexp) |
504 { | 505 { |
505 ClassDeclaration cdthis = thisexp.type.isClassHandle(); | 506 ClassDeclaration cdthis = thisexp.type.isClassHandle(); |
506 assert(cdthis); | 507 assert(cdthis); |
507 //printf("cd = %s\n", cd.toChars()); | 508 //printf("cd = %s\n", cd.toChars()); |
508 //printf("cdthis = %s\n", cdthis.toChars()); | 509 //printf("cdthis = %s\n", cdthis.toChars()); |
509 assert(cd.isNested()); | 510 assert(cd.isNested()); |
513 | 514 |
514 //printf("member = %p\n", member); | 515 //printf("member = %p\n", member); |
515 //printf("cdp = %s\n", cdp.toChars()); | 516 //printf("cdp = %s\n", cdp.toChars()); |
516 //printf("cdthis = %s\n", cdthis.toChars()); | 517 //printf("cdthis = %s\n", cdthis.toChars()); |
517 if (cdp != cdthis) | 518 if (cdp != cdthis) |
518 { | 519 { |
519 int i = cdp.isClassDeclaration().isBaseOf(cdthis, &offset); | 520 int i = cdp.isClassDeclaration().isBaseOf(cdthis, &offset); |
520 assert(i); | 521 assert(i); |
521 } | 522 } |
522 ethis = thisexp.toElem(irs); | 523 ethis = thisexp.toElem(irs); |
523 if (offset) | 524 if (offset) |
536 //printf("ex: "); elem_print(ex); | 537 //printf("ex: "); elem_print(ex); |
537 //printf("ey: "); elem_print(ey); | 538 //printf("ey: "); elem_print(ey); |
538 //printf("ez: "); elem_print(ez); | 539 //printf("ez: "); elem_print(ez); |
539 } | 540 } |
540 else if (cd.isNested()) | 541 else if (cd.isNested()) |
541 { | 542 { |
542 /* Initialize cd.vthis: | 543 /* Initialize cd.vthis: |
543 * *(ey + cd.vthis.offset) = this; | 544 * *(ey + cd.vthis.offset) = this; |
544 */ | 545 */ |
545 ey = setEthis(loc, irs, ey, cd); | 546 ey = setEthis(loc, irs, ey, cd); |
546 } | 547 } |
570 elem* ex = null; | 571 elem* ex = null; |
571 elem* ey = null; | 572 elem* ey = null; |
572 elem* ez = null; | 573 elem* ez = null; |
573 | 574 |
574 if (allocator) | 575 if (allocator) |
575 { | 576 { |
576 elem *ei; | 577 elem *ei; |
577 Symbol *si; | 578 Symbol *si; |
578 | 579 |
579 ex = el_var(allocator.toSymbol()); | 580 ex = el_var(allocator.toSymbol()); |
580 ex = callfunc(loc, irs, 1, type, ex, allocator.type, | 581 ex = callfunc(loc, irs, 1, type, ex, allocator.type, |
590 } | 591 } |
591 else if (member) | 592 else if (member) |
592 ez = el_same(&ex); | 593 ez = el_same(&ex); |
593 | 594 |
594 if (!member) | 595 if (!member) |
595 { | 596 { |
596 /* Statically intialize with default initializer | 597 /* Statically intialize with default initializer |
597 */ | 598 */ |
598 ex = el_una(OPind, TYstruct, ex); | 599 ex = el_una(OPind, TYstruct, ex); |
599 ex = el_bin(OPstreq, TYnptr, ex, ei); | 600 ex = el_bin(OPstreq, TYnptr, ex, ei); |
600 ex.Enumbytes = cd.size(loc); | 601 ex.Enumbytes = cd.size(loc); |
631 //elem_print(ey); | 632 //elem_print(ey); |
632 //elem_print(ez); | 633 //elem_print(ez); |
633 } | 634 } |
634 | 635 |
635 if (cd.isNested()) | 636 if (cd.isNested()) |
636 { | 637 { |
637 /* Initialize cd.vthis: | 638 /* Initialize cd.vthis: |
638 * *(ey + cd.vthis.offset) = this; | 639 * *(ey + cd.vthis.offset) = this; |
639 */ | 640 */ |
640 ey = setEthis(loc, irs, ey, cd); | 641 ey = setEthis(loc, irs, ey, cd); |
641 } | 642 } |
642 | 643 |
643 if (member) | 644 if (member) |
644 { | 645 { |
645 // Call constructor | 646 // Call constructor |
646 ez = callfunc(loc, irs, 1, type, ez, ectype, member, member.type, null, arguments); | 647 ez = callfunc(loc, irs, 1, type, ez, ectype, member, member.type, null, arguments); |
647 version (STRUCTTHISREF) { | 648 version (STRUCTTHISREF) { |
648 /* Structs return a ref, which gets automatically dereferenced. | 649 /* Structs return a ref, which gets automatically dereferenced. |
649 * But we want a pointer to the instance. | 650 * But we want a pointer to the instance. |
659 { | 660 { |
660 TypeDArray tda = cast(TypeDArray)t; | 661 TypeDArray tda = cast(TypeDArray)t; |
661 | 662 |
662 assert(arguments && arguments.dim >= 1); | 663 assert(arguments && arguments.dim >= 1); |
663 if (arguments.dim == 1) | 664 if (arguments.dim == 1) |
664 { | 665 { |
665 // Single dimension array allocations | 666 // Single dimension array allocations |
666 auto arg = arguments[0]; // gives array length | 667 auto arg = arguments[0]; // gives array length |
667 e = arg.toElem(irs); | 668 e = arg.toElem(irs); |
668 ulong elemsize = tda.next.size(); | 669 ulong elemsize = tda.next.size(); |
669 | 670 |
671 e = el_param(e, type.getTypeInfo(null).toElem(irs)); | 672 e = el_param(e, type.getTypeInfo(null).toElem(irs)); |
672 int rtl = tda.next.isZeroInit(Loc(0)) ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; | 673 int rtl = tda.next.isZeroInit(Loc(0)) ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; |
673 e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); | 674 e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); |
674 } | 675 } |
675 else | 676 else |
676 { | 677 { |
677 // Multidimensional array allocations | 678 // Multidimensional array allocations |
678 e = el_long(TYint, arguments.dim); | 679 e = el_long(TYint, arguments.dim); |
679 foreach (Expression arg; arguments) | 680 foreach (Expression arg; arguments) |
680 { | 681 { |
681 e = el_param(arg.toElem(irs), e); | 682 e = el_param(arg.toElem(irs), e); |
723 return true; | 724 return true; |
724 } | 725 } |
725 | 726 |
726 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) | 727 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
727 { | 728 { |
728 assert(false); | 729 int i; |
730 | |
731 if (thisexp) | |
732 { | |
733 expToCBuffer(buf, hgs, thisexp, PREC.PREC_primary); | |
734 buf.writeByte('.'); | |
735 } | |
736 buf.writestring("new "); | |
737 if (newargs && newargs.dim) | |
738 { | |
739 buf.writeByte('('); | |
740 argsToCBuffer(buf, newargs, hgs); | |
741 buf.writeByte(')'); | |
742 } | |
743 newtype.toCBuffer(buf, null, hgs); | |
744 if (arguments && arguments.dim) | |
745 { | |
746 buf.writeByte('('); | |
747 argsToCBuffer(buf, arguments, hgs); | |
748 buf.writeByte(')'); | |
749 } | |
729 } | 750 } |
730 | 751 |
731 override void scanForNestedRef(Scope sc) | 752 override void scanForNestedRef(Scope sc) |
732 { | 753 { |
733 //printf("NewExp.scanForNestedRef(Scope *sc): %s\n", toChars()); | 754 //printf("NewExp.scanForNestedRef(Scope *sc): %s\n", toChars()); |
742 override bool canThrow() | 763 override bool canThrow() |
743 { | 764 { |
744 return 1; | 765 return 1; |
745 } | 766 } |
746 } | 767 } |
747 | 768 |
748 //int inlineCost(InlineCostState *ics); | 769 //int inlineCost(InlineCostState *ics); |
749 | 770 |
750 override Expression doInline(InlineDoState ids) | 771 override Expression doInline(InlineDoState ids) |
751 { | 772 { |
752 //printf("NewExp.doInline(): %s\n", toChars()); | 773 //printf("NewExp.doInline(): %s\n", toChars()); |
756 ne.thisexp = thisexp.doInline(ids); | 777 ne.thisexp = thisexp.doInline(ids); |
757 ne.newargs = arrayExpressiondoInline(ne.newargs, ids); | 778 ne.newargs = arrayExpressiondoInline(ne.newargs, ids); |
758 ne.arguments = arrayExpressiondoInline(ne.arguments, ids); | 779 ne.arguments = arrayExpressiondoInline(ne.arguments, ids); |
759 return ne; | 780 return ne; |
760 } | 781 } |
761 | 782 |
762 //Expression inlineScan(InlineScanState *iss); | 783 //Expression inlineScan(InlineScanState *iss); |
763 } | 784 } |
764 | 785 |