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