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
, IRState
*irs
, int op
)
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;
541 default: r
= RTLSYM_MEMSETN
; break;
544 /* Determine if we need to do postblit
549 while (t
->ty
== Tsarray
)
550 t
= t
->nextOf()->toBasetype();
551 if (t
->ty
== Tstruct
)
552 { StructDeclaration
*sd
= ((TypeStruct
*)t
)->sym
;
554 { /* Need to do postblit.
555 * void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti);
557 r
= (op
== TOKconstruct
) ? RTLSYM_ARRAYSETCTOR
: RTLSYM_ARRAYSETASSIGN
;
558 evalue
= el_una(OPaddr
, TYnptr
, evalue
);
559 Expression
*ti
= tb
->getTypeInfo(NULL
);
560 elem
*eti
= ti
->toElem(irs
);
561 e
= el_params(eti
, edim
, evalue
, eptr
, NULL
);
562 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[r
]),e
);
568 if (r
== RTLSYM_MEMSETN
)
570 // void *_memsetn(void *p, void *value, int dim, int sizelem)
571 evalue
= el_una(OPaddr
, TYnptr
, evalue
);
572 elem
*esz
= el_long(TYint
, sz
);
573 e
= el_params(esz
, edim
, evalue
, eptr
, NULL
);
574 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[r
]),e
);
578 if (sz
> 1 && sz
<= 8 &&
579 evalue
->Eoper
== OPconst
&& el_allbits(evalue
, 0))
582 edim
= el_bin(OPmul
, TYuint
, edim
, el_long(TYuint
, sz
));
585 if (evalue
->Ety
== TYstruct
)
587 evalue
= el_una(OPstrpar
, TYstruct
, evalue
);
588 evalue
->Enumbytes
= evalue
->E1
->Enumbytes
;
589 assert(evalue
->Enumbytes
);
592 // Be careful about parameter side effect ordering
593 if (r
== RTLSYM_MEMSET8
)
595 e
= el_param(edim
, evalue
);
596 e
= el_bin(OPmemset
,TYnptr
,eptr
,e
);
600 e
= el_params(edim
, evalue
, eptr
, NULL
);
601 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[r
]),e
);
606 /***************************************
609 elem
*Expression::toElem(IRState
*irs
)
616 /************************************
619 elem
*SymbolExp::toElem(IRState
*irs
)
623 Type
*tb
= (op
== TOKsymoff
) ? var
->type
->toBasetype() : type
->toBasetype();
624 int offset
= (op
== TOKsymoff
) ? ((SymOffExp
*)this)->offset
: 0;
626 VarDeclaration
*v
= var
->isVarDeclaration();
628 //printf("SymbolExp::toElem('%s') %p\n", toChars(), this);
629 //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
630 if (op
== TOKvar
&& var
->needThis())
632 error("need 'this' to access member %s", toChars());
633 return el_long(TYint
, 0);
637 if (var
->toParent2())
638 fd
= var
->toParent2()->isFuncDeclaration();
641 if (fd
&& fd
->nrvo_can
&& fd
->nrvo_var
== var
)
647 if (s
->Sclass
== SCauto
|| s
->Sclass
== SCparameter
)
649 if (fd
&& fd
!= irs
->getFunc())
650 { // 'var' is a variable in an enclosing function.
654 ethis
= getEthis(loc
, irs
, fd
);
655 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
661 soffset
= s
->Soffset
;
662 /* If fd is a non-static member function of a class or struct,
663 * then ethis isn't the frame pointer.
664 * ethis is the 'this' pointer to the class/struct instance.
669 soffset
-= fd
->vthis
->toSymbol()->Soffset
;
671 //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
677 e
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYnptr
, soffset
));
679 e
= el_una(OPind
, TYnptr
, e
);
680 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
681 e
= el_una(OPind
, s
->ty(), e
);
682 else if (op
== TOKsymoff
&& nrvo
)
683 { e
= el_una(OPind
, TYnptr
, e
);
684 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
690 /* If var is a member of a closure
693 { assert(irs
->sclosure
);
694 e
= el_var(irs
->sclosure
);
695 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, v
->offset
));
697 { e
= el_una(OPind
, type
->totym(), e
);
698 if (tybasic(e
->Ety
) == TYstruct
)
699 e
->Enumbytes
= type
->size();
702 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
704 e
= el_una(OPind
, s
->ty(), e
);
706 else if (op
== TOKsymoff
&& nrvo
)
707 { e
= el_una(OPind
, TYnptr
, e
);
708 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
710 else if (op
== TOKsymoff
)
712 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
717 if (s
->Sclass
== SCauto
&& s
->Ssymnum
== -1)
719 //printf("\tadding symbol\n");
723 if (var
->isImportedSymbol())
725 assert(op
== TOKvar
);
726 e
= el_var(var
->toImport());
727 e
= el_una(OPind
,s
->ty(),e
);
729 else if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
730 { // Static arrays are really passed as pointers to the array
731 // Out parameters are really references
735 e
= el_una(OPind
, s
->ty(), e
);
737 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, offset
));
739 else if (op
== TOKvar
)
742 { e
= nrvo
? el_var(s
) : el_ptr(s
);
743 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
751 e
= el_una(OPind
, 0, e
);
753 if (tb
->ty
== Tfunction
)
759 e
->Ejty
= e
->Ety
= tym
;
760 if (tybasic(tym
) == TYstruct
)
762 e
->Enumbytes
= type
->size();
764 else if (tybasic(tym
) == TYarray
)
766 e
->Ejty
= e
->Ety
= TYstruct
;
767 e
->Enumbytes
= type
->size();
775 elem
*VarExp::toElem(IRState
*irs
)
779 Type
*tb
= type
->toBasetype();
781 VarDeclaration
*v
= var
->isVarDeclaration();
783 //printf("VarExp::toElem('%s') %p\n", toChars(), this);
784 //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
787 error("need 'this' to access member %s", toChars());
788 return el_long(TYint
, 0);
792 if (var
->toParent2())
793 fd
= var
->toParent2()->isFuncDeclaration();
796 if (fd
&& fd
->nrvo_can
&& fd
->nrvo_var
== var
)
802 if (s
->Sclass
== SCauto
|| s
->Sclass
== SCparameter
)
804 if (fd
&& fd
!= irs
->getFunc())
805 { // 'var' is a variable in an enclosing function.
809 ethis
= getEthis(loc
, irs
, fd
);
810 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
816 soffset
= s
->Soffset
;
817 /* If fd is a non-static member function of a class or struct,
818 * then ethis isn't the frame pointer.
819 * ethis is the 'this' pointer to the class/struct instance.
824 soffset
-= fd
->vthis
->toSymbol()->Soffset
;
826 //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
829 ethis
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYnptr
, soffset
));
830 e
= el_una(OPind
, 0, ethis
);
831 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
837 /* If var is a member of a closure
840 { assert(irs
->sclosure
);
841 e
= el_var(irs
->sclosure
);
842 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, v
->offset
));
843 e
= el_una(OPind
, type
->totym(), e
);
844 if (tybasic(e
->Ety
) == TYstruct
)
845 e
->Enumbytes
= type
->size();
848 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
853 if (s
->Sclass
== SCauto
&& s
->Ssymnum
== -1)
855 //printf("\tadding symbol\n");
859 if (var
->isImportedSymbol())
861 e
= el_var(var
->toImport());
862 e
= el_una(OPind
,s
->ty(),e
);
864 else if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
865 { // Static arrays are really passed as pointers to the array
866 // Out parameters are really references
870 e
= el_una(OPind
, s
->ty(), e
);
878 e
= el_una(OPind
, 0, e
);
880 if (tb
->ty
== Tfunction
)
886 e
->Ejty
= e
->Ety
= tym
;
887 if (tybasic(tym
) == TYstruct
)
889 e
->Enumbytes
= type
->size();
891 else if (tybasic(tym
) == TYarray
)
893 e
->Ejty
= e
->Ety
= TYstruct
;
894 e
->Enumbytes
= type
->size();
902 elem
*SymOffExp::toElem(IRState
*irs
)
905 Type
*tb
= var
->type
->toBasetype();
906 VarDeclaration
*v
= var
->isVarDeclaration();
907 FuncDeclaration
*fd
= NULL
;
908 if (var
->toParent2())
909 fd
= var
->toParent2()->isFuncDeclaration();
911 //printf("SymOffExp::toElem(): %s\n", toChars());
915 if (fd
&& fd
->nrvo_can
&& fd
->nrvo_var
== var
)
920 if (s
->Sclass
== SCauto
&& s
->Ssymnum
== -1)
922 assert(!var
->isImportedSymbol());
924 // This code closely parallels that in VarExp::toElem()
925 if (s
->Sclass
== SCauto
|| s
->Sclass
== SCparameter
)
927 if (fd
&& fd
!= irs
->getFunc())
928 { // 'var' is a variable in an enclosing function.
932 ethis
= getEthis(loc
, irs
, fd
);
933 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
939 soffset
= s
->Soffset
;
940 /* If fd is a non-static member function of a class or struct,
941 * then ethis isn't the frame pointer.
942 * ethis is the 'this' pointer to the class/struct instance.
947 soffset
-= fd
->vthis
->toSymbol()->Soffset
;
949 //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset);
954 e
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYnptr
, soffset
));
955 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
956 e
= el_una(OPind
, s
->ty(), e
);
958 { e
= el_una(OPind
, TYnptr
, e
);
959 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
965 /* If var is a member of a closure
968 { assert(irs
->sclosure
);
969 e
= el_var(irs
->sclosure
);
970 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, v
->offset
));
971 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
972 e
= el_una(OPind
, s
->ty(), e
);
974 { e
= el_una(OPind
, TYnptr
, e
);
975 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
980 if ((var
->isParameter() && tb
->ty
== Tsarray
) || var
->isOut() || var
->isRef())
981 { // Static arrays are really passed as pointers to the array
982 // Out parameters are really references
986 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, offset
));
989 { e
= nrvo
? el_var(s
) : el_ptr(s
);
990 e
= el_bin(OPadd
, e
->Ety
, e
, el_long(TYint
, offset
));
999 /**************************************
1002 elem
*FuncExp::toElem(IRState
*irs
)
1007 //printf("FuncExp::toElem() %s\n", toChars());
1012 elem
*ethis
= getEthis(loc
, irs
, fd
);
1013 e
= el_pair(TYullong
, ethis
, e
);
1016 irs
->deferToObj
->push(fd
);
1021 /**************************************
1024 elem
*Dsymbol_toElem(Dsymbol
*s
, IRState
*irs
)
1028 AttribDeclaration
*ad
;
1030 ClassDeclaration
*cd
;
1031 StructDeclaration
*sd
;
1032 FuncDeclaration
*fd
;
1034 TupleDeclaration
*td
;
1035 TypedefDeclaration
*tyd
;
1037 //printf("Dsymbol_toElem() %s\n", s->toChars());
1038 ad
= s
->isAttribDeclaration();
1041 Array
*decl
= ad
->include(NULL
, NULL
);
1042 if (decl
&& decl
->dim
)
1044 for (size_t i
= 0; i
< decl
->dim
; i
++)
1046 s
= (Dsymbol
*)decl
->data
[i
];
1047 e
= el_combine(e
, Dsymbol_toElem(s
, irs
));
1051 else if ((vd
= s
->isVarDeclaration()) != NULL
)
1055 return Dsymbol_toElem(s
, irs
);
1056 if (vd
->isStatic() || vd
->storage_class
& STCextern
)
1062 //printf("\tadding symbol '%s'\n", sp->Sident);
1067 ie
= vd
->init
->isExpInitializer();
1069 e
= ie
->exp
->toElem(irs
);
1073 else if ((cd
= s
->isClassDeclaration()) != NULL
)
1075 irs
->deferToObj
->push(s
);
1077 else if ((sd
= s
->isStructDeclaration()) != NULL
)
1079 irs
->deferToObj
->push(sd
);
1081 else if ((fd
= s
->isFuncDeclaration()) != NULL
)
1083 //printf("function %s\n", fd->toChars());
1084 irs
->deferToObj
->push(fd
);
1086 else if ((tm
= s
->isTemplateMixin()) != NULL
)
1088 //printf("%s\n", tm->toChars());
1091 for (size_t i
= 0; i
< tm
->members
->dim
; i
++)
1093 Dsymbol
*sm
= (Dsymbol
*)tm
->members
->data
[i
];
1094 e
= el_combine(e
, Dsymbol_toElem(sm
, irs
));
1098 else if ((td
= s
->isTupleDeclaration()) != NULL
)
1100 for (size_t i
= 0; i
< td
->objects
->dim
; i
++)
1101 { Object
*o
= (Object
*)td
->objects
->data
[i
];
1102 if (o
->dyncast() == DYNCAST_EXPRESSION
)
1103 { Expression
*eo
= (Expression
*)o
;
1104 if (eo
->op
== TOKdsymbol
)
1105 { DsymbolExp
*se
= (DsymbolExp
*)eo
;
1106 e
= el_combine(e
, Dsymbol_toElem(se
->s
, irs
));
1111 else if ((tyd
= s
->isTypedefDeclaration()) != NULL
)
1113 irs
->deferToObj
->push(tyd
);
1118 elem
*DeclarationExp::toElem(IRState
*irs
)
1121 //printf("DeclarationExp::toElem() %s\n", toChars());
1122 e
= Dsymbol_toElem(declaration
, irs
);
1126 /***************************************
1129 elem
*ThisExp::toElem(IRState
*irs
)
1131 FuncDeclaration
*fd
;
1133 //printf("ThisExp::toElem()\n");
1138 assert(var
->parent
);
1139 fd
= var
->toParent2()->isFuncDeclaration();
1141 ethis
= getEthis(loc
, irs
, fd
);
1144 ethis
= el_var(irs
->sthis
);
1146 el_setLoc(ethis
,loc
);
1150 /***************************************
1153 elem
*IntegerExp::toElem(IRState
*irs
)
1156 e
= el_long(type
->totym(), value
);
1161 /***************************************
1164 elem
*RealExp::toElem(IRState
*irs
)
1168 //printf("RealExp::toElem(%p)\n", this);
1169 memset(&c
, 0, sizeof(c
));
1170 ty
= type
->toBasetype()->totym();
1191 type
->toBasetype()->print();
1192 printf("ty = %d, tym = %x\n", type
->ty
, ty
);
1195 return el_const(ty
, &c
);
1199 /***************************************
1202 elem
*ComplexExp::toElem(IRState
*irs
)
1211 memset(&c
, 0, sizeof(c
));
1216 c
.Vcfloat
.re
= (float) re
;
1217 c
.Vcfloat
.im
= (float) im
;
1221 c
.Vcdouble
.re
= (double) re
;
1222 c
.Vcdouble
.im
= (double) im
;
1226 c
.Vcldouble
.re
= re
;
1227 c
.Vcldouble
.im
= im
;
1233 return el_const(ty
, &c
);
1236 /***************************************
1239 elem
*NullExp::toElem(IRState
*irs
)
1241 return el_long(type
->totym(), 0);
1244 /***************************************
1249 Module
*m
; // module we're generating code for
1257 StringTab stringTab
[STSIZE
];
1260 static Symbol
*assertexp_sfilename
= NULL
;
1261 static char *assertexp_name
= NULL
;
1262 static Module
*assertexp_mn
= NULL
;
1264 void clearStringTab()
1266 //printf("clearStringTab()\n");
1267 memset(stringTab
, 0, sizeof(stringTab
));
1270 assertexp_sfilename
= NULL
;
1271 assertexp_name
= NULL
;
1272 assertexp_mn
= NULL
;
1275 elem
*StringExp::toElem(IRState
*irs
)
1278 Type
*tb
= type
->toBasetype();
1282 printf("StringExp::toElem() %s, type = %s\n", toChars(), type
->toChars());
1285 if (tb
->ty
== Tarray
)
1292 printf("irs->m = %p\n", irs
->m
);
1293 printf(" m = %s\n", irs
->m
->toChars());
1294 printf(" len = %d\n", len
);
1295 printf(" sz = %d\n", sz
);
1297 for (size_t i
= 0; i
< STSIZE
; i
++)
1299 st
= &stringTab
[(stidx
+ i
) % STSIZE
];
1300 //if (!st->m) continue;
1301 //printf(" st.m = %s\n", st->m->toChars());
1302 //printf(" st.len = %d\n", st->len);
1303 //printf(" st.sz = %d\n", st->sz);
1304 if (st
->m
== irs
->m
&&
1308 memcmp(st
->string
, string
, sz
* len
) == 0)
1310 //printf("use cached value\n");
1311 si
= st
->si
; // use cached value
1316 stidx
= (stidx
+ 1) % STSIZE
;
1317 st
= &stringTab
[stidx
];
1322 si
= symbol_generate(SCstatic
,type_fake(TYdarray
));
1325 #if ELFOBJ // Burton
1332 st
->string
= string
;
1338 else if (tb
->ty
== Tsarray
)
1344 dtnzeros(&dt
, sz
); // leave terminating 0
1346 si
= symbol_generate(SCstatic
,type_allocn(TYarray
, tschar
));
1350 #if ELFOBJ // Burton
1357 else if (tb
->ty
== Tpointer
)
1360 e
->Eoper
= OPstring
;
1362 // Match MEM_PH_FREE for OPstring in ztc\el.c
1363 e
->EV
.ss
.Vstring
= (char *)mem_malloc((len
+ 1) * sz
);
1364 memcpy(e
->EV
.ss
.Vstring
, string
, (len
+ 1) * sz
);
1366 e
->EV
.ss
.Vstring
= (char *)string
;
1368 e
->EV
.ss
.Vstrlen
= (len
+ 1) * sz
;
1373 printf("type is %s\n", type
->toChars());
1380 elem
*NewExp::toElem(IRState
*irs
)
1385 //printf("NewExp::toElem() %s\n", toChars());
1386 t
= type
->toBasetype();
1387 //printf("\ttype = %s\n", t->toChars());
1388 if (t
->ty
== Tclass
)
1392 t
= newtype
->toBasetype();
1393 assert(t
->ty
== Tclass
);
1394 TypeClass
*tclass
= (TypeClass
*)(t
);
1395 ClassDeclaration
*cd
= tclass
->sym
;
1398 * 1) ex: call allocator
1399 * 2) ey: set vthis for nested classes
1400 * 3) ez: call constructor
1407 if (allocator
|| onstack
)
1413 /* Create an instance of the class on the stack,
1415 * Set ex to be the &stmp.
1417 Symbol
*s
= symbol_calloc(tclass
->sym
->toChars());
1418 s
->Sclass
= SCstruct
;
1419 s
->Sstruct
= struct_calloc();
1420 s
->Sstruct
->Sflags
|= 0;
1421 s
->Sstruct
->Salignsize
= tclass
->sym
->alignsize
;
1422 s
->Sstruct
->Sstructalign
= tclass
->sym
->structalign
;
1423 s
->Sstruct
->Sstructsize
= tclass
->sym
->structsize
;
1425 ::type
*tc
= type_alloc(TYstruct
);
1426 tc
->Ttag
= (Classsym
*)s
; // structure tag name
1430 Symbol
*stmp
= symbol_genauto(tc
);
1435 ex
= el_var(allocator
->toSymbol());
1436 ex
= callfunc(loc
, irs
, 1, type
, ex
, allocator
->type
,
1437 allocator
, allocator
->type
, NULL
, newargs
);
1440 si
= tclass
->sym
->toInitializer();
1446 ez
= el_copytree(ey
);
1451 ex
= el_una(OPind
, TYstruct
, ex
);
1452 ex
= el_bin(OPstreq
, TYnptr
, ex
, ei
);
1453 ex
->Enumbytes
= cd
->size(loc
);
1454 ex
= el_una(OPaddr
, TYnptr
, ex
);
1459 csym
= cd
->toSymbol();
1460 ex
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_NEWCLASS
]),el_ptr(csym
));
1466 ez
= el_copytree(ey
);
1476 { ClassDeclaration
*cdthis
= thisexp
->type
->isClassHandle();
1478 //printf("cd = %s\n", cd->toChars());
1479 //printf("cdthis = %s\n", cdthis->toChars());
1480 assert(cd
->isNested());
1482 Dsymbol
*cdp
= cd
->toParent2(); // class we're nested in
1485 //printf("member = %p\n", member);
1486 //printf("cdp = %s\n", cdp->toChars());
1487 //printf("cdthis = %s\n", cdthis->toChars());
1489 { int i
= cdp
->isClassDeclaration()->isBaseOf(cdthis
, &offset
);
1492 ethis
= thisexp
->toElem(irs
);
1494 ethis
= el_bin(OPadd
, TYnptr
, ethis
, el_long(TYint
, offset
));
1496 ey
= el_bin(OPadd
, TYnptr
, ey
, el_long(TYint
, cd
->vthis
->offset
));
1497 ey
= el_una(OPind
, TYnptr
, ey
);
1498 ey
= el_bin(OPeq
, TYnptr
, ey
, ethis
);
1500 //printf("ex: "); elem_print(ex);
1501 //printf("ey: "); elem_print(ey);
1502 //printf("ez: "); elem_print(ez);
1504 else if (cd
->isNested())
1505 { /* Initialize cd->vthis:
1506 * *(ey + cd.vthis.offset) = this;
1509 FuncDeclaration
*thisfd
= irs
->getFunc();
1511 Dsymbol
*cdp
= cd
->toParent2(); // class/func we're nested in
1514 { /* Class we're new'ing is a local class in this function:
1515 * void thisfd() { class cd { } }
1518 ethis
= el_var(irs
->sclosure
);
1519 else if (irs
->sthis
)
1522 if (thisfd
->closureVars
.dim
)
1524 if (thisfd
->nestedFrameRef
)
1526 ethis
= el_ptr(irs
->sthis
);
1528 ethis
= el_var(irs
->sthis
);
1532 ethis
= el_long(TYnptr
, 0);
1534 if (thisfd
->closureVars
.dim
)
1536 if (thisfd
->nestedFrameRef
)
1538 ethis
->Eoper
= OPframeptr
;
1541 else if (thisfd
->vthis
&&
1542 (cdp
== thisfd
->toParent2() ||
1543 (cdp
->isClassDeclaration() &&
1544 cdp
->isClassDeclaration()->isBaseOf(thisfd
->toParent2()->isClassDeclaration(), &offset
)
1548 { /* Class we're new'ing is at the same level as thisfd
1550 assert(offset
== 0); // BUG: should handle this case
1551 ethis
= el_var(irs
->sthis
);
1555 ethis
= getEthis(loc
, irs
, cd
->toParent2());
1556 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
1559 ey
= el_bin(OPadd
, TYnptr
, ey
, el_long(TYint
, cd
->vthis
->offset
));
1560 ey
= el_una(OPind
, TYnptr
, ey
);
1561 ey
= el_bin(OPeq
, TYnptr
, ey
, ethis
);
1567 ez
= callfunc(loc
, irs
, 1, type
, ez
, ectype
, member
, member
->type
, NULL
, arguments
);
1569 e
= el_combine(ex
, ey
);
1570 e
= el_combine(e
, ez
);
1572 else if (t
->ty
== Tarray
)
1574 TypeDArray
*tda
= (TypeDArray
*)(t
);
1576 assert(arguments
&& arguments
->dim
>= 1);
1577 if (arguments
->dim
== 1)
1578 { // Single dimension array allocations
1579 Expression
*arg
= (Expression
*)arguments
->data
[0]; // gives array length
1580 e
= arg
->toElem(irs
);
1581 d_uns64 elemsize
= tda
->next
->size();
1583 // call _d_newT(ti, arg)
1584 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1585 int rtl
= tda
->next
->isZeroInit() ? RTLSYM_NEWARRAYT
: RTLSYM_NEWARRAYIT
;
1586 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1589 { // Multidimensional array allocations
1590 e
= el_long(TYint
, arguments
->dim
);
1591 for (size_t i
= 0; i
< arguments
->dim
; i
++)
1593 Expression
*arg
= (Expression
*)arguments
->data
[i
]; // gives array length
1594 e
= el_param(arg
->toElem(irs
), e
);
1595 assert(t
->ty
== Tarray
);
1600 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1602 int rtl
= t
->isZeroInit() ? RTLSYM_NEWARRAYMT
: RTLSYM_NEWARRAYMIT
;
1603 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1606 else if (t
->ty
== Tpointer
)
1608 TypePointer
*tp
= (TypePointer
*)t
;
1609 d_uns64 elemsize
= tp
->next
->size();
1610 Expression
*di
= tp
->next
->defaultInit();
1611 d_uns64 disize
= di
->type
->size();
1613 // call _d_newarrayT(ti, 1)
1614 e
= el_long(TYsize_t
, 1);
1615 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
1617 int rtl
= tp
->next
->isZeroInit() ? RTLSYM_NEWARRAYT
: RTLSYM_NEWARRAYIT
;
1618 e
= el_bin(OPcall
,TYdarray
,el_var(rtlsym
[rtl
]),e
);
1620 // The new functions return an array, so convert to a pointer
1621 // e -> (unsigned)(e >> 32)
1622 e
= el_bin(OPshr
, TYdarray
, e
, el_long(TYint
, 32));
1623 e
= el_una(OP64_32
, t
->totym(), e
);
1634 //////////////////////////// Unary ///////////////////////////////
1636 /***************************************
1639 elem
*NegExp::toElem(IRState
*irs
)
1641 elem
*e
= el_una(OPneg
, type
->totym(), e1
->toElem(irs
));
1646 /***************************************
1649 elem
*ComExp::toElem(IRState
*irs
)
1652 elem
*e1
= this->e1
->toElem(irs
);
1653 tym_t ty
= type
->totym();
1654 if (this->e1
->type
->toBasetype()->ty
== Tbool
)
1655 e
= el_bin(OPxor
, ty
, e1
, el_long(ty
, 1));
1657 e
= el_una(OPcom
,ty
,e1
);
1662 /***************************************
1665 elem
*NotExp::toElem(IRState
*irs
)
1667 elem
*e
= el_una(OPnot
, type
->totym(), e1
->toElem(irs
));
1673 /***************************************
1676 elem
*HaltExp::toElem(IRState
*irs
)
1686 /********************************************
1689 elem
*AssertExp::toElem(IRState
*irs
)
1692 Type
*t1
= e1
->type
->toBasetype();
1694 //printf("AssertExp::toElem() %s\n", toChars());
1695 if (global
.params
.useAssert
)
1697 e
= e1
->toElem(irs
);
1699 InvariantDeclaration
*inv
= (InvariantDeclaration
*)(void *)1;
1701 // If e1 is a class object, call the class invariant on it
1702 if (global
.params
.useInvariants
&& t1
->ty
== Tclass
&&
1703 !((TypeClass
*)t1
)->sym
->isInterfaceDeclaration())
1706 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[RTLSYM__DINVARIANT
]), e
);
1708 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[RTLSYM_DINVARIANT
]), e
);
1711 // If e1 is a struct object, call the struct invariant on it
1712 else if (global
.params
.useInvariants
&&
1713 t1
->ty
== Tpointer
&&
1714 t1
->nextOf()->ty
== Tstruct
&&
1715 (inv
= ((TypeStruct
*)t1
->nextOf())->sym
->inv
) != NULL
)
1717 e
= callfunc(loc
, irs
, 1, inv
->type
->nextOf(), e
, e1
->type
, inv
, inv
->type
, NULL
, NULL
);
1721 // Construct: (e1 || ModuleAssert(line))
1723 Module
*m
= irs
->blx
->module
;
1724 char *mname
= m
->srcfile
->toChars();
1726 //printf("filename = '%s'\n", loc.filename);
1727 //printf("module = '%s'\n", m->srcfile->toChars());
1729 /* If the source file name has changed, probably due
1730 * to a #line directive.
1732 if (loc
.filename
&& (msg
|| strcmp(loc
.filename
, mname
) != 0))
1737 //static Symbol *assertexp_sfilename = NULL;
1738 //static char *assertexp_name = NULL;
1739 //static Module *assertexp_mn = NULL;
1741 if (!assertexp_sfilename
|| strcmp(loc
.filename
, assertexp_name
) != 0 || assertexp_mn
!= m
)
1750 dtabytes(&dt
,TYnptr
, 0, len
+ 1, id
);
1752 assertexp_sfilename
= symbol_generate(SCstatic
,type_fake(TYdarray
));
1753 assertexp_sfilename
->Sdt
= dt
;
1754 assertexp_sfilename
->Sfl
= FLdata
;
1756 assertexp_sfilename
->Sseg
= CDATA
;
1758 outdata(assertexp_sfilename
);
1761 assertexp_name
= id
;
1764 efilename
= el_var(assertexp_sfilename
);
1767 { elem
*emsg
= msg
->toElem(irs
);
1768 ea
= el_var(rtlsym
[RTLSYM_DASSERT_MSG
]);
1769 ea
= el_bin(OPcall
, TYvoid
, ea
, el_params(el_long(TYint
, loc
.linnum
), efilename
, emsg
, NULL
));
1773 ea
= el_var(rtlsym
[RTLSYM_DASSERT
]);
1774 ea
= el_bin(OPcall
, TYvoid
, ea
, el_param(el_long(TYint
, loc
.linnum
), efilename
));
1779 sassert
= m
->toModuleAssert();
1780 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
1781 el_long(TYint
, loc
.linnum
));
1783 e
= el_bin(OPoror
,TYvoid
,e
,ea
);
1787 { // BUG: should replace assert(0); with a HLT instruction
1788 e
= el_long(TYint
, 0);
1794 elem
*PostExp::toElem(IRState
*irs
)
1798 e
= e1
->toElem(irs
);
1799 einc
= e2
->toElem(irs
);
1800 e
= el_bin((op
== TOKplusplus
) ? OPpostinc
: OPpostdec
,
1806 //////////////////////////// Binary ///////////////////////////////
1808 /********************************************
1811 elem
*BinExp::toElemBin(IRState
*irs
,int op
)
1813 //printf("toElemBin() '%s'\n", toChars());
1815 tym_t tym
= type
->totym();
1817 elem
*el
= e1
->toElem(irs
);
1818 elem
*er
= e2
->toElem(irs
);
1819 elem
*e
= el_bin(op
,tym
,el
,er
);
1825 /***************************************
1828 elem
*AddExp::toElem(IRState
*irs
)
1830 Type
*tb1
= e1
->type
->toBasetype();
1831 Type
*tb2
= e2
->type
->toBasetype();
1833 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1834 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
1837 error("Array operations not implemented");
1840 e
= toElemBin(irs
,OPadd
);
1844 /***************************************
1847 elem
*MinExp::toElem(IRState
*irs
)
1849 return toElemBin(irs
,OPmin
);
1852 /***************************************
1855 elem
*CatExp::toElem(IRState
*irs
)
1859 printf("CatExp::toElem()\n");
1863 Type
*tb1
= e1
->type
->toBasetype();
1864 Type
*tb2
= e2
->type
->toBasetype();
1868 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1869 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
1873 Type
*ta
= tb1
->nextOf() ? e1
->type
: e2
->type
;
1874 tn
= tb1
->nextOf() ? tb1
->nextOf() : tb2
->nextOf();
1876 if (e1
->op
== TOKcat
)
1882 ep
= eval_Darray(irs
, ce
->e2
);
1886 ce
= (CatExp
*)ce
->e1
;
1887 ep
= el_param(ep
, eval_Darray(irs
, ce
->e2
));
1888 } while (ce
->e1
->op
== TOKcat
);
1889 ep
= el_param(ep
, eval_Darray(irs
, ce
->e1
));
1894 ta
->getTypeInfo(NULL
)->toElem(irs
),
1896 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATNT
]), ep
);
1901 el_long(TYint
, tn
->size()),
1903 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATN
]), ep
);
1912 e1
= eval_Darray(irs
, this->e1
);
1913 e2
= eval_Darray(irs
, this->e2
);
1915 ep
= el_params(e2
, e1
, ta
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
1916 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCATT
]), ep
);
1918 ep
= el_params(el_long(TYint
, tn
->size()), e2
, e1
, NULL
);
1919 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYCAT
]), ep
);
1925 else if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
1926 e2
->type
->equals(tb1
->next
))
1928 error("array cat with element not implemented");
1929 e
= el_long(TYint
, 0);
1937 /***************************************
1940 elem
*MulExp::toElem(IRState
*irs
)
1942 return toElemBin(irs
,OPmul
);
1945 /************************************
1948 elem
*DivExp::toElem(IRState
*irs
)
1950 return toElemBin(irs
,OPdiv
);
1953 /***************************************
1956 elem
*ModExp::toElem(IRState
*irs
)
1963 tym
= type
->totym();
1965 e1
= this->e1
->toElem(irs
);
1966 e2
= this->e2
->toElem(irs
);
1968 #if 0 // Now inlined
1969 if (this->e1
->type
->isfloating())
1972 switch (this->e1
->type
->ty
)
1976 e1
= el_una(OPf_d
, TYdouble
, e1
);
1977 e2
= el_una(OPf_d
, TYdouble
, e2
);
1980 e1
= el_una(OPd_ld
, TYldouble
, e1
);
1981 e2
= el_una(OPd_ld
, TYldouble
, e2
);
1990 ep
= el_param(e2
,e1
);
1991 e
= el_bin(OPcall
,tym
,el_var(rtlsym
[RTLSYM_MODULO
]),ep
);
1995 e
= el_bin(OPmod
,tym
,e1
,e2
);
2000 /***************************************
2003 elem
*CmpExp::toElem(IRState
*irs
)
2007 Type
*t1
= e1
->type
->toBasetype();
2008 Type
*t2
= e2
->type
->toBasetype();
2012 case TOKlt
: eop
= OPlt
; break;
2013 case TOKgt
: eop
= OPgt
; break;
2014 case TOKle
: eop
= OPle
; break;
2015 case TOKge
: eop
= OPge
; break;
2016 case TOKequal
: eop
= OPeqeq
; break;
2017 case TOKnotequal
: eop
= OPne
; break;
2019 // NCEG floating point compares
2020 case TOKunord
: eop
= OPunord
; break;
2021 case TOKlg
: eop
= OPlg
; break;
2022 case TOKleg
: eop
= OPleg
; break;
2023 case TOKule
: eop
= OPule
; break;
2024 case TOKul
: eop
= OPul
; break;
2025 case TOKuge
: eop
= OPuge
; break;
2026 case TOKug
: eop
= OPug
; break;
2027 case TOKue
: eop
= OPue
; break;
2032 if (!t1
->isfloating())
2034 // Convert from floating point compare to equivalent
2036 eop
= (enum OPER
)rel_integral(eop
);
2038 if ((int)eop
> 1 && t1
->ty
== Tclass
&& t2
->ty
== Tclass
)
2046 ec1
= e1
->toElem(irs
);
2047 ec2
= e2
->toElem(irs
);
2048 e
= el_bin(OPcall
,TYint
,el_var(rtlsym
[RTLSYM_OBJ_CMP
]),el_param(ec1
, ec2
));
2049 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
2052 else if ((int)eop
> 1 &&
2053 (t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
2054 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
2059 Type
*telement
= t1
->nextOf()->toBasetype();
2062 ea1
= e1
->toElem(irs
);
2063 ea1
= array_toDarray(t1
, ea1
);
2064 ea2
= e2
->toElem(irs
);
2065 ea2
= array_toDarray(t2
, ea2
);
2067 ep
= el_params(telement
->getInternalTypeInfo(NULL
)->toElem(irs
), ea2
, ea1
, NULL
);
2068 rtlfunc
= RTLSYM_ARRAYCMP
;
2069 e
= el_bin(OPcall
, TYint
, el_var(rtlsym
[rtlfunc
]), ep
);
2070 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
2077 /* The result is determinate, create:
2080 e
= toElemBin(irs
,OPcomma
);
2081 e
= el_bin(OPcomma
,e
->Ety
,e
,el_long(e
->Ety
,(int)eop
));
2084 e
= toElemBin(irs
,eop
);
2089 elem
*EqualExp::toElem(IRState
*irs
)
2091 //printf("EqualExp::toElem() %s\n", toChars());
2095 Type
*t1
= e1
->type
->toBasetype();
2096 Type
*t2
= e2
->type
->toBasetype();
2100 case TOKequal
: eop
= OPeqeq
; break;
2101 case TOKnotequal
: eop
= OPne
; break;
2107 //printf("EqualExp::toElem()\n");
2108 if (t1
->ty
== Tstruct
)
2109 { // Do bit compare of struct's
2114 es1
= e1
->toElem(irs
);
2115 es2
= e2
->toElem(irs
);
2117 es1
= addressElem(es1
, t1
);
2118 es2
= addressElem(es2
, t2
);
2120 es1
= el_una(OPaddr
, TYnptr
, es1
);
2121 es2
= el_una(OPaddr
, TYnptr
, es2
);
2123 e
= el_param(es1
, es2
);
2124 ecount
= el_long(TYint
, t1
->size());
2125 e
= el_bin(OPmemcmp
, TYint
, e
, ecount
);
2126 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
2130 else if (t1
->ty
== Tclass
&& t2
->ty
== Tclass
)
2135 ec1
= e1
->toElem(irs
);
2136 ec2
= e2
->toElem(irs
);
2137 e
= el_bin(OPcall
,TYint
,el_var(rtlsym
[RTLSYM_OBJ_EQ
]),el_param(ec1
, ec2
));
2140 else if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
2141 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
2146 Type
*telement
= t1
->nextOf()->toBasetype();
2149 ea1
= e1
->toElem(irs
);
2150 ea1
= array_toDarray(t1
, ea1
);
2151 ea2
= e2
->toElem(irs
);
2152 ea2
= array_toDarray(t2
, ea2
);
2154 ep
= el_params(telement
->getInternalTypeInfo(NULL
)->toElem(irs
), ea2
, ea1
, NULL
);
2155 rtlfunc
= RTLSYM_ARRAYEQ
;
2156 e
= el_bin(OPcall
, TYint
, el_var(rtlsym
[rtlfunc
]), ep
);
2157 if (op
== TOKnotequal
)
2158 e
= el_bin(OPxor
, TYint
, e
, el_long(TYint
, 1));
2162 e
= toElemBin(irs
, eop
);
2166 elem
*IdentityExp::toElem(IRState
*irs
)
2170 Type
*t1
= e1
->type
->toBasetype();
2171 Type
*t2
= e2
->type
->toBasetype();
2175 case TOKidentity
: eop
= OPeqeq
; break;
2176 case TOKnotidentity
: eop
= OPne
; break;
2182 //printf("IdentityExp::toElem() %s\n", toChars());
2184 if (t1
->ty
== Tstruct
)
2185 { // Do bit compare of struct's
2190 es1
= e1
->toElem(irs
);
2191 es1
= addressElem(es1
, e1
->type
);
2192 //es1 = el_una(OPaddr, TYnptr, es1);
2193 es2
= e2
->toElem(irs
);
2194 es2
= addressElem(es2
, e2
->type
);
2195 //es2 = el_una(OPaddr, TYnptr, es2);
2196 e
= el_param(es1
, es2
);
2197 ecount
= el_long(TYint
, t1
->size());
2198 e
= el_bin(OPmemcmp
, TYint
, e
, ecount
);
2199 e
= el_bin(eop
, TYint
, e
, el_long(TYint
, 0));
2202 else if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
2203 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
2208 ea1
= e1
->toElem(irs
);
2209 ea1
= array_toDarray(t1
, ea1
);
2210 ea2
= e2
->toElem(irs
);
2211 ea2
= array_toDarray(t2
, ea2
);
2213 e
= el_bin(eop
, type
->totym(), ea1
, ea2
);
2217 e
= toElemBin(irs
, eop
);
2223 /***************************************
2226 elem
*InExp::toElem(IRState
*irs
)
2228 elem
*key
= e1
->toElem(irs
);
2229 elem
*aa
= e2
->toElem(irs
);
2232 TypeAArray
*taa
= (TypeAArray
*)e2
->type
->toBasetype();
2236 // aaIn(aa, keyti, key);
2238 if (key
->Ety
== TYstruct
)
2240 key
= el_una(OPstrpar
, TYstruct
, key
);
2241 key
->Enumbytes
= key
->E1
->Enumbytes
;
2242 assert(key
->Enumbytes
);
2245 Symbol
*s
= taa
->aaGetSymbol("In", 0);
2246 keyti
= taa
->index
->getInternalTypeInfo(NULL
)->toElem(irs
);
2247 ep
= el_params(key
, keyti
, aa
, NULL
);
2248 e
= el_bin(OPcall
, type
->totym(), el_var(s
), ep
);
2254 /***************************************
2257 elem
*RemoveExp::toElem(IRState
*irs
)
2259 Type
*tb
= e1
->type
->toBasetype();
2260 assert(tb
->ty
== Taarray
);
2261 TypeAArray
*taa
= (TypeAArray
*)tb
;
2262 elem
*ea
= e1
->toElem(irs
);
2263 elem
*ekey
= e2
->toElem(irs
);
2267 if (ekey
->Ety
== TYstruct
)
2269 ekey
= el_una(OPstrpar
, TYstruct
, ekey
);
2270 ekey
->Enumbytes
= ekey
->E1
->Enumbytes
;
2271 assert(ekey
->Enumbytes
);
2274 Symbol
*s
= taa
->aaGetSymbol("Del", 0);
2275 keyti
= taa
->index
->getInternalTypeInfo(NULL
)->toElem(irs
);
2276 ep
= el_params(ekey
, keyti
, ea
, NULL
);
2277 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
2283 /***************************************
2286 elem
*AssignExp::toElem(IRState
*irs
)
2292 //printf("AssignExp::toElem('%s')\n", toChars());
2293 t1b
= e1
->type
->toBasetype();
2295 // Look for array.length = n
2296 if (e1
->op
== TOKarraylength
)
2299 // _d_arraysetlength(e2, sizeelem, &ale->e1);
2301 ArrayLengthExp
*ale
= (ArrayLengthExp
*)e1
;
2308 p1
= e2
->toElem(irs
);
2309 p3
= ale
->e1
->toElem(irs
);
2310 p3
= addressElem(p3
, NULL
);
2311 t1
= ale
->e1
->type
->toBasetype();
2314 // call _d_arraysetlengthT(ti, e2, &ale->e1);
2315 p2
= t1
->getTypeInfo(NULL
)->toElem(irs
);
2316 ep
= el_params(p3
, p1
, p2
, NULL
); // c function
2317 r
= t1
->nextOf()->isZeroInit() ? RTLSYM_ARRAYSETLENGTHT
: RTLSYM_ARRAYSETLENGTHIT
;
2319 if (t1
->next
->isZeroInit())
2320 { p2
= t1
->getTypeInfo(NULL
)->toElem(irs
);
2321 ep
= el_params(p3
, p1
, p2
, NULL
); // c function
2322 r
= RTLSYM_ARRAYSETLENGTHT
;
2326 p2
= el_long(TYint
, t1
->next
->size());
2327 ep
= el_params(p3
, p2
, p1
, NULL
); // c function
2328 Expression
*init
= t1
->next
->defaultInit();
2329 ep
= el_param(el_long(TYint
, init
->type
->size()), ep
);
2330 elem
*ei
= init
->toElem(irs
);
2331 ep
= el_param(ei
, ep
);
2332 r
= RTLSYM_ARRAYSETLENGTH3
;
2336 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[r
]), ep
);
2341 // Look for array[]=n
2342 if (e1
->op
== TOKslice
)
2344 SliceExp
*are
= (SliceExp
*)(e1
);
2346 Type
*t2
= e2
->type
->toBasetype();
2348 // which we do if the 'next' types match
2350 { // Do a memset for array[]=v
2351 //printf("Lpair %s\n", toChars());
2352 SliceExp
*are
= (SliceExp
*)e1
;
2361 Type
*ta
= are
->e1
->type
->toBasetype();
2362 Type
*tb
= ta
->nextOf()->toBasetype();
2363 int sz
= tb
->size();
2364 tym_t tym
= type
->totym();
2366 n1
= are
->e1
->toElem(irs
);
2367 elwr
= are
->lwr
? are
->lwr
->toElem(irs
) : NULL
;
2368 eupr
= are
->upr
? are
->upr
->toElem(irs
) : NULL
;
2372 // Look for array[]=n
2373 if (ta
->ty
== Tsarray
)
2377 ts
= (TypeSArray
*) ta
;
2378 n1
= array_toPtr(ta
, n1
);
2379 enbytes
= ts
->dim
->toElem(irs
);
2382 einit
= resolveLengthVar(are
->lengthVar
, &n1
, ta
);
2384 else if (ta
->ty
== Tarray
)
2387 einit
= resolveLengthVar(are
->lengthVar
, &n1
, ta
);
2388 enbytes
= el_copytree(n1
);
2389 n1
= array_toPtr(ta
, n1
);
2390 enbytes
= el_una(OP64_32
, TYint
, enbytes
);
2392 else if (ta
->ty
== Tpointer
)
2395 enbytes
= el_long(TYint
, -1); // largest possible index
2399 // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr
2401 if (elwr
) elwr
= el_same(&elwrx
);
2403 if (eupr
) eupr
= el_same(&euprx
);
2406 printf("sz = %d\n", sz
);
2421 printf("enbytes\n");
2422 elem_print(enbytes
);
2424 einit
= el_combine(n1x
, einit
);
2425 einit
= el_combine(einit
, elwrx
);
2426 einit
= el_combine(einit
, euprx
);
2428 evalue
= this->e2
->toElem(irs
);
2433 printf("enbytes\n");
2434 elem_print(enbytes
);
2437 if (global
.params
.useArrayBounds
&& eupr
&& ta
->ty
!= Tpointer
)
2447 enbytes
= el_same(&enbytesx
);
2448 c1
= el_bin(OPle
, TYint
, el_copytree(eupr
), enbytesx
);
2449 c2
= el_bin(OPle
, TYint
, el_copytree(elwr
), el_copytree(eupr
));
2450 c1
= el_bin(OPandand
, TYint
, c1
, c2
);
2452 // Construct: (c1 || ModuleArray(line))
2455 sassert
= irs
->blx
->module
->toModuleArray();
2456 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
), el_long(TYint
, loc
.linnum
));
2457 eb
= el_bin(OPoror
,TYvoid
,c1
,ea
);
2458 einit
= el_combine(einit
, eb
);
2465 elwr2
= el_copytree(elwr
);
2466 elwr2
= el_bin(OPmul
, TYint
, elwr2
, el_long(TYint
, sz
));
2467 n1
= el_bin(OPadd
, TYnptr
, n1
, elwr2
);
2468 enbytes
= el_bin(OPmin
, TYint
, eupr
, elwr
);
2469 elength
= el_copytree(enbytes
);
2472 elength
= el_copytree(enbytes
);
2473 e
= setArray(n1
, enbytes
, tb
, evalue
, irs
, op
);
2475 e
= el_pair(TYullong
, elength
, e
);
2477 e
= el_combine(einit
, e
);
2483 /* It's array1[]=array2[]
2491 eto
= e1
->toElem(irs
);
2492 efrom
= e2
->toElem(irs
);
2494 unsigned size
= t1
->nextOf()->size();
2495 esize
= el_long(TYint
, size
);
2497 /* Determine if we need to do postblit
2502 t
= t
->nextOf()->toBasetype();
2503 while (t
->ty
== Tsarray
);
2504 if (t
->ty
== Tstruct
)
2505 { StructDeclaration
*sd
= ((TypeStruct
*)t
)->sym
;
2510 assert(e2
->type
->ty
!= Tpointer
);
2512 if (!postblit
&& !global
.params
.useArrayBounds
)
2520 // Determine if elen is a constant
2521 if (eto
->Eoper
== OPpair
&&
2522 eto
->E1
->Eoper
== OPconst
)
2524 elen
= el_copytree(eto
->E1
);
2528 // It's not a constant, so pull it from the dynamic array
2529 elen
= el_una(OP64_32
, TYint
, el_copytree(ex
));
2532 esize
= el_bin(OPmul
, TYint
, elen
, esize
);
2533 epto
= array_toPtr(e1
->type
, ex
);
2534 epfr
= array_toPtr(e2
->type
, efrom
);
2535 e
= el_bin(OPmemcpy
, TYnptr
, epto
, el_param(epfr
, esize
));
2536 e
= el_pair(eto
->Ety
, el_copytree(elen
), e
);
2537 e
= el_combine(eto
, e
);
2539 else if (postblit
&& op
!= TOKblit
)
2542 * _d_arrayassign(ti, efrom, eto)
2544 * _d_arrayctor(ti, efrom, eto)
2547 Expression
*ti
= t1
->nextOf()->toBasetype()->getTypeInfo(NULL
);
2548 ep
= el_params(eto
, efrom
, ti
->toElem(irs
), NULL
);
2549 int rtl
= (op
== TOKconstruct
) ? RTLSYM_ARRAYCTOR
: RTLSYM_ARRAYASSIGN
;
2550 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[rtl
]), ep
);
2555 // _d_arraycopy(eto, efrom, esize)
2557 ep
= el_params(eto
, efrom
, esize
, NULL
);
2558 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[RTLSYM_ARRAYCOPY
]), ep
);
2565 if (e1
->op
== TOKindex
)
2573 ae
= (IndexExp
*)(e1
);
2574 ta
= ae
->e1
->type
->toBasetype();
2578 /* This will work if we can distinguish an assignment from
2579 * an initialization of the lvalue. It'll work if the latter.
2580 * If the former, because of aliasing of the return value with
2581 * function arguments, it'll fail.
2583 if (op
== TOKconstruct
&& e2
->op
== TOKcall
)
2584 { CallExp
*ce
= (CallExp
*)e2
;
2586 TypeFunction
*tf
= (TypeFunction
*)ce
->e1
->type
->toBasetype();
2587 if (tf
->ty
== Tfunction
&& tf
->retStyle() == RETstack
)
2589 elem
*ehidden
= e1
->toElem(irs
);
2590 ehidden
= el_una(OPaddr
, TYnptr
, ehidden
);
2591 assert(!irs
->ehidden
);
2592 irs
->ehidden
= ehidden
;
2593 e
= e2
->toElem(irs
);
2598 if (t1b
->ty
== Tstruct
)
2600 if (e2
->op
== TOKint64
)
2604 * memset(&struct, 0, struct.sizeof)
2606 elem
*el
= e1
->toElem(irs
);
2607 elem
*enbytes
= el_long(TYint
, e1
->type
->size());
2608 elem
*evalue
= el_long(TYint
, 0);
2610 el
= el_una(OPaddr
, TYnptr
, el
);
2611 e
= el_param(enbytes
, evalue
);
2612 e
= el_bin(OPmemset
,TYnptr
,el
,e
);
2614 //e = el_una(OPind, TYstruct, e);
2622 //printf("toElemBin() '%s'\n", toChars());
2624 tym
= type
->totym();
2626 e1
= this->e1
->toElem(irs
);
2628 if (e1
->Eoper
== OPind
)
2630 if (this->e2
->op
== TOKstructliteral
&&
2631 ex
->Eoper
== OPvar
&& ex
->EV
.sp
.Voffset
== 0)
2632 { StructLiteralExp
*se
= (StructLiteralExp
*)this->e2
;
2634 Symbol
*symSave
= se
->sym
;
2635 size_t soffsetSave
= se
->soffset
;
2636 int fillHolesSave
= se
->fillHoles
;
2638 se
->sym
= ex
->EV
.sp
.Vsym
;
2640 se
->fillHoles
= (op
== TOKconstruct
|| op
== TOKblit
) ? 1 : 0;
2643 e
= this->e2
->toElem(irs
);
2646 se
->soffset
= soffsetSave
;
2647 se
->fillHoles
= fillHolesSave
;
2651 e2
= this->e2
->toElem(irs
);
2652 e
= el_bin(OPstreq
,tym
,e1
,e2
);
2653 e
->Enumbytes
= this->e1
->type
->size();
2659 e
= toElemBin(irs
,OPeq
);
2667 /***************************************
2670 elem
*AddAssignExp::toElem(IRState
*irs
)
2672 //printf("AddAssignExp::toElem() %s\n", toChars());
2674 Type
*tb1
= e1
->type
->toBasetype();
2675 Type
*tb2
= e2
->type
->toBasetype();
2677 if ((tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
) &&
2678 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
2681 error("Array operations not implemented");
2684 e
= toElemBin(irs
,OPaddass
);
2689 /***************************************
2692 elem
*MinAssignExp::toElem(IRState
*irs
)
2694 return toElemBin(irs
,OPminass
);
2697 /***************************************
2700 elem
*CatAssignExp::toElem(IRState
*irs
)
2702 //printf("CatAssignExp::toElem('%s')\n", toChars());
2704 Type
*tb1
= e1
->type
->toBasetype();
2705 Type
*tb2
= e2
->type
->toBasetype();
2707 if (tb1
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
2712 e1
= this->e1
->toElem(irs
);
2713 e1
= el_una(OPaddr
, TYnptr
, e1
);
2715 e2
= this->e2
->toElem(irs
);
2716 if (e2
->Ety
== TYstruct
)
2718 e2
= el_una(OPstrpar
, TYstruct
, e2
);
2719 e2
->Enumbytes
= e2
->E1
->Enumbytes
;
2720 assert(e2
->Enumbytes
);
2723 Type
*tb1n
= tb1
->nextOf()->toBasetype();
2724 if ((tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
2725 tb1n
->equals(tb2
->nextOf()->toBasetype()))
2728 ep
= el_params(e2
, e1
, this->e1
->type
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
2729 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDT
]), ep
);
2731 ep
= el_params(el_long(TYint
, tb1n
->size()), e2
, e1
, NULL
);
2732 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPEND
]), ep
);
2738 ep
= el_params(e2
, e1
, this->e1
->type
->getTypeInfo(NULL
)->toElem(irs
), NULL
);
2739 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDCT
]), ep
);
2741 ep
= el_params(e2
, el_long(TYint
, tb1n
->size()), e1
, NULL
);
2742 e
= el_bin(OPcall
, TYdarray
, el_var(rtlsym
[RTLSYM_ARRAYAPPENDC
]), ep
);
2753 /***************************************
2756 elem
*DivAssignExp::toElem(IRState
*irs
)
2758 return toElemBin(irs
,OPdivass
);
2762 /***************************************
2765 elem
*ModAssignExp::toElem(IRState
*irs
)
2767 return toElemBin(irs
,OPmodass
);
2771 /***************************************
2774 elem
*MulAssignExp::toElem(IRState
*irs
)
2776 return toElemBin(irs
,OPmulass
);
2780 /***************************************
2783 elem
*ShlAssignExp::toElem(IRState
*irs
)
2786 e
= toElemBin(irs
,OPshlass
);
2791 /***************************************
2794 elem
*ShrAssignExp::toElem(IRState
*irs
)
2796 return toElemBin(irs
,OPshrass
);
2800 /***************************************
2803 elem
*UshrAssignExp::toElem(IRState
*irs
)
2805 elem
*eleft
= e1
->toElem(irs
);
2806 eleft
->Ety
= touns(eleft
->Ety
);
2807 elem
*eright
= e2
->toElem(irs
);
2808 elem
*e
= el_bin(OPshrass
, type
->totym(), eleft
, eright
);
2814 /***************************************
2817 elem
*AndAssignExp::toElem(IRState
*irs
)
2819 return toElemBin(irs
,OPandass
);
2823 /***************************************
2826 elem
*OrAssignExp::toElem(IRState
*irs
)
2828 return toElemBin(irs
,OPorass
);
2832 /***************************************
2835 elem
*XorAssignExp::toElem(IRState
*irs
)
2837 return toElemBin(irs
,OPxorass
);
2841 /***************************************
2844 elem
*AndAndExp::toElem(IRState
*irs
)
2846 elem
*e
= toElemBin(irs
,OPandand
);
2847 if (global
.params
.cov
&& e2
->loc
.linnum
)
2848 e
->E2
= el_combine(incUsageElem(irs
, e2
->loc
), e
->E2
);
2853 /***************************************
2856 elem
*OrOrExp::toElem(IRState
*irs
)
2858 elem
*e
= toElemBin(irs
,OPoror
);
2859 if (global
.params
.cov
&& e2
->loc
.linnum
)
2860 e
->E2
= el_combine(incUsageElem(irs
, e2
->loc
), e
->E2
);
2865 /***************************************
2868 elem
*XorExp::toElem(IRState
*irs
)
2870 return toElemBin(irs
,OPxor
);
2874 /***************************************
2877 elem
*AndExp::toElem(IRState
*irs
)
2879 return toElemBin(irs
,OPand
);
2883 /***************************************
2886 elem
*OrExp::toElem(IRState
*irs
)
2888 return toElemBin(irs
,OPor
);
2892 /***************************************
2895 elem
*ShlExp::toElem(IRState
*irs
)
2897 return toElemBin(irs
, OPshl
);
2901 /***************************************
2904 elem
*ShrExp::toElem(IRState
*irs
)
2906 return toElemBin(irs
,OPshr
);
2910 /***************************************
2913 elem
*UshrExp::toElem(IRState
*irs
)
2915 elem
*eleft
= e1
->toElem(irs
);
2916 eleft
->Ety
= touns(eleft
->Ety
);
2917 elem
*eright
= e2
->toElem(irs
);
2918 elem
*e
= el_bin(OPshr
, type
->totym(), eleft
, eright
);
2923 /****************************************
2926 elem
*CommaExp::toElem(IRState
*irs
)
2929 elem
*eleft
= e1
->toElem(irs
);
2930 elem
*eright
= e2
->toElem(irs
);
2931 elem
*e
= el_combine(eleft
, eright
);
2938 /***************************************
2941 elem
*CondExp::toElem(IRState
*irs
)
2945 elem
*ec
= econd
->toElem(irs
);
2947 eleft
= e1
->toElem(irs
);
2948 tym_t ty
= eleft
->Ety
;
2949 if (global
.params
.cov
&& e1
->loc
.linnum
)
2950 eleft
= el_combine(incUsageElem(irs
, e1
->loc
), eleft
);
2952 eright
= e2
->toElem(irs
);
2953 if (global
.params
.cov
&& e2
->loc
.linnum
)
2954 eright
= el_combine(incUsageElem(irs
, e2
->loc
), eright
);
2956 elem
*e
= el_bin(OPcond
, ty
, ec
, el_bin(OPcolon
, ty
, eleft
, eright
));
2957 if (tybasic(ty
) == TYstruct
)
2958 e
->Enumbytes
= e1
->type
->size();
2964 /***************************************
2967 elem
*TypeDotIdExp::toElem(IRState
*irs
)
2974 elem
*TypeExp::toElem(IRState
*irs
)
2977 printf("TypeExp::toElem()\n");
2979 error("type %s is not an expression", toChars());
2980 return el_long(TYint
, 0);
2983 elem
*ScopeExp::toElem(IRState
*irs
)
2985 error("%s is not an expression", sds
->toChars());
2986 return el_long(TYint
, 0);
2989 elem
*DotVarExp::toElem(IRState
*irs
)
2993 //printf("DotVarExp::toElem('%s')\n", toChars());
2995 VarDeclaration
*v
= var
->isVarDeclaration();
2998 error("%s is not a field", var
->toChars());
3001 elem
*e
= e1
->toElem(irs
);
3002 Type
*tb1
= e1
->type
->toBasetype();
3003 if (tb1
->ty
!= Tclass
&& tb1
->ty
!= Tpointer
)
3004 e
= el_una(OPaddr
, TYnptr
, e
);
3005 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, v
? v
->offset
: 0));
3006 e
= el_una(OPind
, type
->totym(), e
);
3007 if (tybasic(e
->Ety
) == TYstruct
)
3009 e
->Enumbytes
= type
->size();
3015 elem
*DelegateExp::toElem(IRState
*irs
)
3023 //printf("DelegateExp::toElem() '%s'\n", toChars());
3024 sfunc
= func
->toSymbol();
3025 if (func
->isNested())
3028 ethis
= getEthis(loc
, irs
, func
);
3032 ethis
= e1
->toElem(irs
);
3033 if (e1
->type
->ty
!= Tclass
&& e1
->type
->ty
!= Tpointer
)
3034 ethis
= el_una(OPaddr
, TYnptr
, ethis
);
3036 if (e1
->op
== TOKsuper
)
3039 if (!func
->isThis())
3040 error("delegates are only for non-static functions");
3042 if (!func
->isVirtual() ||
3050 // Get pointer to function out of virtual table
3054 ep
= el_same(ðis
);
3055 ep
= el_una(OPind
, TYnptr
, ep
);
3056 vindex
= func
->vtblIndex
;
3058 // Build *(ep + vindex * 4)
3059 ep
= el_bin(OPadd
,TYnptr
,ep
,el_long(TYint
, vindex
* 4));
3060 ep
= el_una(OPind
,TYnptr
,ep
);
3063 // if (func->tintro)
3064 // func->error(loc, "cannot form delegate due to covariant return type");
3066 if (ethis
->Eoper
== OPcomma
)
3068 ethis
->E2
= el_pair(TYullong
, ethis
->E2
, ep
);
3069 ethis
->Ety
= TYullong
;
3073 e
= el_pair(TYullong
, ethis
, ep
);
3078 elem
*DotTypeExp::toElem(IRState
*irs
)
3080 // Just a pass-thru to e1
3083 //printf("DotTypeExp::toElem() %s\n", toChars());
3084 e
= e1
->toElem(irs
);
3089 elem
*CallExp::toElem(IRState
*irs
)
3091 //printf("CallExp::toElem('%s')\n", toChars());
3095 FuncDeclaration
*fd
;
3096 Type
*t1
= e1
->type
->toBasetype();
3099 elem
*ehidden
= irs
->ehidden
;
3100 irs
->ehidden
= NULL
;
3104 if (e1
->op
== TOKdotvar
&& t1
->ty
!= Tdelegate
)
3105 { DotVarExp
*dve
= (DotVarExp
*)e1
;
3107 fd
= dve
->var
->isFuncDeclaration();
3108 Expression
*ex
= dve
->e1
;
3113 case TOKsuper
: // super.member() calls directly
3114 case TOKdottype
: // type.member() calls directly
3119 ex
= ((CastExp
*)ex
)->e1
;
3128 ec
= dve
->e1
->toElem(irs
);
3129 ectype
= dve
->e1
->type
->toBasetype();
3131 else if (e1
->op
== TOKvar
)
3133 fd
= ((VarExp
*)e1
)->var
->isFuncDeclaration();
3135 if (fd
&& fd
->ident
== Id::alloca
&&
3136 !fd
->fbody
&& fd
->linkage
== LINKc
&&
3137 arguments
&& arguments
->dim
== 1)
3138 { Expression
*arg
= (Expression
*)arguments
->data
[0];
3139 arg
= arg
->optimize(WANTvalue
);
3140 if (arg
->isConst() && arg
->type
->isintegral())
3141 { integer_t sz
= arg
->toInteger();
3142 if (sz
> 0 && sz
< 0x40000)
3144 // It's an alloca(sz) of a fixed amount.
3145 // Replace with an array allocated on the stack
3146 // of the same size: char[sz] tmp;
3152 t
= type_allocn(TYarray
, tschar
);
3154 stmp
= symbol_genauto(t
);
3162 ec
= e1
->toElem(irs
);
3166 ec
= e1
->toElem(irs
);
3168 ec
= callfunc(loc
, irs
, directcall
, type
, ec
, ectype
, fd
, t1
, ehidden
, arguments
);
3173 elem
*AddrExp::toElem(IRState
*irs
)
3177 //printf("AddrExp::toElem('%s')\n", toChars());
3179 e
= e1
->toElem(irs
);
3180 e
= addressElem(e
, e1
->type
);
3182 e
->Ety
= type
->totym();
3187 elem
*PtrExp::toElem(IRState
*irs
)
3190 //printf("PtrExp::toElem() %s\n", toChars());
3191 e
= e1
->toElem(irs
);
3192 e
= el_una(OPind
,type
->totym(),e
);
3193 if (tybasic(e
->Ety
) == TYstruct
)
3195 e
->Enumbytes
= type
->size();
3201 elem
*BoolExp::toElem(IRState
*irs
)
3204 e1
= this->e1
->toElem(irs
);
3205 return el_una(OPbool
,type
->totym(),e1
);
3208 elem
*DeleteExp::toElem(IRState
*irs
)
3213 //printf("DeleteExp::toElem()\n");
3214 if (e1
->op
== TOKindex
)
3216 IndexExp
*ae
= (IndexExp
*)(e1
);
3217 tb
= ae
->e1
->type
->toBasetype();
3218 if (tb
->ty
== Taarray
)
3220 TypeAArray
*taa
= (TypeAArray
*)tb
;
3221 elem
*ea
= ae
->e1
->toElem(irs
);
3222 elem
*ekey
= ae
->e2
->toElem(irs
);
3226 if (ekey
->Ety
== TYstruct
)
3228 ekey
= el_una(OPstrpar
, TYstruct
, ekey
);
3229 ekey
->Enumbytes
= ekey
->E1
->Enumbytes
;
3230 assert(ekey
->Enumbytes
);
3233 Symbol
*s
= taa
->aaGetSymbol("Del", 0);
3234 keyti
= taa
->index
->getInternalTypeInfo(NULL
)->toElem(irs
);
3235 ep
= el_params(ekey
, keyti
, ea
, NULL
);
3236 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
3240 //e1->type->print();
3241 e
= e1
->toElem(irs
);
3242 tb
= e1
->type
->toBasetype();
3246 { e
= addressElem(e
, e1
->type
);
3247 rtl
= RTLSYM_DELARRAYT
;
3249 /* See if we need to run destructors on the array contents
3252 Type
*tv
= tb
->nextOf()->toBasetype();
3253 while (tv
->ty
== Tsarray
)
3254 { TypeSArray
*ta
= (TypeSArray
*)tv
;
3255 tv
= tv
->nextOf()->toBasetype();
3257 if (tv
->ty
== Tstruct
)
3258 { TypeStruct
*ts
= (TypeStruct
*)tv
;
3259 StructDeclaration
*sd
= ts
->sym
;
3261 et
= tb
->nextOf()->getTypeInfo(NULL
)->toElem(irs
);
3263 if (!et
) // if no destructors needed
3264 et
= el_long(TYnptr
, 0); // pass null for TypeInfo
3265 e
= el_params(et
, e
, NULL
);
3266 // call _d_delarray_t(e, et);
3267 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[rtl
]), e
);
3271 if (e1
->op
== TOKvar
)
3272 { VarExp
*ve
= (VarExp
*)e1
;
3273 if (ve
->var
->isVarDeclaration() &&
3274 ve
->var
->isVarDeclaration()->onstack
)
3276 rtl
= RTLSYM_CALLFINALIZER
;
3277 if (tb
->isClassHandle()->isInterfaceDeclaration())
3278 rtl
= RTLSYM_CALLINTERFACEFINALIZER
;
3282 e
= addressElem(e
, e1
->type
);
3283 rtl
= RTLSYM_DELCLASS
;
3284 if (tb
->isClassHandle()->isInterfaceDeclaration())
3285 rtl
= RTLSYM_DELINTERFACE
;
3289 e
= addressElem(e
, e1
->type
);
3290 rtl
= RTLSYM_DELMEMORY
;
3297 e
= el_bin(OPcall
, TYvoid
, el_var(rtlsym
[rtl
]), e
);
3304 elem
*CastExp::toElem(IRState
*irs
)
3315 printf("CastExp::toElem()\n");
3317 printf("\tfrom: %s\n", e1
->type
->toChars());
3318 printf("\tto : %s\n", to
->toChars());
3321 e
= e1
->toElem(irs
);
3322 tfrom
= e1
->type
->toBasetype();
3323 t
= to
->toBasetype(); // skip over typedef's
3324 if (t
->equals(tfrom
))
3328 //printf("fty = %d\n", fty);
3331 if (tty
== Tpointer
&& fty
== Tarray
3333 && (t
->next
->ty
== Tvoid
|| t
->next
->equals(e1
->type
->next
))
3337 if (e
->Eoper
== OPvar
)
3340 e
= el_una(OPaddr
, TYnptr
, e
);
3341 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, 4));
3342 e
= el_una(OPind
,t
->totym(),e
);
3346 // e1 -> (unsigned)(e1 >> 32)
3347 e
= el_bin(OPshr
, TYullong
, e
, el_long(TYint
, 32));
3348 e
= el_una(OP64_32
, t
->totym(), e
);
3353 if (tty
== Tpointer
&& fty
== Tsarray
3355 && (t
->next
->ty
== Tvoid
|| t
->next
->equals(e1
->type
->next
))
3360 e
= el_una(OPaddr
, TYnptr
, e
);
3364 // Convert from static array to dynamic array
3365 if (tty
== Tarray
&& fty
== Tsarray
)
3367 e
= sarray_toDarray(tfrom
, t
, e
);
3371 // Convert from dynamic array to dynamic array
3372 if (tty
== Tarray
&& fty
== Tarray
)
3374 unsigned fsize
= tfrom
->nextOf()->size();
3375 unsigned tsize
= t
->nextOf()->size();
3381 ep
= el_params(e
, el_long(TYint
, fsize
), el_long(TYint
, tsize
), NULL
);
3382 e
= el_bin(OPcall
, type
->totym(), el_var(rtlsym
[RTLSYM_ARRAYCAST
]), ep
);
3387 // Casting from base class to derived class requires a runtime check
3388 if (fty
== Tclass
&& tty
== Tclass
)
3390 // Casting from derived class to base class is a no-op
3391 ClassDeclaration
*cdfrom
;
3392 ClassDeclaration
*cdto
;
3394 int rtl
= RTLSYM_DYNAMIC_CAST
;
3396 cdfrom
= e1
->type
->isClassHandle();
3397 cdto
= t
->isClassHandle();
3398 if (cdfrom
->isInterfaceDeclaration())
3400 rtl
= RTLSYM_INTERFACE_CAST
;
3401 if (cdfrom
->isCPPinterface())
3403 if (cdto
->isCPPinterface())
3405 /* Casting from a C++ interface to a C++ interface
3406 * is always a 'paint' operation
3411 /* Casting from a C++ interface to a class
3412 * always results in null because there is no runtime
3413 * information available to do it.
3415 * Casting from a C++ interface to a non-C++ interface
3416 * always results in null because there's no way one
3417 * can be derived from the other.
3419 e
= el_bin(OPcomma
, TYnptr
, e
, el_long(TYnptr
, 0));
3423 if (cdto
->isBaseOf(cdfrom
, &offset
) && offset
!= OFFSET_RUNTIME
)
3425 /* The offset from cdfrom=>cdto is known at compile time.
3428 //printf("offset = %d\n", offset);
3430 { /* Rewrite cast as (e ? e + offset : null)
3435 if (e1
->op
== TOKthis
)
3436 { // Assume 'this' is never null, so skip null check
3437 e
= el_bin(OPadd
, TYnptr
, e
, el_long(TYint
, offset
));
3442 ex
= el_bin(OPadd
, TYnptr
, etmp
, el_long(TYint
, offset
));
3443 ex
= el_bin(OPcolon
, TYnptr
, ex
, el_long(TYnptr
, 0));
3444 e
= el_bin(OPcond
, TYnptr
, e
, ex
);
3450 /* The offset from cdfrom=>cdto can only be determined at runtime.
3454 ep
= el_param(el_ptr(cdto
->toSymbol()), e
);
3455 e
= el_bin(OPcall
, TYnptr
, el_var(rtlsym
[rtl
]), ep
);
3467 if (fty
== Tdelegate
)
3472 case Tchar
: tty
= Tuns8
; break;
3473 case Twchar
: tty
= Tuns16
; break;
3474 case Tdchar
: tty
= Tuns32
; break;
3475 case Tvoid
: goto Lpaint
;
3479 // Construct e?true:false
3482 e
= el_una(OPbool
, ttym
, e
);
3489 case Tpointer
: fty
= Tuns32
; break;
3490 case Tchar
: fty
= Tuns8
; break;
3491 case Twchar
: fty
= Tuns16
; break;
3492 case Tdchar
: fty
= Tuns32
; break;
3495 #define X(fty, tty) ((fty) * TMAX + (tty))
3503 case X(Tbit
,Tint16
):
3504 case X(Tbit
,Tuns16
):
3505 case X(Tbit
,Tint32
):
3506 case X(Tbit
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3507 case X(Tbit
,Tint64
):
3508 case X(Tbit
,Tuns64
):
3509 case X(Tbit
,Tfloat32
):
3510 case X(Tbit
,Tfloat64
):
3511 case X(Tbit
,Tfloat80
):
3512 case X(Tbit
,Tcomplex32
):
3513 case X(Tbit
,Tcomplex64
):
3514 case X(Tbit
,Tcomplex80
):
3515 e
= el_una(OPu8_16
, TYuint
, e
);
3518 case X(Tbit
,Timaginary32
):
3519 case X(Tbit
,Timaginary64
):
3520 case X(Tbit
,Timaginary80
): goto Lzero
;
3522 /* ============================= */
3524 case X(Tbool
,Tint8
):
3525 case X(Tbool
,Tuns8
):
3527 case X(Tbool
,Tint16
):
3528 case X(Tbool
,Tuns16
):
3529 case X(Tbool
,Tint32
):
3530 case X(Tbool
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3531 case X(Tbool
,Tint64
):
3532 case X(Tbool
,Tuns64
):
3533 case X(Tbool
,Tfloat32
):
3534 case X(Tbool
,Tfloat64
):
3535 case X(Tbool
,Tfloat80
):
3536 case X(Tbool
,Tcomplex32
):
3537 case X(Tbool
,Tcomplex64
):
3538 case X(Tbool
,Tcomplex80
):
3539 e
= el_una(OPu8_16
, TYuint
, e
);
3542 case X(Tbool
,Timaginary32
):
3543 case X(Tbool
,Timaginary64
):
3544 case X(Tbool
,Timaginary80
): goto Lzero
;
3546 /* ============================= */
3548 case X(Tint8
,Tuns8
): goto Lpaint
;
3549 case X(Tint8
,Tint16
):
3550 case X(Tint8
,Tuns16
):
3551 case X(Tint8
,Tint32
):
3552 case X(Tint8
,Tuns32
): eop
= OPs8_16
; goto Leop
;
3553 case X(Tint8
,Tint64
):
3554 case X(Tint8
,Tuns64
):
3555 case X(Tint8
,Tfloat32
):
3556 case X(Tint8
,Tfloat64
):
3557 case X(Tint8
,Tfloat80
):
3558 case X(Tint8
,Tcomplex32
):
3559 case X(Tint8
,Tcomplex64
):
3560 case X(Tint8
,Tcomplex80
):
3561 e
= el_una(OPs8_16
, TYint
, e
);
3564 case X(Tint8
,Timaginary32
):
3565 case X(Tint8
,Timaginary64
):
3566 case X(Tint8
,Timaginary80
): goto Lzero
;
3568 /* ============================= */
3570 case X(Tuns8
,Tint8
): goto Lpaint
;
3571 case X(Tuns8
,Tint16
):
3572 case X(Tuns8
,Tuns16
):
3573 case X(Tuns8
,Tint32
):
3574 case X(Tuns8
,Tuns32
): eop
= OPu8_16
; goto Leop
;
3575 case X(Tuns8
,Tint64
):
3576 case X(Tuns8
,Tuns64
):
3577 case X(Tuns8
,Tfloat32
):
3578 case X(Tuns8
,Tfloat64
):
3579 case X(Tuns8
,Tfloat80
):
3580 case X(Tuns8
,Tcomplex32
):
3581 case X(Tuns8
,Tcomplex64
):
3582 case X(Tuns8
,Tcomplex80
):
3583 e
= el_una(OPu8_16
, TYuint
, e
);
3586 case X(Tuns8
,Timaginary32
):
3587 case X(Tuns8
,Timaginary64
):
3588 case X(Tuns8
,Timaginary80
): goto Lzero
;
3590 /* ============================= */
3592 case X(Tint16
,Tint8
):
3593 case X(Tint16
,Tuns8
): eop
= OP16_8
; goto Leop
;
3594 case X(Tint16
,Tuns16
): goto Lpaint
;
3595 case X(Tint16
,Tint32
):
3596 case X(Tint16
,Tuns32
): eop
= OPs16_32
; goto Leop
;
3597 case X(Tint16
,Tint64
):
3598 case X(Tint16
,Tuns64
): e
= el_una(OPs16_32
, TYint
, e
);
3601 case X(Tint16
,Tfloat32
):
3602 case X(Tint16
,Tfloat64
):
3603 case X(Tint16
,Tfloat80
):
3604 case X(Tint16
,Tcomplex32
):
3605 case X(Tint16
,Tcomplex64
):
3606 case X(Tint16
,Tcomplex80
):
3607 e
= el_una(OPs16_d
, TYdouble
, e
);
3610 case X(Tint16
,Timaginary32
):
3611 case X(Tint16
,Timaginary64
):
3612 case X(Tint16
,Timaginary80
): goto Lzero
;
3614 /* ============================= */
3616 case X(Tuns16
,Tint8
):
3617 case X(Tuns16
,Tuns8
): eop
= OP16_8
; goto Leop
;
3618 case X(Tuns16
,Tint16
): goto Lpaint
;
3619 case X(Tuns16
,Tint32
):
3620 case X(Tuns16
,Tuns32
): eop
= OPu16_32
; goto Leop
;
3621 case X(Tuns16
,Tint64
):
3622 case X(Tuns16
,Tuns64
):
3623 case X(Tuns16
,Tfloat64
):
3624 case X(Tuns16
,Tfloat32
):
3625 case X(Tuns16
,Tfloat80
):
3626 case X(Tuns16
,Tcomplex32
):
3627 case X(Tuns16
,Tcomplex64
):
3628 case X(Tuns16
,Tcomplex80
):
3629 e
= el_una(OPu16_32
, TYuint
, e
);
3632 case X(Tuns16
,Timaginary32
):
3633 case X(Tuns16
,Timaginary64
):
3634 case X(Tuns16
,Timaginary80
): goto Lzero
;
3636 /* ============================= */
3638 case X(Tint32
,Tint8
):
3639 case X(Tint32
,Tuns8
): e
= el_una(OP32_16
, TYshort
, e
);
3642 case X(Tint32
,Tint16
):
3643 case X(Tint32
,Tuns16
): eop
= OP32_16
; goto Leop
;
3644 case X(Tint32
,Tuns32
): goto Lpaint
;
3645 case X(Tint32
,Tint64
):
3646 case X(Tint32
,Tuns64
): eop
= OPs32_64
; goto Leop
;
3647 case X(Tint32
,Tfloat32
):
3648 case X(Tint32
,Tfloat64
):
3649 case X(Tint32
,Tfloat80
):
3650 case X(Tint32
,Tcomplex32
):
3651 case X(Tint32
,Tcomplex64
):
3652 case X(Tint32
,Tcomplex80
):
3653 e
= el_una(OPs32_d
, TYdouble
, e
);
3656 case X(Tint32
,Timaginary32
):
3657 case X(Tint32
,Timaginary64
):
3658 case X(Tint32
,Timaginary80
): goto Lzero
;
3660 /* ============================= */
3662 case X(Tuns32
,Tint8
):
3663 case X(Tuns32
,Tuns8
): e
= el_una(OP32_16
, TYshort
, e
);
3666 case X(Tuns32
,Tint16
):
3667 case X(Tuns32
,Tuns16
): eop
= OP32_16
; goto Leop
;
3668 case X(Tuns32
,Tint32
): goto Lpaint
;
3669 case X(Tuns32
,Tint64
):
3670 case X(Tuns32
,Tuns64
): eop
= OPu32_64
; goto Leop
;
3671 case X(Tuns32
,Tfloat32
):
3672 case X(Tuns32
,Tfloat64
):
3673 case X(Tuns32
,Tfloat80
):
3674 case X(Tuns32
,Tcomplex32
):
3675 case X(Tuns32
,Tcomplex64
):
3676 case X(Tuns32
,Tcomplex80
):
3677 e
= el_una(OPu32_d
, TYdouble
, e
);
3680 case X(Tuns32
,Timaginary32
):
3681 case X(Tuns32
,Timaginary64
):
3682 case X(Tuns32
,Timaginary80
): goto Lzero
;
3684 /* ============================= */
3686 case X(Tint64
,Tint8
):
3687 case X(Tint64
,Tuns8
):
3688 case X(Tint64
,Tint16
):
3689 case X(Tint64
,Tuns16
): e
= el_una(OP64_32
, TYint
, e
);
3692 case X(Tint64
,Tint32
):
3693 case X(Tint64
,Tuns32
): eop
= OP64_32
; goto Leop
;
3694 case X(Tint64
,Tuns64
): goto Lpaint
;
3695 case X(Tint64
,Tfloat32
):
3696 case X(Tint64
,Tfloat64
):
3697 case X(Tint64
,Tfloat80
):
3698 case X(Tint64
,Tcomplex32
):
3699 case X(Tint64
,Tcomplex64
):
3700 case X(Tint64
,Tcomplex80
):
3701 e
= el_una(OPs64_d
, TYdouble
, e
);
3704 case X(Tint64
,Timaginary32
):
3705 case X(Tint64
,Timaginary64
):
3706 case X(Tint64
,Timaginary80
): goto Lzero
;
3708 /* ============================= */
3710 case X(Tuns64
,Tint8
):
3711 case X(Tuns64
,Tuns8
):
3712 case X(Tuns64
,Tint16
):
3713 case X(Tuns64
,Tuns16
): e
= el_una(OP64_32
, TYint
, e
);
3716 case X(Tuns64
,Tint32
):
3717 case X(Tuns64
,Tuns32
): eop
= OP64_32
; goto Leop
;
3718 case X(Tuns64
,Tint64
): goto Lpaint
;
3719 case X(Tuns64
,Tfloat32
):
3720 case X(Tuns64
,Tfloat64
):
3721 case X(Tuns64
,Tfloat80
):
3722 case X(Tuns64
,Tcomplex32
):
3723 case X(Tuns64
,Tcomplex64
):
3724 case X(Tuns64
,Tcomplex80
):
3725 e
= el_una(OPu64_d
, TYdouble
, e
);
3728 case X(Tuns64
,Timaginary32
):
3729 case X(Tuns64
,Timaginary64
):
3730 case X(Tuns64
,Timaginary80
): goto Lzero
;
3732 /* ============================= */
3734 case X(Tfloat32
,Tint8
):
3735 case X(Tfloat32
,Tuns8
):
3736 case X(Tfloat32
,Tint16
):
3737 case X(Tfloat32
,Tuns16
):
3738 case X(Tfloat32
,Tint32
):
3739 case X(Tfloat32
,Tuns32
):
3740 case X(Tfloat32
,Tint64
):
3741 case X(Tfloat32
,Tuns64
):
3742 case X(Tfloat32
,Tfloat80
): e
= el_una(OPf_d
, TYdouble
, e
);
3745 case X(Tfloat32
,Tfloat64
): eop
= OPf_d
; goto Leop
;
3746 case X(Tfloat32
,Timaginary32
): goto Lzero
;
3747 case X(Tfloat32
,Timaginary64
): goto Lzero
;
3748 case X(Tfloat32
,Timaginary80
): goto Lzero
;
3749 case X(Tfloat32
,Tcomplex32
):
3750 case X(Tfloat32
,Tcomplex64
):
3751 case X(Tfloat32
,Tcomplex80
):
3752 e
= el_bin(OPadd
,TYcfloat
,el_long(TYifloat
,0),e
);
3756 /* ============================= */
3758 case X(Tfloat64
,Tint8
):
3759 case X(Tfloat64
,Tuns8
): e
= el_una(OPd_s16
, TYshort
, e
);
3762 case X(Tfloat64
,Tint16
): eop
= OPd_s16
; goto Leop
;
3763 case X(Tfloat64
,Tuns16
): eop
= OPd_u16
; goto Leop
;
3764 case X(Tfloat64
,Tint32
): eop
= OPd_s32
; goto Leop
;
3765 case X(Tfloat64
,Tuns32
): eop
= OPd_u32
; goto Leop
;
3766 case X(Tfloat64
,Tint64
): eop
= OPd_s64
; goto Leop
;
3767 case X(Tfloat64
,Tuns64
): eop
= OPd_u64
; goto Leop
;
3768 case X(Tfloat64
,Tfloat32
): eop
= OPd_f
; goto Leop
;
3769 case X(Tfloat64
,Tfloat80
): eop
= OPd_ld
; goto Leop
;
3770 case X(Tfloat64
,Timaginary32
): goto Lzero
;
3771 case X(Tfloat64
,Timaginary64
): goto Lzero
;
3772 case X(Tfloat64
,Timaginary80
): goto Lzero
;
3773 case X(Tfloat64
,Tcomplex32
):
3774 case X(Tfloat64
,Tcomplex64
):
3775 case X(Tfloat64
,Tcomplex80
):
3776 e
= el_bin(OPadd
,TYcfloat
,el_long(TYidouble
,0),e
);
3780 /* ============================= */
3782 case X(Tfloat80
,Tint8
):
3783 case X(Tfloat80
,Tuns8
):
3784 case X(Tfloat80
,Tint16
):
3785 case X(Tfloat80
,Tuns16
):
3786 case X(Tfloat80
,Tint32
):
3787 case X(Tfloat80
,Tuns32
):
3788 case X(Tfloat80
,Tint64
):
3789 case X(Tfloat80
,Tuns64
):
3790 case X(Tfloat80
,Tfloat32
): e
= el_una(OPld_d
, TYdouble
, e
);
3793 case X(Tfloat80
,Tfloat64
): eop
= OPld_d
; goto Leop
;
3794 case X(Tfloat80
,Timaginary32
): goto Lzero
;
3795 case X(Tfloat80
,Timaginary64
): goto Lzero
;
3796 case X(Tfloat80
,Timaginary80
): goto Lzero
;
3797 case X(Tfloat80
,Tcomplex32
):
3798 case X(Tfloat80
,Tcomplex64
):
3799 case X(Tfloat80
,Tcomplex80
):
3800 e
= el_bin(OPadd
,TYcldouble
,e
,el_long(TYildouble
,0));
3804 /* ============================= */
3806 case X(Timaginary32
,Tint8
):
3807 case X(Timaginary32
,Tuns8
):
3808 case X(Timaginary32
,Tint16
):
3809 case X(Timaginary32
,Tuns16
):
3810 case X(Timaginary32
,Tint32
):
3811 case X(Timaginary32
,Tuns32
):
3812 case X(Timaginary32
,Tint64
):
3813 case X(Timaginary32
,Tuns64
):
3814 case X(Timaginary32
,Tfloat32
):
3815 case X(Timaginary32
,Tfloat64
):
3816 case X(Timaginary32
,Tfloat80
): goto Lzero
;
3817 case X(Timaginary32
,Timaginary64
): eop
= OPf_d
; goto Leop
;
3818 case X(Timaginary32
,Timaginary80
):
3819 e
= el_una(OPf_d
, TYidouble
, e
);
3822 case X(Timaginary32
,Tcomplex32
):
3823 case X(Timaginary32
,Tcomplex64
):
3824 case X(Timaginary32
,Tcomplex80
):
3825 e
= el_bin(OPadd
,TYcfloat
,el_long(TYfloat
,0),e
);
3829 /* ============================= */
3831 case X(Timaginary64
,Tint8
):
3832 case X(Timaginary64
,Tuns8
):
3833 case X(Timaginary64
,Tint16
):
3834 case X(Timaginary64
,Tuns16
):
3835 case X(Timaginary64
,Tint32
):
3836 case X(Timaginary64
,Tuns32
):
3837 case X(Timaginary64
,Tint64
):
3838 case X(Timaginary64
,Tuns64
):
3839 case X(Timaginary64
,Tfloat32
):
3840 case X(Timaginary64
,Tfloat64
):
3841 case X(Timaginary64
,Tfloat80
): goto Lzero
;
3842 case X(Timaginary64
,Timaginary32
): eop
= OPd_f
; goto Leop
;
3843 case X(Timaginary64
,Timaginary80
): eop
= OPd_ld
; goto Leop
;
3844 case X(Timaginary64
,Tcomplex32
):
3845 case X(Timaginary64
,Tcomplex64
):
3846 case X(Timaginary64
,Tcomplex80
):
3847 e
= el_bin(OPadd
,TYcdouble
,el_long(TYdouble
,0),e
);
3851 /* ============================= */
3853 case X(Timaginary80
,Tint8
):
3854 case X(Timaginary80
,Tuns8
):
3855 case X(Timaginary80
,Tint16
):
3856 case X(Timaginary80
,Tuns16
):
3857 case X(Timaginary80
,Tint32
):
3858 case X(Timaginary80
,Tuns32
):
3859 case X(Timaginary80
,Tint64
):
3860 case X(Timaginary80
,Tuns64
):
3861 case X(Timaginary80
,Tfloat32
):
3862 case X(Timaginary80
,Tfloat64
):
3863 case X(Timaginary80
,Tfloat80
): goto Lzero
;
3864 case X(Timaginary80
,Timaginary32
): e
= el_una(OPf_d
, TYidouble
, e
);
3867 case X(Timaginary80
,Timaginary64
): eop
= OPld_d
; goto Leop
;
3868 case X(Timaginary80
,Tcomplex32
):
3869 case X(Timaginary80
,Tcomplex64
):
3870 case X(Timaginary80
,Tcomplex80
):
3871 e
= el_bin(OPadd
,TYcldouble
,el_long(TYldouble
,0),e
);
3875 /* ============================= */
3877 case X(Tcomplex32
,Tint8
):
3878 case X(Tcomplex32
,Tuns8
):
3879 case X(Tcomplex32
,Tint16
):
3880 case X(Tcomplex32
,Tuns16
):
3881 case X(Tcomplex32
,Tint32
):
3882 case X(Tcomplex32
,Tuns32
):
3883 case X(Tcomplex32
,Tint64
):
3884 case X(Tcomplex32
,Tuns64
):
3885 case X(Tcomplex32
,Tfloat32
):
3886 case X(Tcomplex32
,Tfloat64
):
3887 case X(Tcomplex32
,Tfloat80
):
3888 e
= el_una(OPc_r
, TYfloat
, e
);
3891 case X(Tcomplex32
,Timaginary32
):
3892 case X(Tcomplex32
,Timaginary64
):
3893 case X(Tcomplex32
,Timaginary80
):
3894 e
= el_una(OPc_i
, TYifloat
, e
);
3897 case X(Tcomplex32
,Tcomplex64
):
3898 case X(Tcomplex32
,Tcomplex80
):
3899 e
= el_una(OPf_d
, TYcdouble
, e
);
3903 /* ============================= */
3905 case X(Tcomplex64
,Tint8
):
3906 case X(Tcomplex64
,Tuns8
):
3907 case X(Tcomplex64
,Tint16
):
3908 case X(Tcomplex64
,Tuns16
):
3909 case X(Tcomplex64
,Tint32
):
3910 case X(Tcomplex64
,Tuns32
):
3911 case X(Tcomplex64
,Tint64
):
3912 case X(Tcomplex64
,Tuns64
):
3913 case X(Tcomplex64
,Tfloat32
):
3914 case X(Tcomplex64
,Tfloat64
):
3915 case X(Tcomplex64
,Tfloat80
):
3916 e
= el_una(OPc_r
, TYdouble
, e
);
3919 case X(Tcomplex64
,Timaginary32
):
3920 case X(Tcomplex64
,Timaginary64
):
3921 case X(Tcomplex64
,Timaginary80
):
3922 e
= el_una(OPc_i
, TYidouble
, e
);
3925 case X(Tcomplex64
,Tcomplex32
): eop
= OPd_f
; goto Leop
;
3926 case X(Tcomplex64
,Tcomplex80
): eop
= OPd_ld
; goto Leop
;
3928 /* ============================= */
3930 case X(Tcomplex80
,Tint8
):
3931 case X(Tcomplex80
,Tuns8
):
3932 case X(Tcomplex80
,Tint16
):
3933 case X(Tcomplex80
,Tuns16
):
3934 case X(Tcomplex80
,Tint32
):
3935 case X(Tcomplex80
,Tuns32
):
3936 case X(Tcomplex80
,Tint64
):
3937 case X(Tcomplex80
,Tuns64
):
3938 case X(Tcomplex80
,Tfloat32
):
3939 case X(Tcomplex80
,Tfloat64
):
3940 case X(Tcomplex80
,Tfloat80
):
3941 e
= el_una(OPc_r
, TYldouble
, e
);
3944 case X(Tcomplex80
,Timaginary32
):
3945 case X(Tcomplex80
,Timaginary64
):
3946 case X(Tcomplex80
,Timaginary80
):
3947 e
= el_una(OPc_i
, TYildouble
, e
);
3950 case X(Tcomplex80
,Tcomplex32
):
3951 case X(Tcomplex80
,Tcomplex64
):
3952 e
= el_una(OPld_d
, TYcdouble
, e
);
3956 /* ============================= */
3962 //printf("fty = %d, tty = %d\n", fty, tty);
3963 error("e2ir: cannot cast from %s to %s", e1
->type
->toChars(), t
->toChars());
3967 e
= el_long(ttym
, 0);
3975 e
= el_una(eop
, ttym
, e
);
3979 // Adjust for any type paints
3980 t
= type
->toBasetype();
3981 e
->Ety
= t
->totym();
3987 elem
*ArrayLengthExp::toElem(IRState
*irs
)
3989 elem
*e
= e1
->toElem(irs
);
3990 e
= el_una(OP64_32
, type
->totym(), e
);
3995 elem
*SliceExp::toElem(IRState
*irs
)
3999 //printf("SliceExp::toElem()\n");
4000 t1
= e1
->type
->toBasetype();
4001 e
= e1
->toElem(irs
);
4010 einit
= resolveLengthVar(lengthVar
, &e
, t1
);
4012 sz
= t1
->nextOf()->size();
4014 elwr
= lwr
->toElem(irs
);
4015 eupr
= upr
->toElem(irs
);
4017 elwr2
= el_same(&elwr
);
4019 // Create an array reference where:
4020 // length is (upr - lwr)
4021 // pointer is (ptr + lwr*sz)
4022 // Combine as (length pair ptr)
4024 if (global
.params
.useArrayBounds
)
4026 // Checks (unsigned compares):
4027 // upr <= array.length
4037 if (t1
->ty
== Tpointer
)
4039 // Just do lwr <= upr check
4041 eupr2
= el_same(&eupr
);
4042 eupr2
->Ety
= TYuint
; // make sure unsigned comparison
4043 c1
= el_bin(OPle
, TYint
, elwr2
, eupr2
);
4044 c1
= el_combine(eupr
, c1
);
4047 else if (t1
->ty
== Tsarray
)
4048 { TypeSArray
*tsa
= (TypeSArray
*)t1
;
4049 integer_t length
= tsa
->dim
->toInteger();
4051 elength
= el_long(TYuint
, length
);
4054 else if (t1
->ty
== Tarray
)
4057 elength
= el_var(lengthVar
->toSymbol());
4061 e
= el_same(&elength
);
4062 elength
= el_una(OP64_32
, TYuint
, elength
);
4065 eupr2
= el_same(&eupr
);
4066 c1
= el_bin(OPle
, TYint
, eupr
, elength
);
4067 eupr2
->Ety
= TYuint
; // make sure unsigned comparison
4068 c2
= el_bin(OPle
, TYint
, elwr2
, eupr2
);
4069 c1
= el_bin(OPandand
, TYint
, c1
, c2
); // (c1 && c2)
4072 // Construct: (c1 || ModuleArray(line))
4075 sassert
= irs
->blx
->module
->toModuleArray();
4076 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
), el_long(TYint
, loc
.linnum
));
4077 eb
= el_bin(OPoror
,TYvoid
,c1
,ea
);
4078 elwr
= el_combine(elwr
, eb
);
4080 elwr2
= el_copytree(elwr2
);
4081 eupr
= el_copytree(eupr2
);
4085 eptr
= array_toPtr(e1
->type
, e
);
4087 elem
*elength
= el_bin(OPmin
, TYint
, eupr
, elwr2
);
4088 eptr
= el_bin(OPadd
, TYnptr
, eptr
, el_bin(OPmul
, TYint
, el_copytree(elwr2
), el_long(TYint
, sz
)));
4090 e
= el_pair(TYullong
, elength
, eptr
);
4091 e
= el_combine(elwr
, e
);
4092 e
= el_combine(einit
, e
);
4094 else if (t1
->ty
== Tsarray
)
4096 e
= sarray_toDarray(t1
, NULL
, e
);
4102 elem
*IndexExp::toElem(IRState
*irs
)
4104 elem
*n1
= e1
->toElem(irs
);
4109 //printf("IndexExp::toElem() %s\n", toChars());
4110 t1
= e1
->type
->toBasetype();
4111 if (t1
->ty
== Taarray
)
4114 // *aaGet(aa, keyti, valuesize, index);
4116 TypeAArray
*taa
= (TypeAArray
*)t1
;
4119 int vsize
= taa
->next
->size();
4123 // n2 becomes the index, also known as the key
4124 n2
= e2
->toElem(irs
);
4125 if (n2
->Ety
== TYstruct
|| n2
->Ety
== TYarray
)
4127 n2
= el_una(OPstrpar
, TYstruct
, n2
);
4128 n2
->Enumbytes
= n2
->E1
->Enumbytes
;
4129 //printf("numbytes = %d\n", n2->Enumbytes);
4130 assert(n2
->Enumbytes
);
4132 valuesize
= el_long(TYuint
, vsize
); // BUG: should be TYsize_t
4133 //printf("valuesize: "); elem_print(valuesize);
4136 n1
= el_una(OPaddr
, TYnptr
, n1
);
4137 s
= taa
->aaGetSymbol("Get", 1);
4141 s
= taa
->aaGetSymbol("GetRvalue", 1);
4143 //printf("taa->index = %s\n", taa->index->toChars());
4144 keyti
= taa
->index
->getInternalTypeInfo(NULL
)->toElem(irs
);
4145 //keyti = taa->index->getTypeInfo(NULL)->toElem(irs);
4146 //printf("keyti:\n");
4147 //elem_print(keyti);
4148 ep
= el_params(n2
, valuesize
, keyti
, n1
, NULL
);
4149 e
= el_bin(OPcall
, TYnptr
, el_var(s
), ep
);
4150 if (global
.params
.useArrayBounds
)
4157 // Construct: ((e || ModuleAssert(line)),n)
4160 sassert
= irs
->blx
->module
->toModuleArray();
4161 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
4162 el_long(TYint
, loc
.linnum
));
4163 e
= el_bin(OPoror
,TYvoid
,e
,ea
);
4164 e
= el_bin(OPcomma
, TYnptr
, e
, n
);
4166 e
= el_una(OPind
, type
->totym(), e
);
4167 if (tybasic(e
->Ety
) == TYstruct
)
4168 e
->Enumbytes
= type
->size();
4173 einit
= resolveLengthVar(lengthVar
, &n1
, t1
);
4174 n2
= e2
->toElem(irs
);
4176 if (global
.params
.useArrayBounds
)
4182 if (t1
->ty
== Tsarray
)
4183 { TypeSArray
*tsa
= (TypeSArray
*)t1
;
4184 integer_t length
= tsa
->dim
->toInteger();
4186 elength
= el_long(TYuint
, length
);
4189 else if (t1
->ty
== Tarray
)
4192 n1
= el_same(&elength
);
4193 elength
= el_una(OP64_32
, TYuint
, elength
);
4197 n2x
= el_bin(OPlt
, TYint
, n2x
, elength
);
4199 // Construct: (n2x || ModuleAssert(line))
4202 sassert
= irs
->blx
->module
->toModuleArray();
4203 ea
= el_bin(OPcall
,TYvoid
,el_var(sassert
),
4204 el_long(TYint
, loc
.linnum
));
4205 eb
= el_bin(OPoror
,TYvoid
,n2x
,ea
);
4209 n1
= array_toPtr(t1
, n1
);
4213 escale
= el_long(TYint
, t1
->nextOf()->size());
4214 n2
= el_bin(OPmul
, TYint
, n2
, escale
);
4215 e
= el_bin(OPadd
, TYnptr
, n1
, n2
);
4216 e
= el_una(OPind
, type
->totym(), e
);
4217 if (tybasic(e
->Ety
) == TYstruct
|| tybasic(e
->Ety
) == TYarray
)
4218 { e
->Ety
= TYstruct
;
4219 e
->Enumbytes
= type
->size();
4223 eb
= el_combine(einit
, eb
);
4224 e
= el_combine(eb
, e
);
4231 elem
*TupleExp::toElem(IRState
*irs
)
4234 //printf("TupleExp::toElem() %s\n", toChars());
4235 for (size_t i
= 0; i
< exps
->dim
; i
++)
4236 { Expression
*el
= (Expression
*)exps
->data
[i
];
4237 elem
*ep
= el
->toElem(irs
);
4239 e
= el_combine(e
, ep
);
4245 elem
*ArrayLiteralExp::toElem(IRState
*irs
)
4249 //printf("ArrayLiteralExp::toElem() %s\n", toChars());
4252 dim
= elements
->dim
;
4253 e
= el_long(TYint
, dim
);
4254 for (size_t i
= 0; i
< dim
; i
++)
4255 { Expression
*el
= (Expression
*)elements
->data
[i
];
4256 elem
*ep
= el
->toElem(irs
);
4258 if (tybasic(ep
->Ety
) == TYstruct
|| tybasic(ep
->Ety
) == TYarray
)
4260 ep
= el_una(OPstrpar
, TYstruct
, ep
);
4261 ep
->Enumbytes
= el
->type
->size();
4263 e
= el_param(ep
, e
);
4268 e
= el_long(TYint
, 0);
4270 Type
*tb
= type
->toBasetype();
4272 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
4274 // call _d_arrayliteralT(ti, dim, ...)
4275 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ARRAYLITERALT
]),e
);
4277 e
= el_param(e
, el_long(TYint
, tb
->next
->size()));
4279 // call _d_arrayliteral(size, dim, ...)
4280 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ARRAYLITERAL
]),e
);
4282 if (tb
->ty
== Tarray
)
4284 e
= el_pair(TYullong
, el_long(TYint
, dim
), e
);
4286 else if (tb
->ty
== Tpointer
)
4291 e
= el_una(OPind
,TYstruct
,e
);
4292 e
->Enumbytes
= type
->size();
4300 elem
*AssocArrayLiteralExp::toElem(IRState
*irs
)
4304 //printf("AssocArrayLiteralExp::toElem() %s\n", toChars());
4306 e
= el_long(TYint
, dim
);
4307 for (size_t i
= 0; i
< dim
; i
++)
4308 { Expression
*el
= (Expression
*)keys
->data
[i
];
4310 for (int j
= 0; j
< 2; j
++)
4312 elem
*ep
= el
->toElem(irs
);
4314 if (tybasic(ep
->Ety
) == TYstruct
|| tybasic(ep
->Ety
) == TYarray
)
4316 ep
= el_una(OPstrpar
, TYstruct
, ep
);
4317 ep
->Enumbytes
= el
->type
->size();
4319 //printf("[%d] %s\n", i, el->toChars());
4321 e
= el_param(ep
, e
);
4322 el
= (Expression
*)values
->data
[i
];
4325 e
= el_param(e
, type
->getTypeInfo(NULL
)->toElem(irs
));
4327 // call _d_assocarrayliteralT(ti, dim, ...)
4328 e
= el_bin(OPcall
,TYnptr
,el_var(rtlsym
[RTLSYM_ASSOCARRAYLITERALT
]),e
);
4335 /*******************************************
4336 * Generate elem to zero fill contents of Symbol stmp
4337 * from *poffset..offset2.
4338 * May store anywhere from 0..maxoff, as this function
4339 * tries to use aligned int stores whereever possible.
4340 * Update *poffset to end of initialized hole; *poffset will be >= offset2.
4343 elem
*fillHole(Symbol
*stmp
, size_t *poffset
, size_t offset2
, size_t maxoff
)
4347 while (*poffset
< offset2
)
4351 if (tybasic(stmp
->Stype
->Tty
) == TYnptr
)
4358 size_t sz
= maxoff
- *poffset
;
4360 { case 1: ty
= TYchar
; break;
4361 case 2: ty
= TYshort
; break;
4370 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, *poffset
));
4371 e1
= el_una(OPind
, ty
, e1
);
4372 e1
= el_bin(OPeq
, ty
, e1
, el_long(ty
, 0));
4373 e
= el_combine(e
, e1
);
4374 *poffset
+= tysize
[ty
];
4379 elem
*StructLiteralExp::toElem(IRState
*irs
)
4383 //printf("StructLiteralExp::toElem() %s\n", toChars());
4385 // struct symbol to initialize with the literal
4386 Symbol
*stmp
= sym
? sym
: symbol_genauto(sd
->type
->toCtype());
4392 /* Initialize all alignment 'holes' to zero.
4393 * Do before initializing fields, as the hole filling process
4394 * can spill over into the fields.
4397 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
4399 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
4400 VarDeclaration
*v
= s
->isVarDeclaration();
4403 e
= el_combine(e
, fillHole(stmp
, &offset
, v
->offset
, sd
->structsize
));
4404 size_t vend
= v
->offset
+ v
->type
->size();
4408 e
= el_combine(e
, fillHole(stmp
, &offset
, sd
->structsize
, sd
->structsize
));
4413 dim
= elements
->dim
;
4414 assert(dim
<= sd
->fields
.dim
);
4415 for (size_t i
= 0; i
< dim
; i
++)
4416 { Expression
*el
= (Expression
*)elements
->data
[i
];
4420 Dsymbol
*s
= (Dsymbol
*)sd
->fields
.data
[i
];
4421 VarDeclaration
*v
= s
->isVarDeclaration();
4425 if (tybasic(stmp
->Stype
->Tty
) == TYnptr
)
4426 { e1
= el_var(stmp
);
4427 e1
->EV
.sp
.Voffset
= soffset
;
4430 { e1
= el_ptr(stmp
);
4432 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, soffset
));
4434 e1
= el_bin(OPadd
, TYnptr
, e1
, el_long(TYsize_t
, v
->offset
));
4436 elem
*ep
= el
->toElem(irs
);
4438 Type
*t1b
= v
->type
->toBasetype();
4439 Type
*t2b
= el
->type
->toBasetype();
4440 if (t1b
->ty
== Tsarray
)
4442 if (t2b
->implicitConvTo(t1b
))
4443 { elem
*esize
= el_long(TYsize_t
, t1b
->size());
4444 ep
= array_toPtr(el
->type
, ep
);
4445 e1
= el_bin(OPmemcpy
, TYnptr
, e1
, el_param(ep
, esize
));
4449 elem
*edim
= el_long(TYsize_t
, t1b
->size() / t2b
->size());
4450 e1
= setArray(e1
, edim
, t2b
, ep
, irs
, TOKconstruct
);
4455 tym_t ty
= v
->type
->totym();
4456 e1
= el_una(OPind
, ty
, e1
);
4458 e1
->Enumbytes
= v
->type
->size();
4459 e1
= el_bin(OPeq
, ty
, e1
, ep
);
4461 { e1
->Eoper
= OPstreq
;
4462 e1
->Enumbytes
= v
->type
->size();
4465 e
= el_combine(e
, e1
);
4469 elem
*ev
= el_var(stmp
);
4470 ev
->Enumbytes
= sd
->structsize
;
4471 e
= el_combine(e
, ev
);