2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
17 #include "expression.h"
20 #include "declaration.h"
22 #include "aggregate.h"
29 #include "..\tk\mem.h" // for mem_malloc
31 #include "../tk/mem.h" // for mem_malloc
46 static char __file__
[] = __FILE__
; /* for tassert.h */
50 elem
*addressElem(elem
*e
, Type
*t
);
51 elem
*array_toPtr(Type
*t
, elem
*e
);
52 elem
*bit_assign(enum OPER op
, elem
*eb
, elem
*ei
, elem
*ev
, int result
);
53 elem
*bit_read(elem
*eb
, elem
*ei
, int result
);
54 elem
*exp2_copytotemp(elem
*e
);
56 #define el_setLoc(e,loc) ((e)->Esrcpos.Sfilename = (loc).filename, \
57 (e)->Esrcpos.Slinnum = (loc).linnum)
59 /************************************
63 elem
*callfunc(Loc loc
,
65 int directcall
, // 1: don't do virtual call
66 Type
*tret
, // return type
67 elem
*ec
, // evaluates to function address
68 Type
*ectype
, // original type of ec
69 FuncDeclaration
*fd
, // if !=NULL, this is the function being called
70 Type
*t
, // TypeDelegate or TypeFunction for this function
71 elem
*ehidden
, // if !=NULL, this is the 'hidden' argument
87 printf("callfunc(directcall = %d, tret = '%s', ec = %p, fd = %p)\n",
88 directcall
, tret
->toChars(), ec
, fd
);
89 printf("ec: "); elem_print(ec
);
91 printf("fd = '%s'\n", fd
->toChars());
95 if (t
->ty
== Tdelegate
)
97 // A delegate consists of:
98 // { Object *this; Function *funcptr; }
100 assert(t
->nextOf()->ty
== Tfunction
);
101 tf
= (TypeFunction
*)(t
->nextOf());
103 ec
= el_same(ðis
);
104 ethis
= el_una(OP64_32
, TYnptr
, ethis
); // get this
105 ec
= array_toPtr(t
, ec
); // get funcptr
106 ec
= el_una(OPind
, tf
->totym(), ec
);
109 { assert(t
->ty
== Tfunction
);
110 tf
= (TypeFunction
*)(t
);
112 retmethod
= tf
->retStyle();
115 ty
= fd
->toSymbol()->Stype
->Tty
;
116 reverse
= tyrevfunc(ty
);
120 // j=1 if _arguments[] is first argument
121 int j
= (tf
->linkage
== LINKd
&& tf
->varargs
== 1);
123 for (i
= 0; i
< arguments
->dim
; i
++)
127 arg
= (Expression
*)arguments
->data
[i
];
128 //printf("\targ[%d]: %s\n", i, arg->toChars());
130 size_t nparams
= Argument::dim(tf
->parameters
);
131 if (i
- j
< nparams
&& i
>= j
)
133 Argument
*p
= Argument::getNth(tf
->parameters
, i
- j
);
135 if (p
->storageClass
& (STCout
| STCref
))
137 // Convert argument to a pointer,
138 // use AddrExp::toElem()
139 Expression
*ae
= arg
->addressOf(NULL
);
140 ea
= ae
->toElem(irs
);
144 ea
= arg
->toElem(irs
);
146 if (ea
->Ety
== TYstruct
)
148 ea
= el_una(OPstrpar
, TYstruct
, ea
);
149 ea
->Enumbytes
= ea
->E1
->Enumbytes
;
150 assert(ea
->Enumbytes
);
153 ep
= el_param(ep
,ea
);
155 ep
= el_param(ea
,ep
);
159 if (retmethod
== RETstack
)
162 { // Don't have one, so create one
165 if (tf
->next
->toBasetype()->ty
== Tstruct
)
166 t
= tf
->next
->toCtype();
168 t
= type_fake(tf
->next
->totym());
169 Symbol
*stmp
= symbol_genauto(t
);
170 ehidden
= el_ptr(stmp
);
174 #if 0 // BUG: implement
175 if (reverse
&& type_mangle(tfunc
) == mTYman_cpp
)
176 ep
= el_param(ehidden
,ep
);
179 ep
= el_param(ep
,ehidden
);
185 assert(ehidden
== NULL
);
187 if (fd
&& fd
->isMember2())
189 InterfaceDeclaration
*intd
;
191 AggregateDeclaration
*ad
;
197 if (ad
->handle
->ty
== Tpointer
&& tybasic(ec
->Ety
) != TYnptr
)
199 ethis
= addressElem(ec
, ectype
);
204 // Evaluate ec for side effects
207 sfunc
= fd
->toSymbol();
209 if (!fd
->isVirtual() ||
210 directcall
|| // BUG: fix
224 ev
= el_same(ðis
);
225 ev
= el_una(OPind
, TYnptr
, ev
);
226 vindex
= fd
->vtblIndex
;
228 // Build *(ev + vindex * 4)
229 ec
= el_bin(OPadd
,TYnptr
,ev
,el_long(TYint
, vindex
* 4));
230 ec
= el_una(OPind
,TYnptr
,ec
);
231 ec
= el_una(OPind
,tybasic(sfunc
->Stype
->Tty
),ec
);
234 else if (fd
&& fd
->isNested())
237 ethis
= getEthis(0, irs
, fd
);
241 ep
= el_param(ep
, ethis
);
243 tyret
= tret
->totym();
245 // Look for intrinsic functions
246 if (ec
->Eoper
== OPvar
&& (op
= intrinsic_op(ec
->EV
.sp
.Vsym
->Sident
)) != -1)
258 e
->E1
= el_una(OPs32_d
, TYdouble
, e
->E2
);
259 e
->E1
= el_una(OPd_ld
, TYldouble
, e
->E1
);
265 e
= el_una(op
,tyret
,ep
);
268 e
= el_bin(OPcall
,tyret
,ec
,ep
);
270 e
= el_una(OPucall
,tyret
,ec
);
272 if (retmethod
== RETstack
)
275 e
= el_una(OPind
, tyret
, e
);
277 if (tybasic(tyret
) == TYstruct
)
279 e
->Enumbytes
= tret
->size();
281 e
= el_combine(eside
, e
);
285 /*******************************************
286 * Take address of an elem.
289 elem
*addressElem(elem
*e
, Type
*t
)
293 //printf("addressElem()\n");
295 for (pe
= &e
; (*pe
)->Eoper
== OPcomma
; pe
= &(*pe
)->E2
)
297 if ((*pe
)->Eoper
!= OPvar
&& (*pe
)->Eoper
!= OPind
)
303 // Convert to ((tmp=e),tmp)
305 if (t
&& ((ty
= t
->toBasetype()->ty
) == Tstruct
|| ty
== Tsarray
))
308 tx
= type_fake(e
->Ety
);
309 stmp
= symbol_genauto(tx
);
310 eeq
= el_bin(OPeq
,e
->Ety
,el_var(stmp
),e
);
311 if (e
->Ety
== TYstruct
)
313 eeq
->Eoper
= OPstreq
;
314 eeq
->Enumbytes
= e
->Enumbytes
;
316 else if (e
->Ety
== TYarray
)
318 eeq
->Eoper
= OPstreq
;
319 eeq
->Ejty
= eeq
->Ety
= TYstruct
;
320 eeq
->Enumbytes
= t
->size();
322 *pe
= el_bin(OPcomma
,e
->Ety
,eeq
,el_var(stmp
));
324 e
= el_una(OPaddr
,TYnptr
,e
);
328 /*****************************************
329 * Convert array to a pointer to the data.
332 elem
*array_toPtr(Type
*t
, elem
*e
)
334 //printf("array_toPtr()\n");
344 if (e
->Eoper
== OPcomma
)
347 e
->E2
= array_toPtr(t
, e
->E2
);
349 else if (e
->Eoper
== OPpair
)
357 e
= el_una(OPmsw
, TYnptr
, e
);
359 e
= el_una(OPaddr
, TYnptr
, e
);
360 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, 4));
361 e
= el_una(OPind
, TYnptr
, e
);
367 e
= el_una(OPaddr
, TYnptr
, e
);
377 /*****************************************
378 * Convert array to a dynamic array.
381 elem
*array_toDarray(Type
*t
, elem
*e
)
387 //printf("array_toDarray(t = %s)\n", t->toChars());
396 e
= el_una(OPaddr
, TYnptr
, e
);
397 dim
= ((TypeSArray
*)t
)->dim
->toInteger();
398 e
= el_pair(TYullong
, el_long(TYint
, dim
), e
);
407 size_t len
= tysize
[tybasic(e
->Ety
)];
408 elem
*es
= el_calloc();
409 es
->Eoper
= OPstring
;
411 // Match MEM_PH_FREE for OPstring in ztc\el.c
412 es
->EV
.ss
.Vstring
= (char *)mem_malloc(len
);
413 memcpy(es
->EV
.ss
.Vstring
, &e
->EV
, len
);
415 es
->EV
.ss
.Vstrlen
= len
;
422 e
= el_una(OPaddr
, TYnptr
, e
);
426 ef
= el_combine(ef
, e
->E1
);
444 // Copy expression to a variable and take the
445 // address of that variable.
447 tym_t ty
= tybasic(e
->Ety
);
451 if (e
->Enumbytes
== 4)
453 else if (e
->Enumbytes
== 8)
457 stmp
= symbol_genauto(type_fake(ty
));
458 e
= el_bin(OPeq
, e
->Ety
, el_var(stmp
), e
);
459 e
= el_bin(OPcomma
, TYnptr
, e
, el_una(OPaddr
, TYnptr
, el_var(stmp
)));
464 e
= el_pair(TYullong
, el_long(TYint
, dim
), e
);
467 return el_combine(ef
, e
);
470 /*****************************************
471 * Evaluate elem and convert to dynamic array.
474 elem
*eval_Darray(IRState
*irs
, Expression
*e
)
479 return array_toDarray(e
->type
, ex
);
482 /************************************
485 elem
*sarray_toDarray(Type
*tfrom
, Type
*tto
, elem
*e
)
487 //printf("sarray_toDarray()\n");
491 unsigned dim
= ((TypeSArray
*)tfrom
)->dim
->toInteger();
495 unsigned fsize
= tfrom
->nextOf()->size();
496 unsigned tsize
= tto
->nextOf()->size();
498 if ((dim
* fsize
) % tsize
!= 0)
501 error((Loc
)0, "cannot cast %s to %s since sizes don't line up", tfrom
->toChars(), tto
->toChars());
503 dim
= (dim
* fsize
) / tsize
;
506 elen
= el_long(TYint
, dim
);
507 e
= el_una(OPaddr
, TYnptr
, e
);
508 e
= el_pair(TYullong
, elen
, e
);
512 /*******************************************
513 * Set an array pointed to by eptr to evalue:
514 * eptr[0..edim] = evalue;
516 * eptr where to write the data to
517 * evalue value to write
518 * edim number of times to write evalue to eptr[]
522 elem
*setArray(elem
*eptr
, elem
*edim
, Type
*tb
, elem
*evalue
)
527 if (tb
->ty
== Tfloat80
|| tb
->ty
== Timaginary80
)
529 else if (tb
->ty
== Tcomplex80
)
530 r
= RTLSYM_MEMSET160
;
531 else if (tb
->ty
== Tcomplex64
)
532 r
= RTLSYM_MEMSET128
;
537 case 1: r
= RTLSYM_MEMSET8
; break;
538 case 2: r
= RTLSYM_MEMSET16
; break;
539 case 4: r
= RTLSYM_MEMSET32
; break;
540 case 8: r
= RTLSYM_MEMSET64
; break;
544 evalue
= el_una(OPaddr
, TYnptr
, evalue
);
545 elem
*esz
= el_long(TYint
, sz
);
546 e
= el_params(esz
, edim
, evalue
, eptr
, NULL
);
547 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[r
]),e
);
551 if (sz
> 1 && sz
<= 8 &&
552 evalue
->Eoper
== OPconst
&& el_allbits(evalue
, 0))
555 edim
= el_bin(OPmul
, TYuint
, edim
, el_long(TYuint
, sz
));
558 if (evalue
->Ety
== TYstruct
)
560 evalue
= el_una(OPstrpar
, TYstruct
, evalue
);
561 evalue
->Enumbytes
= evalue
->E1
->Enumbytes
;
562 assert(evalue
->Enumbytes
);
565 // Be careful about parameter side effect ordering
566 if (r
== RTLSYM_MEMSET8
)
568 e
= el_param(edim
, evalue
);
569 e
= el_bin(OPmemset
,TYnptr
,eptr
,e
);
573 e
= el_params(edim
, evalue
, eptr
, NULL
);
574 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[r
]),e
);
579 /***************************************
582 elem
*Expression::toElem(IRState
*irs
)
589 /***************************************
592 elem
*VarExp::toElem(IRState
*irs
)
596 Type
*tb
= type
->toBasetype();
599 //printf("VarExp::toElem('%s') %p\n", toChars(), this);
600 //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
603 error("need 'this' to access member %s", toChars());
604 return el_long(TYint
, 0);
608 if (var
->toParent2())
609 fd
= var
->toParent2()->isFuncDeclaration();
612 if (fd
&& fd
->nrvo_can
&& fd
->nrvo_var
== var
)
618 if (s
->Sclass
== SCauto
|| s
->Sclass
== SCparameter
)
620 if (fd
&& fd
!= irs
->getFunc())
621 { // 'var' is a variable in an enclosing function.
625 ethis
= getEthis(loc
, irs
, fd
);
626 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
630 /* If fd is a non-static member function of a class or struct,
631 * then ethis isn't the frame pointer.
632 * ethis is the 'this' pointer to the class/struct instance.
637 offset
-= fd
->vthis
->toSymbol()->Soffset
;
639 //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
641 ethis
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYnptr
, offset
));
642 e
= el_una(OPind
, 0, ethis
);
643 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
649 if (s
->Sclass
== SCauto
&& s
->Ssymnum
== -1)
651 //printf("\tadding symbol\n");
654 if (var
->isImportedSymbol())
656 e
= el_var(var
->toImport());
657 e
= el_una(OPind
,s
->ty(),e
);
659 else if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
660 { // Static arrays are really passed as pointers to the array
661 // Out parameters are really references
665 e
= el_una(OPind
, s
->ty(), e
);
673 e
= el_una(OPind
, 0, e
);
675 if (tb
->ty
== Tfunction
)
681 e
->Ejty
= e
->Ety
= tym
;
682 if (tybasic(tym
) == TYstruct
)
684 e
->Enumbytes
= type
->size();
686 else if (tybasic(tym
) == TYarray
)
688 e
->Ejty
= e
->Ety
= TYstruct
;
689 e
->Enumbytes
= type
->size();
695 /*****************************************
698 elem
*FuncExp::toElem(IRState
*irs
)
703 //printf("FuncExp::toElem() %s\n", toChars());
708 elem
*ethis
= getEthis(loc
, irs
, fd
);
709 e
= el_pair(TYullong
, ethis
, e
);
712 irs
->deferToObj
->push(fd
);
717 /**************************************
720 elem
*Dsymbol_toElem(Dsymbol
*s
, IRState
*irs
)
724 AttribDeclaration
*ad
;
726 ClassDeclaration
*cd
;
727 StructDeclaration
*sd
;
730 TupleDeclaration
*td
;
731 TypedefDeclaration
*tyd
;
733 //printf("Dsymbol_toElem() %s\n", s->toChars());
734 ad
= s
->isAttribDeclaration();
737 Array
*decl
= ad
->include(NULL
, NULL
);
738 if (decl
&& decl
->dim
)
740 for (size_t i
= 0; i
< decl
->dim
; i
++)
742 s
= (Dsymbol
*)decl
->data
[i
];
743 e
= el_combine(e
, Dsymbol_toElem(s
, irs
));
747 else if ((vd
= s
->isVarDeclaration()) != NULL
)
751 return Dsymbol_toElem(s
, irs
);
752 if (vd
->isStatic() || vd
->isConst() || vd
->storage_class
& STCextern
)
758 //printf("\tadding symbol '%s'\n", sp->Sident);
763 ie
= vd
->init
->isExpInitializer();
765 e
= ie
->exp
->toElem(irs
);
769 else if ((cd
= s
->isClassDeclaration()) != NULL
)
771 irs
->deferToObj
->push(s
);
774 else if ((sd
= s
->isStructDeclaration()) != NULL
)
776 irs
->deferToObj
->push(sd
);
779 else if ((fd
= s
->isFuncDeclaration()) != NULL
)
781 //printf("function %s\n", fd->toChars());
782 irs
->deferToObj
->push(fd
);
785 else if ((tm
= s
->isTemplateMixin()) != NULL
)
787 //printf("%s\n", tm->toChars());
790 for (size_t i
= 0; i
< tm
->members
->dim
; i
++)
792 Dsymbol
*sm
= (Dsymbol
*)tm
->members
->data
[i
];
793 e
= el_combine(e
, Dsymbol_toElem(sm
, irs
));
797 else if ((td
= s
->isTupleDeclaration()) != NULL
)
799 for (size_t i
= 0; i
< td
->objects
->dim
; i
++)
800 { Object
*o
= (Object
*)td
->objects
->data
[i
];
801 if (o
->dyncast() == DYNCAST_EXPRESSION
)
802 { Expression
*eo
= (Expression
*)o
;
803 if (eo
->op
== TOKdsymbol
)
804 { DsymbolExp
*se
= (DsymbolExp
*)eo
;
805 e
= el_combine(e
, Dsymbol_toElem(se
->s
, irs
));
810 else if ((tyd
= s
->isTypedefDeclaration()) != NULL
)
812 irs
->deferToObj
->push(tyd
);
817 elem
*DeclarationExp::toElem(IRState
*irs
)
820 //printf("DeclarationExp::toElem() %s\n", toChars());
821 e
= Dsymbol_toElem(declaration
, irs
);
825 /***************************************
828 elem
*ThisExp::toElem(IRState
*irs
)
832 //printf("ThisExp::toElem()\n");
838 fd
= var
->toParent2()->isFuncDeclaration();
840 ethis
= getEthis(loc
, irs
, fd
);
843 ethis
= el_var(irs
->sthis
);
845 el_setLoc(ethis
,loc
);
849 /***************************************
852 elem
*IntegerExp::toElem(IRState
*irs
)
855 e
= el_long(type
->totym(), value
);
860 /***************************************
863 elem
*RealExp::toElem(IRState
*irs
)
867 //printf("RealExp::toElem(%p)\n", this);
868 memset(&c
, 0, sizeof(c
));
869 ty
= type
->toBasetype()->totym();
890 type
->toBasetype()->print();
891 printf("ty = %d, tym = %x\n", type
->ty
, ty
);
894 return el_const(ty
, &c
);
898 /***************************************
901 elem
*ComplexExp::toElem(IRState
*irs
)
910 memset(&c
, 0, sizeof(c
));
915 c
.Vcfloat
.re
= (float) re
;
916 c
.Vcfloat
.im
= (float) im
;
920 c
.Vcdouble
.re
= (double) re
;
921 c
.Vcdouble
.im
= (double) im
;
932 return el_const(ty
, &c
);
935 /***************************************
938 elem
*NullExp::toElem(IRState
*irs
)
940 return el_long(type
->totym(), 0);
943 /***************************************
948 Module
*m
; // module we're generating code for
956 StringTab stringTab
[STSIZE
];
959 static Symbol
*assertexp_sfilename
= NULL
;
960 static char *assertexp_name
= NULL
;
961 static Module
*assertexp_mn
= NULL
;
963 void clearStringTab()
965 //printf("clearStringTab()\n");
966 memset(stringTab
, 0, sizeof(stringTab
));
969 assertexp_sfilename
= NULL
;
970 assertexp_name
= NULL
;
974 elem
*StringExp::toElem(IRState
*irs
)
977 Type
*tb
= type
->toBasetype();
981 printf("StringExp::toElem() %s, type = %s\n", toChars(), type
->toChars());
984 if (tb
->ty
== Tarray
)
991 printf("irs->m = %p\n", irs
->m
);
992 printf(" m = %s\n", irs
->m
->toChars());
993 printf(" len = %d\n", len
);
994 printf(" sz = %d\n", sz
);
996 for (size_t i
= 0; i
< STSIZE
; i
++)
998 st
= &stringTab
[(stidx
+ i
) % STSIZE
];
999 //if (!st->m) continue;
1000 //printf(" st.m = %s\n", st->m->toChars());
1001 //printf(" st.len = %d\n", st->len);
1002 //printf(" st.sz = %d\n", st->sz);
1003 if (st
->m
== irs
->m
&&
1007 memcmp(st
->string
, string
, sz
* len
) == 0)
1009 //printf("use cached value\n");
1010 si
= st
->si
; // use cached value
1015 stidx
= (stidx
+ 1) % STSIZE
;
1016 st
= &stringTab
[stidx
];
1021 si
= symbol_generate(SCstatic
,type_fake(TYdarray
));
1024 #if ELFOBJ // Burton
1031 st
->string
= string
;
1037 else if (tb
->ty
== Tsarray
)
1043 dtnzeros(&dt
, sz
); // leave terminating 0
1045 si
= symbol_generate(SCstatic
,type_allocn(TYarray
, tschar
));
1049 #if ELFOBJ // Burton
1056 else if (tb
->ty
== Tpointer
)
1059 e
->Eoper
= OPstring
;
1061 // Match MEM_PH_FREE for OPstring in ztc\el.c
1062 e
->EV
.ss
.Vstring
= (char *)mem_malloc((len
+ 1) * sz
);
1063 memcpy(e
->EV
.ss
.Vstring
, string
, (len
+ 1) * sz
);
1065 e
->EV
.ss
.Vstring
= (char *)string
;
1067 e
->EV
.ss
.Vstrlen
= (len
+ 1) * sz
;
1072 printf("type is %s\n", type
->toChars());
1079 elem
*NewExp::toElem(IRState
*irs
)
1084 //printf("NewExp::toElem() %s\n", toChars());
1085 t
= type
->toBasetype();
1086 //printf("\ttype = %s\n", t->toChars());
1087 if (t
->ty
== Tclass
)
1091 t
= newtype
->toBasetype();
1092 assert(t
->ty
== Tclass
);
1093 TypeClass
*tclass
= (TypeClass
*)(t
);
1094 ClassDeclaration
*cd
= tclass
->sym
;
1097 * 1) ex: call allocator
1098 * 2) ey: set vthis for nested classes
1099 * 3) ez: call constructor
1106 if (allocator
|| onstack
)
1112 /* Create an instance of the class on the stack,
1114 * Set ex to be the &stmp.
1116 Symbol
*s
= symbol_calloc(tclass
->sym
->toChars());
1117 s
->Sclass
= SCstruct
;
1118 s
->Sstruct
= struct_calloc();
1119 s
->Sstruct
->Sflags
|= 0;
1120 s
->Sstruct
->Salignsize
= tclass
->sym
->alignsize
;
1121 s
->Sstruct
->Sstructalign
= tclass
->sym
->structalign
;
1122 s
->Sstruct
->Sstructsize
= tclass
->sym
->structsize
;
1124 ::type
*tc
= type_alloc(TYstruct
);
1125 tc
->Ttag
= (Classsym
*)s
; // structure tag name
1129 Symbol
*stmp
= symbol_genauto(tc
);
1134 ex
= el_var(allocator
->toSymbol());
1135 ex
= callfunc(loc
, irs
, 1, type
, ex
, allocator
->type
,
1136 allocator
, allocator
->type
, NULL
, newargs
);
1139 si
= tclass
->sym
->toInitializer();
1145 ez
= el_copytree(ey
);
1150 ex
= el_una(OPind
, TYstruct
, ex
);
1151 ex
= el_bin(OPstreq
, TYnptr
, ex
, ei
);
1152 ex
->Enumbytes
= cd
->size(loc
);
1153 ex
= el_una(OPaddr
, TYnptr
, ex
);
1158 csym
= cd
->toSymbol();
1159 ex
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_NEWCLASS
]),el_ptr(csym
));
1165 ez
= el_copytree(ey
);
1175 { ClassDeclaration
*cdthis
= thisexp
->type
->isClassHandle();
1177 //printf("cd = %s\n", cd->toChars());
1178 //printf("cdthis = %s\n", cdthis->toChars());
1179 assert(cd
->isNested());
1181 Dsymbol
*cdp
= cd
->toParent2(); // class we're nested in
1184 //printf("member = %p\n", member);
1185 //printf("cdp = %s\n", cdp->toChars());
1186 //printf("cdthis = %s\n", cdthis->toChars());
1188 { int i
= cdp
->isClassDeclaration()->isBaseOf(cdthis
, &offset
);
1191 ethis
= thisexp
->toElem(irs
);
1193 ethis
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYint
, offset
));
1195 ey
= el_bin(OPadd
, TYnptr
, ey
, el_long(TYint
, cd
->vthis
->offset
));
1196 ey
= el_una(OPind
, TYnptr
, ey
);
1197 ey
= el_bin(OPeq
, TYnptr
, ey
, ethis
);
1199 //printf("ex: "); elem_print(ex);
1200 //printf("ey: "); elem_print(ey);
1201 //printf("ez: "); elem_print(ez);
1203 else if (cd
->isNested())
1204 { /* Initialize cd->vthis:
1205 * *(ey + cd.vthis.offset) = this;
1208 FuncDeclaration
*thisfd
= irs
->getFunc();
1210 Dsymbol
*cdp
= cd
->toParent2(); // class/func we're nested in
1213 { /* Class we're new'ing is a local class in this function:
1214 * void thisfd() { class cd { } }
1219 if (thisfd
->closureVars
.dim
)
1221 if (thisfd
->nestedFrameRef
)
1224 ethis
= el_ptr(irs
->sthis
);
1227 ethis
= el_var(irs
->sthis
);
1231 ethis
= el_long(TYnptr
, 0);
1233 if (thisfd
->closureVars
.dim
)
1235 if (thisfd
->nestedFrameRef
)
1238 ethis
->Eoper
= OPframeptr
;
1242 else if (thisfd
->vthis
&&
1243 (cdp
== thisfd
->toParent2() ||
1244 (cdp
->isClassDeclaration() &&
1245 cdp
->isClassDeclaration()->isBaseOf(thisfd
->toParent2()->isClassDeclaration(), &offset
)
1249 { /* Class we're new'ing is at the same level as thisfd
1251 assert(offset
== 0); // BUG: should handle this case
1252 ethis
= el_var(irs
->sthis
);
1256 ethis
= getEthis(loc
, irs
, cd
->toParent2());
1257 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
1260 ey
= el_bin(OPadd
, TYnptr
, ey
, el_long(TYint
, cd
->vthis
->offset
));
1261 ey
= el_una(OPind
, TYnptr
, ey
);
1262 ey
= el_bin(OPeq
, TYnptr
, ey
, ethis
);
1268 ez
= callfunc(loc
, irs
, 1, type
, ez
, ectype
, member
, member
->type
, NULL
, arguments
);
1270 e
= el_combine(ex
, ey
);
1271 e
= el_combine(e
, ez
);
1273 else if (t
->ty
== Tarray
)
1275 TypeDArray
*tda
= (TypeDArray
*)(t
);
1277 assert(arguments
&& arguments
->dim
>= 1);
1278 if (arguments
->dim
== 1)
1279 { // Single dimension array allocations
1280 Expression
*arg
= (Expression
*)arguments
->data
[0]; // gives array length
1281 e
= arg
->toElem(irs
);
1282 d_uns64 elemsize
= tda
->next
->size();
1284 // call _d_newT(ti, arg)
1285 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1286 int rtl
= t
->next
->isZeroInit() ? RTLSYM_NEWARRAYT
: RTLSYM_NEWARRAYIT
;
1287 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1290 { // Multidimensional array allocations
1291 e
= el_long(TYint
, arguments
->dim
);
1292 for (size_t i
= 0; i
< arguments
->dim
; i
++)
1294 Expression
*arg
= (Expression
*)arguments
->data
[i
]; // gives array length
1295 e
= el_param(arg
->toElem(irs
), e
);
1296 assert(t
->ty
== Tarray
);
1301 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1303 int rtl
= t
->isZeroInit() ? RTLSYM_NEWARRAYMT
: RTLSYM_NEWARRAYMIT
;
1304 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1307 else if (t
->ty
== Tpointer
)
1309 d_uns64 elemsize
= t
->next
->size();
1310 Expression
*di
= t
->next
->defaultInit();
1311 d_uns64 disize
= di
->type
->size();
1313 // call _d_newarrayT(ti, 1)
1314 e
= el_long(TYsize_t
, 1);
1315 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1317 int rtl
= t
->next
->isZeroInit() ? RTLSYM_NEWARRAYT
: RTLSYM_NEWARRAYIT
;
1318 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1320 // The new functions return an array, so convert to a pointer
1321 // e -> (unsigned)(e >> 32)
1322 e
= el_bin(OPshr
, TYdarray
, e
, el_long(TYint
, 32));
1323 e
= el_una(OP64_32
, t
->totym(), e
);
1334 elem
*SymOffExp::toElem(IRState
*irs
)
1337 Type
*tb
= var
->type
->toBasetype();
1338 FuncDeclaration
*fd
= NULL
;
1339 if (var
->toParent2())
1340 fd
= var
->toParent2()->isFuncDeclaration();
1342 //printf("SymOffExp::toElem(): %s\n", toChars());
1343 s
= var
->toSymbol();
1346 if (fd
&& fd
->nrvo_can
&& fd
->nrvo_var
== var
)
1351 if (s
->Sclass
== SCauto
&& s
->Ssymnum
== -1)
1353 assert(!var
->isImportedSymbol());
1355 // This code closely parallels that in VarExp::toElem()
1356 if (s
->Sclass
== SCauto
|| s
->Sclass
== SCparameter
)
1358 if (fd
&& fd
!= irs
->getFunc())
1359 { // 'var' is a variable in an enclosing function.
1363 ethis
= getEthis(loc
, irs
, fd
);
1364 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
1366 soffset
= s
->Soffset
;
1368 // If fd is a non-static member function, then ethis isn't the
1369 // frame pointer. We must offset it.
1372 soffset
-= fd
->vthis
->toSymbol()->Soffset
;
1377 e
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYnptr
, soffset
));
1378 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
1379 e
= el_una(OPind
, s
->ty(), e
);
1381 { e
= el_una(OPind
, TYnptr
, e
);
1382 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
1387 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
1388 { // Static arrays are really passed as pointers to the array
1389 // Out parameters are really references
1393 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, offset
));
1396 { e
= nrvo
? el_var(s
) : el_ptr(s
);
1397 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
1405 //////////////////////////// Unary ///////////////////////////////
1407 /***************************************
1410 elem
*NegExp::toElem(IRState
*irs
)
1412 elem
*e
= el_una(OPneg
, type
->totym(), e1
->toElem(irs
));
1417 /***************************************
1420 elem
*ComExp::toElem(IRState
*irs
)
1423 elem
*e1
= this->e1
->toElem(irs
);
1424 tym_t ty
= type
->totym();
1425 if (this->e1
->type
->toBasetype()->ty
== Tbool
)
1426 e
= el_bin(OPxor
, ty
, e1
, el_long(ty
, 1));
1428 e
= el_una(OPcom
,ty
,e1
);
1433 /***************************************
1436 elem
*NotExp::toElem(IRState
*irs
)
1438 elem
*e
= el_una(OPnot
, type
->totym(), e1
->toElem(irs
));
1444 /***************************************
1447 elem
*HaltExp::toElem(IRState
*irs
)
1457 /********************************************
1460 elem
*AssertExp::toElem(IRState
*irs
)
1463 Type
*t1
= e1
->type
->toBasetype();
1465 //printf("AssertExp::toElem() %s\n", toChars());
1466 if (global
.params
.useAssert
)
1468 e
= e1
->toElem(irs
);
1470 InvariantDeclaration
*inv
= (InvariantDeclaration
*)(void *)1;
1472 // If e1 is a class object, call the class invariant on it
1473 if (global
.params
.useInvariants
&& t1
->ty
== Tclass
&&
1474 !((TypeClass
*)t1
)->sym
->isInterfaceDeclaration())
1477 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[RTLSYM__DINVARIANT
]), e
);
1479 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[RTLSYM_DINVARIANT
]), e
);
1482 // If e1 is a struct object, call the struct invariant on it
1483 else if (global
.params
.useInvariants
&&
1484 t1
->ty
== Tpointer
&&
1485 t1
->nextOf()->ty
== Tstruct
&&
1486 (inv
= ((TypeStruct
*)t1
->nextOf())->sym
->inv
) != NULL
)
1488 e
= callfunc(loc
, irs
, 1, inv
->type
->nextOf(), e
, e1
->type
, inv
, inv
->type
, NULL
, NULL
);
1492 // Construct: (e1 || ModuleAssert(line))
1494 Module
*m
= irs
->blx
->module
;
1495 char *mname
= m
->srcfile
->toChars();
1497 //printf("filename = '%s'\n", loc.filename);
1498 //printf("module = '%s'\n", m->srcfile->toChars());
1500 /* If the source file name has changed, probably due
1501 * to a #line directive.
1503 if (loc
.filename
&& (msg
|| strcmp(loc
.filename
, mname
) != 0))
1508 //static Symbol *assertexp_sfilename = NULL;
1509 //static char *assertexp_name = NULL;
1510 //static Module *assertexp_mn = NULL;
1512 if (!assertexp_sfilename
|| strcmp(loc
.filename
, assertexp_name
) != 0 || assertexp_mn
!= m
)
1521 dtabytes(&dt
,TYnptr
, 0, len
+ 1, id
);
1523 assertexp_sfilename
= symbol_generate(SCstatic
,type_fake(TYdarray
));
1524 assertexp_sfilename
->Sdt
= dt
;
1525 assertexp_sfilename
->Sfl
= FLdata
;
1527 assertexp_sfilename
->Sseg
= CDATA
;
1529 outdata(assertexp_sfilename
);
1532 assertexp_name
= id
;
1535 efilename
= el_var(assertexp_sfilename
);
1538 { elem
*emsg
= msg
->toElem(irs
);
1539 ea
= el_var(rtlsym
[RTLSYM_DASSERT_MSG
]);
1540 ea
= el_bin(OPcall
, TYvoid
, ea
, el_params(el_long(TYint
, loc
.linnum
), efilename
, emsg
, NULL
));
1544 ea
= el_var(rtlsym
[RTLSYM_DASSERT
]);
1545 ea
= el_bin(OPcall
, TYvoid
, ea
, el_param(el_long(TYint
, loc
.linnum
), efilename
));
1550 sassert
= m
->toModuleAssert();
1551 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
1552 el_long(TYint
, loc
.linnum
));
1554 e
= el_bin(OPoror
,TYvoid
,e
,ea
);
1558 { // BUG: should replace assert(0); with a HLT instruction
1559 e
= el_long(TYint
, 0);
1565 elem
*PostExp::toElem(IRState
*irs
)
1569 e
= e1
->toElem(irs
);
1570 einc
= e2
->toElem(irs
);
1571 e
= el_bin((op
== TOKplusplus
) ? OPpostinc
: OPpostdec
,
1577 //////////////////////////// Binary ///////////////////////////////
1579 /********************************************
1582 elem
*BinExp::toElemBin(IRState
*irs
,int op
)
1584 //printf("toElemBin() '%s'\n", toChars());
1586 tym_t tym
= type
->totym();
1588 elem
*el
= e1
->toElem(irs
);
1589 elem
*er
= e2
->toElem(irs
);
1590 elem
*e
= el_bin(op
,tym
,el
,er
);
1595 /****************************************
1598 elem
*CommaExp::toElem(IRState
*irs
)
1601 elem
*eleft
= e1
->toElem(irs
);
1602 elem
*eright
= e2
->toElem(irs
);
1603 elem
*e
= el_combine(eleft
, eright
);
1610 /***************************************
1613 elem
*CondExp::toElem(IRState
*irs
)
1617 elem
*ec
= econd
->toElem(irs
);
1619 eleft
= e1
->toElem(irs
);
1620 tym_t ty
= eleft
->Ety
;
1621 if (global
.params
.cov
&& e1
->loc
.linnum
)
1622 eleft
= el_combine(incUsageElem(irs
, e1
->loc
), eleft
);
1624 eright
= e2
->toElem(irs
);
1625 if (global
.params
.cov
&& e2
->loc
.linnum
)
1626 eright
= el_combine(incUsageElem(irs
, e2
->loc
), eright
);
1628 elem
*e
= el_bin(OPcond
, ty
, ec
, el_bin(OPcolon
, ty
, eleft
, eright
));
1629 if (tybasic(ty
) == TYstruct
)
1630 e
->Enumbytes
= e1
->type
->size();
1635 /***************************************
1638 elem
*AddExp::toElem(IRState
*irs
)
1640 Type
*tb1
= e1
->type
->toBasetype();
1641 Type
*tb2
= e2
->type
->toBasetype();
1643 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1644 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
1647 error("Array operations not implemented");
1650 e
= toElemBin(irs
,OPadd
);
1654 /***************************************
1657 elem
*MinExp::toElem(IRState
*irs
)
1659 return toElemBin(irs
,OPmin
);
1662 /***************************************
1665 elem
*CatExp::toElem(IRState
*irs
)
1669 printf("CatExp::toElem()\n");
1673 Type
*tb1
= e1
->type
->toBasetype();
1674 Type
*tb2
= e2
->type
->toBasetype();
1678 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1679 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
1683 Type
*ta
= tb1
->nextOf() ? e1
->type
: e2
->type
;
1684 tn
= tb1
->nextOf() ? tb1
->nextOf() : tb2
->nextOf();
1686 if (e1
->op
== TOKcat
)
1692 ep
= eval_Darray(irs
, ce
->e2
);
1696 ce
= (CatExp
*)ce
->e1
;
1697 ep
= el_param(ep
, eval_Darray(irs
, ce
->e2
));
1698 } while (ce
->e1
->op
== TOKcat
);
1699 ep
= el_param(ep
, eval_Darray(irs
, ce
->e1
));
1704 ta
->getTypeInfo(NULL
)->toElem(irs
),
1706 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATNT
]), ep
);
1711 el_long(TYint
, tn
->size()),
1713 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATN
]), ep
);
1722 e1
= eval_Darray(irs
, this->e1
);
1723 e2
= eval_Darray(irs
, this->e2
);
1725 ep
= el_params(e2
, e1
, ta
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
1726 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATT
]), ep
);
1728 ep
= el_params(el_long(TYint
, tn
->size()), e2
, e1
, NULL
);
1729 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCAT
]), ep
);
1735 else if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1736 e2
->type
->equals(tb1
->next
))
1738 error("array cat with element not implemented");
1739 e
= el_long(TYint
, 0);
1747 /***************************************
1750 elem
*MulExp::toElem(IRState
*irs
)
1752 return toElemBin(irs
,OPmul
);
1755 /************************************
1758 elem
*DivExp::toElem(IRState
*irs
)
1760 return toElemBin(irs
,OPdiv
);
1763 /***************************************
1766 elem
*ModExp::toElem(IRState
*irs
)
1773 tym
= type
->totym();
1775 e1
= this->e1
->toElem(irs
);
1776 e2
= this->e2
->toElem(irs
);
1778 #if 0 // Now inlined
1779 if (this->e1
->type
->isfloating())
1782 switch (this->e1
->type
->ty
)
1786 e1
= el_una(OPf_d
, TYdouble
, e1
);
1787 e2
= el_una(OPf_d
, TYdouble
, e2
);
1790 e1
= el_una(OPd_ld
, TYldouble
, e1
);
1791 e2
= el_una(OPd_ld
, TYldouble
, e2
);
1800 ep
= el_param(e2
,e1
);
1801 e
= el_bin(OPcall
,tym
,el_var(rtlsym
[RTLSYM_MODULO
]),ep
);
1805 e
= el_bin(OPmod
,tym
,e1
,e2
);
1810 /***************************************
1813 elem
*CmpExp::toElem(IRState
*irs
)
1817 Type
*t1
= e1
->type
->toBasetype();
1818 Type
*t2
= e2
->type
->toBasetype();
1822 case TOKlt
: eop
= OPlt
; break;
1823 case TOKgt
: eop
= OPgt
; break;
1824 case TOKle
: eop
= OPle
; break;
1825 case TOKge
: eop
= OPge
; break;
1826 case TOKequal
: eop
= OPeqeq
; break;
1827 case TOKnotequal
: eop
= OPne
; break;
1829 // NCEG floating point compares
1830 case TOKunord
: eop
= OPunord
; break;
1831 case TOKlg
: eop
= OPlg
; break;
1832 case TOKleg
: eop
= OPleg
; break;
1833 case TOKule
: eop
= OPule
; break;
1834 case TOKul
: eop
= OPul
; break;
1835 case TOKuge
: eop
= OPuge
; break;
1836 case TOKug
: eop
= OPug
; break;
1837 case TOKue
: eop
= OPue
; break;
1842 if (!t1
->isfloating())
1844 // Convert from floating point compare to equivalent
1846 eop
= (enum OPER
)rel_integral(eop
);
1848 if ((int)eop
> 1 && t1
->ty
== Tclass
&& t2
->ty
== Tclass
)
1856 ec1
= e1
->toElem(irs
);
1857 ec2
= e2
->toElem(irs
);
1858 e
= el_bin(OPcall
,TYint
,el_var(rtlsym
[RTLSYM_OBJ_CMP
]),el_param(ec1
, ec2
));
1859 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
1862 else if ((int)eop
> 1 &&
1863 (t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
1864 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
1869 Type
*telement
= t1
->nextOf()->toBasetype();
1872 ea1
= e1
->toElem(irs
);
1873 ea1
= array_toDarray(t1
, ea1
);
1874 ea2
= e2
->toElem(irs
);
1875 ea2
= array_toDarray(t2
, ea2
);
1877 ep
= el_params(telement
->getInternalTypeInfo(NULL
)->toElem(irs
), ea2
, ea1
, NULL
);
1878 rtlfunc
= RTLSYM_ARRAYCMP
;
1879 e
= el_bin(OPcall
, TYint
, el_var(rtlsym
[rtlfunc
]), ep
);
1880 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
1887 /* The result is determinate, create:
1890 e
= toElemBin(irs
,OPcomma
);
1891 e
= el_bin(OPcomma
,e
->Ety
,e
,el_long(e
->Ety
,(int)eop
));
1894 e
= toElemBin(irs
,eop
);
1899 elem
*EqualExp::toElem(IRState
*irs
)
1901 //printf("EqualExp::toElem() %s\n", toChars());
1905 Type
*t1
= e1
->type
->toBasetype();
1906 Type
*t2
= e2
->type
->toBasetype();
1910 case TOKequal
: eop
= OPeqeq
; break;
1911 case TOKnotequal
: eop
= OPne
; break;
1917 //printf("EqualExp::toElem()\n");
1918 if (t1
->ty
== Tstruct
)
1919 { // Do bit compare of struct's
1924 es1
= e1
->toElem(irs
);
1925 es2
= e2
->toElem(irs
);
1927 es1
= addressElem(es1
, t1
);
1928 es2
= addressElem(es2
, t2
);
1930 es1
= el_una(OPaddr
, TYnptr
, es1
);
1931 es2
= el_una(OPaddr
, TYnptr
, es2
);
1933 e
= el_param(es1
, es2
);
1934 ecount
= el_long(TYint
, t1
->size());
1935 e
= el_bin(OPmemcmp
, TYint
, e
, ecount
);
1936 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
1940 else if (t1
->ty
== Tclass
&& t2
->ty
== Tclass
)
1945 ec1
= e1
->toElem(irs
);
1946 ec2
= e2
->toElem(irs
);
1947 e
= el_bin(OPcall
,TYint
,el_var(rtlsym
[RTLSYM_OBJ_EQ
]),el_param(ec1
, ec2
));
1950 else if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
1951 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
1956 Type
*telement
= t1
->nextOf()->toBasetype();
1959 ea1
= e1
->toElem(irs
);
1960 ea1
= array_toDarray(t1
, ea1
);
1961 ea2
= e2
->toElem(irs
);
1962 ea2
= array_toDarray(t2
, ea2
);
1964 ep
= el_params(telement
->getInternalTypeInfo(NULL
)->toElem(irs
), ea2
, ea1
, NULL
);
1965 rtlfunc
= RTLSYM_ARRAYEQ
;
1966 e
= el_bin(OPcall
, TYint
, el_var(rtlsym
[rtlfunc
]), ep
);
1967 if (op
== TOKnotequal
)
1968 e
= el_bin(OPxor
, TYint
, e
, el_long(TYint
, 1));
1972 e
= toElemBin(irs
, eop
);
1976 elem
*IdentityExp::toElem(IRState
*irs
)
1980 Type
*t1
= e1
->type
->toBasetype();
1981 Type
*t2
= e2
->type
->toBasetype();
1985 case TOKidentity
: eop
= OPeqeq
; break;
1986 case TOKnotidentity
: eop
= OPne
; break;
1992 //printf("IdentityExp::toElem() %s\n", toChars());
1994 if (t1
->ty
== Tstruct
)
1995 { // Do bit compare of struct's
2000 es1
= e1
->toElem(irs
);
2001 es1
= addressElem(es1
, e1
->type
);
2002 //es1 = el_una(OPaddr, TYnptr, es1);
2003 es2
= e2
->toElem(irs
);
2004 es2
= addressElem(es2
, e2
->type
);
2005 //es2 = el_una(OPaddr, TYnptr, es2);
2006 e
= el_param(es1
, es2
);
2007 ecount
= el_long(TYint
, t1
->size());
2008 e
= el_bin(OPmemcmp
, TYint
, e
, ecount
);
2009 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
2012 else if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
2013 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
2018 ea1
= e1
->toElem(irs
);
2019 ea1
= array_toDarray(t1
, ea1
);
2020 ea2
= e2
->toElem(irs
);
2021 ea2
= array_toDarray(t2
, ea2
);
2023 e
= el_bin(eop
, type
->totym(), ea1
, ea2
);
2027 e
= toElemBin(irs
, eop
);
2033 /***************************************
2036 elem
*InExp::toElem(IRState
*irs
)
2038 elem
*key
= e1
->toElem(irs
);
2039 elem
*aa
= e2
->toElem(irs
);
2042 TypeAArray
*taa
= (TypeAArray
*)e2
->type
->toBasetype();
2046 // aaIn(aa, keyti, key);
2048 if (key
->Ety
== TYstruct
)
2050 key
= el_una(OPstrpar
, TYstruct
, key
);
2051 key
->Enumbytes
= key
->E1
->Enumbytes
;
2052 assert(key
->Enumbytes
);
2055 Symbol
*s
= taa
->aaGetSymbol("In", 0);
2056 keyti
= taa
->key
->getInternalTypeInfo(NULL
)->toElem(irs
);
2057 ep
= el_params(key
, keyti
, aa
, NULL
);
2058 e
= el_bin(OPcall
, type
->totym(), el_var(s
), ep
);
2064 /***************************************
2067 elem
*RemoveExp::toElem(IRState
*irs
)
2069 Type
*tb
= e1
->type
->toBasetype();
2070 assert(tb
->ty
== Taarray
);
2071 TypeAArray
*taa
= (TypeAArray
*)tb
;
2072 elem
*ea
= e1
->toElem(irs
);
2073 elem
*ekey
= e2
->toElem(irs
);
2077 if (ekey
->Ety
== TYstruct
)
2079 ekey
= el_una(OPstrpar
, TYstruct
, ekey
);
2080 ekey
->Enumbytes
= ekey
->E1
->Enumbytes
;
2081 assert(ekey
->Enumbytes
);
2084 Symbol
*s
= taa
->aaGetSymbol("Del", 0);
2085 keyti
= taa
->key
->getInternalTypeInfo(NULL
)->toElem(irs
);
2086 ep
= el_params(ekey
, keyti
, ea
, NULL
);
2087 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
2093 /***************************************
2096 elem
*AssignExp::toElem(IRState
*irs
)
2102 //printf("AssignExp::toElem('%s')\n", toChars());
2103 t1b
= e1
->type
->toBasetype();
2105 // Look for array.length = n
2106 if (e1
->op
== TOKarraylength
)
2109 // _d_arraysetlength(e2, sizeelem, &ale->e1);
2111 ArrayLengthExp
*ale
= (ArrayLengthExp
*)e1
;
2118 p1
= e2
->toElem(irs
);
2119 p3
= ale
->e1
->toElem(irs
);
2120 p3
= addressElem(p3
, NULL
);
2121 t1
= ale
->e1
->type
->toBasetype();
2124 // call _d_arraysetlengthT(ti, e2, &ale->e1);
2125 p2
= t1
->getTypeInfo(NULL
)->toElem(irs
);
2126 ep
= el_params(p3
, p1
, p2
, NULL
); // c function
2127 r
= t1
->nextOf()->isZeroInit() ? RTLSYM_ARRAYSETLENGTHT
: RTLSYM_ARRAYSETLENGTHIT
;
2129 if (t1
->next
->isZeroInit())
2130 { p2
= t1
->getTypeInfo(NULL
)->toElem(irs
);
2131 ep
= el_params(p3
, p1
, p2
, NULL
); // c function
2132 r
= RTLSYM_ARRAYSETLENGTHT
;
2136 p2
= el_long(TYint
, t1
->next
->size());
2137 ep
= el_params(p3
, p2
, p1
, NULL
); // c function
2138 Expression
*init
= t1
->next
->defaultInit();
2139 ep
= el_param(el_long(TYint
, init
->type
->size()), ep
);
2140 elem
*ei
= init
->toElem(irs
);
2141 ep
= el_param(ei
, ep
);
2142 r
= RTLSYM_ARRAYSETLENGTH3
;
2146 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[r
]), ep
);
2151 // Look for array[]=n
2152 if (e1
->op
== TOKslice
)
2154 SliceExp
*are
= (SliceExp
*)(e1
);
2156 Type
*t2
= e2
->type
->toBasetype();
2158 // which we do if the 'next' types match
2160 { // Do a memset for array[]=n
2161 //printf("Lpair %s\n", toChars());
2162 SliceExp
*are
= (SliceExp
*)e1
;
2171 Type
*ta
= are
->e1
->type
->toBasetype();
2172 Type
*tb
= ta
->nextOf()->toBasetype();
2173 int sz
= tb
->size();
2174 tym_t tym
= type
->totym();
2176 n1
= are
->e1
->toElem(irs
);
2177 elwr
= are
->lwr
? are
->lwr
->toElem(irs
) : NULL
;
2178 eupr
= are
->upr
? are
->upr
->toElem(irs
) : NULL
;
2182 // Look for array[]=n
2183 if (ta
->ty
== Tsarray
)
2187 ts
= (TypeSArray
*) ta
;
2188 n1
= array_toPtr(ta
, n1
);
2189 enbytes
= ts
->dim
->toElem(irs
);
2192 einit
= resolveLengthVar(are
->lengthVar
, &n1
, ta
);
2194 else if (ta
->ty
== Tarray
)
2197 einit
= resolveLengthVar(are
->lengthVar
, &n1
, ta
);
2198 enbytes
= el_copytree(n1
);
2199 n1
= array_toPtr(ta
, n1
);
2200 enbytes
= el_una(OP64_32
, TYint
, enbytes
);
2202 else if (ta
->ty
== Tpointer
)
2205 enbytes
= el_long(TYint
, -1); // largest possible index
2209 // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr
2211 if (elwr
) elwr
= el_same(&elwrx
);
2213 if (eupr
) eupr
= el_same(&euprx
);
2216 printf("sz = %d\n", sz
);
2231 printf("enbytes\n");
2232 elem_print(enbytes
);
2234 einit
= el_combine(n1x
, einit
);
2235 einit
= el_combine(einit
, elwrx
);
2236 einit
= el_combine(einit
, euprx
);
2238 evalue
= this->e2
->toElem(irs
);
2243 printf("enbytes\n");
2244 elem_print(enbytes
);
2247 if (global
.params
.useArrayBounds
&& eupr
&& ta
->ty
!= Tpointer
)
2257 enbytes
= el_same(&enbytesx
);
2258 c1
= el_bin(OPle
, TYint
, el_copytree(eupr
), enbytesx
);
2259 c2
= el_bin(OPle
, TYint
, el_copytree(elwr
), el_copytree(eupr
));
2260 c1
= el_bin(OPandand
, TYint
, c1
, c2
);
2262 // Construct: (c1 || ModuleArray(line))
2265 sassert
= irs
->blx
->module
->toModuleArray();
2266 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
), el_long(TYint
, loc
.linnum
));
2267 eb
= el_bin(OPoror
,TYvoid
,c1
,ea
);
2268 einit
= el_combine(einit
, eb
);
2275 elwr2
= el_copytree(elwr
);
2276 elwr2
= el_bin(OPmul
, TYint
, elwr2
, el_long(TYint
, sz
));
2277 n1
= el_bin(OPadd
, TYnptr
, n1
, elwr2
);
2278 enbytes
= el_bin(OPmin
, TYint
, eupr
, elwr
);
2279 elength
= el_copytree(enbytes
);
2282 elength
= el_copytree(enbytes
);
2283 e
= setArray(n1
, enbytes
, tb
, evalue
);
2285 e
= el_pair(TYullong
, elength
, e
);
2287 e
= el_combine(einit
, e
);
2293 /* It's array1[]=array2[]
2301 eto
= e1
->toElem(irs
);
2302 efrom
= e2
->toElem(irs
);
2306 size
= t1
->nextOf()->size();
2307 esize
= el_long(TYint
, size
);
2309 if (e2
->type
->ty
== Tpointer
|| !global
.params
.useArrayBounds
)
2317 // Determine if elen is a constant
2318 if (eto
->Eoper
== OPpair
&&
2319 eto
->E1
->Eoper
== OPconst
)
2321 elen
= el_copytree(eto
->E1
);
2325 // It's not a constant, so pull it from the dynamic array
2326 elen
= el_una(OP64_32
, TYint
, el_copytree(ex
));
2329 esize
= el_bin(OPmul
, TYint
, elen
, esize
);
2330 epto
= array_toPtr(e1
->type
, ex
);
2331 epfr
= array_toPtr(e2
->type
, efrom
);
2332 e
= el_bin(OPmemcpy
, TYnptr
, epto
, el_param(epfr
, esize
));
2333 e
= el_pair(eto
->Ety
, el_copytree(elen
), e
);
2334 e
= el_combine(eto
, e
);
2339 // _d_arraycopy(eto, efrom, esize)
2341 // If eto is a static array, need to convert it to
2343 //if (are->e1->type->ty == Tsarray)
2344 // eto = sarray_toDarray(are->e1->type, eto);
2346 ep
= el_params(eto
, efrom
, esize
, NULL
);
2347 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[RTLSYM_ARRAYCOPY
]), ep
);
2354 if (e1
->op
== TOKindex
)
2362 ae
= (IndexExp
*)(e1
);
2363 ta
= ae
->e1
->type
->toBasetype();
2367 /* This will work if we can distinguish an assignment from
2368 * an initialization of the lvalue. It'll work if the latter.
2369 * If the former, because of aliasing of the return value with
2370 * function arguments, it'll fail.
2372 if (op
== TOKconstruct
&& e2
->op
== TOKcall
)
2373 { CallExp
*ce
= (CallExp
*)e2
;
2375 TypeFunction
*tf
= (TypeFunction
*)ce
->e1
->type
->toBasetype();
2376 if (tf
->ty
== Tfunction
&& tf
->retStyle() == RETstack
)
2378 elem
*ehidden
= e1
->toElem(irs
);
2379 ehidden
= el_una(OPaddr
, TYnptr
, ehidden
);
2380 assert(!irs
->ehidden
);
2381 irs
->ehidden
= ehidden
;
2382 e
= e2
->toElem(irs
);
2387 if (t1b
->ty
== Tstruct
)
2389 if (e2
->op
== TOKint64
)
2393 * memset(&struct, 0, struct.sizeof)
2395 elem
*el
= e1
->toElem(irs
);
2396 elem
*enbytes
= el_long(TYint
, e1
->type
->size());
2397 elem
*evalue
= el_long(TYint
, 0);
2399 el
= el_una(OPaddr
, TYnptr
, el
);
2400 e
= el_param(enbytes
, evalue
);
2401 e
= el_bin(OPmemset
,TYnptr
,el
,e
);
2403 //e = el_una(OPind, TYstruct, e);
2411 //printf("toElemBin() '%s'\n", toChars());
2413 tym
= type
->totym();
2415 e1
= this->e1
->toElem(irs
);
2417 if (e1
->Eoper
== OPind
)
2419 if (this->e2
->op
== TOKstructliteral
&&
2420 ex
->Eoper
== OPvar
&& ex
->EV
.sp
.Voffset
== 0)
2421 { StructLiteralExp
*se
= (StructLiteralExp
*)this->e2
;
2423 Symbol
*symSave
= se
->sym
;
2424 size_t soffsetSave
= se
->soffset
;
2425 int fillHolesSave
= se
->fillHoles
;
2427 se
->sym
= ex
->EV
.sp
.Vsym
;
2429 se
->fillHoles
= (op
== TOKconstruct
) ? 1 : 0;
2432 e
= this->e2
->toElem(irs
);
2435 se
->soffset
= soffsetSave
;
2436 se
->fillHoles
= fillHolesSave
;
2440 e2
= this->e2
->toElem(irs
);
2441 e
= el_bin(OPstreq
,tym
,e1
,e2
);
2442 e
->Enumbytes
= this->e1
->type
->size();
2448 e
= toElemBin(irs
,OPeq
);
2456 /***************************************
2459 elem
*AddAssignExp::toElem(IRState
*irs
)
2461 //printf("AddAssignExp::toElem() %s\n", toChars());
2463 Type
*tb1
= e1
->type
->toBasetype();
2464 Type
*tb2
= e2
->type
->toBasetype();
2466 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
2467 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
2470 error("Array operations not implemented");
2473 e
= toElemBin(irs
,OPaddass
);
2478 /***************************************
2481 elem
*MinAssignExp::toElem(IRState
*irs
)
2483 return toElemBin(irs
,OPminass
);
2486 /***************************************
2489 elem
*CatAssignExp::toElem(IRState
*irs
)
2491 //printf("CatAssignExp::toElem('%s')\n", toChars());
2493 Type
*tb1
= e1
->type
->toBasetype();
2494 Type
*tb2
= e2
->type
->toBasetype();
2496 if (tb1
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
2501 e1
= this->e1
->toElem(irs
);
2502 e1
= el_una(OPaddr
, TYnptr
, e1
);
2504 e2
= this->e2
->toElem(irs
);
2505 if (e2
->Ety
== TYstruct
)
2507 e2
= el_una(OPstrpar
, TYstruct
, e2
);
2508 e2
->Enumbytes
= e2
->E1
->Enumbytes
;
2509 assert(e2
->Enumbytes
);
2512 Type
*tb1n
= tb1
->nextOf()->toBasetype();
2513 if ((tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
2514 tb1n
->equals(tb2
->nextOf()->toBasetype()))
2517 ep
= el_params(e2
, e1
, this->e1
->type
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
2518 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDT
]), ep
);
2520 ep
= el_params(el_long(TYint
, tb1n
->size()), e2
, e1
, NULL
);
2521 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPEND
]), ep
);
2527 ep
= el_params(e2
, e1
, this->e1
->type
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
2528 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDCT
]), ep
);
2530 ep
= el_params(e2
, el_long(TYint
, tb1n
->size()), e1
, NULL
);
2531 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDC
]), ep
);
2542 /***************************************
2545 elem
*DivAssignExp::toElem(IRState
*irs
)
2547 return toElemBin(irs
,OPdivass
);
2551 /***************************************
2554 elem
*ModAssignExp::toElem(IRState
*irs
)
2556 return toElemBin(irs
,OPmodass
);
2560 /***************************************
2563 elem
*MulAssignExp::toElem(IRState
*irs
)
2565 return toElemBin(irs
,OPmulass
);
2569 /***************************************
2572 elem
*ShlAssignExp::toElem(IRState
*irs
)
2575 e
= toElemBin(irs
,OPshlass
);
2580 /***************************************
2583 elem
*ShrAssignExp::toElem(IRState
*irs
)
2585 return toElemBin(irs
,OPshrass
);
2589 /***************************************
2592 elem
*UshrAssignExp::toElem(IRState
*irs
)
2594 elem
*eleft
= e1
->toElem(irs
);
2595 eleft
->Ety
= touns(eleft
->Ety
);
2596 elem
*eright
= e2
->toElem(irs
);
2597 elem
*e
= el_bin(OPshrass
, type
->totym(), eleft
, eright
);
2603 /***************************************
2606 elem
*AndAssignExp::toElem(IRState
*irs
)
2608 return toElemBin(irs
,OPandass
);
2612 /***************************************
2615 elem
*OrAssignExp::toElem(IRState
*irs
)
2617 return toElemBin(irs
,OPorass
);
2621 /***************************************
2624 elem
*XorAssignExp::toElem(IRState
*irs
)
2626 return toElemBin(irs
,OPxorass
);
2630 /***************************************
2633 elem
*AndAndExp::toElem(IRState
*irs
)
2635 elem
*e
= toElemBin(irs
,OPandand
);
2636 if (global
.params
.cov
&& e2
->loc
.linnum
)
2637 e
->E2
= el_combine(incUsageElem(irs
, e2
->loc
), e
->E2
);
2642 /***************************************
2645 elem
*OrOrExp::toElem(IRState
*irs
)
2647 elem
*e
= toElemBin(irs
,OPoror
);
2648 if (global
.params
.cov
&& e2
->loc
.linnum
)
2649 e
->E2
= el_combine(incUsageElem(irs
, e2
->loc
), e
->E2
);
2654 /***************************************
2657 elem
*XorExp::toElem(IRState
*irs
)
2659 return toElemBin(irs
,OPxor
);
2663 /***************************************
2666 elem
*AndExp::toElem(IRState
*irs
)
2668 return toElemBin(irs
,OPand
);
2672 /***************************************
2675 elem
*OrExp::toElem(IRState
*irs
)
2677 return toElemBin(irs
,OPor
);
2681 /***************************************
2684 elem
*ShlExp::toElem(IRState
*irs
)
2686 return toElemBin(irs
, OPshl
);
2690 /***************************************
2693 elem
*ShrExp::toElem(IRState
*irs
)
2695 return toElemBin(irs
,OPshr
);
2699 /***************************************
2702 elem
*UshrExp::toElem(IRState
*irs
)
2704 elem
*eleft
= e1
->toElem(irs
);
2705 eleft
->Ety
= touns(eleft
->Ety
);
2706 elem
*eright
= e2
->toElem(irs
);
2707 elem
*e
= el_bin(OPshr
, type
->totym(), eleft
, eright
);
2712 elem
*TypeDotIdExp::toElem(IRState
*irs
)
2719 elem
*TypeExp::toElem(IRState
*irs
)
2722 printf("TypeExp::toElem()\n");
2724 error("type %s is not an expression", toChars());
2725 return el_long(TYint
, 0);
2728 elem
*ScopeExp::toElem(IRState
*irs
)
2730 error("%s is not an expression", sds
->toChars());
2731 return el_long(TYint
, 0);
2734 elem
*DotVarExp::toElem(IRState
*irs
)
2738 //printf("DotVarExp::toElem('%s')\n", toChars());
2740 VarDeclaration
*v
= var
->isVarDeclaration();
2743 error("%s is not a field", var
->toChars());
2746 elem
*e
= e1
->toElem(irs
);
2747 Type
*tb1
= e1
->type
->toBasetype();
2748 if (tb1
->ty
!= Tclass
&& tb1
->ty
!= Tpointer
)
2749 e
= el_una(OPaddr
, TYnptr
, e
);
2750 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, v
? v
->offset
: 0));
2751 e
= el_una(OPind
, type
->totym(), e
);
2752 if (tybasic(e
->Ety
) == TYstruct
)
2754 e
->Enumbytes
= type
->size();
2760 elem
*DelegateExp::toElem(IRState
*irs
)
2768 //printf("DelegateExp::toElem() '%s'\n", toChars());
2769 sfunc
= func
->toSymbol();
2770 if (func
->isNested())
2773 ethis
= getEthis(loc
, irs
, func
);
2777 ethis
= e1
->toElem(irs
);
2778 if (e1
->type
->ty
!= Tclass
&& e1
->type
->ty
!= Tpointer
)
2779 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
2781 if (e1
->op
== TOKsuper
)
2784 if (!func
->isThis())
2785 error("delegates are only for non-static functions");
2787 if (!func
->isVirtual() ||
2795 // Get pointer to function out of virtual table
2799 ep
= el_same(ðis
);
2800 ep
= el_una(OPind
, TYnptr
, ep
);
2801 vindex
= func
->vtblIndex
;
2803 // Build *(ep + vindex * 4)
2804 ep
= el_bin(OPadd
,TYnptr
,ep
,el_long(TYint
, vindex
* 4));
2805 ep
= el_una(OPind
,TYnptr
,ep
);
2808 // if (func->tintro)
2809 // func->error(loc, "cannot form delegate due to covariant return type");
2811 if (ethis
->Eoper
== OPcomma
)
2813 ethis
->E2
= el_pair(TYullong
, ethis
->E2
, ep
);
2814 ethis
->Ety
= TYullong
;
2818 e
= el_pair(TYullong
, ethis
, ep
);
2823 elem
*DotTypeExp::toElem(IRState
*irs
)
2825 // Just a pass-thru to e1
2828 //printf("DotTypeExp::toElem() %s\n", toChars());
2829 e
= e1
->toElem(irs
);
2834 elem
*CallExp::toElem(IRState
*irs
)
2836 //printf("CallExp::toElem('%s')\n", toChars());
2840 FuncDeclaration
*fd
;
2841 Type
*t1
= e1
->type
->toBasetype();
2844 elem
*ehidden
= irs
->ehidden
;
2845 irs
->ehidden
= NULL
;
2849 if (e1
->op
== TOKdotvar
&& t1
->ty
!= Tdelegate
)
2850 { DotVarExp
*dve
= (DotVarExp
*)e1
;
2852 fd
= dve
->var
->isFuncDeclaration();
2853 Expression
*ex
= dve
->e1
;
2858 case TOKsuper
: // super.member() calls directly
2859 case TOKdottype
: // type.member() calls directly
2864 ex
= ((CastExp
*)ex
)->e1
;
2873 ec
= dve
->e1
->toElem(irs
);
2874 ectype
= dve
->e1
->type
->toBasetype();
2876 else if (e1
->op
== TOKvar
)
2878 fd
= ((VarExp
*)e1
)->var
->isFuncDeclaration();
2880 if (fd
&& fd
->ident
== Id::alloca
&&
2881 !fd
->fbody
&& fd
->linkage
== LINKc
&&
2882 arguments
&& arguments
->dim
== 1)
2883 { Expression
*arg
= (Expression
*)arguments
->data
[0];
2884 arg
= arg
->optimize(WANTvalue
);
2885 if (arg
->isConst() && arg
->type
->isintegral())
2886 { integer_t sz
= arg
->toInteger();
2887 if (sz
> 0 && sz
< 0x40000)
2889 // It's an alloca(sz) of a fixed amount.
2890 // Replace with an array allocated on the stack
2891 // of the same size: char[sz] tmp;
2897 t
= type_allocn(TYarray
, tschar
);
2899 stmp
= symbol_genauto(t
);
2907 ec
= e1
->toElem(irs
);
2911 ec
= e1
->toElem(irs
);
2913 ec
= callfunc(loc
, irs
, directcall
, type
, ec
, ectype
, fd
, t1
, ehidden
, arguments
);
2918 elem
*AddrExp::toElem(IRState
*irs
)
2922 //printf("AddrExp::toElem('%s')\n", toChars());
2924 e
= e1
->toElem(irs
);
2925 e
= addressElem(e
, e1
->type
);
2927 e
->Ety
= type
->totym();
2932 elem
*PtrExp::toElem(IRState
*irs
)
2935 //printf("PtrExp::toElem() %s\n", toChars());
2936 e
= e1
->toElem(irs
);
2937 e
= el_una(OPind
,type
->totym(),e
);
2938 if (tybasic(e
->Ety
) == TYstruct
)
2940 e
->Enumbytes
= type
->size();
2946 elem
*BoolExp::toElem(IRState
*irs
)
2949 e1
= this->e1
->toElem(irs
);
2950 return el_una(OPbool
,type
->totym(),e1
);
2953 elem
*DeleteExp::toElem(IRState
*irs
)
2958 //printf("DeleteExp::toElem()\n");
2959 if (e1
->op
== TOKindex
)
2961 IndexExp
*ae
= (IndexExp
*)(e1
);
2962 tb
= ae
->e1
->type
->toBasetype();
2963 if (tb
->ty
== Taarray
)
2965 TypeAArray
*taa
= (TypeAArray
*)tb
;
2966 elem
*ea
= ae
->e1
->toElem(irs
);
2967 elem
*ekey
= ae
->e2
->toElem(irs
);
2971 if (ekey
->Ety
== TYstruct
)
2973 ekey
= el_una(OPstrpar
, TYstruct
, ekey
);
2974 ekey
->Enumbytes
= ekey
->E1
->Enumbytes
;
2975 assert(ekey
->Enumbytes
);
2978 Symbol
*s
= taa
->aaGetSymbol("Del", 0);
2979 keyti
= taa
->key
->getInternalTypeInfo(NULL
)->toElem(irs
);
2980 ep
= el_params(ekey
, keyti
, ea
, NULL
);
2981 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
2985 //e1->type->print();
2986 e
= e1
->toElem(irs
);
2987 rtl
= RTLSYM_DELCLASS
;
2988 tb
= e1
->type
->toBasetype();
2992 e
= addressElem(e
, e1
->type
);
2993 rtl
= RTLSYM_DELARRAY
;
2997 if (e1
->op
== TOKvar
)
2998 { VarExp
*ve
= (VarExp
*)e1
;
2999 if (ve
->var
->isVarDeclaration() &&
3000 ve
->var
->isVarDeclaration()->onstack
)
3002 rtl
= RTLSYM_CALLFINALIZER
;
3003 if (tb
->isClassHandle()->isInterfaceDeclaration())
3004 rtl
= RTLSYM_CALLINTERFACEFINALIZER
;
3008 e
= addressElem(e
, e1
->type
);
3009 rtl
= RTLSYM_DELCLASS
;
3010 if (tb
->isClassHandle()->isInterfaceDeclaration())
3011 rtl
= RTLSYM_DELINTERFACE
;
3015 e
= addressElem(e
, e1
->type
);
3016 rtl
= RTLSYM_DELMEMORY
;
3023 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[rtl
]), e
);
3030 elem
*CastExp::toElem(IRState
*irs
)
3041 printf("CastExp::toElem()\n");
3043 printf("\tfrom: %s\n", e1
->type
->toChars());
3044 printf("\tto : %s\n", to
->toChars());
3047 e
= e1
->toElem(irs
);
3048 tfrom
= e1
->type
->toBasetype();
3049 t
= to
->toBasetype(); // skip over typedef's
3050 if (t
->equals(tfrom
))
3054 //printf("fty = %d\n", fty);
3057 if (tty
== Tpointer
&& fty
== Tarray
3059 && (t
->next
->ty
== Tvoid
|| t
->next
->equals(e1
->type
->next
))
3063 if (e
->Eoper
== OPvar
)
3066 e
= el_una(OPaddr
, TYnptr
, e
);
3067 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, 4));
3068 e
= el_una(OPind
,t
->totym(),e
);
3072 // e1 -> (unsigned)(e1 >> 32)
3073 e
= el_bin(OPshr
, TYullong
, e
, el_long(TYint
, 32));
3074 e
= el_una(OP64_32
, t
->totym(), e
);
3079 if (tty
== Tpointer
&& fty
== Tsarray
3081 && (t
->next
->ty
== Tvoid
|| t
->next
->equals(e1
->type
->next
))
3086 e
= el_una(OPaddr
, TYnptr
, e
);
3090 // Convert from static array to dynamic array
3091 if (tty
== Tarray
&& fty
== Tsarray
)
3093 e
= sarray_toDarray(tfrom
, t
, e
);
3097 // Convert from dynamic array to dynamic array
3098 if (tty
== Tarray
&& fty
== Tarray
)
3100 unsigned fsize
= tfrom
->nextOf()->size();
3101 unsigned tsize
= t
->nextOf()->size();
3107 ep
= el_params(e
, el_long(TYint
, fsize
), el_long(TYint
, tsize
), NULL
);
3108 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[RTLSYM_ARRAYCAST
]), ep
);
3113 // Casting from base class to derived class requires a runtime check
3114 if (fty
== Tclass
&& tty
== Tclass
)
3116 // Casting from derived class to base class is a no-op
3117 ClassDeclaration
*cdfrom
;
3118 ClassDeclaration
*cdto
;
3120 int rtl
= RTLSYM_DYNAMIC_CAST
;
3122 cdfrom
= e1
->type
->isClassHandle();
3123 cdto
= t
->isClassHandle();
3124 if (cdfrom
->isInterfaceDeclaration())
3126 rtl
= RTLSYM_INTERFACE_CAST
;
3127 if (cdfrom
->isCOMinterface())
3129 if (cdto
->isCOMinterface())
3131 /* Casting from a com interface to a com interface
3132 * is always a 'paint' operation
3137 /* Casting from a COM interface to a class
3138 * always results in null because there is no runtime
3139 * information available to do it.
3141 * Casting from a COM interface to a non-COM interface
3142 * always results in null because there's no way one
3143 * can be derived from the other.
3145 e
= el_bin(OPcomma
, TYnptr
, e
, el_long(TYnptr
, 0));
3149 if (cdto
->isBaseOf(cdfrom
, &offset
) && offset
!= OFFSET_RUNTIME
)
3151 /* The offset from cdfrom=>cdto is known at compile time.
3154 //printf("offset = %d\n", offset);
3156 { /* Rewrite cast as (e ? e + offset : null)
3161 if (e1
->op
== TOKthis
)
3162 { // Assume 'this' is never null, so skip null check
3163 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, offset
));
3168 ex
= el_bin(OPadd
, TYnptr
, etmp
, el_long(TYint
, offset
));
3169 ex
= el_bin(OPcolon
, TYnptr
, ex
, el_long(TYnptr
, 0));
3170 e
= el_bin(OPcond
, TYnptr
, e
, ex
);
3176 /* The offset from cdfrom=>cdto can only be determined at runtime.
3180 ep
= el_param(el_ptr(cdto
->toSymbol()), e
);
3181 e
= el_bin(OPcall
, TYnptr
, el_var(rtlsym
[rtl
]), ep
);
3193 if (fty
== Tdelegate
)
3198 case Tchar
: tty
= Tuns8
; break;
3199 case Twchar
: tty
= Tuns16
; break;
3200 case Tdchar
: tty
= Tuns32
; break;
3201 case Tvoid
: goto Lpaint
;
3205 // Construct e?true:false
3208 e
= el_una(OPbool
, ttym
, e
);
3215 case Tpointer
: fty
= Tuns32
; break;
3216 case Tchar
: fty
= Tuns8
; break;
3217 case Twchar
: fty
= Tuns16
; break;
3218 case Tdchar
: fty
= Tuns32
; break;
3221 #define X(fty, tty) ((fty) * TMAX + (tty))
3229 case X(Tbit
,Tint16
):
3230 case X(Tbit
,Tuns16
):
3231 case X(Tbit
,Tint32
):
3232 case X(Tbit
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3233 case X(Tbit
,Tint64
):
3234 case X(Tbit
,Tuns64
):
3235 case X(Tbit
,Tfloat32
):
3236 case X(Tbit
,Tfloat64
):
3237 case X(Tbit
,Tfloat80
):
3238 case X(Tbit
,Tcomplex32
):
3239 case X(Tbit
,Tcomplex64
):
3240 case X(Tbit
,Tcomplex80
):
3241 e
= el_una(OPu8_16
, TYuint
, e
);
3244 case X(Tbit
,Timaginary32
):
3245 case X(Tbit
,Timaginary64
):
3246 case X(Tbit
,Timaginary80
): goto Lzero
;
3248 /* ============================= */
3250 case X(Tbool
,Tint8
):
3251 case X(Tbool
,Tuns8
):
3253 case X(Tbool
,Tint16
):
3254 case X(Tbool
,Tuns16
):
3255 case X(Tbool
,Tint32
):
3256 case X(Tbool
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3257 case X(Tbool
,Tint64
):
3258 case X(Tbool
,Tuns64
):
3259 case X(Tbool
,Tfloat32
):
3260 case X(Tbool
,Tfloat64
):
3261 case X(Tbool
,Tfloat80
):
3262 case X(Tbool
,Tcomplex32
):
3263 case X(Tbool
,Tcomplex64
):
3264 case X(Tbool
,Tcomplex80
):
3265 e
= el_una(OPu8_16
, TYuint
, e
);
3268 case X(Tbool
,Timaginary32
):
3269 case X(Tbool
,Timaginary64
):
3270 case X(Tbool
,Timaginary80
): goto Lzero
;
3272 /* ============================= */
3274 case X(Tint8
,Tuns8
): goto Lpaint
;
3275 case X(Tint8
,Tint16
):
3276 case X(Tint8
,Tuns16
):
3277 case X(Tint8
,Tint32
):
3278 case X(Tint8
,Tuns32
): eop
= OPs8_16
; goto Leop
;
3279 case X(Tint8
,Tint64
):
3280 case X(Tint8
,Tuns64
):
3281 case X(Tint8
,Tfloat32
):
3282 case X(Tint8
,Tfloat64
):
3283 case X(Tint8
,Tfloat80
):
3284 case X(Tint8
,Tcomplex32
):
3285 case X(Tint8
,Tcomplex64
):
3286 case X(Tint8
,Tcomplex80
):
3287 e
= el_una(OPs8_16
, TYint
, e
);
3290 case X(Tint8
,Timaginary32
):
3291 case X(Tint8
,Timaginary64
):
3292 case X(Tint8
,Timaginary80
): goto Lzero
;
3294 /* ============================= */
3296 case X(Tuns8
,Tint8
): goto Lpaint
;
3297 case X(Tuns8
,Tint16
):
3298 case X(Tuns8
,Tuns16
):
3299 case X(Tuns8
,Tint32
):
3300 case X(Tuns8
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3301 case X(Tuns8
,Tint64
):
3302 case X(Tuns8
,Tuns64
):
3303 case X(Tuns8
,Tfloat32
):
3304 case X(Tuns8
,Tfloat64
):
3305 case X(Tuns8
,Tfloat80
):
3306 case X(Tuns8
,Tcomplex32
):
3307 case X(Tuns8
,Tcomplex64
):
3308 case X(Tuns8
,Tcomplex80
):
3309 e
= el_una(OPu8_16
, TYuint
, e
);
3312 case X(Tuns8
,Timaginary32
):
3313 case X(Tuns8
,Timaginary64
):
3314 case X(Tuns8
,Timaginary80
): goto Lzero
;
3316 /* ============================= */
3318 case X(Tint16
,Tint8
):
3319 case X(Tint16
,Tuns8
): eop
= OP16_8
; goto Leop
;
3320 case X(Tint16
,Tuns16
): goto Lpaint
;
3321 case X(Tint16
,Tint32
):
3322 case X(Tint16
,Tuns32
): eop
= OPs16_32
; goto Leop
;
3323 case X(Tint16
,Tint64
):
3324 case X(Tint16
,Tuns64
): e
= el_una(OPs16_32
, TYint
, e
);
3327 case X(Tint16
,Tfloat32
):
3328 case X(Tint16
,Tfloat64
):
3329 case X(Tint16
,Tfloat80
):
3330 case X(Tint16
,Tcomplex32
):
3331 case X(Tint16
,Tcomplex64
):
3332 case X(Tint16
,Tcomplex80
):
3333 e
= el_una(OPs16_d
, TYdouble
, e
);
3336 case X(Tint16
,Timaginary32
):
3337 case X(Tint16
,Timaginary64
):
3338 case X(Tint16
,Timaginary80
): goto Lzero
;
3340 /* ============================= */
3342 case X(Tuns16
,Tint8
):
3343 case X(Tuns16
,Tuns8
): eop
= OP16_8
; goto Leop
;
3344 case X(Tuns16
,Tint16
): goto Lpaint
;
3345 case X(Tuns16
,Tint32
):
3346 case X(Tuns16
,Tuns32
): eop
= OPu16_32
; goto Leop
;
3347 case X(Tuns16
,Tint64
):
3348 case X(Tuns16
,Tuns64
):
3349 case X(Tuns16
,Tfloat64
):
3350 case X(Tuns16
,Tfloat32
):
3351 case X(Tuns16
,Tfloat80
):
3352 case X(Tuns16
,Tcomplex32
):
3353 case X(Tuns16
,Tcomplex64
):
3354 case X(Tuns16
,Tcomplex80
):
3355 e
= el_una(OPu16_32
, TYuint
, e
);
3358 case X(Tuns16
,Timaginary32
):
3359 case X(Tuns16
,Timaginary64
):
3360 case X(Tuns16
,Timaginary80
): goto Lzero
;
3362 /* ============================= */
3364 case X(Tint32
,Tint8
):
3365 case X(Tint32
,Tuns8
): e
= el_una(OP32_16
, TYshort
, e
);
3368 case X(Tint32
,Tint16
):
3369 case X(Tint32
,Tuns16
): eop
= OP32_16
; goto Leop
;
3370 case X(Tint32
,Tuns32
): goto Lpaint
;
3371 case X(Tint32
,Tint64
):
3372 case X(Tint32
,Tuns64
): eop
= OPs32_64
; goto Leop
;
3373 case X(Tint32
,Tfloat32
):
3374 case X(Tint32
,Tfloat64
):
3375 case X(Tint32
,Tfloat80
):
3376 case X(Tint32
,Tcomplex32
):
3377 case X(Tint32
,Tcomplex64
):
3378 case X(Tint32
,Tcomplex80
):
3379 e
= el_una(OPs32_d
, TYdouble
, e
);
3382 case X(Tint32
,Timaginary32
):
3383 case X(Tint32
,Timaginary64
):
3384 case X(Tint32
,Timaginary80
): goto Lzero
;
3386 /* ============================= */
3388 case X(Tuns32
,Tint8
):
3389 case X(Tuns32
,Tuns8
): e
= el_una(OP32_16
, TYshort
, e
);
3392 case X(Tuns32
,Tint16
):
3393 case X(Tuns32
,Tuns16
): eop
= OP32_16
; goto Leop
;
3394 case X(Tuns32
,Tint32
): goto Lpaint
;
3395 case X(Tuns32
,Tint64
):
3396 case X(Tuns32
,Tuns64
): eop
= OPu32_64
; goto Leop
;
3397 case X(Tuns32
,Tfloat32
):
3398 case X(Tuns32
,Tfloat64
):
3399 case X(Tuns32
,Tfloat80
):
3400 case X(Tuns32
,Tcomplex32
):
3401 case X(Tuns32
,Tcomplex64
):
3402 case X(Tuns32
,Tcomplex80
):
3403 e
= el_una(OPu32_d
, TYdouble
, e
);
3406 case X(Tuns32
,Timaginary32
):
3407 case X(Tuns32
,Timaginary64
):
3408 case X(Tuns32
,Timaginary80
): goto Lzero
;
3410 /* ============================= */
3412 case X(Tint64
,Tint8
):
3413 case X(Tint64
,Tuns8
):
3414 case X(Tint64
,Tint16
):
3415 case X(Tint64
,Tuns16
): e
= el_una(OP64_32
, TYint
, e
);
3418 case X(Tint64
,Tint32
):
3419 case X(Tint64
,Tuns32
): eop
= OP64_32
; goto Leop
;
3420 case X(Tint64
,Tuns64
): goto Lpaint
;
3421 case X(Tint64
,Tfloat32
):
3422 case X(Tint64
,Tfloat64
):
3423 case X(Tint64
,Tfloat80
):
3424 case X(Tint64
,Tcomplex32
):
3425 case X(Tint64
,Tcomplex64
):
3426 case X(Tint64
,Tcomplex80
):
3427 e
= el_una(OPs64_d
, TYdouble
, e
);
3430 case X(Tint64
,Timaginary32
):
3431 case X(Tint64
,Timaginary64
):
3432 case X(Tint64
,Timaginary80
): goto Lzero
;
3434 /* ============================= */
3436 case X(Tuns64
,Tint8
):
3437 case X(Tuns64
,Tuns8
):
3438 case X(Tuns64
,Tint16
):
3439 case X(Tuns64
,Tuns16
): e
= el_una(OP64_32
, TYint
, e
);
3442 case X(Tuns64
,Tint32
):
3443 case X(Tuns64
,Tuns32
): eop
= OP64_32
; goto Leop
;
3444 case X(Tuns64
,Tint64
): goto Lpaint
;
3445 case X(Tuns64
,Tfloat32
):
3446 case X(Tuns64
,Tfloat64
):
3447 case X(Tuns64
,Tfloat80
):
3448 case X(Tuns64
,Tcomplex32
):
3449 case X(Tuns64
,Tcomplex64
):
3450 case X(Tuns64
,Tcomplex80
):
3451 e
= el_una(OPu64_d
, TYdouble
, e
);
3454 case X(Tuns64
,Timaginary32
):
3455 case X(Tuns64
,Timaginary64
):
3456 case X(Tuns64
,Timaginary80
): goto Lzero
;
3458 /* ============================= */
3460 case X(Tfloat32
,Tint8
):
3461 case X(Tfloat32
,Tuns8
):
3462 case X(Tfloat32
,Tint16
):
3463 case X(Tfloat32
,Tuns16
):
3464 case X(Tfloat32
,Tint32
):
3465 case X(Tfloat32
,Tuns32
):
3466 case X(Tfloat32
,Tint64
):
3467 case X(Tfloat32
,Tuns64
):
3468 case X(Tfloat32
,Tfloat80
): e
= el_una(OPf_d
, TYdouble
, e
);
3471 case X(Tfloat32
,Tfloat64
): eop
= OPf_d
; goto Leop
;
3472 case X(Tfloat32
,Timaginary32
): goto Lzero
;
3473 case X(Tfloat32
,Timaginary64
): goto Lzero
;
3474 case X(Tfloat32
,Timaginary80
): goto Lzero
;
3475 case X(Tfloat32
,Tcomplex32
):
3476 case X(Tfloat32
,Tcomplex64
):
3477 case X(Tfloat32
,Tcomplex80
):
3478 e
= el_bin(OPadd
,TYcfloat
,el_long(TYifloat
,0),e
);
3482 /* ============================= */
3484 case X(Tfloat64
,Tint8
):
3485 case X(Tfloat64
,Tuns8
): e
= el_una(OPd_s16
, TYshort
, e
);
3488 case X(Tfloat64
,Tint16
): eop
= OPd_s16
; goto Leop
;
3489 case X(Tfloat64
,Tuns16
): eop
= OPd_u16
; goto Leop
;
3490 case X(Tfloat64
,Tint32
): eop
= OPd_s32
; goto Leop
;
3491 case X(Tfloat64
,Tuns32
): eop
= OPd_u32
; goto Leop
;
3492 case X(Tfloat64
,Tint64
): eop
= OPd_s64
; goto Leop
;
3493 case X(Tfloat64
,Tuns64
): eop
= OPd_u64
; goto Leop
;
3494 case X(Tfloat64
,Tfloat32
): eop
= OPd_f
; goto Leop
;
3495 case X(Tfloat64
,Tfloat80
): eop
= OPd_ld
; goto Leop
;
3496 case X(Tfloat64
,Timaginary32
): goto Lzero
;
3497 case X(Tfloat64
,Timaginary64
): goto Lzero
;
3498 case X(Tfloat64
,Timaginary80
): goto Lzero
;
3499 case X(Tfloat64
,Tcomplex32
):
3500 case X(Tfloat64
,Tcomplex64
):
3501 case X(Tfloat64
,Tcomplex80
):
3502 e
= el_bin(OPadd
,TYcfloat
,el_long(TYidouble
,0),e
);
3506 /* ============================= */
3508 case X(Tfloat80
,Tint8
):
3509 case X(Tfloat80
,Tuns8
):
3510 case X(Tfloat80
,Tint16
):
3511 case X(Tfloat80
,Tuns16
):
3512 case X(Tfloat80
,Tint32
):
3513 case X(Tfloat80
,Tuns32
):
3514 case X(Tfloat80
,Tint64
):
3515 case X(Tfloat80
,Tuns64
):
3516 case X(Tfloat80
,Tfloat32
): e
= el_una(OPld_d
, TYdouble
, e
);
3519 case X(Tfloat80
,Tfloat64
): eop
= OPld_d
; goto Leop
;
3520 case X(Tfloat80
,Timaginary32
): goto Lzero
;
3521 case X(Tfloat80
,Timaginary64
): goto Lzero
;
3522 case X(Tfloat80
,Timaginary80
): goto Lzero
;
3523 case X(Tfloat80
,Tcomplex32
):
3524 case X(Tfloat80
,Tcomplex64
):
3525 case X(Tfloat80
,Tcomplex80
):
3526 e
= el_bin(OPadd
,TYcldouble
,e
,el_long(TYildouble
,0));
3530 /* ============================= */
3532 case X(Timaginary32
,Tint8
):
3533 case X(Timaginary32
,Tuns8
):
3534 case X(Timaginary32
,Tint16
):
3535 case X(Timaginary32
,Tuns16
):
3536 case X(Timaginary32
,Tint32
):
3537 case X(Timaginary32
,Tuns32
):
3538 case X(Timaginary32
,Tint64
):
3539 case X(Timaginary32
,Tuns64
):
3540 case X(Timaginary32
,Tfloat32
):
3541 case X(Timaginary32
,Tfloat64
):
3542 case X(Timaginary32
,Tfloat80
): goto Lzero
;
3543 case X(Timaginary32
,Timaginary64
): eop
= OPf_d
; goto Leop
;
3544 case X(Timaginary32
,Timaginary80
):
3545 e
= el_una(OPf_d
, TYidouble
, e
);
3548 case X(Timaginary32
,Tcomplex32
):
3549 case X(Timaginary32
,Tcomplex64
):
3550 case X(Timaginary32
,Tcomplex80
):
3551 e
= el_bin(OPadd
,TYcfloat
,el_long(TYfloat
,0),e
);
3555 /* ============================= */
3557 case X(Timaginary64
,Tint8
):
3558 case X(Timaginary64
,Tuns8
):
3559 case X(Timaginary64
,Tint16
):
3560 case X(Timaginary64
,Tuns16
):
3561 case X(Timaginary64
,Tint32
):
3562 case X(Timaginary64
,Tuns32
):
3563 case X(Timaginary64
,Tint64
):
3564 case X(Timaginary64
,Tuns64
):
3565 case X(Timaginary64
,Tfloat32
):
3566 case X(Timaginary64
,Tfloat64
):
3567 case X(Timaginary64
,Tfloat80
): goto Lzero
;
3568 case X(Timaginary64
,Timaginary32
): eop
= OPd_f
; goto Leop
;
3569 case X(Timaginary64
,Timaginary80
): eop
= OPd_ld
; goto Leop
;
3570 case X(Timaginary64
,Tcomplex32
):
3571 case X(Timaginary64
,Tcomplex64
):
3572 case X(Timaginary64
,Tcomplex80
):
3573 e
= el_bin(OPadd
,TYcdouble
,el_long(TYdouble
,0),e
);
3577 /* ============================= */
3579 case X(Timaginary80
,Tint8
):
3580 case X(Timaginary80
,Tuns8
):
3581 case X(Timaginary80
,Tint16
):
3582 case X(Timaginary80
,Tuns16
):
3583 case X(Timaginary80
,Tint32
):
3584 case X(Timaginary80
,Tuns32
):
3585 case X(Timaginary80
,Tint64
):
3586 case X(Timaginary80
,Tuns64
):
3587 case X(Timaginary80
,Tfloat32
):
3588 case X(Timaginary80
,Tfloat64
):
3589 case X(Timaginary80
,Tfloat80
): goto Lzero
;
3590 case X(Timaginary80
,Timaginary32
): e
= el_una(OPf_d
, TYidouble
, e
);
3593 case X(Timaginary80
,Timaginary64
): eop
= OPld_d
; goto Leop
;
3594 case X(Timaginary80
,Tcomplex32
):
3595 case X(Timaginary80
,Tcomplex64
):
3596 case X(Timaginary80
,Tcomplex80
):
3597 e
= el_bin(OPadd
,TYcldouble
,el_long(TYldouble
,0),e
);
3601 /* ============================= */
3603 case X(Tcomplex32
,Tint8
):
3604 case X(Tcomplex32
,Tuns8
):
3605 case X(Tcomplex32
,Tint16
):
3606 case X(Tcomplex32
,Tuns16
):
3607 case X(Tcomplex32
,Tint32
):
3608 case X(Tcomplex32
,Tuns32
):
3609 case X(Tcomplex32
,Tint64
):
3610 case X(Tcomplex32
,Tuns64
):
3611 case X(Tcomplex32
,Tfloat32
):
3612 case X(Tcomplex32
,Tfloat64
):
3613 case X(Tcomplex32
,Tfloat80
):
3614 e
= el_una(OPc_r
, TYfloat
, e
);
3617 case X(Tcomplex32
,Timaginary32
):
3618 case X(Tcomplex32
,Timaginary64
):
3619 case X(Tcomplex32
,Timaginary80
):
3620 e
= el_una(OPc_i
, TYifloat
, e
);
3623 case X(Tcomplex32
,Tcomplex64
):
3624 case X(Tcomplex32
,Tcomplex80
):
3625 e
= el_una(OPf_d
, TYcdouble
, e
);
3629 /* ============================= */
3631 case X(Tcomplex64
,Tint8
):
3632 case X(Tcomplex64
,Tuns8
):
3633 case X(Tcomplex64
,Tint16
):
3634 case X(Tcomplex64
,Tuns16
):
3635 case X(Tcomplex64
,Tint32
):
3636 case X(Tcomplex64
,Tuns32
):
3637 case X(Tcomplex64
,Tint64
):
3638 case X(Tcomplex64
,Tuns64
):
3639 case X(Tcomplex64
,Tfloat32
):
3640 case X(Tcomplex64
,Tfloat64
):
3641 case X(Tcomplex64
,Tfloat80
):
3642 e
= el_una(OPc_r
, TYdouble
, e
);
3645 case X(Tcomplex64
,Timaginary32
):
3646 case X(Tcomplex64
,Timaginary64
):
3647 case X(Tcomplex64
,Timaginary80
):
3648 e
= el_una(OPc_i
, TYidouble
, e
);
3651 case X(Tcomplex64
,Tcomplex32
): eop
= OPd_f
; goto Leop
;
3652 case X(Tcomplex64
,Tcomplex80
): eop
= OPd_ld
; goto Leop
;
3654 /* ============================= */
3656 case X(Tcomplex80
,Tint8
):
3657 case X(Tcomplex80
,Tuns8
):
3658 case X(Tcomplex80
,Tint16
):
3659 case X(Tcomplex80
,Tuns16
):
3660 case X(Tcomplex80
,Tint32
):
3661 case X(Tcomplex80
,Tuns32
):
3662 case X(Tcomplex80
,Tint64
):
3663 case X(Tcomplex80
,Tuns64
):
3664 case X(Tcomplex80
,Tfloat32
):
3665 case X(Tcomplex80
,Tfloat64
):
3666 case X(Tcomplex80
,Tfloat80
):
3667 e
= el_una(OPc_r
, TYldouble
, e
);
3670 case X(Tcomplex80
,Timaginary32
):
3671 case X(Tcomplex80
,Timaginary64
):
3672 case X(Tcomplex80
,Timaginary80
):
3673 e
= el_una(OPc_i
, TYildouble
, e
);
3676 case X(Tcomplex80
,Tcomplex32
):
3677 case X(Tcomplex80
,Tcomplex64
):
3678 e
= el_una(OPld_d
, TYcdouble
, e
);
3682 /* ============================= */
3688 //printf("fty = %d, tty = %d\n", fty, tty);
3689 error("e2ir: cannot cast from %s to %s", e1
->type
->toChars(), t
->toChars());
3693 e
= el_long(ttym
, 0);
3701 e
= el_una(eop
, ttym
, e
);
3705 // Adjust for any type paints
3706 t
= type
->toBasetype();
3707 e
->Ety
= t
->totym();
3713 elem
*ArrayLengthExp::toElem(IRState
*irs
)
3715 elem
*e
= e1
->toElem(irs
);
3716 e
= el_una(OP64_32
, type
->totym(), e
);
3721 elem
*SliceExp::toElem(IRState
*irs
)
3725 //printf("SliceExp::toElem()\n");
3726 t1
= e1
->type
->toBasetype();
3727 e
= e1
->toElem(irs
);
3736 einit
= resolveLengthVar(lengthVar
, &e
, t1
);
3738 sz
= t1
->nextOf()->size();
3740 elwr
= lwr
->toElem(irs
);
3741 eupr
= upr
->toElem(irs
);
3743 elwr2
= el_same(&elwr
);
3745 // Create an array reference where:
3746 // length is (upr - lwr)
3747 // pointer is (ptr + lwr*sz)
3748 // Combine as (length pair ptr)
3750 if (global
.params
.useArrayBounds
)
3752 // Checks (unsigned compares):
3753 // upr <= array.length
3763 if (t1
->ty
== Tpointer
)
3765 // Just do lwr <= upr check
3767 eupr2
= el_same(&eupr
);
3768 eupr2
->Ety
= TYuint
; // make sure unsigned comparison
3769 c1
= el_bin(OPle
, TYint
, elwr2
, eupr2
);
3770 c1
= el_combine(eupr
, c1
);
3773 else if (t1
->ty
== Tsarray
)
3774 { TypeSArray
*tsa
= (TypeSArray
*)t1
;
3775 integer_t length
= tsa
->dim
->toInteger();
3777 elength
= el_long(TYuint
, length
);
3780 else if (t1
->ty
== Tarray
)
3783 elength
= el_var(lengthVar
->toSymbol());
3787 e
= el_same(&elength
);
3788 elength
= el_una(OP64_32
, TYuint
, elength
);
3791 eupr2
= el_same(&eupr
);
3792 c1
= el_bin(OPle
, TYint
, eupr
, elength
);
3793 eupr2
->Ety
= TYuint
; // make sure unsigned comparison
3794 c2
= el_bin(OPle
, TYint
, elwr2
, eupr2
);
3795 c1
= el_bin(OPandand
, TYint
, c1
, c2
); // (c1 && c2)
3798 // Construct: (c1 || ModuleArray(line))
3801 sassert
= irs
->blx
->module
->toModuleArray();
3802 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
), el_long(TYint
, loc
.linnum
));
3803 eb
= el_bin(OPoror
,TYvoid
,c1
,ea
);
3804 elwr
= el_combine(elwr
, eb
);
3806 elwr2
= el_copytree(elwr2
);
3807 eupr
= el_copytree(eupr2
);
3811 eptr
= array_toPtr(e1
->type
, e
);
3813 elem
*elength
= el_bin(OPmin
, TYint
, eupr
, elwr2
);
3814 eptr
= el_bin(OPadd
, TYnptr
, eptr
, el_bin(OPmul
, TYint
, el_copytree(elwr2
), el_long(TYint
, sz
)));
3816 e
= el_pair(TYullong
, elength
, eptr
);
3817 e
= el_combine(elwr
, e
);
3818 e
= el_combine(einit
, e
);
3820 else if (t1
->ty
== Tsarray
)
3822 e
= sarray_toDarray(t1
, NULL
, e
);
3828 elem
*IndexExp::toElem(IRState
*irs
)
3830 elem
*n1
= e1
->toElem(irs
);
3835 //printf("IndexExp::toElem() %s\n", toChars());
3836 t1
= e1
->type
->toBasetype();
3837 if (t1
->ty
== Taarray
)
3840 // *aaGet(aa, keyti, valuesize, index);
3842 TypeAArray
*taa
= (TypeAArray
*)t1
;
3845 int vsize
= taa
->next
->size();
3849 // n2 becomes the index, also known as the key
3850 n2
= e2
->toElem(irs
);
3851 if (n2
->Ety
== TYstruct
|| n2
->Ety
== TYarray
)
3853 n2
= el_una(OPstrpar
, TYstruct
, n2
);
3854 n2
->Enumbytes
= n2
->E1
->Enumbytes
;
3855 //printf("numbytes = %d\n", n2->Enumbytes);
3856 assert(n2
->Enumbytes
);
3858 valuesize
= el_long(TYuint
, vsize
); // BUG: should be TYsize_t
3859 //printf("valuesize: "); elem_print(valuesize);
3862 n1
= el_una(OPaddr
, TYnptr
, n1
);
3863 s
= taa
->aaGetSymbol("Get", 1);
3867 s
= taa
->aaGetSymbol("GetRvalue", 1);
3869 //printf("taa->key = %s\n", taa->key->toChars());
3870 keyti
= taa
->key
->getInternalTypeInfo(NULL
)->toElem(irs
);
3871 //keyti = taa->key->getTypeInfo(NULL)->toElem(irs);
3872 //printf("keyti:\n");
3873 //elem_print(keyti);
3874 ep
= el_params(n2
, valuesize
, keyti
, n1
, NULL
);
3875 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
3876 if (global
.params
.useArrayBounds
)
3883 // Construct: ((e || ModuleAssert(line)),n)
3886 sassert
= irs
->blx
->module
->toModuleArray();
3887 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
3888 el_long(TYint
, loc
.linnum
));
3889 e
= el_bin(OPoror
,TYvoid
,e
,ea
);
3890 e
= el_bin(OPcomma
, TYnptr
, e
, n
);
3892 e
= el_una(OPind
, type
->totym(), e
);
3893 if (tybasic(e
->Ety
) == TYstruct
)
3894 e
->Enumbytes
= type
->size();
3899 einit
= resolveLengthVar(lengthVar
, &n1
, t1
);
3900 n2
= e2
->toElem(irs
);
3902 if (global
.params
.useArrayBounds
)
3908 if (t1
->ty
== Tsarray
)
3909 { TypeSArray
*tsa
= (TypeSArray
*)t1
;
3910 integer_t length
= tsa
->dim
->toInteger();
3912 elength
= el_long(TYuint
, length
);
3915 else if (t1
->ty
== Tarray
)
3918 n1
= el_same(&elength
);
3919 elength
= el_una(OP64_32
, TYuint
, elength
);
3923 n2x
= el_bin(OPlt
, TYint
, n2x
, elength
);
3925 // Construct: (n2x || ModuleAssert(line))
3928 sassert
= irs
->blx
->module
->toModuleArray();
3929 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
3930 el_long(TYint
, loc
.linnum
));
3931 eb
= el_bin(OPoror
,TYvoid
,n2x
,ea
);
3935 n1
= array_toPtr(t1
, n1
);
3939 escale
= el_long(TYint
, t1
->nextOf()->size());
3940 n2
= el_bin(OPmul
, TYint
, n2
, escale
);
3941 e
= el_bin(OPadd
, TYnptr
, n1
, n2
);
3942 e
= el_una(OPind
, type
->totym(), e
);
3943 if (tybasic(e
->Ety
) == TYstruct
|| tybasic(e
->Ety
) == TYarray
)
3944 { e
->Ety
= TYstruct
;
3945 e
->Enumbytes
= type
->size();
3949 eb
= el_combine(einit
, eb
);
3950 e
= el_combine(eb
, e
);
3957 elem
*TupleExp::toElem(IRState
*irs
)
3960 //printf("TupleExp::toElem() %s\n", toChars());
3961 for (size_t i
= 0; i
< exps
->dim
; i
++)
3962 { Expression
*el
= (Expression
*)exps
->data
[i
];
3963 elem
*ep
= el
->toElem(irs
);
3965 e
= el_combine(e
, ep
);
3971 elem
*ArrayLiteralExp::toElem(IRState
*irs
)
3975 //printf("ArrayLiteralExp::toElem() %s\n", toChars());
3978 dim
= elements
->dim
;
3979 e
= el_long(TYint
, dim
);
3980 for (size_t i
= 0; i
< dim
; i
++)
3981 { Expression
*el
= (Expression
*)elements
->data
[i
];
3982 elem
*ep
= el
->toElem(irs
);
3984 if (tybasic(ep
->Ety
) == TYstruct
|| tybasic(ep
->Ety
) == TYarray
)
3986 ep
= el_una(OPstrpar
, TYstruct
, ep
);
3987 ep
->Enumbytes
= el
->type
->size();
3989 e
= el_param(ep
, e
);
3994 e
= el_long(TYint
, 0);
3996 Type
*tb
= type
->toBasetype();
3998 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
4000 // call _d_arrayliteralT(ti, dim, ...)
4001 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ARRAYLITERALT
]),e
);
4003 e
= el_param(e
, el_long(TYint
, tb
->next
->size()));
4005 // call _d_arrayliteral(size, dim, ...)
4006 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ARRAYLITERAL
]),e
);
4008 if (tb
->ty
== Tarray
)
4010 e
= el_pair(TYullong
, el_long(TYint
, dim
), e
);
4012 else if (tb
->ty
== Tpointer
)
4017 e
= el_una(OPind
,TYstruct
,e
);
4018 e
->Enumbytes
= type
->size();
4026 elem
*AssocArrayLiteralExp::toElem(IRState
*irs
)
4030 //printf("AssocArrayLiteralExp::toElem() %s\n", toChars());
4032 e
= el_long(TYint
, dim
);
4033 for (size_t i
= 0; i
< dim
; i
++)
4034 { Expression
*el
= (Expression
*)keys
->data
[i
];
4036 for (int j
= 0; j
< 2; j
++)
4038 elem
*ep
= el
->toElem(irs
);
4040 if (tybasic(ep
->Ety
) == TYstruct
|| tybasic(ep
->Ety
) == TYarray
)
4042 ep
= el_una(OPstrpar
, TYstruct
, ep
);
4043 ep
->Enumbytes
= el
->type
->size();
4045 //printf("[%d] %s\n", i, el->toChars());
4047 e
= el_param(ep
, e
);
4048 el
= (Expression
*)values
->data
[i
];
4051 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
4053 // call _d_assocarrayliteralT(ti, dim, ...)
4054 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ASSOCARRAYLITERALT
]),e
);
4061 /*******************************************
4062 * Generate elem to zero fill contents of Symbol stmp
4063 * from *poffset..offset2.
4064 * May store anywhere from 0..maxoff, as this function
4065 * tries to use aligned int stores whereever possible.
4066 * Update *poffset to end of initialized hole; *poffset will be >= offset2.
4069 elem
*fillHole(Symbol
*stmp
, size_t *poffset
, size_t offset2
, size_t maxoff
)
4073 while (*poffset
< offset2
)
4077 if (tybasic(stmp
->Stype
->Tty
) == TYnptr
)
4084 size_t sz
= maxoff
- *poffset
;
4086 { case 1: ty
= TYchar
; break;
4087 case 2: ty
= TYshort
; break;
4096 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, *poffset
));
4097 e1
= el_una(OPind
, ty
, e1
);
4098 e1
= el_bin(OPeq
, ty
, e1
, el_long(ty
, 0));
4099 e
= el_combine(e
, e1
);
4100 *poffset
+= tysize
[ty
];
4105 elem
*StructLiteralExp::toElem(IRState
*irs
)
4109 //printf("StructLiteralExp::toElem() %s\n", toChars());
4111 // struct symbol to initialize with the literal
4112 Symbol
*stmp
= sym
? sym
: symbol_genauto(sd
->type
->toCtype());
4118 /* Initialize all alignment 'holes' to zero.
4119 * Do before initializing fields, as the hole filling process
4120 * can spill over into the fields.
4123 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
4125 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
4126 VarDeclaration
*v
= s
->isVarDeclaration();
4129 e
= el_combine(e
, fillHole(stmp
, &offset
, v
->offset
, sd
->structsize
));
4130 size_t vend
= v
->offset
+ v
->type
->size();
4134 e
= el_combine(e
, fillHole(stmp
, &offset
, sd
->structsize
, sd
->structsize
));
4139 dim
= elements
->dim
;
4140 assert(dim
<= sd
->fields
.dim
);
4141 for (size_t i
= 0; i
< dim
; i
++)
4142 { Expression
*el
= (Expression
*)elements
->data
[i
];
4146 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
4147 VarDeclaration
*v
= s
->isVarDeclaration();
4151 if (tybasic(stmp
->Stype
->Tty
) == TYnptr
)
4152 { e1
= el_var(stmp
);
4153 e1
->EV
.sp
.Voffset
= soffset
;
4156 { e1
= el_ptr(stmp
);
4158 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, soffset
));
4160 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, v
->offset
));
4162 elem
*ep
= el
->toElem(irs
);
4164 Type
*t1b
= v
->type
->toBasetype();
4165 Type
*t2b
= el
->type
->toBasetype();
4166 if (t1b
->ty
== Tsarray
)
4168 if (t2b
->implicitConvTo(t1b
))
4169 { elem
*esize
= el_long(TYsize_t
, t1b
->size());
4170 ep
= array_toPtr(el
->type
, ep
);
4171 e1
= el_bin(OPmemcpy
, TYnptr
, e1
, el_param(ep
, esize
));
4175 elem
*edim
= el_long(TYsize_t
, t1b
->size() / t2b
->size());
4176 e1
= setArray(e1
, edim
, t2b
, ep
);
4181 tym_t ty
= v
->type
->totym();
4182 e1
= el_una(OPind
, ty
, e1
);
4184 e1
->Enumbytes
= v
->type
->size();
4185 e1
= el_bin(OPeq
, ty
, e1
, ep
);
4187 { e1
->Eoper
= OPstreq
;
4188 e1
->Enumbytes
= v
->type
->size();
4191 e
= el_combine(e
, e1
);
4195 elem
*ev
= el_var(stmp
);
4196 ev
->Enumbytes
= sd
->structsize
;
4197 e
= el_combine(e
, ev
);