root/branches/dmdfe-2.0/e2ir.c

Revision 914, 103.3 kB (checked in by Gregor, 3 months ago)

MERGE: DMD 2.019

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2008 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include    <stdio.h>
11 #include    <string.h>
12 #include    <time.h>
13 #include    <complex.h>
14
15 #include    "lexer.h"
16 #include    "expression.h"
17 #include    "mtype.h"
18 #include    "dsymbol.h"
19 #include    "declaration.h"
20 #include    "enum.h"
21 #include    "aggregate.h"
22 #include    "attrib.h"
23 #include    "module.h"
24 #include    "init.h"
25 #include    "template.h"
26
27 #if _WIN32
28 #include    "..\tk\mem.h"   // for mem_malloc
29 #elif linux
30 #include    "../tk/mem.h"   // for mem_malloc
31 #endif
32
33 #include    "cc.h"
34 #include    "el.h"
35 #include    "oper.h"
36 #include    "global.h"
37 #include    "code.h"
38 #include    "type.h"
39 #include    "dt.h"
40 #include    "irstate.h"
41 #include    "id.h"
42 #include    "type.h"
43 #include    "toir.h"
44
45 static char __file__[] = __FILE__;  /* for tassert.h        */
46 #include    "tassert.h"
47
48
49 elem *addressElem(elem *e, Type *t);
50 elem *array_toPtr(Type *t, elem *e);
51 elem *bit_assign(enum OPER op, elem *eb, elem *ei, elem *ev, int result);
52 elem *bit_read(elem *eb, elem *ei, int result);
53 elem *exp2_copytotemp(elem *e);
54
55 #define el_setLoc(e,loc)    ((e)->Esrcpos.Sfilename = (loc).filename, \
56                  (e)->Esrcpos.Slinnum = (loc).linnum)
57
58 /************************************
59  * Call a function.
60  */
61
62 elem *callfunc(Loc loc,
63     IRState *irs,
64     int directcall,     // 1: don't do virtual call
65     Type *tret,     // return type
66     elem *ec,       // evaluates to function address
67     Type *ectype,       // original type of ec
68     FuncDeclaration *fd,    // if !=NULL, this is the function being called
69     Type *t,        // TypeDelegate or TypeFunction for this function
70     elem *ehidden,      // if !=NULL, this is the 'hidden' argument
71     Array *arguments)
72 {
73     elem *ep;
74     elem *e;
75     elem *ethis = NULL;
76     elem *eside = NULL;
77     int i;
78     tym_t ty;
79     tym_t tyret;
80     enum RET retmethod;
81     int reverse;
82     TypeFunction *tf;
83     int op;
84
85 #if 0
86     printf("callfunc(directcall = %d, tret = '%s', ec = %p, fd = %p)\n",
87     directcall, tret->toChars(), ec, fd);
88     printf("ec: "); elem_print(ec);
89     if (fd)
90     printf("fd = '%s'\n", fd->toChars());
91 #endif
92
93     t = t->toBasetype();
94     if (t->ty == Tdelegate)
95     {
96     // A delegate consists of:
97     //  { Object *this; Function *funcptr; }
98     assert(!fd);
99     assert(t->nextOf()->ty == Tfunction);
100     tf = (TypeFunction *)(t->nextOf());
101     ethis = ec;
102     ec = el_same(&ethis);
103     ethis = el_una(OP64_32, TYnptr, ethis); // get this
104     ec = array_toPtr(t, ec);        // get funcptr
105     ec = el_una(OPind, tf->totym(), ec);
106     }
107     else
108     {   assert(t->ty == Tfunction);
109     tf = (TypeFunction *)(t);
110     }
111     retmethod = tf->retStyle();
112     ty = ec->Ety;
113     if (fd)
114     ty = fd->toSymbol()->Stype->Tty;
115     reverse = tyrevfunc(ty);
116     ep = NULL;
117     if (arguments)
118     {
119     // j=1 if _arguments[] is first argument
120     int j = (tf->linkage == LINKd && tf->varargs == 1);
121
122     for (i = 0; i < arguments->dim ; i++)
123     {   Expression *arg;
124         elem *ea;
125
126         arg = (Expression *)arguments->data[i];
127         //printf("\targ[%d]: %s\n", i, arg->toChars());
128
129         size_t nparams = Argument::dim(tf->parameters);
130         if (i - j < nparams && i >= j)
131         {
132         Argument *p = Argument::getNth(tf->parameters, i - j);
133
134         if (p->storageClass & (STCout | STCref))
135         {
136             // Convert argument to a pointer,
137             // use AddrExp::toElem()
138             Expression *ae = arg->addressOf(NULL);
139             ea = ae->toElem(irs);
140             goto L1;
141         }
142         }
143         ea = arg->toElem(irs);
144     L1:
145         if (ea->Ety == TYstruct)
146         {
147         ea = el_una(OPstrpar, TYstruct, ea);
148         ea->Enumbytes = ea->E1->Enumbytes;
149         assert(ea->Enumbytes);
150         }
151         if (reverse)
152         ep = el_param(ep,ea);
153         else
154         ep = el_param(ea,ep);
155     }
156     }
157
158     if (retmethod == RETstack)
159     {
160     if (!ehidden)
161     {   // Don't have one, so create one
162         type *t;
163
164         if (tf->next->toBasetype()->ty == Tstruct)
165         t = tf->next->toCtype();
166         else
167         t = type_fake(tf->next->totym());
168         Symbol *stmp = symbol_genauto(t);
169         ehidden = el_ptr(stmp);
170     }
171     if (ep)
172     {
173 #if 0 // BUG: implement
174         if (reverse && type_mangle(tfunc) == mTYman_cpp)
175         ep = el_param(ehidden,ep);
176         else
177 #endif
178         ep = el_param(ep,ehidden);
179     }
180     else
181         ep = ehidden;
182     ehidden = NULL;
183     }
184     assert(ehidden == NULL);
185
186     if (fd && fd->isMember2())
187     {
188     InterfaceDeclaration *intd;
189     Symbol *sfunc;
190     AggregateDeclaration *ad;
191
192     ad = fd->isThis();
193     if (ad)
194     {
195         ethis = ec;
196         if (ad->handle->ty == Tpointer && tybasic(ec->Ety) != TYnptr)
197         {
198         ethis = addressElem(ec, ectype);
199         }
200     }
201     else
202     {
203         // Evaluate ec for side effects
204         eside = ec;
205     }
206     sfunc = fd->toSymbol();
207
208     if (!fd->isVirtual() ||
209         directcall ||       // BUG: fix
210         fd->isFinal()
211        )
212     {
213         // make static call
214         ec = el_var(sfunc);
215     }
216     else
217     {
218         // make virtual call
219         elem *ev;
220         unsigned vindex;
221
222         assert(ethis);
223         ev = el_same(&ethis);
224         ev = el_una(OPind, TYnptr, ev);
225         vindex = fd->vtblIndex;
226
227         // Build *(ev + vindex * 4)
228         ec = el_bin(OPadd,TYnptr,ev,el_long(TYint, vindex * 4));
229         ec = el_una(OPind,TYnptr,ec);
230         ec = el_una(OPind,tybasic(sfunc->Stype->Tty),ec);
231     }
232     }
233     else if (fd && fd->isNested())
234     {
235     assert(!ethis);
236     ethis = getEthis(0, irs, fd);
237
238     }
239
240     ep = el_param(ep, ethis);
241
242     tyret = tret->totym();
243
244     // Look for intrinsic functions
245     if (ec->Eoper == OPvar && (op = intrinsic_op(ec->EV.sp.Vsym->Sident)) != -1)
246     {
247     el_free(ec);
248     if (OTbinary(op))
249     {
250         ep->Eoper = op;
251         ep->Ety = tyret;
252         e = ep;
253         if (op == OPscale)
254         {   elem *et;
255
256         et = e->E1;
257         e->E1 = el_una(OPs32_d, TYdouble, e->E2);
258         e->E1 = el_una(OPd_ld, TYldouble, e->E1);
259         e->E2 = et;
260         e->Ety = tyret;
261         }
262     }
263     else
264         e = el_una(op,tyret,ep);
265     }
266     else if (ep)
267     e = el_bin(OPcall,tyret,ec,ep);
268     else
269     e = el_una(OPucall,tyret,ec);
270
271     if (retmethod == RETstack)
272     {
273     e->Ety = TYnptr;
274     e = el_una(OPind, tyret, e);
275     }
276     if (tybasic(tyret) == TYstruct)
277     {
278     e->Enumbytes = tret->size();
279     }
280     e = el_combine(eside, e);
281     return e;
282 }
283
284 /*******************************************
285  * Take address of an elem.
286  */
287
288 elem *addressElem(elem *e, Type *t)
289 {
290     elem **pe;
291
292     //printf("addressElem()\n");
293
294     for (pe = &e; (*pe)->Eoper == OPcomma; pe = &(*pe)->E2)
295     ;
296     if ((*pe)->Eoper != OPvar && (*pe)->Eoper != OPind)
297     {   Symbol *stmp;
298     elem *eeq;
299     elem *e = *pe;
300     type *tx;
301
302     // Convert to ((tmp=e),tmp)
303     TY ty;
304     if (t && ((ty = t->toBasetype()->ty) == Tstruct || ty == Tsarray))
305         tx = t->toCtype();
306     else
307         tx = type_fake(e->Ety);
308     stmp = symbol_genauto(tx);
309     eeq = el_bin(OPeq,e->Ety,el_var(stmp),e);
310     if (e->Ety == TYstruct)
311     {
312         eeq->Eoper = OPstreq;
313         eeq->Enumbytes = e->Enumbytes;
314     }
315     else if (e->Ety == TYarray)
316     {
317         eeq->Eoper = OPstreq;
318         eeq->Ejty = eeq->Ety = TYstruct;
319         eeq->Enumbytes = t->size();
320     }
321     *pe = el_bin(OPcomma,e->Ety,eeq,el_var(stmp));
322     }
323     e = el_una(OPaddr,TYnptr,e);
324     return e;
325 }
326
327 /*****************************************
328  * Convert array to a pointer to the data.
329  */
330
331 elem *array_toPtr(Type *t, elem *e)
332 {
333     //printf("array_toPtr()\n");
334     //elem_print(e);
335     t = t->toBasetype();
336     switch (t->ty)
337     {
338     case Tpointer:
339         break;
340
341     case Tarray:
342     case Tdelegate:
343         if (e->Eoper == OPcomma)
344         {
345         e->Ety = TYnptr;
346         e->E2 = array_toPtr(t, e->E2);
347         }
348         else if (e->Eoper == OPpair)
349         {
350         e->Eoper = OPcomma;
351         e->Ety = TYnptr;
352         }
353         else
354         {
355 #if 1
356         e = el_una(OPmsw, TYnptr, e);
357 #else
358         e = el_una(OPaddr, TYnptr, e);
359         e = el_bin(OPadd, TYnptr, e, el_long(TYint, 4));
360         e = el_una(OPind, TYnptr, e);
361 #endif
362         }
363         break;
364
365     case Tsarray:
366         e = el_una(OPaddr, TYnptr, e);
367         break;
368
369     default:
370         t->print();
371         assert(0);
372     }
373     return e;
374 }
375
376 /*****************************************
377  * Convert array to a dynamic array.
378  */
379
380 elem *array_toDarray(Type *t, elem *e)
381 {
382     unsigned dim;
383     elem *ef = NULL;
384     elem *ex;
385
386     //printf("array_toDarray(t = %s)\n", t->toChars());
387     //elem_print(e);
388     t = t->toBasetype();
389     switch (t->ty)
390     {
391     case Tarray:
392         break;
393
394     case Tsarray:
395         e = el_una(OPaddr, TYnptr, e);
396         dim = ((TypeSArray *)t)->dim->toInteger();
397         e = el_pair(TYullong, el_long(TYint, dim), e);
398         break;
399
400     default:
401     L1:
402         switch (e->Eoper)
403         {
404         case OPconst:
405         {
406             size_t len = tysize[tybasic(e->Ety)];
407             elem *es = el_calloc();
408             es->Eoper = OPstring;
409
410             // Match MEM_PH_FREE for OPstring in ztc\el.c
411             es->EV.ss.Vstring = (char *)mem_malloc(len);
412             memcpy(es->EV.ss.Vstring, &e->EV, len);
413
414             es->EV.ss.Vstrlen = len;
415             es->Ety = TYnptr;
416             e = es;
417             break;
418         }
419
420         case OPvar:
421             e = el_una(OPaddr, TYnptr, e);
422             break;
423
424         case OPcomma:
425             ef = el_combine(ef, e->E1);
426             ex = e;
427             e = e->E2;
428             ex->E1 = NULL;
429             ex->E2 = NULL;
430             el_free(ex);
431             goto L1;
432
433         case OPind:
434             ex = e;
435             e = e->E1;
436             ex->E1 = NULL;
437             ex->E2 = NULL;
438             el_free(ex);
439             break;
440
441         default:
442         {
443             // Copy expression to a variable and take the
444             // address of that variable.
445             Symbol *stmp;
446             tym_t ty = tybasic(e->Ety);
447
448             if (ty == TYstruct)
449             {
450             if (e->Enumbytes == 4)
451                 ty = TYint;
452             else if (e->Enumbytes == 8)
453                 ty = TYllong;
454             }
455             e->Ety = ty;
456             stmp = symbol_genauto(type_fake(ty));
457             e = el_bin(OPeq, e->Ety, el_var(stmp), e);
458             e = el_bin(OPcomma, TYnptr, e, el_una(OPaddr, TYnptr, el_var(stmp)));
459             break;
460         }
461         }
462         dim = 1;
463         e = el_pair(TYullong, el_long(TYint, dim), e);
464         break;
465     }
466     return el_combine(ef, e);
467 }
468
469 /*****************************************
470  * Evaluate elem and convert to dynamic array.
471  */
472
473 elem *eval_Darray(IRState *irs, Expression *e)
474 {
475     elem *ex;
476
477     ex = e->toElem(irs);
478     return array_toDarray(e->type, ex);
479 }
480
481 /************************************
482  */
483
484 elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e)
485 {
486     //printf("sarray_toDarray()\n");
487     //elem_print(e);
488
489     elem *elen;
490     unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger();
491
492     if (tto)
493     {
494     unsigned fsize = tfrom->nextOf()->size();
495     unsigned tsize = tto->nextOf()->size();
496
497     if ((dim * fsize) % tsize != 0)
498     {
499       Lerr:
500         error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars());
501     }
502     dim = (dim * fsize) / tsize;
503     }
504   L1:
505     elen = el_long(TYint, dim);
506     e = el_una(OPaddr, TYnptr, e);
507     e = el_pair(TYullong, elen, e);
508     return e;
509 }
510
511 /*******************************************
512  * Set an array pointed to by eptr to evalue:
513  *  eptr[0..edim] = evalue;
514  * Input:
515  *  eptr    where to write the data to
516  *  evalue  value to write
517  *  edim    number of times to write evalue to eptr[]
518  *  tb  type of evalue
519  */
520
521 elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue, IRState *irs, int op)
522 {   int r;
523     elem *e;
524     int sz = tb->size();
525
526     if (tb->ty == Tfloat80 || tb->ty == Timaginary80)
527     r = RTLSYM_MEMSET80;
528     else if (tb->ty == Tcomplex80)
529     r = RTLSYM_MEMSET160;
530     else if (tb->ty == Tcomplex64)
531     r = RTLSYM_MEMSET128;
532     else
533     {
534     switch (sz)
535     {
536         case 1:  r = RTLSYM_MEMSET8;    break;
537         case 2:  r = RTLSYM_MEMSET16;   break;
538         case 4:  r = RTLSYM_MEMSET32;   break;
539         case 8:  r = RTLSYM_MEMSET64;   break;
540         default:     r = RTLSYM_MEMSETN;    break;
541     }
542
543     /* Determine if we need to do postblit
544      */
545     if (op != TOKblit)
546     {
547         Type *t = tb;
548         while (t->ty == Tsarray)
549         t = t->nextOf()->toBasetype();
550         if (t->ty == Tstruct)
551         {   StructDeclaration *sd = ((TypeStruct *)t)->sym;
552         if (sd->postblit)
553         {   /* Need to do postblit.
554              *   void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti);
555              */
556             r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN;
557             evalue = el_una(OPaddr, TYnptr, evalue);
558             Expression *ti = tb->getTypeInfo(NULL);
559             elem *eti = ti->toElem(irs);
560             e = el_params(eti, edim, evalue, eptr, NULL);
561             e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
562             return e;
563         }
564         }
565     }
566
567     if (r == RTLSYM_MEMSETN)
568     {
569         // void *_memsetn(void *p, void *value, int dim, int sizelem)
570         evalue = el_una(OPaddr, TYnptr, evalue);
571         elem *esz = el_long(TYint, sz);
572         e = el_params(esz, edim, evalue, eptr, NULL);
573         e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
574         return e;
575     }
576     }
577     if (sz > 1 && sz <= 8 &&
578     evalue->Eoper == OPconst && el_allbits(evalue, 0))
579     {
580     r = RTLSYM_MEMSET8;
581     edim = el_bin(OPmul, TYuint, edim, el_long(TYuint, sz));
582     }
583
584     if (evalue->Ety == TYstruct)
585     {
586     evalue = el_una(OPstrpar, TYstruct, evalue);
587     evalue->Enumbytes = evalue->E1->Enumbytes;
588     assert(evalue->Enumbytes);
589     }
590
591     // Be careful about parameter side effect ordering
592     if (r == RTLSYM_MEMSET8)
593     {
594     e = el_param(edim, evalue);
595     e = el_bin(OPmemset,TYnptr,eptr,e);
596     }
597     else
598     {
599     e = el_params(edim, evalue, eptr, NULL);
600     e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e);
601     }
602     return e;
603 }
604
605 /***************************************
606  */
607
608 elem *Expression::toElem(IRState *irs)
609 {
610     print();
611     assert(0);
612     return NULL;
613 }
614
615 /************************************
616  */
617
618 elem *SymbolExp::toElem(IRState *irs)
619 {   Symbol *s;
620     elem *e;
621     tym_t tym;
622     Type *tb = (op == TOKsymoff) ? var->type->toBasetype() : type->toBasetype();
623     int offset = (op == TOKsymoff) ? ((SymOffExp*)this)->offset : 0;
624     FuncDeclaration *fd;
625     VarDeclaration *v = var->isVarDeclaration();
626
627     //printf("SymbolExp::toElem('%s') %p\n", toChars(), this);
628     //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null");
629     if (op == TOKvar && var->needThis())
630     {
631     error("need 'this' to access member %s",