1: 
   2: // Compiler implementation of the D programming language
   3: // Copyright (c) 1999-2011 by Digital Mars
   4: // All Rights Reserved
   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.
  10: 
  11: #include        <stdio.h>
  12: #include        <string.h>
  13: #include        <time.h>
  14: //#include        <complex.h>
  15: 
  16: #include        "port.h"
  17: 
  18: #include        "lexer.h"
  19: #include        "expression.h"
  20: #include        "mtype.h"
  21: #include        "dsymbol.h"
  22: #include        "declaration.h"
  23: #include        "enum.h"
  24: #include        "aggregate.h"
  25: #include        "attrib.h"
  26: #include        "module.h"
  27: #include        "init.h"
  28: #include        "template.h"
  29: 
  30: #include        "mem.h" // for tk/mem_malloc
  31: 
  32: #include        "cc.h"
  33: #include        "el.h"
  34: #include        "oper.h"
  35: #include        "global.h"
  36: #include        "code.h"
  37: #include        "type.h"
  38: #include        "dt.h"
  39: #include        "irstate.h"
  40: #include        "id.h"
  41: #include        "type.h"
  42: #include        "toir.h"
  43: 
  44: static char __file__[] = __FILE__;      /* for tassert.h                */
  45: #include        "tassert.h"
  46: 
  47: typedef ArrayBase<elem> Elems;
  48: 
  49: elem *addressElem(elem *e, Type *t);
  50: elem *array_toPtr(Type *t, elem *e);
  51: elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi);
  52: 
  53: #define el_setLoc(e,loc)        ((e)->Esrcpos.Sfilename = (char *)(loc).filename, \
  54:                                  (e)->Esrcpos.Slinnum = (loc).linnum)
  55: 
  56: /* If variable var of type typ is a reference
  57:  */
  58: #if SARRAYVALUE
  59: #define ISREF(var, tb) (var->isOut() || var->isRef())
  60: #else
  61: #define ISREF(var, tb) ((var->isParameter() && tb->ty == Tsarray) || var->isOut() || var->isRef())
  62: #endif
  63: 
  64: /************************************
  65:  * Call a function.
  66:  */
  67: 
  68: elem *callfunc(Loc loc,
  69:         IRState *irs,
  70:         int directcall,         // 1: don't do virtual call
  71:         Type *tret,             // return type
  72:         elem *ec,               // evaluates to function address
  73:         Type *ectype,           // original type of ec
  74:         FuncDeclaration *fd,    // if !=NULL, this is the function being called
  75:         Type *t,                // TypeDelegate or TypeFunction for this function
  76:         elem *ehidden,          // if !=NULL, this is the 'hidden' argument
  77:         Expressions *arguments)
  78: {
  79:     elem *ep;
  80:     elem *e;
  81:     elem *ethis = NULL;
  82:     elem *eside = NULL;
  83:     int i;
  84:     tym_t ty;
  85:     tym_t tyret;
  86:     enum RET retmethod;
  87:     int reverse;
  88:     TypeFunction *tf;
  89:     int op;
  90: 
  91: #if 0
  92:     printf("callfunc(directcall = %d, tret = '%s', ec = %p, fd = %p)\n",
  93:         directcall, tret->toChars(), ec, fd);
  94:     printf("ec: "); elem_print(ec);
  95:     if (fd)
  96:         printf("fd = '%s'\n", fd->toChars());
  97: #endif
  98: 
  99:     t = t->toBasetype();
 100:     if (t->ty == Tdelegate)
 101:     {
 102:         // A delegate consists of:
 103:         //      { Object *this; Function *funcptr; }
 104:         assert(!fd);
 105:         assert(t->nextOf()->ty == Tfunction);
 106:         tf = (TypeFunction *)(t->nextOf());
 107:         ethis = ec;
 108:         ec = el_same(&ethis);
 109:         ethis = el_una(I64 ? OP128_64 : OP64_32, TYnptr, ethis); // get this
 110:         ec = array_toPtr(t, ec);                // get funcptr
 111:         ec = el_una(OPind, tf->totym(), ec);
 112:     }
 113:     else
 114:     {   assert(t->ty == Tfunction);
 115:         tf = (TypeFunction *)(t);
 116:     }
 117:     retmethod = tf->retStyle();
 118:     ty = ec->Ety;
 119:     if (fd)
 120:         ty = fd->toSymbol()->Stype->Tty;
 121:     reverse = tyrevfunc(ty);
 122:     ep = NULL;
 123:     if (arguments)
 124:     {
 125:         // j=1 if _arguments[] is first argument
 126:         int j = (tf->linkage == LINKd && tf->varargs == 1);
 127: 
 128:         for (i = 0; i < arguments->dim ; i++)
warning C4018: '<' : signed/unsigned mismatch
129: { Expression *arg = arguments->tdata()[i]; 130: elem *ea; 131: 132: //printf("\targ[%d]: %s\n", i, arg->toChars()); 133: 134: size_t nparams = Parameter::dim(tf->parameters); 135: if (i - j < nparams && i >= j)
warning C4018: '<' : signed/unsigned mismatch
136: { 137: Parameter *p = Parameter::getNth(tf->parameters, i - j); 138: 139: if (p->storageClass & (STCout | STCref)) 140: { 141: // Convert argument to a pointer, 142: // use AddrExp::toElem() 143: Expression *ae = arg->addressOf(NULL); 144: ea = ae->toElem(irs); 145: goto L1; 146: } 147: } 148: ea = arg->toElem(irs); 149: L1: 150: if (tybasic(ea->Ety) == TYstruct || tybasic(ea->Ety) == TYarray) 151: { 152: ea = el_una(OPstrpar, TYstruct, ea); 153: ea->ET = ea->E1->ET; 154: } 155: if (reverse) 156: ep = el_param(ep,ea); 157: else 158: ep = el_param(ea,ep); 159: } 160: } 161: 162: if (retmethod == RETstack) 163: { 164: if (!ehidden) 165: { // Don't have one, so create one 166: type *t;
warning C6246: Local declaration of 't' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '75' of 'c:\projects\extern\d\dmd\src\e2ir.c': Lines: 75
167: 168: Type *tret = tf->next;
warning C6246: Local declaration of 'tret' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '71' of 'c:\projects\extern\d\dmd\src\e2ir.c': Lines: 71
169: if (tret->toBasetype()->ty == Tstruct || 170: tret->toBasetype()->ty == Tsarray) 171: t = tret->toCtype(); 172: else 173: t = type_fake(tret->totym()); 174: Symbol *stmp = symbol_genauto(t); 175: ehidden = el_ptr(stmp); 176: } 177: if ((global.params.isLinux || 178: global.params.isOSX || 179: global.params.isFreeBSD || 180: global.params.isSolaris) && tf->linkage != LINKd) 181: ; // ehidden goes last on Linux/OSX C++ 182: else 183: { 184: if (ep) 185: { 186: #if 0 // BUG: implement 187: if (reverse && type_mangle(tfunc) == mTYman_cpp) 188: ep = el_param(ehidden,ep); 189: else 190: #endif 191: ep = el_param(ep,ehidden); 192: } 193: else 194: ep = ehidden; 195: ehidden = NULL; 196: } 197: } 198: 199: if (fd && fd->isMember2()) 200: { 201: InterfaceDeclaration *intd;
warning C4101: 'intd' : unreferenced local variable
202: Symbol *sfunc; 203: AggregateDeclaration *ad; 204: 205: ad = fd->isThis(); 206: if (ad) 207: { 208: ethis = ec; 209: if (ad->isStructDeclaration() && tybasic(ec->Ety) != TYnptr) 210: { 211: ethis = addressElem(ec, ectype); 212: } 213: } 214: else 215: { 216: // Evaluate ec for side effects 217: eside = ec; 218: } 219: sfunc = fd->toSymbol(); 220: 221: if (!fd->isVirtual() || 222: directcall || // BUG: fix 223: fd->isFinal() 224: /* Future optimization: || (whole program analysis && not overridden) 225: */ 226: ) 227: { 228: // make static call 229: ec = el_var(sfunc); 230: } 231: else 232: { 233: // make virtual call 234: elem *ev; 235: unsigned vindex; 236: 237: assert(ethis); 238: ev = el_same(&ethis); 239: ev = el_una(OPind, TYnptr, ev); 240: vindex = fd->vtblIndex; 241: 242: // Build *(ev + vindex * 4) 243: if (I32) assert(tysize[TYnptr] == 4); 244: ec = el_bin(OPadd,TYnptr,ev,el_long(TYsize_t, vindex * tysize[TYnptr])); 245: ec = el_una(OPind,TYnptr,ec); 246: ec = el_una(OPind,tybasic(sfunc->Stype->Tty),ec); 247: } 248: } 249: else if (fd && fd->isNested()) 250: { 251: assert(!ethis); 252: ethis = getEthis(0, irs, fd); 253: 254: } 255: 256: ep = el_param(ep, ethis); 257: if (ehidden) 258: ep = el_param(ep, ehidden); // if ehidden goes last 259: 260: tyret = tret->totym(); 261: 262: // Look for intrinsic functions 263: if (ec->Eoper == OPvar && (op = intrinsic_op(ec->EV.sp.Vsym->Sident)) != -1) 264: { 265: el_free(ec); 266: if (OTbinary(op)) 267: { 268: ep->Eoper = op; 269: ep->Ety = tyret; 270: e = ep; 271: if (op == OPscale) 272: { 273: elem *et = e->E1; 274: e->E1 = el_una(OPs32_d, TYdouble, e->E2); 275: e->E1 = el_una(OPd_ld, TYldouble, e->E1); 276: e->E2 = et; 277: } 278: else if (op == OPyl2x || op == OPyl2xp1) 279: { 280: elem *et = e->E1; 281: e->E1 = e->E2; 282: e->E2 = et; 283: } 284: } 285: else 286: e = el_una(op,tyret,ep); 287: } 288: else if (ep) 289: { /* Do not do "no side effect" calls if a hidden parameter is passed, 290: * as the return value is stored through the hidden parameter, which 291: * is a side effect. 292: */ 293: e = el_bin(((fd ? fd->isPure() : tf->purity) == PUREstrong && 294: tf->isnothrow && (retmethod != RETstack)) ? 295: OPcallns : OPcall,tyret,ec,ep); 296: if (tf->varargs) 297: e->Eflags |= EFLAGS_variadic; 298: } 299: else 300: { e = el_una(((fd ? fd->isPure() : tf->purity) == PUREstrong && 301: tf->isnothrow && (retmethod != RETstack)) ? 302: OPucallns : OPucall,tyret,ec); 303: if (tf->varargs) 304: e->Eflags |= EFLAGS_variadic; 305: } 306: 307: if (retmethod == RETstack) 308: { 309: e->Ety = TYnptr; 310: e = el_una(OPind, tyret, e); 311: } 312: 313: #if DMDV2 314: if (tf->isref) 315: { 316: e->Ety = TYnptr; 317: e = el_una(OPind, tyret, e); 318: } 319: #endif 320: 321: if (tybasic(tyret) == TYstruct) 322: { 323: e->ET = tret->toCtype(); 324: } 325: e = el_combine(eside, e); 326: return e; 327: } 328: 329: /******************************************* 330: * Take address of an elem. 331: */ 332: 333: elem *addressElem(elem *e, Type *t) 334: { 335: elem **pe; 336: 337: //printf("addressElem()\n"); 338: 339: for (pe = &e; (*pe)->Eoper == OPcomma; pe = &(*pe)->E2) 340: ; 341: if ((*pe)->Eoper != OPvar && (*pe)->Eoper != OPind) 342: { Symbol *stmp; 343: elem *eeq; 344: elem *e = *pe;
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '333' of 'c:\projects\extern\d\dmd\src\e2ir.c': Lines: 333
345: type *tx; 346: 347: // Convert to ((tmp=e),tmp) 348: TY ty; 349: if (t && ((ty = t->toBasetype()->ty) == Tstruct || ty == Tsarray)) 350: tx = t->toCtype(); 351: else 352: tx = type_fake(e->Ety); 353: stmp = symbol_genauto(tx); 354: eeq = el_bin(OPeq,e->Ety,el_var(stmp),e); 355: if (tybasic(e->Ety) == TYstruct) 356: { 357: eeq->Eoper = OPstreq; 358: eeq->ET = e->ET; 359: } 360: else if (tybasic(e->Ety) == TYarray) 361: { 362: eeq->Eoper = OPstreq; 363: eeq->Ejty = eeq->Ety = TYstruct; 364: eeq->ET = t->toCtype();
warning C6011: Dereferencing NULL pointer 't': Lines: 335, 339, 341, 342, 343, 344, 345, 348, 349, 352, 353, 354, 355, 360, 362, 363, 364
365: } 366: *pe = el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); 367: } 368: e = el_una(OPaddr,TYnptr,e); 369: return e; 370: } 371: 372: /***************************************** 373: * Convert array to a pointer to the data. 374: */ 375: 376: elem *array_toPtr(Type *t, elem *e) 377: { 378: //printf("array_toPtr()\n"); 379: //elem_print(e); 380: t = t->toBasetype(); 381: switch (t->ty) 382: { 383: case Tpointer: 384: break; 385: 386: case Tarray: 387: case Tdelegate: 388: if (e->Eoper == OPcomma) 389: { 390: e->Ety = TYnptr; 391: e->E2 = array_toPtr(t, e->E2); 392: } 393: else if (e->Eoper == OPpair) 394: { 395: e->Eoper = OPcomma; 396: e->Ety = TYnptr; 397: } 398: else 399: { 400: #if 1 401: e = el_una(OPmsw, TYnptr, e); 402: #else 403: e = el_una(OPaddr, TYnptr, e); 404: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, 4)); 405: e = el_una(OPind, TYnptr, e); 406: #endif 407: } 408: break; 409: 410: case Tsarray: 411: e = el_una(OPaddr, TYnptr, e); 412: break; 413: 414: default: 415: t->print(); 416: assert(0); 417: } 418: return e; 419: } 420: 421: /***************************************** 422: * Convert array to a dynamic array. 423: */ 424: 425: elem *array_toDarray(Type *t, elem *e) 426: { 427: unsigned dim; 428: elem *ef = NULL; 429: elem *ex; 430: 431: //printf("array_toDarray(t = %s)\n", t->toChars()); 432: //elem_print(e); 433: t = t->toBasetype(); 434: switch (t->ty) 435: { 436: case Tarray: 437: break; 438: 439: case Tsarray: 440: e = addressElem(e, t); 441: dim = ((TypeSArray *)t)->dim->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
442: e = el_pair(TYdarray, el_long(TYsize_t, dim), e); 443: break; 444: 445: default: 446: L1: 447: switch (e->Eoper) 448: { 449: case OPconst:
warning C6011: Dereferencing NULL pointer 'e': Lines: 427, 428, 429, 433, 434, 445, 446, 447, 469, 470, 471, 472, 473, 474, 475, 476, 445, 446, 447, 469, 470, 471, 472, 473, 474, 475, 476, 445, 446, 447, 449
450: { 451: size_t len = tysize[tybasic(e->Ety)]; 452: elem *es = el_calloc(); 453: es->Eoper = OPstring; 454: 455: // freed in el_free 456: es->EV.ss.Vstring = (char *)mem_malloc(len); 457: memcpy(es->EV.ss.Vstring, &e->EV, len); 458: 459: es->EV.ss.Vstrlen = len; 460: es->Ety = TYnptr; 461: e = es; 462: break; 463: } 464: 465: case OPvar: 466: e = el_una(OPaddr, TYnptr, e); 467: break; 468: 469: case OPcomma: 470: ef = el_combine(ef, e->E1); 471: ex = e; 472: e = e->E2; 473: ex->E1 = NULL;
warning C6011: Dereferencing NULL pointer 'ex': Lines: 427, 428, 429, 433, 434, 445, 446, 447, 469, 470, 471, 472, 473
474: ex->E2 = NULL; 475: el_free(ex); 476: goto L1; 477: 478: case OPind: 479: ex = e; 480: e = e->E1; 481: ex->E1 = NULL; 482: ex->E2 = NULL; 483: el_free(ex); 484: break; 485: 486: default: 487: { 488: // Copy expression to a variable and take the 489: // address of that variable. 490: Symbol *stmp; 491: tym_t ty = tybasic(e->Ety); 492: 493: if (ty == TYstruct) 494: { unsigned sz = type_size(e->ET); 495: if (sz <= 4) 496: ty = TYint; 497: else if (sz <= 8) 498: ty = TYllong; 499: } 500: e->Ety = ty; 501: stmp = symbol_genauto(type_fake(ty)); 502: e = el_bin(OPeq, e->Ety, el_var(stmp), e); 503: e = el_bin(OPcomma, TYnptr, e, el_una(OPaddr, TYnptr, el_var(stmp))); 504: break; 505: } 506: } 507: dim = 1; 508: e = el_pair(TYdarray, el_long(TYsize_t, dim), e); 509: break; 510: } 511: return el_combine(ef, e); 512: } 513: 514: /***************************************** 515: * Evaluate elem and convert to dynamic array. 516: */ 517: 518: elem *eval_Darray(IRState *irs, Expression *e) 519: { 520: elem *ex; 521: 522: ex = e->toElem(irs); 523: return array_toDarray(e->type, ex); 524: } 525: 526: /************************************ 527: */ 528: 529: elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e) 530: { 531: //printf("sarray_toDarray()\n"); 532: //elem_print(e); 533: 534: unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
535: 536: if (tto) 537: { 538: unsigned fsize = tfrom->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
539: unsigned tsize = tto->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
540: 541: if ((dim * fsize) % tsize != 0) 542: { 543: Lerr:
warning C4102: 'Lerr' : unreferenced label
544: error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); 545: } 546: dim = (dim * fsize) / tsize; 547: } 548: L1:
warning C4102: 'L1' : unreferenced label
549: elem *elen = el_long(TYsize_t, dim); 550: e = addressElem(e, tfrom); 551: e = el_pair(TYdarray, elen, e); 552: return e; 553: } 554: 555: /******************************************** 556: * Determine if t is an array of structs that need a postblit. 557: */ 558: 559: StructDeclaration *needsPostblit(Type *t) 560: { 561: t = t->toBasetype(); 562: while (t->ty == Tsarray) 563: t = t->nextOf()->toBasetype(); 564: if (t->ty == Tstruct) 565: { StructDeclaration *sd = ((TypeStruct *)t)->sym; 566: if (sd->postblit) 567: return sd; 568: } 569: return NULL; 570: } 571: 572: /******************************************* 573: * Set an array pointed to by eptr to evalue: 574: * eptr[0..edim] = evalue; 575: * Input: 576: * eptr where to write the data to 577: * evalue value to write 578: * edim number of times to write evalue to eptr[] 579: * tb type of evalue 580: */ 581: 582: elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue, IRState *irs, int op) 583: { int r; 584: elem *e; 585: int sz = tb->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
586: 587: switch (tb->ty) 588: { 589: case Tfloat80: 590: case Timaginary80: 591: r = RTLSYM_MEMSET80; 592: break; 593: case Tcomplex80: 594: r = RTLSYM_MEMSET160; 595: break; 596: case Tcomplex64: 597: r = RTLSYM_MEMSET128; 598: break; 599: case Tfloat32: 600: case Timaginary32: 601: if (I32) 602: goto Ldefault; // legacy binary compatibility 603: r = RTLSYM_MEMSETFLOAT; 604: break; 605: case Tfloat64: 606: case Timaginary64: 607: if (I32) 608: goto Ldefault; // legacy binary compatibility 609: r = RTLSYM_MEMSETDOUBLE; 610: break; 611: 612: default: 613: Ldefault: 614: switch (sz) 615: { 616: case 1: r = RTLSYM_MEMSET8; break; 617: case 2: r = RTLSYM_MEMSET16; break; 618: case 4: r = RTLSYM_MEMSET32; break; 619: case 8: r = RTLSYM_MEMSET64; break; 620: case 16: r = RTLSYM_MEMSET128; break; 621: default: r = RTLSYM_MEMSETN; break; 622: } 623: 624: /* Determine if we need to do postblit 625: */ 626: if (op != TOKblit) 627: { 628: StructDeclaration *sd = needsPostblit(tb); 629: if (sd) 630: { /* Need to do postblit. 631: * void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti); 632: */ 633: r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN; 634: evalue = el_una(OPaddr, TYnptr, evalue); 635: Expression *ti = tb->getTypeInfo(NULL); 636: elem *eti = ti->toElem(irs); 637: e = el_params(eti, edim, evalue, eptr, NULL); 638: e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 639: return e; 640: } 641: } 642: 643: if (r == RTLSYM_MEMSETN) 644: { 645: // void *_memsetn(void *p, void *value, int dim, int sizelem) 646: evalue = el_una(OPaddr, TYnptr, evalue); 647: elem *esz = el_long(TYsize_t, sz); 648: e = el_params(esz, edim, evalue, eptr, NULL); 649: e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 650: return e; 651: } 652: break; 653: } 654: if (sz > 1 && sz <= 8 && 655: evalue->Eoper == OPconst && el_allbits(evalue, 0)) 656: { 657: r = RTLSYM_MEMSET8; 658: edim = el_bin(OPmul, TYsize_t, edim, el_long(TYsize_t, sz)); 659: } 660: 661: if (tybasic(evalue->Ety) == TYstruct || tybasic(evalue->Ety) == TYarray) 662: { 663: evalue = el_una(OPstrpar, TYstruct, evalue); 664: evalue->ET = evalue->E1->ET; 665: } 666: 667: // Be careful about parameter side effect ordering 668: if (r == RTLSYM_MEMSET8) 669: { 670: e = el_param(edim, evalue); 671: e = el_bin(OPmemset,TYnptr,eptr,e); 672: } 673: else 674: { 675: e = el_params(edim, evalue, eptr, NULL); 676: e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 677: } 678: return e; 679: } 680: 681: /*************************************** 682: */ 683: 684: elem *Expression::toElem(IRState *irs) 685: { 686: print(); 687: assert(0); 688: return NULL; 689: } 690: 691: /******************************************* 692: * Evaluate Expression, then call destructors on any temporaries in it. 693: */ 694: 695: elem *Expression::toElemDtor(IRState *irs) 696: { 697: //printf("Expression::toElemDtor() %s\n", toChars()); 698: size_t starti = irs->varsInScope ? irs->varsInScope->dim : 0; 699: elem *er = toElem(irs); 700: size_t endi = irs->varsInScope ? irs->varsInScope->dim : 0; 701: 702: // Add destructors 703: er = appendDtors(irs, er, starti, endi); 704: return er; 705: } 706: 707: /************************************ 708: */ 709: #if DMDV2 710: elem *SymbolExp::toElem(IRState *irs) 711: { Symbol *s; 712: elem *e; 713: tym_t tym; 714: Type *tb = (op == TOKsymoff) ? var->type->toBasetype() : type->toBasetype(); 715: int offset = (op == TOKsymoff) ? ((SymOffExp*)this)->offset : 0; 716: FuncDeclaration *fd; 717: VarDeclaration *v = var->isVarDeclaration(); 718: 719: //printf("SymbolExp::toElem('%s') %p\n", toChars(), this); 720: //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null"); 721: if (op == TOKvar && var->needThis()) 722: { 723: error("need 'this' to access member %s", toChars()); 724: return el_long(TYsize_t, 0); 725: } 726: 727: /* The magic variable __ctfe is always false at runtime 728: */ 729: if (op == TOKvar && v && v->ident == Id::ctfe) 730: return el_long(type->totym(), 0); 731: 732: s = var->toSymbol(); 733: fd = NULL; 734: if (var->toParent2()) 735: fd = var->toParent2()->isFuncDeclaration(); 736: 737: int nrvo = 0; 738: if (fd && fd->nrvo_can && fd->nrvo_var == var) 739: { 740: s = fd->shidden; 741: nrvo = 1; 742: } 743: 744: if (s->Sclass == SCauto || s->Sclass == SCparameter) 745: { 746: if (fd && fd != irs->getFunc()) 747: { // 'var' is a variable in an enclosing function. 748: elem *ethis; 749: int soffset; 750: 751: ethis = getEthis(loc, irs, fd); 752: ethis = el_una(OPaddr, TYnptr, ethis); 753: 754: if (v && v->offset) 755: soffset = v->offset; 756: else 757: { 758: soffset = s->Soffset; 759: /* If fd is a non-static member function of a class or struct, 760: * then ethis isn't the frame pointer. 761: * ethis is the 'this' pointer to the class/struct instance. 762: * We must offset it. 763: */ 764: if (fd->vthis) 765: { 766: soffset -= fd->vthis->toSymbol()->Soffset; 767: } 768: //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset); 769: } 770: 771: if (!nrvo) 772: soffset += offset; 773: 774: e = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset)); 775: if (op == TOKvar) 776: e = el_una(OPind, TYnptr, e); 777: if (ISREF(var, tb)) 778: e = el_una(OPind, s->ty(), e); 779: else if (op == TOKsymoff && nrvo) 780: { e = el_una(OPind, TYnptr, e); 781: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 782: } 783: goto L1; 784: } 785: } 786: 787: /* If var is a member of a closure 788: */ 789: if (v && v->offset) 790: { assert(irs->sclosure); 791: e = el_var(irs->sclosure); 792: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, v->offset)); 793: if (op == TOKvar) 794: { e = el_una(OPind, type->totym(), e); 795: if (tybasic(e->Ety) == TYstruct) 796: e->ET = type->toCtype(); 797: el_setLoc(e, loc); 798: } 799: if (ISREF(var, tb)) 800: { e->Ety = TYnptr; 801: e = el_una(OPind, s->ty(), e); 802: } 803: else if (op == TOKsymoff && nrvo) 804: { e = el_una(OPind, TYnptr, e); 805: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 806: } 807: else if (op == TOKsymoff) 808: { 809: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 810: } 811: goto L1; 812: } 813: 814: if (s->Sclass == SCauto && s->Ssymnum == -1) 815: { 816: //printf("\tadding symbol %s\n", s->Sident); 817: symbol_add(s); 818: } 819: 820: if (var->isImportedSymbol()) 821: { 822: assert(op == TOKvar); 823: e = el_var(var->toImport()); 824: e = el_una(OPind,s->ty(),e); 825: } 826: else if (ISREF(var, tb)) 827: { // Static arrays are really passed as pointers to the array 828: // Out parameters are really references 829: e = el_var(s); 830: e->Ety = TYnptr; 831: if (op == TOKvar) 832: e = el_una(OPind, s->ty(), e); 833: else if (offset) 834: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, offset)); 835: } 836: else if (op == TOKvar) 837: e = el_var(s); 838: else 839: { e = nrvo ? el_var(s) : el_ptr(s); 840: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 841: } 842: L1: 843: if (op == TOKvar) 844: { 845: if (nrvo) 846: { 847: e->Ety = TYnptr; 848: e = el_una(OPind, 0, e); 849: } 850: if (tb->ty == Tfunction) 851: { 852: tym = s->Stype->Tty; 853: } 854: else 855: tym = type->totym(); 856: e->Ejty = e->Ety = tym; 857: if (tybasic(tym) == TYstruct) 858: { 859: e->ET = type->toCtype(); 860: } 861: else if (tybasic(tym) == TYarray) 862: { 863: e->Ejty = e->Ety = TYstruct; 864: e->ET = type->toCtype(); 865: } 866: } 867: el_setLoc(e,loc); 868: return e; 869: } 870: #endif 871: 872: #if DMDV1 873: elem *VarExp::toElem(IRState *irs) 874: { Symbol *s; 875: elem *e; 876: tym_t tym; 877: Type *tb = type->toBasetype(); 878: FuncDeclaration *fd; 879: VarDeclaration *v = var->isVarDeclaration(); 880: 881: //printf("VarExp::toElem('%s') %p\n", toChars(), this); 882: //printf("\tparent = '%s'\n", var->parent ? var->parent->toChars() : "null"); 883: if (var->needThis()) 884: { 885: error("need 'this' to access member %s", toChars()); 886: return el_long(TYsize_t, 0); 887: } 888: s = var->toSymbol(); 889: fd = NULL; 890: if (var->toParent2()) 891: fd = var->toParent2()->isFuncDeclaration(); 892: 893: int nrvo = 0; 894: if (fd && fd->nrvo_can && fd->nrvo_var == var) 895: { 896: s = fd->shidden; 897: nrvo = 1; 898: } 899: 900: if (s->Sclass == SCauto || s->Sclass == SCparameter) 901: { 902: if (fd && fd != irs->getFunc()) 903: { // 'var' is a variable in an enclosing function. 904: elem *ethis; 905: int soffset; 906: 907: ethis = getEthis(loc, irs, fd); 908: ethis = el_una(OPaddr, TYnptr, ethis); 909: 910: if (v && v->offset) 911: soffset = v->offset; 912: else 913: { 914: soffset = s->Soffset; 915: /* If fd is a non-static member function of a class or struct, 916: * then ethis isn't the frame pointer. 917: * ethis is the 'this' pointer to the class/struct instance. 918: * We must offset it. 919: */ 920: if (fd->vthis) 921: { 922: soffset -= fd->vthis->toSymbol()->Soffset; 923: } 924: //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset); 925: } 926: 927: ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset)); 928: e = el_una(OPind, 0, ethis); 929: if (ISREF(var, tb)) 930: goto L2; 931: goto L1; 932: } 933: } 934: 935: /* If var is a member of a closure 936: */ 937: if (v && v->offset) 938: { assert(irs->sclosure); 939: e = el_var(irs->sclosure); 940: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, v->offset)); 941: e = el_una(OPind, type->totym(), e); 942: if (tybasic(e->Ety) == TYstruct) 943: e->ET = type->toCtype(); 944: el_setLoc(e, loc); 945: 946: if (ISREF(var, tb)) 947: goto L2; 948: goto L1; 949: } 950: 951: if (s->Sclass == SCauto && s->Ssymnum == -1) 952: { 953: //printf("\tadding symbol\n"); 954: symbol_add(s); 955: } 956: 957: if (var->isImportedSymbol()) 958: { 959: e = el_var(var->toImport()); 960: e = el_una(OPind,s->ty(),e); 961: } 962: else if (ISREF(var, tb)) 963: { // Static arrays are really passed as pointers to the array 964: // Out parameters are really references 965: e = el_var(s); 966: L2: 967: e->Ety = TYnptr; 968: e = el_una(OPind, s->ty(), e); 969: } 970: else 971: e = el_var(s); 972: L1: 973: if (nrvo) 974: { 975: e->Ety = TYnptr; 976: e = el_una(OPind, 0, e); 977: } 978: if (tb->ty == Tfunction) 979: { 980: tym = s->Stype->Tty; 981: } 982: else 983: tym = type->totym(); 984: e->Ejty = e->Ety = tym; 985: if (tybasic(tym) == TYstruct) 986: { 987: e->ET = type->toCtype(); 988: } 989: else if (tybasic(tym) == TYarray) 990: { 991: e->Ejty = e->Ety = TYstruct; 992: e->ET = type->toCtype(); 993: } 994: el_setLoc(e,loc); 995: return e; 996: } 997: #endif 998: 999: #if 0 1000: elem *SymOffExp::toElem(IRState *irs) 1001: { Symbol *s; 1002: elem *e; 1003: Type *tb = var->type->toBasetype(); 1004: VarDeclaration *v = var->isVarDeclaration(); 1005: FuncDeclaration *fd = NULL; 1006: if (var->toParent2()) 1007: fd = var->toParent2()->isFuncDeclaration(); 1008: 1009: //printf("SymOffExp::toElem(): %s\n", toChars()); 1010: s = var->toSymbol(); 1011: 1012: int nrvo = 0; 1013: if (fd && fd->nrvo_can && fd->nrvo_var == var) 1014: { s = fd->shidden; 1015: nrvo = 1; 1016: } 1017: 1018: if (s->Sclass == SCauto && s->Ssymnum == -1) 1019: symbol_add(s); 1020: assert(!var->isImportedSymbol()); 1021: 1022: // This code closely parallels that in VarExp::toElem() 1023: if (s->Sclass == SCauto || s->Sclass == SCparameter) 1024: { 1025: if (fd && fd != irs->getFunc()) 1026: { // 'var' is a variable in an enclosing function. 1027: elem *ethis; 1028: int soffset; 1029: 1030: ethis = getEthis(loc, irs, fd); 1031: ethis = el_una(OPaddr, TYnptr, ethis); 1032: 1033: if (v && v->offset) 1034: soffset = v->offset; 1035: else 1036: { 1037: soffset = s->Soffset; 1038: /* If fd is a non-static member function of a class or struct, 1039: * then ethis isn't the frame pointer. 1040: * ethis is the 'this' pointer to the class/struct instance. 1041: * We must offset it. 1042: */ 1043: if (fd->vthis) 1044: { 1045: soffset -= fd->vthis->toSymbol()->Soffset; 1046: } 1047: //printf("\tSoffset = x%x, sthis->Soffset = x%x\n", s->Soffset, irs->sthis->Soffset); 1048: } 1049: 1050: if (!nrvo) 1051: soffset += offset; 1052: e = el_bin(OPadd, TYnptr, ethis, el_long(TYnptr, soffset)); 1053: if (ISREF(var, tb)) 1054: e = el_una(OPind, s->ty(), e); 1055: else if (nrvo) 1056: { e = el_una(OPind, TYnptr, e); 1057: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 1058: } 1059: goto L1; 1060: } 1061: } 1062: 1063: /* If var is a member of a closure 1064: */ 1065: if (v && v->offset) 1066: { assert(irs->sclosure); 1067: e = el_var(irs->sclosure); 1068: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, v->offset)); 1069: if (ISREF(var, tb)) 1070: e = el_una(OPind, s->ty(), e); 1071: else if (nrvo) 1072: { e = el_una(OPind, TYnptr, e); 1073: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 1074: } 1075: goto L1; 1076: } 1077: 1078: if (ISREF(var, tb)) 1079: { // Static arrays are really passed as pointers to the array 1080: // Out parameters are really references 1081: e = el_var(s); 1082: e->Ety = TYnptr; 1083: if (offset) 1084: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, offset)); 1085: } 1086: else 1087: { e = nrvo ? el_var(s) : el_ptr(s); 1088: e = el_bin(OPadd, e->Ety, e, el_long(TYsize_t, offset)); 1089: } 1090: 1091: L1: 1092: el_setLoc(e,loc); 1093: return e; 1094: } 1095: #endif 1096: 1097: /************************************** 1098: */ 1099: 1100: elem *FuncExp::toElem(IRState *irs) 1101: { 1102: elem *e; 1103: Symbol *s; 1104: 1105: //printf("FuncExp::toElem() %s\n", toChars()); 1106: s = fd->toSymbol(); 1107: e = el_ptr(s); 1108: if (fd->isNested()) 1109: { 1110: elem *ethis = getEthis(loc, irs, fd); 1111: e = el_pair(TYdelegate, ethis, e); 1112: } 1113: 1114: irs->deferToObj->push(fd); 1115: el_setLoc(e,loc); 1116: return e; 1117: } 1118: 1119: /************************************** 1120: * Mirrors logic in Dsymbol_canThrow(). 1121: */ 1122: 1123: elem *Dsymbol_toElem(Dsymbol *s, IRState *irs) 1124: { 1125: elem *e = NULL; 1126: Symbol *sp; 1127: AttribDeclaration *ad; 1128: VarDeclaration *vd; 1129: ClassDeclaration *cd; 1130: StructDeclaration *sd; 1131: FuncDeclaration *fd; 1132: TemplateMixin *tm; 1133: TupleDeclaration *td; 1134: TypedefDeclaration *tyd; 1135: 1136: //printf("Dsymbol_toElem() %s\n", s->toChars()); 1137: ad = s->isAttribDeclaration(); 1138: if (ad) 1139: { 1140: Dsymbols *decl = ad->include(NULL, NULL); 1141: if (decl && decl->dim) 1142: { 1143: for (size_t i = 0; i < decl->dim; i++) 1144: { 1145: s = decl->tdata()[i]; 1146: e = el_combine(e, Dsymbol_toElem(s, irs)); 1147: } 1148: } 1149: } 1150: else if ((vd = s->isVarDeclaration()) != NULL) 1151: { 1152: s = s->toAlias(); 1153: if (s != vd) 1154: return Dsymbol_toElem(s, irs); 1155: if (vd->storage_class & STCmanifest) 1156: return NULL; 1157: else if (vd->isStatic() || vd->storage_class & (STCextern | STCtls | STCgshared)) 1158: vd->toObjFile(0); 1159: else 1160: { 1161: sp = s->toSymbol(); 1162: symbol_add(sp); 1163: //printf("\tadding symbol '%s'\n", sp->Sident); 1164: if (vd->init) 1165: { 1166: ExpInitializer *ie; 1167: 1168: ie = vd->init->isExpInitializer(); 1169: if (ie) 1170: e = ie->exp->toElem(irs); 1171: } 1172: 1173: /* Mark the point of construction of a variable that needs to be destructed. 1174: */ 1175: if (vd->edtor && !vd->noscope) 1176: { 1177: e = el_dctor(e, vd); 1178: 1179: // Put vd on list of things needing destruction 1180: if (!irs->varsInScope) 1181: irs->varsInScope = new VarDeclarations(); 1182: irs->varsInScope->push(vd); 1183: } 1184: } 1185: } 1186: else if ((cd = s->isClassDeclaration()) != NULL) 1187: { 1188: irs->deferToObj->push(s); 1189: } 1190: else if ((sd = s->isStructDeclaration()) != NULL) 1191: { 1192: irs->deferToObj->push(sd); 1193: } 1194: else if ((fd = s->isFuncDeclaration()) != NULL) 1195: { 1196: //printf("function %s\n", fd->toChars()); 1197: irs->deferToObj->push(fd); 1198: } 1199: else if ((tm = s->isTemplateMixin()) != NULL) 1200: { 1201: //printf("%s\n", tm->toChars()); 1202: if (tm->members) 1203: { 1204: for (size_t i = 0; i < tm->members->dim; i++) 1205: { 1206: Dsymbol *sm = tm->members->tdata()[i]; 1207: e = el_combine(e, Dsymbol_toElem(sm, irs)); 1208: } 1209: } 1210: } 1211: else if ((td = s->isTupleDeclaration()) != NULL) 1212: { 1213: for (size_t i = 0; i < td->objects->dim; i++) 1214: { Object *o = td->objects->tdata()[i]; 1215: if (o->dyncast() == DYNCAST_EXPRESSION) 1216: { Expression *eo = (Expression *)o; 1217: if (eo->op == TOKdsymbol) 1218: { DsymbolExp *se = (DsymbolExp *)eo; 1219: e = el_combine(e, Dsymbol_toElem(se->s, irs)); 1220: } 1221: } 1222: } 1223: } 1224: else if ((tyd = s->isTypedefDeclaration()) != NULL) 1225: { 1226: irs->deferToObj->push(tyd); 1227: } 1228: return e; 1229: } 1230: 1231: elem *DeclarationExp::toElem(IRState *irs) 1232: { 1233: //printf("DeclarationExp::toElem() %s\n", toChars()); 1234: elem *e = Dsymbol_toElem(declaration, irs); 1235: return e; 1236: } 1237: 1238: /*************************************** 1239: */ 1240: 1241: elem *ThisExp::toElem(IRState *irs) 1242: { elem *ethis; 1243: FuncDeclaration *fd; 1244: 1245: //printf("ThisExp::toElem()\n"); 1246: assert(irs->sthis); 1247: 1248: if (var) 1249: { 1250: assert(var->parent); 1251: fd = var->toParent2()->isFuncDeclaration(); 1252: assert(fd); 1253: ethis = getEthis(loc, irs, fd); 1254: } 1255: else 1256: ethis = el_var(irs->sthis); 1257: 1258: #if STRUCTTHISREF 1259: if (type->ty == Tstruct) 1260: { ethis = el_una(OPind, TYstruct, ethis); 1261: ethis->ET = type->toCtype(); 1262: } 1263: #endif 1264: el_setLoc(ethis,loc); 1265: return ethis; 1266: } 1267: 1268: /*************************************** 1269: */ 1270: 1271: elem *IntegerExp::toElem(IRState *irs) 1272: { elem *e; 1273: 1274: e = el_long(type->totym(), value); 1275: el_setLoc(e,loc); 1276: return e; 1277: } 1278: 1279: /*************************************** 1280: */ 1281: 1282: elem *RealExp::toElem(IRState *irs) 1283: { union eve c; 1284: tym_t ty; 1285: 1286: //printf("RealExp::toElem(%p) %s\n", this, toChars()); 1287: memset(&c, 0, sizeof(c)); 1288: ty = type->toBasetype()->totym(); 1289: switch (tybasic(ty)) 1290: { 1291: case TYfloat: 1292: case TYifloat: 1293: /* This assignment involves a conversion, which 1294: * unfortunately also converts SNAN to QNAN. 1295: */ 1296: c.Vfloat = value;
warning C4244: '=' : conversion from 'real_t' to 'targ_float', possible loss of data
1297: if (Port::isSignallingNan(value)) 1298: // Put SNAN back 1299: c.Vuns &= 0xFFBFFFFFL; 1300: break; 1301: 1302: case TYdouble: 1303: case TYidouble: 1304: /* This assignment involves a conversion, which 1305: * unfortunately also converts SNAN to QNAN. 1306: */ 1307: c.Vdouble = value; 1308: if (Port::isSignallingNan(value)) 1309: // Put SNAN back 1310: c.Vullong &= 0xFFF7FFFFFFFFFFFFULL; 1311: break; 1312: 1313: case TYldouble: 1314: case TYildouble: 1315: c.Vldouble = value; 1316: break; 1317: 1318: default: 1319: print(); 1320: type->print(); 1321: type->toBasetype()->print(); 1322: printf("ty = %d, tym = %x\n", type->ty, ty); 1323: assert(0); 1324: } 1325: return el_const(ty, &c); 1326: } 1327: 1328: 1329: /*************************************** 1330: */ 1331: 1332: elem *ComplexExp::toElem(IRState *irs) 1333: { union eve c; 1334: tym_t ty; 1335: real_t re; 1336: real_t im; 1337: 1338: //printf("ComplexExp::toElem(%p) %s\n", this, toChars()); 1339: 1340: memset(&c, 0, sizeof(c)); 1341: re = creall(value); 1342: im = cimagl(value); 1343: 1344: ty = type->totym(); 1345: switch (tybasic(ty)) 1346: { 1347: case TYcfloat: 1348: c.Vcfloat.re = (float) re; 1349: if (Port::isSignallingNan(re)) 1350: { union { float f; unsigned i; } u; 1351: u.f = c.Vcfloat.re; 1352: u.i &= 0xFFBFFFFFL; 1353: c.Vcfloat.re = u.f; 1354: } 1355: c.Vcfloat.im = (float) im; 1356: if (Port::isSignallingNan(im)) 1357: { union { float f; unsigned i; } u; 1358: u.f = c.Vcfloat.im; 1359: u.i &= 0xFFBFFFFFL; 1360: c.Vcfloat.im = u.f; 1361: } 1362: break; 1363: 1364: case TYcdouble: 1365: c.Vcdouble.re = (double) re; 1366: if (Port::isSignallingNan(re)) 1367: { union { double d; unsigned long long i; } u; 1368: u.d = c.Vcdouble.re; 1369: u.i &= 0xFFF7FFFFFFFFFFFFULL; 1370: c.Vcdouble.re = u.d; 1371: } 1372: c.Vcdouble.im = (double) im; 1373: if (Port::isSignallingNan(re)) 1374: { union { double d; unsigned long long i; } u; 1375: u.d = c.Vcdouble.im; 1376: u.i &= 0xFFF7FFFFFFFFFFFFULL; 1377: c.Vcdouble.im = u.d; 1378: } 1379: break; 1380: 1381: case TYcldouble: 1382: #if 1 1383: c.Vcldouble.re = re; 1384: c.Vcldouble.im = im; 1385: #else 1386: {unsigned short *p = (unsigned short *)&c.Vcldouble; 1387: for (int i = 0; i < (LNGDBLSIZE*2)/2; i++) printf("%04x ", p[i]); 1388: printf("\n");} 1389: c.Vcldouble.im = im; 1390: {unsigned short *p = (unsigned short *)&c.Vcldouble; 1391: for (int i = 0; i < (LNGDBLSIZE*2)/2; i++) printf("%04x ", p[i]); 1392: printf("\n");} 1393: c.Vcldouble.re = re; 1394: {unsigned short *p = (unsigned short *)&c.Vcldouble; 1395: for (int i = 0; i < (LNGDBLSIZE*2)/2; i++) printf("%04x ", p[i]); 1396: printf("\n");} 1397: #endif 1398: break; 1399: 1400: default: 1401: assert(0); 1402: } 1403: return el_const(ty, &c); 1404: } 1405: 1406: /*************************************** 1407: */ 1408: 1409: elem *NullExp::toElem(IRState *irs) 1410: { 1411: return el_long(type->totym(), 0); 1412: } 1413: 1414: /*************************************** 1415: */ 1416: 1417: struct StringTab 1418: { 1419: Module *m; // module we're generating code for 1420: Symbol *si; 1421: void *string; 1422: size_t sz; 1423: size_t len; 1424: }; 1425: 1426: #define STSIZE 16 1427: StringTab stringTab[STSIZE]; 1428: size_t stidx; 1429: 1430: static Symbol *assertexp_sfilename = NULL; 1431: static const char *assertexp_name = NULL; 1432: static Module *assertexp_mn = NULL; 1433: 1434: void clearStringTab() 1435: { 1436: //printf("clearStringTab()\n"); 1437: memset(stringTab, 0, sizeof(stringTab)); 1438: stidx = 0; 1439: 1440: assertexp_sfilename = NULL; 1441: assertexp_name = NULL; 1442: assertexp_mn = NULL; 1443: } 1444: 1445: elem *StringExp::toElem(IRState *irs) 1446: { 1447: elem *e; 1448: Type *tb= type->toBasetype(); 1449: 1450: 1451: #if 0 1452: printf("StringExp::toElem() %s, type = %s\n", toChars(), type->toChars()); 1453: #endif 1454: 1455: if (tb->ty == Tarray) 1456: { 1457: Symbol *si; 1458: dt_t *dt; 1459: StringTab *st; 1460: 1461: #if 0 1462: printf("irs->m = %p\n", irs->m); 1463: printf(" m = %s\n", irs->m->toChars()); 1464: printf(" len = %d\n", len); 1465: printf(" sz = %d\n", sz); 1466: #endif 1467: for (size_t i = 0; i < STSIZE; i++) 1468: { 1469: st = &stringTab[(stidx + i) % STSIZE]; 1470: //if (!st->m) continue; 1471: //printf(" st.m = %s\n", st->m->toChars()); 1472: //printf(" st.len = %d\n", st->len); 1473: //printf(" st.sz = %d\n", st->sz); 1474: if (st->m == irs->m && 1475: st->si && 1476: st->len == len && 1477: st->sz == sz && 1478: memcmp(st->string, string, sz * len) == 0) 1479: { 1480: //printf("use cached value\n"); 1481: si = st->si; // use cached value 1482: goto L1; 1483: } 1484: } 1485: 1486: stidx = (stidx + 1) % STSIZE; 1487: st = &stringTab[stidx]; 1488: 1489: dt = NULL; 1490: toDt(&dt); 1491: 1492: si = symbol_generate(SCstatic,type_fake(TYdarray)); 1493: si->Sdt = dt; 1494: si->Sfl = FLdata; 1495: #if ELFOBJ // Burton 1496: si->Sseg = CDATA; 1497: #endif 1498: #if MACHOBJ 1499: si->Sseg = DATA; 1500: #endif 1501: outdata(si); 1502: 1503: st->m = irs->m; 1504: st->si = si; 1505: st->string = string; 1506: st->len = len; 1507: st->sz = sz; 1508: L1: 1509: e = el_var(si); 1510: } 1511: else if (tb->ty == Tsarray) 1512: { 1513: dt_t *dt = NULL; 1514: 1515: toDt(&dt); 1516: dtnzeros(&dt, sz); // leave terminating 0 1517: 1518: ::type *t = type_allocn(TYarray, tschar); 1519: t->Tdim = sz * len; 1520: Symbol *si = symbol_generate(SCstatic, t); 1521: si->Sdt = dt; 1522: si->Sfl = FLdata; 1523: 1524: #if ELFOBJ || MACHOBJ // Burton 1525: si->Sseg = CDATA; 1526: #endif 1527: outdata(si); 1528: 1529: e = el_var(si); 1530: e->ET = t; 1531: t->Tcount++; 1532: } 1533: else if (tb->ty == Tpointer) 1534: { 1535: e = el_calloc(); 1536: e->Eoper = OPstring; 1537: // freed in el_free 1538: e->EV.ss.Vstring = (char *)mem_malloc((len + 1) * sz); 1539: memcpy(e->EV.ss.Vstring, string, (len + 1) * sz); 1540: e->EV.ss.Vstrlen = (len + 1) * sz; 1541: e->Ety = TYnptr; 1542: } 1543: else 1544: { 1545: printf("type is %s\n", type->toChars()); 1546: assert(0); 1547: } 1548: el_setLoc(e,loc); 1549: return e; 1550: } 1551: 1552: elem *NewExp::toElem(IRState *irs) 1553: { elem *e; 1554: Type *t; 1555: Type *ectype; 1556: 1557: //printf("NewExp::toElem() %s\n", toChars()); 1558: t = type->toBasetype(); 1559: //printf("\ttype = %s\n", t->toChars()); 1560: //if (member) 1561: //printf("\tmember = %s\n", member->toChars()); 1562: if (t->ty == Tclass) 1563: { 1564: Symbol *csym; 1565: 1566: t = newtype->toBasetype(); 1567: assert(t->ty == Tclass); 1568: TypeClass *tclass = (TypeClass *)(t); 1569: ClassDeclaration *cd = tclass->sym; 1570: 1571: /* Things to do: 1572: * 1) ex: call allocator 1573: * 2) ey: set vthis for nested classes 1574: * 3) ez: call constructor 1575: */ 1576: 1577: elem *ex = NULL; 1578: elem *ey = NULL; 1579: elem *ez = NULL; 1580: 1581: if (allocator || onstack) 1582: { elem *ei; 1583: Symbol *si; 1584: 1585: if (onstack) 1586: { 1587: /* Create an instance of the class on the stack, 1588: * and call it stmp. 1589: * Set ex to be the &stmp. 1590: */ 1591: Symbol *s = symbol_calloc(tclass->sym->toChars()); 1592: s->Sclass = SCstruct; 1593: s->Sstruct = struct_calloc(); 1594: s->Sstruct->Sflags |= 0; 1595: s->Sstruct->Salignsize = tclass->sym->alignsize; 1596: s->Sstruct->Sstructalign = tclass->sym->structalign; 1597: s->Sstruct->Sstructsize = tclass->sym->structsize; 1598: 1599: ::type *tc = type_alloc(TYstruct); 1600: tc->Ttag = (Classsym *)s; // structure tag name 1601: tc->Tcount++; 1602: s->Stype = tc; 1603: 1604: Symbol *stmp = symbol_genauto(tc); 1605: ex = el_ptr(stmp); 1606: } 1607: else 1608: { 1609: ex = el_var(allocator->toSymbol()); 1610: ex = callfunc(loc, irs, 1, type, ex, allocator->type, 1611: allocator, allocator->type, NULL, newargs); 1612: } 1613: 1614: si = tclass->sym->toInitializer(); 1615: ei = el_var(si); 1616: 1617: if (cd->isNested()) 1618: { 1619: ey = el_same(&ex); 1620: ez = el_copytree(ey); 1621: } 1622: else if (member) 1623: ez = el_same(&ex); 1624: 1625: ex = el_una(OPind, TYstruct, ex); 1626: ex = el_bin(OPstreq, TYnptr, ex, ei); 1627: ex->ET = tclass->toCtype()->Tnext; 1628: ex = el_una(OPaddr, TYnptr, ex); 1629: ectype = tclass; 1630: } 1631: else 1632: { 1633: csym = cd->toSymbol(); 1634: ex = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_NEWCLASS]),el_ptr(csym)); 1635: ectype = NULL; 1636: 1637: if (cd->isNested()) 1638: { 1639: ey = el_same(&ex); 1640: ez = el_copytree(ey); 1641: } 1642: else if (member) 1643: ez = el_same(&ex); 1644: //elem_print(ex); 1645: //elem_print(ey); 1646: //elem_print(ez); 1647: } 1648: 1649: if (thisexp) 1650: { ClassDeclaration *cdthis = thisexp->type->isClassHandle(); 1651: assert(cdthis); 1652: //printf("cd = %s\n", cd->toChars()); 1653: //printf("cdthis = %s\n", cdthis->toChars()); 1654: assert(cd->isNested()); 1655: int offset = 0; 1656: Dsymbol *cdp = cd->toParent2(); // class we're nested in 1657: elem *ethis; 1658: 1659: //printf("member = %p\n", member); 1660: //printf("cdp = %s\n", cdp->toChars()); 1661: //printf("cdthis = %s\n", cdthis->toChars()); 1662: if (cdp != cdthis) 1663: { int i = cdp->isClassDeclaration()->isBaseOf(cdthis, &offset); 1664: assert(i); 1665: } 1666: ethis = thisexp->toElem(irs); 1667: if (offset) 1668: ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYsize_t, offset)); 1669: 1670: if (!cd->vthis) 1671: { 1672: error("forward reference to %s", cd->toChars()); 1673: } 1674: else 1675: { 1676: ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, cd->vthis->offset)); 1677: ey = el_una(OPind, TYnptr, ey); 1678: ey = el_bin(OPeq, TYnptr, ey, ethis); 1679: } 1680: //printf("ex: "); elem_print(ex); 1681: //printf("ey: "); elem_print(ey); 1682: //printf("ez: "); elem_print(ez); 1683: } 1684: else if (cd->isNested()) 1685: { /* Initialize cd->vthis: 1686: * *(ey + cd.vthis.offset) = this; 1687: */ 1688: ey = setEthis(loc, irs, ey, cd); 1689: } 1690: 1691: if (member) 1692: // Call constructor 1693: ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments); 1694: 1695: e = el_combine(ex, ey); 1696: e = el_combine(e, ez); 1697: } 1698: #if DMDV2 1699: else if (t->ty == Tpointer && t->nextOf()->toBasetype()->ty == Tstruct) 1700: { 1701: Symbol *csym;
warning C4101: 'csym' : unreferenced local variable
1702: 1703: t = newtype->toBasetype(); 1704: assert(t->ty == Tstruct); 1705: TypeStruct *tclass = (TypeStruct *)(t); 1706: StructDeclaration *cd = tclass->sym; 1707: 1708: /* Things to do: 1709: * 1) ex: call allocator 1710: * 2) ey: set vthis for nested classes 1711: * 3) ez: call constructor 1712: */ 1713: 1714: elem *ex = NULL; 1715: elem *ey = NULL; 1716: elem *ez = NULL; 1717: 1718: if (allocator) 1719: { elem *ei; 1720: Symbol *si; 1721: 1722: ex = el_var(allocator->toSymbol()); 1723: ex = callfunc(loc, irs, 1, type, ex, allocator->type, 1724: allocator, allocator->type, NULL, newargs); 1725: 1726: si = tclass->sym->toInitializer(); 1727: ei = el_var(si); 1728: 1729: if (cd->isNested()) 1730: { 1731: ey = el_same(&ex); 1732: ez = el_copytree(ey); 1733: } 1734: else if (member) 1735: ez = el_same(&ex); 1736: 1737: if (!member) 1738: { /* Statically intialize with default initializer 1739: */ 1740: ex = el_una(OPind, TYstruct, ex); 1741: ex = el_bin(OPstreq, TYnptr, ex, ei); 1742: ex->ET = tclass->toCtype(); 1743: ex = el_una(OPaddr, TYnptr, ex); 1744: } 1745: ectype = tclass; 1746: } 1747: else 1748: { 1749: d_uns64 elemsize = cd->size(loc); 1750: 1751: // call _d_newarrayT(ti, 1) 1752: e = el_long(TYsize_t, 1); 1753: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 1754: 1755: int rtl = t->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; 1756: e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); 1757: 1758: // The new functions return an array, so convert to a pointer 1759: // ex -> (unsigned)(e >> 32) 1760: e = el_bin(OPshr, TYdarray, e, el_long(TYint, PTRSIZE * 8)); 1761: ex = el_una(OP64_32, TYnptr, e); 1762: 1763: ectype = NULL; 1764: 1765: if (cd->isNested()) 1766: { 1767: ey = el_same(&ex); 1768: ez = el_copytree(ey); 1769: } 1770: else if (member) 1771: ez = el_same(&ex); 1772: //elem_print(ex); 1773: //elem_print(ey); 1774: //elem_print(ez); 1775: } 1776: 1777: if (cd->isNested()) 1778: { /* Initialize cd->vthis: 1779: * *(ey + cd.vthis.offset) = this; 1780: */ 1781: ey = setEthis(loc, irs, ey, cd); 1782: } 1783: 1784: if (member) 1785: { // Call constructor 1786: ez = callfunc(loc, irs, 1, type, ez, ectype, member, member->type, NULL, arguments); 1787: #if STRUCTTHISREF 1788: /* Structs return a ref, which gets automatically dereferenced. 1789: * But we want a pointer to the instance. 1790: */ 1791: ez = el_una(OPaddr, TYnptr, ez); 1792: #endif 1793: } 1794: 1795: e = el_combine(ex, ey); 1796: e = el_combine(e, ez); 1797: } 1798: #endif 1799: else if (t->ty == Tarray) 1800: { 1801: TypeDArray *tda = (TypeDArray *)(t); 1802: 1803: assert(arguments && arguments->dim >= 1); 1804: if (arguments->dim == 1) 1805: { // Single dimension array allocations 1806: Expression *arg = arguments->tdata()[0]; // gives array length 1807: e = arg->toElem(irs); 1808: d_uns64 elemsize = tda->next->size(); 1809: 1810: // call _d_newT(ti, arg) 1811: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 1812: int rtl = tda->next->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; 1813: e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); 1814: } 1815: else 1816: { // Multidimensional array allocations 1817: e = el_long(TYsize_t, arguments->dim); 1818: for (size_t i = 0; i < arguments->dim; i++) 1819: { 1820: Expression *arg = arguments->tdata()[i]; // gives array length 1821: e = el_param(arg->toElem(irs), e); 1822: assert(t->ty == Tarray); 1823: t = t->nextOf(); 1824: assert(t); 1825: } 1826: 1827: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 1828: 1829: int rtl = t->isZeroInit() ? RTLSYM_NEWARRAYMT : RTLSYM_NEWARRAYMIT; 1830: e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); 1831: e->Eflags |= EFLAGS_variadic; 1832: } 1833: } 1834: else if (t->ty == Tpointer) 1835: { 1836: TypePointer *tp = (TypePointer *)t; 1837: d_uns64 elemsize = tp->next->size(); 1838: Expression *di = tp->next->defaultInit(); 1839: d_uns64 disize = di->type->size(); 1840: 1841: // call _d_newarrayT(ti, 1) 1842: e = el_long(TYsize_t, 1); 1843: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 1844: 1845: int rtl = tp->next->isZeroInit() ? RTLSYM_NEWARRAYT : RTLSYM_NEWARRAYIT; 1846: e = el_bin(OPcall,TYdarray,el_var(rtlsym[rtl]),e); 1847: 1848: // The new functions return an array, so convert to a pointer 1849: // e -> (unsigned)(e >> 32) 1850: e = el_bin(OPshr, TYdarray, e, el_long(TYsize_t, PTRSIZE * 8)); 1851: e = el_una(I64 ? OP128_64 : OP64_32, t->totym(), e); 1852: } 1853: else 1854: { 1855: assert(0); 1856: } 1857: 1858: el_setLoc(e,loc); 1859: return e; 1860: } 1861: 1862: //////////////////////////// Unary /////////////////////////////// 1863: 1864: /*************************************** 1865: */ 1866: 1867: elem *NegExp::toElem(IRState *irs) 1868: { 1869: elem *e = el_una(OPneg, type->totym(), e1->toElem(irs)); 1870: 1871: Type *tb1 = e1->type->toBasetype(); 1872: if (tb1->ty == Tarray || tb1->ty == Tsarray) 1873: { 1874: error("Array operation %s not implemented", toChars()); 1875: e = el_long(type->totym(), 0); // error recovery 1876: } 1877: 1878: el_setLoc(e,loc); 1879: return e; 1880: } 1881: 1882: /*************************************** 1883: */ 1884: 1885: elem *ComExp::toElem(IRState *irs) 1886: { elem *e; 1887: 1888: elem *e1 = this->e1->toElem(irs); 1889: tym_t ty = type->totym(); 1890: if (this->e1->type->toBasetype()->ty == Tbool) 1891: e = el_bin(OPxor, ty, e1, el_long(ty, 1)); 1892: else 1893: e = el_una(OPcom,ty,e1); 1894: el_setLoc(e,loc); 1895: return e; 1896: } 1897: 1898: /*************************************** 1899: */ 1900: 1901: elem *NotExp::toElem(IRState *irs) 1902: { 1903: elem *e = el_una(OPnot, type->totym(), e1->toElem(irs)); 1904: el_setLoc(e,loc); 1905: return e; 1906: } 1907: 1908: 1909: /*************************************** 1910: */ 1911: 1912: elem *HaltExp::toElem(IRState *irs) 1913: { elem *e; 1914: 1915: e = el_calloc(); 1916: e->Ety = TYvoid; 1917: e->Eoper = OPhalt; 1918: el_setLoc(e,loc); 1919: return e; 1920: } 1921: 1922: /******************************************** 1923: */ 1924: 1925: elem *AssertExp::toElem(IRState *irs) 1926: { elem *e; 1927: elem *ea; 1928: Type *t1 = e1->type->toBasetype(); 1929: 1930: //printf("AssertExp::toElem() %s\n", toChars()); 1931: if (global.params.useAssert) 1932: { 1933: e = e1->toElem(irs); 1934: 1935: InvariantDeclaration *inv = (InvariantDeclaration *)(void *)1; 1936: 1937: // If e1 is a class object, call the class invariant on it 1938: if (global.params.useInvariants && t1->ty == Tclass && 1939: !((TypeClass *)t1)->sym->isInterfaceDeclaration()) 1940: { 1941: #if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 1942: e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM__DINVARIANT]), e); 1943: #else 1944: e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DINVARIANT]), e); 1945: #endif 1946: } 1947: // If e1 is a struct object, call the struct invariant on it 1948: else if (global.params.useInvariants && 1949: t1->ty == Tpointer && 1950: t1->nextOf()->ty == Tstruct && 1951: (inv = ((TypeStruct *)t1->nextOf())->sym->inv) != NULL) 1952: { 1953: e = callfunc(loc, irs, 1, inv->type->nextOf(), e, e1->type, inv, inv->type, NULL, NULL); 1954: } 1955: else 1956: { 1957: // Construct: (e1 || ModuleAssert(line)) 1958: Module *m = irs->blx->module; 1959: char *mname = m->srcfile->toChars(); 1960: 1961: //printf("filename = '%s'\n", loc.filename); 1962: //printf("module = '%s'\n", m->srcfile->toChars()); 1963: 1964: /* Determine if we are in a unittest 1965: */ 1966: FuncDeclaration *fd = irs->getFunc(); 1967: UnitTestDeclaration *ud = fd ? fd->isUnitTestDeclaration() : NULL; 1968: 1969: /* If the source file name has changed, probably due 1970: * to a #line directive. 1971: */ 1972: if (loc.filename && (msg || strcmp(loc.filename, mname) != 0)) 1973: { elem *efilename; 1974: 1975: /* Cache values. 1976: */ 1977: //static Symbol *assertexp_sfilename = NULL; 1978: //static char *assertexp_name = NULL; 1979: //static Module *assertexp_mn = NULL; 1980: 1981: if (!assertexp_sfilename || strcmp(loc.filename, assertexp_name) != 0 || assertexp_mn != m) 1982: { 1983: dt_t *dt = NULL; 1984: const char *id; 1985: int len; 1986: 1987: id = loc.filename; 1988: len = strlen(id); 1989: dtsize_t(&dt, len); 1990: dtabytes(&dt,TYnptr, 0, len + 1, id); 1991: 1992: assertexp_sfilename = symbol_generate(SCstatic,type_fake(TYdarray)); 1993: assertexp_sfilename->Sdt = dt; 1994: assertexp_sfilename->Sfl = FLdata; 1995: #if ELFOBJ 1996: assertexp_sfilename->Sseg = CDATA; 1997: #endif 1998: #if MACHOBJ 1999: assertexp_sfilename->Sseg = DATA; 2000: #endif 2001: outdata(assertexp_sfilename); 2002: 2003: assertexp_mn = m; 2004: assertexp_name = id; 2005: } 2006: 2007: efilename = el_var(assertexp_sfilename); 2008: 2009: if (msg) 2010: { elem *emsg = msg->toElem(irs); 2011: ea = el_var(rtlsym[ud ? RTLSYM_DUNITTEST_MSG : RTLSYM_DASSERT_MSG]); 2012: ea = el_bin(OPcall, TYvoid, ea, el_params(el_long(TYint, loc.linnum), efilename, emsg, NULL)); 2013: } 2014: else 2015: { 2016: ea = el_var(rtlsym[ud ? RTLSYM_DUNITTEST : RTLSYM_DASSERT]); 2017: ea = el_bin(OPcall, TYvoid, ea, el_param(el_long(TYint, loc.linnum), efilename)); 2018: } 2019: } 2020: else 2021: { 2022: Symbol *sassert = ud ? m->toModuleUnittest() : m->toModuleAssert(); 2023: ea = el_bin(OPcall,TYvoid,el_var(sassert), 2024: el_long(TYint, loc.linnum)); 2025: } 2026: e = el_bin(OPoror,TYvoid,e,ea); 2027: } 2028: } 2029: else 2030: { // BUG: should replace assert(0); with a HLT instruction 2031: e = el_long(TYint, 0); 2032: } 2033: el_setLoc(e,loc); 2034: return e; 2035: } 2036: 2037: elem *PostExp::toElem(IRState *irs) 2038: { 2039: elem *e = e1->toElem(irs); 2040: elem *einc = e2->toElem(irs); 2041: e = el_bin((op == TOKplusplus) ? OPpostinc : OPpostdec, 2042: e->Ety,e,einc); 2043: el_setLoc(e,loc); 2044: return e; 2045: } 2046: 2047: //////////////////////////// Binary /////////////////////////////// 2048: 2049: /******************************************** 2050: */ 2051: 2052: elem *BinExp::toElemBin(IRState *irs,int op) 2053: { 2054: //printf("toElemBin() '%s'\n", toChars()); 2055: 2056: Type *tb1 = e1->type->toBasetype(); 2057: Type *tb2 = e2->type->toBasetype(); 2058: 2059: if ((tb1->ty == Tarray || tb1->ty == Tsarray || 2060: tb2->ty == Tarray || tb2->ty == Tsarray) && 2061: tb2->ty != Tvoid && 2062: op != OPeq && op != OPandand && op != OPoror 2063: ) 2064: { 2065: error("Array operation %s not implemented", toChars()); 2066: return el_long(type->totym(), 0); // error recovery 2067: } 2068: 2069: tym_t tym = type->totym(); 2070: 2071: elem *el = e1->toElem(irs); 2072: elem *er = e2->toElem(irs); 2073: elem *e = el_bin(op,tym,el,er); 2074: 2075: el_setLoc(e,loc); 2076: return e; 2077: } 2078: 2079: /*************************************** 2080: */ 2081: 2082: elem *AddExp::toElem(IRState *irs) 2083: { 2084: elem *e = toElemBin(irs,OPadd); 2085: return e; 2086: } 2087: 2088: /*************************************** 2089: */ 2090: 2091: elem *MinExp::toElem(IRState *irs) 2092: { 2093: elem *e = toElemBin(irs,OPmin); 2094: return e; 2095: } 2096: 2097: /*************************************** 2098: */ 2099: 2100: elem *CatExp::toElem(IRState *irs) 2101: { elem *e; 2102: 2103: #if 0 2104: printf("CatExp::toElem()\n"); 2105: print(); 2106: #endif 2107: 2108: Type *tb1 = e1->type->toBasetype(); 2109: Type *tb2 = e2->type->toBasetype(); 2110: Type *tn; 2111: 2112: #if 0 2113: if ((tb1->ty == Tarray || tb1->ty == Tsarray) && 2114: (tb2->ty == Tarray || tb2->ty == Tsarray) 2115: ) 2116: #endif 2117: 2118: Type *ta = tb1->nextOf() ? e1->type : e2->type; 2119: tn = tb1->nextOf() ? tb1->nextOf() : tb2->nextOf(); 2120: { 2121: if (e1->op == TOKcat) 2122: { 2123: elem *ep; 2124: CatExp *ce = this; 2125: int n = 2; 2126: 2127: ep = eval_Darray(irs, ce->e2); 2128: do 2129: { 2130: n++; 2131: ce = (CatExp *)ce->e1; 2132: ep = el_param(ep, eval_Darray(irs, ce->e2)); 2133: } while (ce->e1->op == TOKcat); 2134: ep = el_param(ep, eval_Darray(irs, ce->e1)); 2135: #if 1 2136: ep = el_params( 2137: ep, 2138: el_long(TYsize_t, n), 2139: ta->getTypeInfo(NULL)->toElem(irs), 2140: NULL); 2141: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); 2142: e->Eflags |= EFLAGS_variadic; 2143: #else 2144: ep = el_params( 2145: ep, 2146: el_long(TYsize_t, n), 2147: el_long(TYsize_t, tn->size()), 2148: NULL); 2149: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 2150: e->Eflags |= EFLAGS_variadic; 2151: #endif 2152: } 2153: else 2154: { 2155: elem *e1; 2156: elem *e2; 2157: elem *ep; 2158: 2159: e1 = eval_Darray(irs, this->e1); 2160: e2 = eval_Darray(irs, this->e2); 2161: #if 1 2162: ep = el_params(e2, e1, ta->getTypeInfo(NULL)->toElem(irs), NULL); 2163: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATT]), ep); 2164: #else 2165: ep = el_params(el_long(TYsize_t, tn->size()), e2, e1, NULL); 2166: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCAT]), ep); 2167: #endif 2168: } 2169: el_setLoc(e,loc); 2170: } 2171: #if 0 2172: else if ((tb1->ty == Tarray || tb1->ty == Tsarray) && 2173: e2->type->equals(tb1->next)) 2174: { 2175: error("array cat with element not implemented"); 2176: e = el_long(TYint, 0); 2177: } 2178: else 2179: assert(0); 2180: #endif 2181: return e; 2182: } 2183: 2184: /*************************************** 2185: */ 2186: 2187: elem *MulExp::toElem(IRState *irs) 2188: { 2189: return toElemBin(irs,OPmul); 2190: } 2191: 2192: /************************************ 2193: */ 2194: 2195: elem *DivExp::toElem(IRState *irs) 2196: { 2197: return toElemBin(irs,OPdiv); 2198: } 2199: 2200: /*************************************** 2201: */ 2202: 2203: elem *ModExp::toElem(IRState *irs) 2204: { 2205: elem *e; 2206: elem *e1; 2207: elem *e2; 2208: tym_t tym; 2209: 2210: tym = type->totym(); 2211: 2212: e1 = this->e1->toElem(irs); 2213: e2 = this->e2->toElem(irs); 2214: 2215: #if 0 // Now inlined 2216: if (this->e1->type->isfloating()) 2217: { elem *ep; 2218: 2219: switch (this->e1->type->ty) 2220: { 2221: case Tfloat32: 2222: case Timaginary32: 2223: e1 = el_una(OPf_d, TYdouble, e1); 2224: e2 = el_una(OPf_d, TYdouble, e2); 2225: case Tfloat64: 2226: case Timaginary64: 2227: e1 = el_una(OPd_ld, TYldouble, e1); 2228: e2 = el_una(OPd_ld, TYldouble, e2); 2229: break; 2230: case Tfloat80: 2231: case Timaginary80: 2232: break; 2233: default: 2234: assert(0); 2235: break; 2236: } 2237: ep = el_param(e2,e1); 2238: e = el_bin(OPcall,tym,el_var(rtlsym[RTLSYM_MODULO]),ep); 2239: } 2240: else 2241: #endif 2242: e = el_bin(OPmod,tym,e1,e2); 2243: el_setLoc(e,loc); 2244: return e; 2245: } 2246: 2247: /*************************************** 2248: */ 2249: 2250: elem *CmpExp::toElem(IRState *irs) 2251: { 2252: elem *e; 2253: enum OPER eop; 2254: Type *t1 = e1->type->toBasetype(); 2255: Type *t2 = e2->type->toBasetype(); 2256: 2257: switch (op) 2258: { 2259: case TOKlt: eop = OPlt; break; 2260: case TOKgt: eop = OPgt; break; 2261: case TOKle: eop = OPle; break; 2262: case TOKge: eop = OPge; break; 2263: case TOKequal: eop = OPeqeq; break; 2264: case TOKnotequal: eop = OPne; break; 2265: 2266: // NCEG floating point compares 2267: case TOKunord: eop = OPunord; break; 2268: case TOKlg: eop = OPlg; break; 2269: case TOKleg: eop = OPleg; break; 2270: case TOKule: eop = OPule; break; 2271: case TOKul: eop = OPul; break; 2272: case TOKuge: eop = OPuge; break; 2273: case TOKug: eop = OPug; break; 2274: case TOKue: eop = OPue; break; 2275: default: 2276: dump(0); 2277: assert(0); 2278: } 2279: if (!t1->isfloating()) 2280: { 2281: // Convert from floating point compare to equivalent 2282: // integral compare 2283: eop = (enum OPER)rel_integral(eop); 2284: } 2285: if ((int)eop > 1 && t1->ty == Tclass && t2->ty == Tclass) 2286: { 2287: #if 1 2288: assert(0); 2289: #else 2290: elem *ec1; 2291: elem *ec2; 2292: 2293: ec1 = e1->toElem(irs); 2294: ec2 = e2->toElem(irs); 2295: e = el_bin(OPcall,TYint,el_var(rtlsym[RTLSYM_OBJ_CMP]),el_param(ec1, ec2)); 2296: e = el_bin(eop, TYint, e, el_long(TYint, 0)); 2297: #endif 2298: } 2299: else if ((int)eop > 1 && 2300: (t1->ty == Tarray || t1->ty == Tsarray) && 2301: (t2->ty == Tarray || t2->ty == Tsarray)) 2302: { 2303: elem *ea1; 2304: elem *ea2; 2305: elem *ep; 2306: Type *telement = t1->nextOf()->toBasetype(); 2307: int rtlfunc; 2308: 2309: ea1 = e1->toElem(irs); 2310: ea1 = array_toDarray(t1, ea1); 2311: ea2 = e2->toElem(irs); 2312: ea2 = array_toDarray(t2, ea2); 2313: 2314: #if DMDV2 2315: ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs), 2316: ea2, ea1, NULL); 2317: rtlfunc = RTLSYM_ARRAYCMP2; 2318: #else 2319: ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL); 2320: rtlfunc = RTLSYM_ARRAYCMP; 2321: #endif 2322: e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep); 2323: e = el_bin(eop, TYint, e, el_long(TYint, 0)); 2324: el_setLoc(e,loc); 2325: } 2326: else 2327: { 2328: if ((int)eop <= 1) 2329: { 2330: /* The result is determinate, create: 2331: * (e1 , e2) , eop 2332: */ 2333: e = toElemBin(irs,OPcomma); 2334: e = el_bin(OPcomma,e->Ety,e,el_long(e->Ety,(int)eop)); 2335: } 2336: else 2337: e = toElemBin(irs,eop); 2338: } 2339: return e; 2340: } 2341: 2342: elem *EqualExp::toElem(IRState *irs) 2343: { 2344: //printf("EqualExp::toElem() %s\n", toChars()); 2345: 2346: elem *e; 2347: enum OPER eop; 2348: Type *t1 = e1->type->toBasetype(); 2349: Type *t2 = e2->type->toBasetype(); 2350: 2351: switch (op) 2352: { 2353: case TOKequal: eop = OPeqeq; break; 2354: case TOKnotequal: eop = OPne; break; 2355: default: 2356: dump(0); 2357: assert(0); 2358: } 2359: 2360: //printf("EqualExp::toElem()\n"); 2361: if (t1->ty == Tstruct) 2362: { // Do bit compare of struct's 2363: 2364: elem *es1 = e1->toElem(irs); 2365: elem *es2 = e2->toElem(irs); 2366: es1 = addressElem(es1, t1); 2367: es2 = addressElem(es2, t2); 2368: e = el_param(es1, es2); 2369: elem *ecount = el_long(TYsize_t, t1->size()); 2370: e = el_bin(OPmemcmp, TYint, e, ecount); 2371: e = el_bin(eop, TYint, e, el_long(TYint, 0)); 2372: el_setLoc(e,loc); 2373: } 2374: #if 0 2375: else if (t1->ty == Tclass && t2->ty == Tclass) 2376: { 2377: elem *ec1 = e1->toElem(irs); 2378: elem *ec2 = e2->toElem(irs); 2379: e = el_bin(OPcall,TYint,el_var(rtlsym[RTLSYM_OBJ_EQ]),el_param(ec1, ec2)); 2380: } 2381: #endif 2382: else if ((t1->ty == Tarray || t1->ty == Tsarray) && 2383: (t2->ty == Tarray || t2->ty == Tsarray)) 2384: { 2385: Type *telement = t1->nextOf()->toBasetype(); 2386: 2387: elem *ea1 = e1->toElem(irs); 2388: ea1 = array_toDarray(t1, ea1); 2389: elem *ea2 = e2->toElem(irs); 2390: ea2 = array_toDarray(t2, ea2); 2391: 2392: #if DMDV2 2393: elem *ep = el_params(telement->arrayOf()->getInternalTypeInfo(NULL)->toElem(irs), 2394: ea2, ea1, NULL); 2395: int rtlfunc = RTLSYM_ARRAYEQ2; 2396: #else 2397: elem *ep = el_params(telement->getInternalTypeInfo(NULL)->toElem(irs), ea2, ea1, NULL); 2398: int rtlfunc = RTLSYM_ARRAYEQ; 2399: #endif 2400: e = el_bin(OPcall, TYint, el_var(rtlsym[rtlfunc]), ep); 2401: if (op == TOKnotequal) 2402: e = el_bin(OPxor, TYint, e, el_long(TYint, 1)); 2403: el_setLoc(e,loc); 2404: } 2405: else if (t1->ty == Taarray && t2->ty == Taarray) 2406: { TypeAArray *taa = (TypeAArray *)t1; 2407: Symbol *s = taa->aaGetSymbol("Equal", 0); 2408: elem *ti = taa->getTypeInfo(NULL)->toElem(irs); 2409: elem *ea1 = e1->toElem(irs); 2410: elem *ea2 = e2->toElem(irs); 2411: // aaEqual(ti, e1, e2) 2412: elem *ep = el_params(ea2, ea1, ti, NULL); 2413: e = el_bin(OPcall, TYnptr, el_var(s), ep); 2414: if (op == TOKnotequal) 2415: e = el_bin(OPxor, TYint, e, el_long(TYint, 1)); 2416: el_setLoc(e,loc); 2417: return e; 2418: } 2419: else 2420: e = toElemBin(irs, eop); 2421: return e; 2422: } 2423: 2424: elem *IdentityExp::toElem(IRState *irs) 2425: { 2426: elem *e; 2427: enum OPER eop; 2428: Type *t1 = e1->type->toBasetype(); 2429: Type *t2 = e2->type->toBasetype(); 2430: 2431: switch (op) 2432: { 2433: case TOKidentity: eop = OPeqeq; break; 2434: case TOKnotidentity: eop = OPne; break; 2435: default: 2436: dump(0); 2437: assert(0); 2438: } 2439: 2440: //printf("IdentityExp::toElem() %s\n", toChars()); 2441: 2442: if (t1->ty == Tstruct || t1->isfloating()) 2443: { // Do bit compare of struct's 2444: elem *es1; 2445: elem *es2; 2446: elem *ecount; 2447: 2448: es1 = e1->toElem(irs); 2449: es1 = addressElem(es1, e1->type); 2450: //es1 = el_una(OPaddr, TYnptr, es1); 2451: es2 = e2->toElem(irs); 2452: es2 = addressElem(es2, e2->type); 2453: //es2 = el_una(OPaddr, TYnptr, es2); 2454: e = el_param(es1, es2); 2455: ecount = el_long(TYsize_t, t1->size()); 2456: e = el_bin(OPmemcmp, TYint, e, ecount); 2457: e = el_bin(eop, TYint, e, el_long(TYint, 0)); 2458: el_setLoc(e,loc); 2459: } 2460: else if ((t1->ty == Tarray || t1->ty == Tsarray) && 2461: (t2->ty == Tarray || t2->ty == Tsarray)) 2462: { 2463: elem *ea1; 2464: elem *ea2; 2465: 2466: ea1 = e1->toElem(irs); 2467: ea1 = array_toDarray(t1, ea1); 2468: ea2 = e2->toElem(irs); 2469: ea2 = array_toDarray(t2, ea2); 2470: 2471: e = el_bin(eop, type->totym(), ea1, ea2); 2472: el_setLoc(e,loc); 2473: } 2474: else 2475: e = toElemBin(irs, eop); 2476: 2477: return e; 2478: } 2479: 2480: 2481: /*************************************** 2482: */ 2483: 2484: elem *InExp::toElem(IRState *irs) 2485: { elem *e; 2486: elem *key = e1->toElem(irs); 2487: elem *aa = e2->toElem(irs); 2488: elem *ep; 2489: elem *keyti; 2490: TypeAArray *taa = (TypeAArray *)e2->type->toBasetype(); 2491: 2492: 2493: // set to: 2494: Symbol *s; 2495: if (I64) 2496: { 2497: // aaInX(aa, keyti, key); 2498: key = addressElem(key, e1->type); 2499: s = taa->aaGetSymbol("InX", 0); 2500: } 2501: else 2502: { 2503: // aaIn(aa, keyti, key); 2504: if (tybasic(key->Ety) == TYstruct) 2505: { 2506: key = el_una(OPstrpar, TYstruct, key); 2507: key->ET = key->E1->ET; 2508: } 2509: else if (tybasic(key->Ety) == TYarray && taa->index->ty == Tsarray) 2510: { // e2->elem() turns string literals into a TYarray, so the 2511: // length is lost. Restore it. 2512: key = el_una(OPstrpar, TYstruct, key); 2513: assert(e1->type->size() == taa->index->size()); 2514: key->ET = taa->index->toCtype(); 2515: } 2516: 2517: s = taa->aaGetSymbol("In", 0); 2518: } 2519: keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 2520: ep = el_params(key, keyti, aa, NULL); 2521: e = el_bin(OPcall, type->totym(), el_var(s), ep); 2522: 2523: el_setLoc(e,loc); 2524: return e; 2525: } 2526: 2527: /*************************************** 2528: */ 2529: 2530: elem *RemoveExp::toElem(IRState *irs) 2531: { elem *e; 2532: Type *tb = e1->type->toBasetype(); 2533: assert(tb->ty == Taarray); 2534: TypeAArray *taa = (TypeAArray *)tb; 2535: elem *ea = e1->toElem(irs); 2536: elem *ekey = e2->toElem(irs); 2537: elem *ep; 2538: elem *keyti; 2539: 2540: Symbol *s; 2541: if (I64) 2542: { 2543: ekey = addressElem(ekey, e1->type); 2544: s = taa->aaGetSymbol("DelX", 0); 2545: } 2546: else 2547: { 2548: if (tybasic(ekey->Ety) == TYstruct || tybasic(ekey->Ety) == TYarray) 2549: { 2550: ekey = el_una(OPstrpar, TYstruct, ekey); 2551: ekey->ET = ekey->E1->ET; 2552: } 2553: 2554: s = taa->aaGetSymbol("Del", 0); 2555: } 2556: keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 2557: ep = el_params(ekey, keyti, ea, NULL); 2558: e = el_bin(OPcall, TYnptr, el_var(s), ep); 2559: 2560: el_setLoc(e,loc); 2561: return e; 2562: } 2563: 2564: /*************************************** 2565: */ 2566: 2567: elem *AssignExp::toElem(IRState *irs) 2568: { 2569: //printf("AssignExp::toElem('%s')\n", toChars()); 2570: Type *t1b = e1->type->toBasetype(); 2571: 2572: // Look for array.length = n 2573: if (e1->op == TOKarraylength) 2574: { 2575: // Generate: 2576: // _d_arraysetlength(e2, sizeelem, &ale->e1); 2577: 2578: ArrayLengthExp *ale = (ArrayLengthExp *)e1; 2579: 2580: elem *p1 = e2->toElem(irs); 2581: elem *p3 = ale->e1->toElem(irs); 2582: p3 = addressElem(p3, NULL); 2583: Type *t1 = ale->e1->type->toBasetype(); 2584: 2585: // call _d_arraysetlengthT(ti, e2, &ale->e1); 2586: elem *p2 = t1->getTypeInfo(NULL)->toElem(irs); 2587: elem *ep = el_params(p3, p1, p2, NULL); // c function 2588: int r = t1->nextOf()->isZeroInit() ? RTLSYM_ARRAYSETLENGTHT : RTLSYM_ARRAYSETLENGTHIT; 2589: 2590: elem *e = el_bin(OPcall, type->totym(), el_var(rtlsym[r]), ep); 2591: el_setLoc(e, loc); 2592: return e; 2593: } 2594: 2595: elem *e; 2596: IndexExp *ae; 2597: 2598: // Look for array[]=n 2599: if (e1->op == TOKslice) 2600: { 2601: SliceExp *are = (SliceExp *)(e1); 2602: Type *t1 = t1b; 2603: Type *t2 = e2->type->toBasetype(); 2604: 2605: // which we do if the 'next' types match 2606: if (ismemset) 2607: { // Do a memset for array[]=v 2608: //printf("Lpair %s\n", toChars()); 2609: SliceExp *are = (SliceExp *)e1;
warning C6246: Local declaration of 'are' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '2601' of 'c:\projects\extern\d\dmd\src\e2ir.c': Lines: 2601
2610: elem *evalue; 2611: elem *enbytes; 2612: elem *elength; 2613: elem *einit; 2614: dinteger_t value;
warning C4101: 'value' : unreferenced local variable
2615: Type *ta = are->e1->type->toBasetype(); 2616: Type *tb = ta->nextOf()->toBasetype(); 2617: int sz = tb->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
2618: tym_t tym = type->totym(); 2619: 2620: elem *n1 = are->e1->toElem(irs); 2621: elem *elwr = are->lwr ? are->lwr->toElem(irs) : NULL; 2622: elem *eupr = are->upr ? are->upr->toElem(irs) : NULL; 2623: 2624: elem *n1x = n1; 2625: 2626: // Look for array[]=n 2627: if (ta->ty == Tsarray) 2628: { 2629: TypeSArray *ts = (TypeSArray *) ta; 2630: n1 = array_toPtr(ta, n1); 2631: enbytes = ts->dim->toElem(irs); 2632: n1x = n1; 2633: n1 = el_same(&n1x); 2634: einit = resolveLengthVar(are->lengthVar, &n1, ta); 2635: } 2636: else if (ta->ty == Tarray) 2637: { 2638: n1 = el_same(&n1x); 2639: einit = resolveLengthVar(are->lengthVar, &n1, ta); 2640: enbytes = el_copytree(n1); 2641: n1 = array_toPtr(ta, n1); 2642: enbytes = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, enbytes); 2643: } 2644: else if (ta->ty == Tpointer) 2645: { 2646: n1 = el_same(&n1x); 2647: enbytes = el_long(TYsize_t, -1); // largest possible index 2648: einit = NULL; 2649: } 2650: 2651: // Enforce order of evaluation of n1[elwr..eupr] as n1,elwr,eupr 2652: elem *elwrx = elwr; 2653: if (elwr) elwr = el_same(&elwrx); 2654: elem *euprx = eupr; 2655: if (eupr) eupr = el_same(&euprx); 2656: 2657: #if 0 2658: printf("sz = %d\n", sz); 2659: printf("n1x\n"); 2660: elem_print(n1x); 2661: printf("einit\n"); 2662: elem_print(einit); 2663: printf("elwrx\n"); 2664: elem_print(elwrx); 2665: printf("euprx\n"); 2666: elem_print(euprx); 2667: printf("n1\n"); 2668: elem_print(n1); 2669: printf("elwr\n"); 2670: elem_print(elwr); 2671: printf("eupr\n"); 2672: elem_print(eupr); 2673: printf("enbytes\n"); 2674: elem_print(enbytes); 2675: #endif 2676: einit = el_combine(n1x, einit); 2677: einit = el_combine(einit, elwrx); 2678: einit = el_combine(einit, euprx); 2679: 2680: evalue = this->e2->toElem(irs); 2681: 2682: #if 0 2683: printf("n1\n"); 2684: elem_print(n1); 2685: printf("enbytes\n"); 2686: elem_print(enbytes); 2687: #endif 2688: 2689: if (irs->arrayBoundsCheck() && eupr && ta->ty != Tpointer) 2690: { 2691: elem *c1; 2692: elem *c2; 2693: elem *ea; 2694: elem *eb; 2695: elem *enbytesx; 2696: 2697: assert(elwr); 2698: enbytesx = enbytes; 2699: enbytes = el_same(&enbytesx); 2700: c1 = el_bin(OPle, TYint, el_copytree(eupr), enbytesx); 2701: c2 = el_bin(OPle, TYint, el_copytree(elwr), el_copytree(eupr)); 2702: c1 = el_bin(OPandand, TYint, c1, c2); 2703: 2704: // Construct: (c1 || ModuleArray(line)) 2705: Symbol *sassert; 2706: 2707: sassert = irs->blx->module->toModuleArray(); 2708: ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 2709: eb = el_bin(OPoror,TYvoid,c1,ea); 2710: einit = el_combine(einit, eb); 2711: } 2712: 2713: if (elwr) 2714: { elem *elwr2; 2715: 2716: el_free(enbytes); 2717: elwr2 = el_copytree(elwr); 2718: elwr2 = el_bin(OPmul, TYsize_t, elwr2, el_long(TYsize_t, sz)); 2719: n1 = el_bin(OPadd, TYnptr, n1, elwr2); 2720: enbytes = el_bin(OPmin, TYsize_t, eupr, elwr); 2721: elength = el_copytree(enbytes); 2722: } 2723: else 2724: elength = el_copytree(enbytes); 2725: e = setArray(n1, enbytes, tb, evalue, irs, op); 2726: Lpair:
warning C4102: 'Lpair' : unreferenced label
2727: e = el_pair(TYdarray, elength, e); 2728: Lret2:
warning C4102: 'Lret2' : unreferenced label
2729: e = el_combine(einit, e); 2730: //elem_print(e); 2731: goto Lret; 2732: } 2733: #if 0 2734: else if (e2->op == TOKadd || e2->op == TOKmin) 2735: { 2736: /* It's ea[] = eb[] +- ec[] 2737: */ 2738: BinExp *e2a = (BinExp *)e2; 2739: Type *t = e2->type->toBasetype()->nextOf()->toBasetype(); 2740: if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80) 2741: { 2742: e2->error("array add/min for %s not supported", t->toChars()); 2743: return el_long(TYint, 0); 2744: } 2745: elem *ea = e1->toElem(irs); 2746: ea = array_toDarray(e1->type, ea); 2747: elem *eb = e2a->e1->toElem(irs); 2748: eb = array_toDarray(e2a->e1->type, eb); 2749: elem *ec = e2a->e2->toElem(irs); 2750: ec = array_toDarray(e2a->e2->type, ec); 2751: 2752: int rtl = RTLSYM_ARRAYASSADDFLOAT; 2753: if (t->ty == Tfloat64) 2754: rtl = RTLSYM_ARRAYASSADDDOUBLE; 2755: else if (t->ty == Tfloat80) 2756: rtl = RTLSYM_ARRAYASSADDREAL; 2757: if (e2->op == TOKmin) 2758: { 2759: rtl = RTLSYM_ARRAYASSMINFLOAT; 2760: if (t->ty == Tfloat64) 2761: rtl = RTLSYM_ARRAYASSMINDOUBLE; 2762: else if (t->ty == Tfloat80) 2763: rtl = RTLSYM_ARRAYASSMINREAL; 2764: } 2765: 2766: /* Set parameters so the order of evaluation is eb, ec, ea 2767: */ 2768: elem *ep = el_params(eb, ec, ea, NULL); 2769: e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep); 2770: goto Lret; 2771: } 2772: #endif 2773: else 2774: { 2775: /* It's array1[]=array2[] 2776: * which is a memcpy 2777: */ 2778: elem *ep; 2779: 2780: elem *eto = e1->toElem(irs); 2781: elem *efrom = e2->toElem(irs); 2782: 2783: unsigned size = t1->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
2784: elem *esize = el_long(TYsize_t, size); 2785: 2786: /* Determine if we need to do postblit 2787: */ 2788: int postblit = 0; 2789: if (needsPostblit(t1)) 2790: postblit = 1; 2791: 2792: assert(e2->type->ty != Tpointer); 2793: 2794: if (!postblit && !irs->arrayBoundsCheck()) 2795: { 2796: elem *ex = el_same(&eto); 2797: 2798: // Determine if elen is a constant 2799: elem *elen; 2800: if (eto->Eoper == OPpair && 2801: eto->E1->Eoper == OPconst) 2802: { 2803: elen = el_copytree(eto->E1); 2804: } 2805: else 2806: { 2807: // It's not a constant, so pull it from the dynamic array 2808: elen = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, el_copytree(ex)); 2809: } 2810: 2811: esize = el_bin(OPmul, TYsize_t, elen, esize); 2812: elem *epto = array_toPtr(e1->type, ex); 2813: elem *epfr = array_toPtr(e2->type, efrom); 2814: #if 1 2815: // memcpy() is faster, so if we can't beat 'em, join 'em 2816: e = el_params(esize, epfr, epto, NULL); 2817: e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_MEMCPY]),e); 2818: #else 2819: e = el_bin(OPmemcpy, TYnptr, epto, el_param(epfr, esize)); 2820: #endif 2821: e = el_pair(eto->Ety, el_copytree(elen), e); 2822: e = el_combine(eto, e); 2823: } 2824: #if DMDV2 2825: else if (postblit && op != TOKblit) 2826: { 2827: /* Generate: 2828: * _d_arrayassign(ti, efrom, eto) 2829: * or: 2830: * _d_arrayctor(ti, efrom, eto) 2831: */ 2832: el_free(esize); 2833: Expression *ti = t1->nextOf()->toBasetype()->getTypeInfo(NULL); 2834: ep = el_params(eto, efrom, ti->toElem(irs), NULL); 2835: int rtl = (op == TOKconstruct) ? RTLSYM_ARRAYCTOR : RTLSYM_ARRAYASSIGN; 2836: e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep); 2837: } 2838: #endif 2839: else 2840: { 2841: // Generate: 2842: // _d_arraycopy(eto, efrom, esize) 2843: 2844: ep = el_params(eto, efrom, esize, NULL); 2845: e = el_bin(OPcall, type->totym(), el_var(rtlsym[RTLSYM_ARRAYCOPY]), ep); 2846: } 2847: el_setLoc(e, loc); 2848: return e; 2849: } 2850: } 2851: 2852: if (e1->op == TOKindex) 2853: { 2854: elem *eb;
warning C4101: 'eb' : unreferenced local variable
2855: elem *ei;
warning C4101: 'ei' : unreferenced local variable
2856: elem *ev;
warning C4101: 'ev' : unreferenced local variable
2857: TY ty; 2858: Type *ta; 2859: 2860: ae = (IndexExp *)(e1); 2861: ta = ae->e1->type->toBasetype(); 2862: ty = ta->ty; 2863: } 2864: 2865: #if DMDV2 2866: /* Look for reference initializations 2867: */ 2868: if (op == TOKconstruct && e1->op == TOKvar) 2869: { 2870: VarExp *ve = (VarExp *)e1; 2871: Declaration *s = ve->var; 2872: if (s->storage_class & (STCout | STCref)) 2873: { 2874: #if 0 2875: Expression *ae = e2->addressOf(NULL); 2876: e = ae->toElem(irs); 2877: #else 2878: e = e2->toElem(irs); 2879: e = addressElem(e, e2->type); 2880: #endif 2881: elem *es = el_var(s->toSymbol()); 2882: es->Ety = TYnptr; 2883: e = el_bin(OPeq, TYnptr, es, e); 2884: // BUG: type is struct, and e2 is TOKint64 2885: goto Lret; 2886: } 2887: } 2888: #endif 2889: 2890: #if 1 2891: /* This will work if we can distinguish an assignment from 2892: * an initialization of the lvalue. It'll work if the latter. 2893: * If the former, because of aliasing of the return value with 2894: * function arguments, it'll fail. 2895: */ 2896: if (op == TOKconstruct && e2->op == TOKcall) 2897: { CallExp *ce = (CallExp *)e2; 2898: 2899: TypeFunction *tf = (TypeFunction *)ce->e1->type->toBasetype(); 2900: if (tf->ty == Tfunction && tf->retStyle() == RETstack) 2901: { 2902: elem *ehidden = e1->toElem(irs); 2903: ehidden = el_una(OPaddr, TYnptr, ehidden); 2904: assert(!irs->ehidden); 2905: irs->ehidden = ehidden; 2906: e = e2->toElem(irs); 2907: goto Lret; 2908: } 2909: } 2910: #endif 2911: //if (op == TOKconstruct) printf("construct\n"); 2912: if (t1b->ty == Tstruct || t1b->ty == Tsarray) 2913: { elem *eleft = e1->toElem(irs); 2914: 2915: if (e2->op == TOKint64) 2916: { /* Implement: 2917: * (struct = 0) 2918: * with: 2919: * memset(&struct, 0, struct.sizeof) 2920: */ 2921: elem *ey = NULL; 2922: int sz = e1->type->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
2923: StructDeclaration *sd = ((TypeStruct *)t1b)->sym; 2924: if (sd->isnested && op == TOKconstruct) 2925: { 2926: ey = el_una(OPaddr, TYnptr, eleft); 2927: eleft = el_same(&ey); 2928: ey = setEthis(loc, irs, ey, sd); 2929: sz = sd->vthis->offset; 2930: } 2931: 2932: elem *el = eleft; 2933: elem *enbytes = el_long(TYsize_t, sz); 2934: elem *evalue = el_long(TYsize_t, 0); 2935: 2936: if (!(sd->isnested && op == TOKconstruct)) 2937: el = el_una(OPaddr, TYnptr, el); 2938: e = el_param(enbytes, evalue); 2939: e = el_bin(OPmemset,TYnptr,el,e); 2940: e = el_combine(ey, e); 2941: el_setLoc(e, loc); 2942: //e = el_una(OPind, TYstruct, e); 2943: } 2944: else 2945: { 2946: //printf("toElemBin() '%s'\n", toChars()); 2947: 2948: tym_t tym = type->totym(); 2949: 2950: elem *e1 = eleft; 2951: elem *ex = e1; 2952: if (e1->Eoper == OPind) 2953: ex = e1->E1; 2954: if (this->e2->op == TOKstructliteral && 2955: ex->Eoper == OPvar && ex->EV.sp.Voffset == 0) 2956: { StructLiteralExp *se = (StructLiteralExp *)this->e2; 2957: 2958: Symbol *symSave = se->sym; 2959: size_t soffsetSave = se->soffset; 2960: int fillHolesSave = se->fillHoles; 2961: 2962: se->sym = ex->EV.sp.Vsym; 2963: se->soffset = 0; 2964: se->fillHoles = (op == TOKconstruct || op == TOKblit) ? 1 : 0; 2965: 2966: el_free(e1); 2967: e = this->e2->toElem(irs); 2968: 2969: se->sym = symSave; 2970: se->soffset = soffsetSave; 2971: se->fillHoles = fillHolesSave; 2972: } 2973: else 2974: { 2975: elem *e2 = this->e2->toElem(irs); 2976: e = el_bin(OPstreq,tym,e1,e2); 2977: e->ET = this->e1->type->toCtype(); 2978: if (type_size(e->ET) == 0) 2979: e->Eoper = OPcomma; 2980: } 2981: goto Lret; 2982: } 2983: } 2984: else 2985: e = toElemBin(irs,OPeq); 2986: return e; 2987: 2988: Lret: 2989: el_setLoc(e,loc); 2990: return e; 2991: } 2992: 2993: /*************************************** 2994: */ 2995: 2996: elem *AddAssignExp::toElem(IRState *irs) 2997: { 2998: //printf("AddAssignExp::toElem() %s\n", toChars()); 2999: elem *e = toElemBin(irs,OPaddass); 3000: return e; 3001: } 3002: 3003: 3004: /*************************************** 3005: */ 3006: 3007: elem *MinAssignExp::toElem(IRState *irs) 3008: { 3009: return toElemBin(irs,OPminass); 3010: } 3011: 3012: /*************************************** 3013: */ 3014: 3015: elem *CatAssignExp::toElem(IRState *irs) 3016: { 3017: //printf("CatAssignExp::toElem('%s')\n", toChars()); 3018: elem *e; 3019: Type *tb1 = e1->type->toBasetype(); 3020: Type *tb2 = e2->type->toBasetype(); 3021: 3022: if (tb1->ty == Tarray && tb2->ty == Tdchar && 3023: (tb1->nextOf()->ty == Tchar || tb1->nextOf()->ty == Twchar)) 3024: { // Append dchar to char[] or wchar[] 3025: 3026: elem *e1 = this->e1->toElem(irs); 3027: e1 = el_una(OPaddr, TYnptr, e1); 3028: 3029: elem *e2 = this->e2->toElem(irs); 3030: 3031: elem *ep = el_params(e2, e1, NULL); 3032: int rtl = (tb1->nextOf()->ty == Tchar) 3033: ? RTLSYM_ARRAYAPPENDCD 3034: : RTLSYM_ARRAYAPPENDWD; 3035: e = el_bin(OPcall, TYdarray, el_var(rtlsym[rtl]), ep); 3036: el_setLoc(e,loc); 3037: } 3038: else if (tb1->ty == Tarray || tb2->ty == Tsarray) 3039: { 3040: elem *e1 = this->e1->toElem(irs); 3041: elem *e2 = this->e2->toElem(irs); 3042: 3043: Type *tb1n = tb1->nextOf()->toBasetype(); 3044: if ((tb2->ty == Tarray || tb2->ty == Tsarray) && 3045: tb1n->equals(tb2->nextOf()->toBasetype())) 3046: { // Append array 3047: e1 = el_una(OPaddr, TYnptr, e1); 3048: if (tybasic(e2->Ety) == TYstruct || tybasic(e2->Ety) == TYarray) 3049: { 3050: e2 = el_una(OPstrpar, TYstruct, e2); 3051: e2->ET = e2->E1->ET; 3052: } 3053: elem *ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL); 3054: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDT]), ep); 3055: } 3056: else if (I64) 3057: { // Append element 3058: 3059: elem *e2x = NULL; 3060: 3061: if (e2->Eoper != OPvar && e2->Eoper != OPconst) 3062: { 3063: // Evaluate e2 and assign result to temporary s2. 3064: // Do this because of: 3065: // a ~= a[$-1] 3066: // because $ changes its value 3067: symbol *s2 = symbol_genauto(tb2->toCtype()); 3068: e2x = el_bin(OPeq, e2->Ety, el_var(s2), e2); 3069: if (tybasic(e2->Ety) == TYstruct) 3070: { 3071: e2x->Eoper = OPstreq; 3072: e2x->ET = tb1n->toCtype(); 3073: } 3074: else if (tybasic(e2->Ety) == TYarray) 3075: { 3076: e2x->Eoper = OPstreq; 3077: e2x->Ejty = e2x->Ety = TYstruct; 3078: e2x->ET = tb1n->toCtype(); 3079: } 3080: e2 = el_var(s2); 3081: } 3082: 3083: // Extend array with _d_arrayappendcTX(TypeInfo ti, e1, 1) 3084: e1 = el_una(OPaddr, TYnptr, e1); 3085: elem *ep = el_param(e1, this->e1->type->getTypeInfo(NULL)->toElem(irs)); 3086: ep = el_param(el_long(TYsize_t, 1), ep); 3087: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCTX]), ep); 3088: symbol *stmp = symbol_genauto(tb1->toCtype()); 3089: e = el_bin(OPeq, TYdarray, el_var(stmp), e); 3090: 3091: // Assign e2 to last element in stmp[] 3092: // *(stmp.ptr + (stmp.length - 1) * szelem) = e2 3093: 3094: elem *eptr = array_toPtr(tb1, el_var(stmp)); 3095: elem *elength = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, el_var(stmp)); 3096: elength = el_bin(OPmin, TYsize_t, elength, el_long(TYsize_t, 1)); 3097: elength = el_bin(OPmul, TYsize_t, elength, el_long(TYsize_t, this->e2->type->size())); 3098: eptr = el_bin(OPadd, TYnptr, eptr, elength); 3099: StructDeclaration *sd = needsPostblit(tb2); 3100: elem *epost = NULL; 3101: if (sd) 3102: epost = el_same(&eptr); 3103: elem *ederef = el_una(OPind, e2->Ety, eptr); 3104: elem *eeq = el_bin(OPeq, e2->Ety, ederef, e2); 3105: 3106: if (tybasic(e2->Ety) == TYstruct) 3107: { 3108: eeq->Eoper = OPstreq; 3109: eeq->ET = tb1n->toCtype(); 3110: } 3111: else if (tybasic(e2->Ety) == TYarray) 3112: { 3113: eeq->Eoper = OPstreq; 3114: eeq->Ejty = eeq->Ety = TYstruct; 3115: eeq->ET = tb1n->toCtype(); 3116: } 3117: 3118: /* Need to call postblit on eeq 3119: */ 3120: if (sd) 3121: { FuncDeclaration *fd = sd->postblit; 3122: epost = callfunc(loc, irs, 1, Type::tvoid, epost, sd->type->pointerTo(), fd, fd->type, NULL, NULL); 3123: eeq = el_bin(OPcomma, epost->Ety, eeq, epost); 3124: } 3125: 3126: e = el_combine(e2x, e); 3127: e = el_combine(e, eeq); 3128: e = el_combine(e, el_var(stmp)); 3129: } 3130: else 3131: { // Append element 3132: e1 = el_una(OPaddr, TYnptr, e1); 3133: if (tybasic(e2->Ety) == TYstruct || tybasic(e2->Ety) == TYarray) 3134: { 3135: e2 = el_una(OPstrpar, TYstruct, e2); 3136: e2->ET = e2->E1->ET; 3137: } 3138: elem *ep = el_params(e2, e1, this->e1->type->getTypeInfo(NULL)->toElem(irs), NULL); 3139: e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYAPPENDCT]), ep); 3140: e->Eflags |= EFLAGS_variadic; 3141: } 3142: 3143: el_setLoc(e,loc); 3144: } 3145: else 3146: assert(0); 3147: return e; 3148: } 3149: 3150: 3151: /*************************************** 3152: */ 3153: 3154: elem *DivAssignExp::toElem(IRState *irs) 3155: { 3156: return toElemBin(irs,OPdivass); 3157: } 3158: 3159: 3160: /*************************************** 3161: */ 3162: 3163: elem *ModAssignExp::toElem(IRState *irs) 3164: { 3165: return toElemBin(irs,OPmodass); 3166: } 3167: 3168: 3169: /*************************************** 3170: */ 3171: 3172: elem *MulAssignExp::toElem(IRState *irs) 3173: { 3174: return toElemBin(irs,OPmulass); 3175: } 3176: 3177: 3178: /*************************************** 3179: */ 3180: 3181: elem *ShlAssignExp::toElem(IRState *irs) 3182: { 3183: return toElemBin(irs,OPshlass); 3184: } 3185: 3186: 3187: /*************************************** 3188: */ 3189: 3190: elem *ShrAssignExp::toElem(IRState *irs) 3191: { 3192: //printf("ShrAssignExp::toElem() %s, %s\n", e1->type->toChars(), e1->toChars()); 3193: Type *t1 = e1->type; 3194: if (e1->op == TOKcast) 3195: { /* Use the type before it was integrally promoted to int 3196: */ 3197: CastExp *ce = (CastExp *)e1; 3198: t1 = ce->e1->type; 3199: } 3200: return toElemBin(irs, t1->isunsigned() ? OPshrass : OPashrass); 3201: } 3202: 3203: 3204: /*************************************** 3205: */ 3206: 3207: elem *UshrAssignExp::toElem(IRState *irs) 3208: { 3209: return toElemBin(irs, OPshrass); 3210: } 3211: 3212: 3213: /*************************************** 3214: */ 3215: 3216: elem *AndAssignExp::toElem(IRState *irs) 3217: { 3218: return toElemBin(irs,OPandass); 3219: } 3220: 3221: 3222: /*************************************** 3223: */ 3224: 3225: elem *OrAssignExp::toElem(IRState *irs) 3226: { 3227: return toElemBin(irs,OPorass); 3228: } 3229: 3230: 3231: /*************************************** 3232: */ 3233: 3234: elem *XorAssignExp::toElem(IRState *irs) 3235: { 3236: return toElemBin(irs,OPxorass); 3237: } 3238: 3239: 3240: /*************************************** 3241: */ 3242: 3243: elem *AndAndExp::toElem(IRState *irs) 3244: { 3245: tym_t tym = type->totym(); 3246: 3247: elem *el = e1->toElem(irs); 3248: elem *er = e2->toElemDtor(irs); 3249: elem *e = el_bin(OPandand,tym,el,er); 3250: 3251: el_setLoc(e,loc); 3252: 3253: if (global.params.cov && e2->loc.linnum) 3254: e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2); 3255: return e; 3256: } 3257: 3258: 3259: /*************************************** 3260: */ 3261: 3262: elem *OrOrExp::toElem(IRState *irs) 3263: { 3264: tym_t tym = type->totym(); 3265: 3266: elem *el = e1->toElem(irs); 3267: elem *er = e2->toElemDtor(irs); 3268: elem *e = el_bin(OPoror,tym,el,er); 3269: 3270: el_setLoc(e,loc); 3271: 3272: if (global.params.cov && e2->loc.linnum) 3273: e->E2 = el_combine(incUsageElem(irs, e2->loc), e->E2); 3274: return e; 3275: } 3276: 3277: 3278: /*************************************** 3279: */ 3280: 3281: elem *XorExp::toElem(IRState *irs) 3282: { 3283: return toElemBin(irs,OPxor); 3284: } 3285: 3286: 3287: /*************************************** 3288: */ 3289: 3290: elem *AndExp::toElem(IRState *irs) 3291: { 3292: return toElemBin(irs,OPand); 3293: } 3294: 3295: 3296: /*************************************** 3297: */ 3298: 3299: elem *OrExp::toElem(IRState *irs) 3300: { 3301: return toElemBin(irs,OPor); 3302: } 3303: 3304: 3305: /*************************************** 3306: */ 3307: 3308: elem *ShlExp::toElem(IRState *irs) 3309: { 3310: return toElemBin(irs, OPshl); 3311: } 3312: 3313: 3314: /*************************************** 3315: */ 3316: 3317: elem *ShrExp::toElem(IRState *irs) 3318: { 3319: return toElemBin(irs, e1->type->isunsigned() ? OPshr : OPashr); 3320: } 3321: 3322: 3323: /*************************************** 3324: */ 3325: 3326: elem *UshrExp::toElem(IRState *irs) 3327: { 3328: //return toElemBin(irs, OPshr); 3329: elem *eleft = e1->toElem(irs); 3330: eleft->Ety = touns(eleft->Ety); 3331: elem *eright = e2->toElem(irs); 3332: elem *e = el_bin(OPshr, type->totym(), eleft, eright); 3333: el_setLoc(e, loc); 3334: return e; 3335: } 3336: 3337: /**************************************** 3338: */ 3339: 3340: elem *CommaExp::toElem(IRState *irs) 3341: { 3342: assert(e1 && e2); 3343: elem *eleft = e1->toElem(irs); 3344: elem *eright = e2->toElem(irs); 3345: elem *e = el_combine(eleft, eright); 3346: if (e) 3347: el_setLoc(e, loc); 3348: return e; 3349: } 3350: 3351: 3352: /*************************************** 3353: */ 3354: 3355: elem *CondExp::toElem(IRState *irs) 3356: { 3357: elem *ec = econd->toElem(irs); 3358: 3359: elem *eleft = e1->toElemDtor(irs); 3360: tym_t ty = eleft->Ety; 3361: if (global.params.cov && e1->loc.linnum) 3362: eleft = el_combine(incUsageElem(irs, e1->loc), eleft); 3363: 3364: elem *eright = e2->toElemDtor(irs); 3365: if (global.params.cov && e2->loc.linnum) 3366: eright = el_combine(incUsageElem(irs, e2->loc), eright); 3367: 3368: elem *e = el_bin(OPcond, ty, ec, el_bin(OPcolon, ty, eleft, eright)); 3369: if (tybasic(ty) == TYstruct) 3370: e->ET = e1->type->toCtype(); 3371: el_setLoc(e, loc); 3372: return e; 3373: } 3374: 3375: 3376: /*************************************** 3377: */ 3378: 3379: elem *TypeExp::toElem(IRState *irs) 3380: { 3381: #ifdef DEBUG 3382: printf("TypeExp::toElem()\n"); 3383: #endif 3384: error("type %s is not an expression", toChars()); 3385: return el_long(TYint, 0); 3386: } 3387: 3388: elem *ScopeExp::toElem(IRState *irs) 3389: { 3390: error("%s is not an expression", sds->toChars()); 3391: return el_long(TYint, 0); 3392: } 3393: 3394: elem *DotVarExp::toElem(IRState *irs) 3395: { 3396: // *(&e + offset) 3397: 3398: //printf("DotVarExp::toElem('%s')\n", toChars()); 3399: 3400: VarDeclaration *v = var->isVarDeclaration(); 3401: if (!v) 3402: { 3403: error("%s is not a field, but a %s", var->toChars(), var->kind()); 3404: } 3405: 3406: elem *e = e1->toElem(irs); 3407: Type *tb1 = e1->type->toBasetype(); 3408: if (tb1->ty != Tclass && tb1->ty != Tpointer) 3409: //e = el_una(OPaddr, TYnptr, e); 3410: e = addressElem(e, tb1); 3411: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, v ? v->offset : 0)); 3412: e = el_una(OPind, type->totym(), e); 3413: if (tybasic(e->Ety) == TYstruct) 3414: { 3415: e->ET = type->toCtype(); 3416: } 3417: el_setLoc(e,loc); 3418: return e; 3419: } 3420: 3421: elem *DelegateExp::toElem(IRState *irs) 3422: { 3423: elem *e; 3424: elem *ethis; 3425: elem *ep; 3426: Symbol *sfunc; 3427: int directcall = 0; 3428: 3429: //printf("DelegateExp::toElem() '%s'\n", toChars()); 3430: sfunc = func->toSymbol(); 3431: if (func->isNested()) 3432: { 3433: ep = el_ptr(sfunc); 3434: ethis = getEthis(loc, irs, func); 3435: } 3436: else 3437: { 3438: ethis = e1->toElem(irs); 3439: if (e1->type->ty != Tclass && e1->type->ty != Tpointer) 3440: ethis = addressElem(ethis, e1->type); 3441: 3442: if (e1->op == TOKsuper || e1->op == TOKdottype) 3443: directcall = 1; 3444: 3445: if (!func->isThis()) 3446: error("delegates are only for non-static functions"); 3447: 3448: if (!func->isVirtual() || 3449: directcall || 3450: func->isFinal()) 3451: { 3452: ep = el_ptr(sfunc); 3453: } 3454: else 3455: { 3456: // Get pointer to function out of virtual table 3457: unsigned vindex; 3458: 3459: assert(ethis); 3460: ep = el_same(&ethis); 3461: ep = el_una(OPind, TYnptr, ep); 3462: vindex = func->vtblIndex; 3463: 3464: if ((int)vindex < 0) 3465: error("Internal compiler error: malformed delegate. See Bugzilla 4860"); 3466: 3467: // Build *(ep + vindex * 4) 3468: ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * PTRSIZE)); 3469: ep = el_una(OPind,TYnptr,ep); 3470: } 3471: 3472: // if (func->tintro) 3473: // func->error(loc, "cannot form delegate due to covariant return type"); 3474: } 3475: if (ethis->Eoper == OPcomma) 3476: { 3477: ethis->E2 = el_pair(TYdelegate, ethis->E2, ep); 3478: ethis->Ety = TYdelegate; 3479: e = ethis; 3480: } 3481: else 3482: e = el_pair(TYdelegate, ethis, ep); 3483: el_setLoc(e,loc); 3484: return e; 3485: } 3486: 3487: elem *DotTypeExp::toElem(IRState *irs) 3488: { 3489: // Just a pass-thru to e1 3490: elem *e; 3491: 3492: //printf("DotTypeExp::toElem() %s\n", toChars()); 3493: e = e1->toElem(irs); 3494: el_setLoc(e,loc); 3495: return e; 3496: } 3497: 3498: elem *CallExp::toElem(IRState *irs) 3499: { 3500: //printf("CallExp::toElem('%s')\n", toChars()); 3501: assert(e1->type); 3502: elem *ec; 3503: int directcall; 3504: FuncDeclaration *fd; 3505: Type *t1 = e1->type->toBasetype(); 3506: Type *ectype = t1; 3507: elem *eeq = NULL; 3508: 3509: elem *ehidden = irs->ehidden; 3510: irs->ehidden = NULL; 3511: 3512: directcall = 0; 3513: fd = NULL; 3514: if (e1->op == TOKdotvar && t1->ty != Tdelegate) 3515: { DotVarExp *dve = (DotVarExp *)e1; 3516: 3517: fd = dve->var->isFuncDeclaration(); 3518: Expression *ex = dve->e1; 3519: while (1) 3520: { 3521: switch (ex->op) 3522: { 3523: case TOKsuper: // super.member() calls directly 3524: case TOKdottype: // type.member() calls directly 3525: directcall = 1; 3526: break; 3527: 3528: case TOKcast: 3529: ex = ((CastExp *)ex)->e1; 3530: continue; 3531: 3532: default: 3533: //ex->dump(0); 3534: break; 3535: } 3536: break; 3537: } 3538: ec = dve->e1->toElem(irs); 3539: ectype = dve->e1->type->toBasetype(); 3540: } 3541: else if (e1->op == TOKvar) 3542: { 3543: fd = ((VarExp *)e1)->var->isFuncDeclaration(); 3544: 3545: if (fd && fd->ident == Id::alloca && 3546: !fd->fbody && fd->linkage == LINKc && 3547: arguments && arguments->dim == 1) 3548: { Expression *arg = arguments->tdata()[0]; 3549: arg = arg->optimize(WANTvalue); 3550: if (arg->isConst() && arg->type->isintegral()) 3551: { dinteger_t sz = arg->toInteger(); 3552: if (sz > 0 && sz < 0x40000) 3553: { 3554: // It's an alloca(sz) of a fixed amount. 3555: // Replace with an array allocated on the stack 3556: // of the same size: char[sz] tmp; 3557: 3558: Symbol *stmp; 3559: ::type *t; 3560: 3561: assert(!ehidden); 3562: t = type_allocn(TYarray, tschar); 3563: t->Tdim = sz;
warning C4244: '=' : conversion from 'dinteger_t' to 'targ_size_t', possible loss of data
3564: stmp = symbol_genauto(t); 3565: ec = el_ptr(stmp); 3566: el_setLoc(ec,loc); 3567: return ec; 3568: } 3569: } 3570: } 3571: 3572: ec = e1->toElem(irs); 3573: } 3574: else 3575: { 3576: ec = e1->toElem(irs); 3577: if (arguments && arguments->dim) 3578: { 3579: /* The idea is to enforce expressions being evaluated left to right, 3580: * even though call trees are evaluated parameters first. 3581: * We just do a quick hack to catch the more obvious cases, though 3582: * we need to solve this generally. 3583: */ 3584: if (ec->Eoper == OPind && el_sideeffect(ec->E1)) 3585: { /* Rewrite (*exp)(arguments) as: 3586: * tmp=exp, (*tmp)(arguments) 3587: */ 3588: elem *ec1 = ec->E1; 3589: Symbol *stmp = symbol_genauto(type_fake(ec1->Ety)); 3590: eeq = el_bin(OPeq, ec->Ety, el_var(stmp), ec1); 3591: ec->E1 = el_var(stmp); 3592: } 3593: else if (tybasic(ec->Ety) == TYdelegate && el_sideeffect(ec)) 3594: { /* Rewrite (exp)(arguments) as: 3595: * tmp=exp, (tmp)(arguments) 3596: */ 3597: Symbol *stmp = symbol_genauto(type_fake(ec->Ety)); 3598: eeq = el_bin(OPeq, ec->Ety, el_var(stmp), ec); 3599: ec = el_var(stmp); 3600: } 3601: } 3602: } 3603: ec = callfunc(loc, irs, directcall, type, ec, ectype, fd, t1, ehidden, arguments); 3604: el_setLoc(ec,loc); 3605: if (eeq) 3606: ec = el_combine(eeq, ec); 3607: return ec; 3608: } 3609: 3610: elem *AddrExp::toElem(IRState *irs) 3611: { elem *e; 3612: elem **pe;
warning C4101: 'pe' : unreferenced local variable
3613: 3614: //printf("AddrExp::toElem('%s')\n", toChars()); 3615: 3616: e = e1->toElem(irs); 3617: e = addressElem(e, e1->type); 3618: L2:
warning C4102: 'L2' : unreferenced label
3619: e->Ety = type->totym(); 3620: el_setLoc(e,loc); 3621: return e; 3622: } 3623: 3624: elem *PtrExp::toElem(IRState *irs) 3625: { elem *e; 3626: 3627: //printf("PtrExp::toElem() %s\n", toChars()); 3628: e = e1->toElem(irs); 3629: e = el_una(OPind,type->totym(),e); 3630: if (tybasic(e->Ety) == TYstruct) 3631: { 3632: e->ET = type->toCtype(); 3633: } 3634: el_setLoc(e,loc); 3635: return e; 3636: } 3637: 3638: elem *BoolExp::toElem(IRState *irs) 3639: { elem *e1; 3640: 3641: e1 = this->e1->toElem(irs); 3642: return el_una(OPbool,type->totym(),e1); 3643: } 3644: 3645: elem *DeleteExp::toElem(IRState *irs) 3646: { elem *e; 3647: int rtl; 3648: Type *tb; 3649: 3650: //printf("DeleteExp::toElem()\n"); 3651: if (e1->op == TOKindex) 3652: { 3653: IndexExp *ae = (IndexExp *)(e1); 3654: tb = ae->e1->type->toBasetype(); 3655: if (tb->ty == Taarray) 3656: { 3657: TypeAArray *taa = (TypeAArray *)tb; 3658: elem *ea = ae->e1->toElem(irs); 3659: elem *ekey = ae->e2->toElem(irs); 3660: elem *ep; 3661: elem *keyti; 3662: 3663: if (tybasic(ekey->Ety) == TYstruct || tybasic(ekey->Ety) == TYarray) 3664: { 3665: ekey = el_una(OPstrpar, TYstruct, ekey); 3666: ekey->ET = ekey->E1->ET; 3667: } 3668: 3669: Symbol *s = taa->aaGetSymbol("Del", 0); 3670: keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 3671: ep = el_params(ekey, keyti, ea, NULL); 3672: e = el_bin(OPcall, TYnptr, el_var(s), ep); 3673: goto Lret; 3674: } 3675: } 3676: //e1->type->print(); 3677: e = e1->toElem(irs); 3678: tb = e1->type->toBasetype(); 3679: switch (tb->ty) 3680: { 3681: case Tarray: 3682: { e = addressElem(e, e1->type); 3683: rtl = RTLSYM_DELARRAYT; 3684: 3685: /* See if we need to run destructors on the array contents 3686: */ 3687: elem *et = NULL; 3688: Type *tv = tb->nextOf()->toBasetype(); 3689: while (tv->ty == Tsarray) 3690: { TypeSArray *ta = (TypeSArray *)tv; 3691: tv = tv->nextOf()->toBasetype(); 3692: } 3693: if (tv->ty == Tstruct) 3694: { TypeStruct *ts = (TypeStruct *)tv; 3695: StructDeclaration *sd = ts->sym; 3696: if (sd->dtor) 3697: et = tb->nextOf()->getTypeInfo(NULL)->toElem(irs); 3698: } 3699: if (!et) // if no destructors needed 3700: et = el_long(TYnptr, 0); // pass null for TypeInfo 3701: e = el_params(et, e, NULL); 3702: // call _d_delarray_t(e, et); 3703: e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e); 3704: goto Lret; 3705: } 3706: case Tclass: 3707: if (e1->op == TOKvar) 3708: { VarExp *ve = (VarExp *)e1; 3709: if (ve->var->isVarDeclaration() && 3710: ve->var->isVarDeclaration()->onstack) 3711: { 3712: rtl = RTLSYM_CALLFINALIZER; 3713: if (tb->isClassHandle()->isInterfaceDeclaration()) 3714: rtl = RTLSYM_CALLINTERFACEFINALIZER; 3715: break; 3716: } 3717: } 3718: e = addressElem(e, e1->type); 3719: rtl = RTLSYM_DELCLASS; 3720: if (tb->isClassHandle()->isInterfaceDeclaration()) 3721: rtl = RTLSYM_DELINTERFACE; 3722: break; 3723: 3724: case Tpointer: 3725: e = addressElem(e, e1->type); 3726: rtl = RTLSYM_DELMEMORY; 3727: break; 3728: 3729: default: 3730: assert(0); 3731: break; 3732: } 3733: e = el_bin(OPcall, TYvoid, el_var(rtlsym[rtl]), e); 3734: 3735: Lret: 3736: el_setLoc(e,loc); 3737: return e; 3738: } 3739: 3740: elem *CastExp::toElem(IRState *irs) 3741: { 3742: TY fty; 3743: TY tty; 3744: tym_t ftym; 3745: tym_t ttym; 3746: enum OPER eop; 3747: 3748: #if 0 3749: printf("CastExp::toElem()\n"); 3750: print(); 3751: printf("\tfrom: %s\n", e1->type->toChars()); 3752: printf("\tto : %s\n", to->toChars()); 3753: #endif 3754: 3755: elem *e = e1->toElem(irs); 3756: Type *tfrom = e1->type->toBasetype(); 3757: Type *t = to->toBasetype(); // skip over typedef's 3758: 3759: #if DMDV2 3760: if (tfrom->ty == Taarray) 3761: tfrom = ((TypeAArray*)tfrom)->getImpl()->type; 3762: if (t->ty == Taarray) 3763: t = ((TypeAArray*)t)->getImpl()->type; 3764: #endif 3765: 3766: if (t->equals(tfrom)) 3767: goto Lret; 3768: 3769: fty = tfrom->ty; 3770: //printf("fty = %d\n", fty); 3771: tty = t->ty; 3772: 3773: if (tty == Tpointer && fty == Tarray 3774: #if 0 3775: && (t->next->ty == Tvoid || t->next->equals(e1->type->next)) 3776: #endif 3777: ) 3778: { 3779: if (e->Eoper == OPvar) 3780: { 3781: // e1 -> *(&e1 + 4) 3782: e = el_una(OPaddr, TYnptr, e); 3783: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, tysize[TYnptr])); 3784: e = el_una(OPind,t->totym(),e); 3785: } 3786: else 3787: { 3788: // e1 -> (unsigned)(e1 >> 32) 3789: if (I64) 3790: { 3791: e = el_bin(OPshr, TYucent, e, el_long(TYint, 64)); 3792: e = el_una(OP128_64, t->totym(), e); 3793: } 3794: else 3795: { 3796: e = el_bin(OPshr, TYullong, e, el_long(TYint, 32)); 3797: e = el_una(OP64_32, t->totym(), e); 3798: } 3799: } 3800: goto Lret; 3801: } 3802: 3803: if (tty == Tpointer && fty == Tsarray 3804: #if 0 3805: && (t->next->ty == Tvoid || t->next->equals(e1->type->next)) 3806: #endif 3807: ) 3808: { 3809: // e1 -> &e1 3810: e = el_una(OPaddr, TYnptr, e); 3811: goto Lret; 3812: } 3813: 3814: // Convert from static array to dynamic array 3815: if (tty == Tarray && fty == Tsarray) 3816: { 3817: e = sarray_toDarray(loc, tfrom, t, e); 3818: goto Lret; 3819: } 3820: 3821: // Convert from dynamic array to dynamic array 3822: if (tty == Tarray && fty == Tarray) 3823: { 3824: unsigned fsize = tfrom->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
3825: unsigned tsize = t->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
3826: 3827: if (fsize != tsize) 3828: { // Array element sizes do not match, so we must adjust the dimensions 3829: elem *ep = el_params(e, el_long(TYsize_t, fsize), el_long(TYsize_t, tsize), NULL); 3830: e = el_bin(OPcall, type->totym(), el_var(rtlsym[RTLSYM_ARRAYCAST]), ep); 3831: } 3832: goto Lret; 3833: } 3834: 3835: // Casting from base class to derived class requires a runtime check 3836: if (fty == Tclass && tty == Tclass) 3837: { 3838: // Casting from derived class to base class is a no-op 3839: int offset; 3840: int rtl = RTLSYM_DYNAMIC_CAST; 3841: 3842: ClassDeclaration *cdfrom = tfrom->isClassHandle(); 3843: ClassDeclaration *cdto = t->isClassHandle(); 3844: if (cdfrom->isInterfaceDeclaration()) 3845: { 3846: rtl = RTLSYM_INTERFACE_CAST; 3847: if (cdfrom->isCPPinterface()) 3848: { 3849: if (cdto->isCPPinterface()) 3850: { 3851: /* Casting from a C++ interface to a C++ interface 3852: * is always a 'paint' operation 3853: */ 3854: goto Lret; // no-op 3855: } 3856: 3857: /* Casting from a C++ interface to a class 3858: * always results in null because there is no runtime 3859: * information available to do it. 3860: * 3861: * Casting from a C++ interface to a non-C++ interface 3862: * always results in null because there's no way one 3863: * can be derived from the other. 3864: */ 3865: e = el_bin(OPcomma, TYnptr, e, el_long(TYnptr, 0)); 3866: goto Lret; 3867: } 3868: } 3869: if (cdto->isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME) 3870: { 3871: /* The offset from cdfrom=>cdto is known at compile time. 3872: */ 3873: 3874: //printf("offset = %d\n", offset); 3875: if (offset) 3876: { /* Rewrite cast as (e ? e + offset : null) 3877: */ 3878: if (e1->op == TOKthis) 3879: { // Assume 'this' is never null, so skip null check 3880: e = el_bin(OPadd, TYnptr, e, el_long(TYsize_t, offset)); 3881: } 3882: else 3883: { 3884: elem *etmp = el_same(&e); 3885: elem *ex = el_bin(OPadd, TYnptr, etmp, el_long(TYsize_t, offset)); 3886: ex = el_bin(OPcolon, TYnptr, ex, el_long(TYnptr, 0)); 3887: e = el_bin(OPcond, TYnptr, e, ex); 3888: } 3889: } 3890: goto Lret; // no-op 3891: } 3892: 3893: /* The offset from cdfrom=>cdto can only be determined at runtime. 3894: */ 3895: elem *ep = el_param(el_ptr(cdto->toSymbol()), e); 3896: e = el_bin(OPcall, TYnptr, el_var(rtlsym[rtl]), ep); 3897: goto Lret; 3898: } 3899: 3900: ftym = tybasic(e->Ety); 3901: ttym = tybasic(t->totym()); 3902: if (ftym == ttym) 3903: goto Lret; 3904: 3905: /* Reduce combinatorial explosion by rewriting the 'to' and 'from' types to a 3906: * generic equivalent (as far as casting goes) 3907: */ 3908: switch (tty) 3909: { 3910: case Tpointer: 3911: if (fty == Tdelegate) 3912: goto Lpaint; 3913: tty = I64 ? Tuns64 : Tuns32; 3914: break; 3915: 3916: case Tchar: tty = Tuns8; break; 3917: case Twchar: tty = Tuns16; break; 3918: case Tdchar: tty = Tuns32; break; 3919: case Tvoid: goto Lpaint; 3920: 3921: case Tbool: 3922: { 3923: // Construct e?true:false 3924: e = el_una(OPbool, ttym, e); 3925: goto Lret; 3926: } 3927: } 3928: 3929: switch (fty) 3930: { 3931: case Tpointer: fty = I64 ? Tuns64 : Tuns32; break; 3932: case Tchar: fty = Tuns8; break; 3933: case Twchar: fty = Tuns16; break; 3934: case Tdchar: fty = Tuns32; break; 3935: } 3936: 3937: #define X(fty, tty) ((fty) * TMAX + (tty)) 3938: Lagain: 3939: switch (X(fty,tty)) 3940: { 3941: /* ============================= */ 3942: 3943: case X(Tbool,Tint8): 3944: case X(Tbool,Tuns8): 3945: goto Lpaint; 3946: case X(Tbool,Tint16): 3947: case X(Tbool,Tuns16): 3948: case X(Tbool,Tint32): 3949: case X(Tbool,Tuns32): eop = OPu8_16; goto Leop; 3950: case X(Tbool,Tint64): 3951: case X(Tbool,Tuns64): 3952: case X(Tbool,Tfloat32): 3953: case X(Tbool,Tfloat64): 3954: case X(Tbool,Tfloat80): 3955: case X(Tbool,Tcomplex32): 3956: case X(Tbool,Tcomplex64): 3957: case X(Tbool,Tcomplex80): 3958: e = el_una(OPu8_16, TYuint, e); 3959: fty = Tuns32; 3960: goto Lagain; 3961: case X(Tbool,Timaginary32): 3962: case X(Tbool,Timaginary64): 3963: case X(Tbool,Timaginary80): goto Lzero; 3964: 3965: /* ============================= */ 3966: 3967: case X(Tint8,Tuns8): goto Lpaint; 3968: case X(Tint8,Tint16): 3969: case X(Tint8,Tuns16): 3970: case X(Tint8,Tint32): 3971: case X(Tint8,Tuns32): eop = OPs8_16; goto Leop; 3972: case X(Tint8,Tint64): 3973: case X(Tint8,Tuns64): 3974: case X(Tint8,Tfloat32): 3975: case X(Tint8,Tfloat64): 3976: case X(Tint8,Tfloat80): 3977: case X(Tint8,Tcomplex32): 3978: case X(Tint8,Tcomplex64): 3979: case X(Tint8,Tcomplex80): 3980: e = el_una(OPs8_16, TYint, e); 3981: fty = Tint32; 3982: goto Lagain; 3983: case X(Tint8,Timaginary32): 3984: case X(Tint8,Timaginary64): 3985: case X(Tint8,Timaginary80): goto Lzero; 3986: 3987: /* ============================= */ 3988: 3989: case X(Tuns8,Tint8): goto Lpaint; 3990: case X(Tuns8,Tint16): 3991: case X(Tuns8,Tuns16): 3992: case X(Tuns8,Tint32): 3993: case X(Tuns8,Tuns32): eop = OPu8_16; goto Leop; 3994: case X(Tuns8,Tint64): 3995: case X(Tuns8,Tuns64): 3996: case X(Tuns8,Tfloat32): 3997: case X(Tuns8,Tfloat64): 3998: case X(Tuns8,Tfloat80): 3999: case X(Tuns8,Tcomplex32): 4000: case X(Tuns8,Tcomplex64): 4001: case X(Tuns8,Tcomplex80): 4002: e = el_una(OPu8_16, TYuint, e); 4003: fty = Tuns32; 4004: goto Lagain; 4005: case X(Tuns8,Timaginary32): 4006: case X(Tuns8,Timaginary64): 4007: case X(Tuns8,Timaginary80): goto Lzero; 4008: 4009: /* ============================= */ 4010: 4011: case X(Tint16,Tint8): 4012: case X(Tint16,Tuns8): eop = OP16_8; goto Leop; 4013: case X(Tint16,Tuns16): goto Lpaint; 4014: case X(Tint16,Tint32): 4015: case X(Tint16,Tuns32): eop = OPs16_32; goto Leop; 4016: case X(Tint16,Tint64): 4017: case X(Tint16,Tuns64): e = el_una(OPs16_32, TYint, e); 4018: fty = Tint32; 4019: goto Lagain; 4020: case X(Tint16,Tfloat32): 4021: case X(Tint16,Tfloat64): 4022: case X(Tint16,Tfloat80): 4023: case X(Tint16,Tcomplex32): 4024: case X(Tint16,Tcomplex64): 4025: case X(Tint16,Tcomplex80): 4026: e = el_una(OPs16_d, TYdouble, e); 4027: fty = Tfloat64; 4028: goto Lagain; 4029: case X(Tint16,Timaginary32): 4030: case X(Tint16,Timaginary64): 4031: case X(Tint16,Timaginary80): goto Lzero; 4032: 4033: /* ============================= */ 4034: 4035: case X(Tuns16,Tint8): 4036: case X(Tuns16,Tuns8): eop = OP16_8; goto Leop; 4037: case X(Tuns16,Tint16): goto Lpaint; 4038: case X(Tuns16,Tint32): 4039: case X(Tuns16,Tuns32): eop = OPu16_32; goto Leop; 4040: case X(Tuns16,Tint64): 4041: case X(Tuns16,Tuns64): 4042: case X(Tuns16,Tfloat64): 4043: case X(Tuns16,Tfloat32): 4044: case X(Tuns16,Tfloat80): 4045: case X(Tuns16,Tcomplex32): 4046: case X(Tuns16,Tcomplex64): 4047: case X(Tuns16,Tcomplex80): 4048: e = el_una(OPu16_32, TYuint, e); 4049: fty = Tuns32; 4050: goto Lagain; 4051: case X(Tuns16,Timaginary32): 4052: case X(Tuns16,Timaginary64): 4053: case X(Tuns16,Timaginary80): goto Lzero; 4054: 4055: /* ============================= */ 4056: 4057: case X(Tint32,Tint8): 4058: case X(Tint32,Tuns8): e = el_una(OP32_16, TYshort, e); 4059: fty = Tint16; 4060: goto Lagain; 4061: case X(Tint32,Tint16): 4062: case X(Tint32,Tuns16): eop = OP32_16; goto Leop; 4063: case X(Tint32,Tuns32): goto Lpaint; 4064: case X(Tint32,Tint64): 4065: case X(Tint32,Tuns64): eop = OPs32_64; goto Leop; 4066: case X(Tint32,Tfloat32): 4067: case X(Tint32,Tfloat64): 4068: case X(Tint32,Tfloat80): 4069: case X(Tint32,Tcomplex32): 4070: case X(Tint32,Tcomplex64): 4071: case X(Tint32,Tcomplex80): 4072: e = el_una(OPs32_d, TYdouble, e); 4073: fty = Tfloat64; 4074: goto Lagain; 4075: case X(Tint32,Timaginary32): 4076: case X(Tint32,Timaginary64): 4077: case X(Tint32,Timaginary80): goto Lzero; 4078: 4079: /* ============================= */ 4080: 4081: case X(Tuns32,Tint8): 4082: case X(Tuns32,Tuns8): e = el_una(OP32_16, TYshort, e); 4083: fty = Tuns16; 4084: goto Lagain; 4085: case X(Tuns32,Tint16): 4086: case X(Tuns32,Tuns16): eop = OP32_16; goto Leop; 4087: case X(Tuns32,Tint32): goto Lpaint; 4088: case X(Tuns32,Tint64): 4089: case X(Tuns32,Tuns64): eop = OPu32_64; goto Leop; 4090: case X(Tuns32,Tfloat32): 4091: case X(Tuns32,Tfloat64): 4092: case X(Tuns32,Tfloat80): 4093: case X(Tuns32,Tcomplex32): 4094: case X(Tuns32,Tcomplex64): 4095: case X(Tuns32,Tcomplex80): 4096: e = el_una(OPu32_d, TYdouble, e); 4097: fty = Tfloat64; 4098: goto Lagain; 4099: case X(Tuns32,Timaginary32): 4100: case X(Tuns32,Timaginary64): 4101: case X(Tuns32,Timaginary80): goto Lzero; 4102: 4103: /* ============================= */ 4104: 4105: case X(Tint64,Tint8): 4106: case X(Tint64,Tuns8): 4107: case X(Tint64,Tint16): 4108: case X(Tint64,Tuns16): e = el_una(OP64_32, TYint, e); 4109: fty = Tint32; 4110: goto Lagain; 4111: case X(Tint64,Tint32): 4112: case X(Tint64,Tuns32): eop = OP64_32; goto Leop; 4113: case X(Tint64,Tuns64): goto Lpaint; 4114: case X(Tint64,Tfloat32): 4115: case X(Tint64,Tfloat64): 4116: case X(Tint64,Tfloat80): 4117: case X(Tint64,Tcomplex32): 4118: case X(Tint64,Tcomplex64): 4119: case X(Tint64,Tcomplex80): 4120: e = el_una(OPs64_d, TYdouble, e); 4121: fty = Tfloat64; 4122: goto Lagain; 4123: case X(Tint64,Timaginary32): 4124: case X(Tint64,Timaginary64): 4125: case X(Tint64,Timaginary80): goto Lzero; 4126: 4127: /* ============================= */ 4128: 4129: case X(Tuns64,Tint8): 4130: case X(Tuns64,Tuns8): 4131: case X(Tuns64,Tint16): 4132: case X(Tuns64,Tuns16): e = el_una(OP64_32, TYint, e); 4133: fty = Tint32; 4134: goto Lagain; 4135: case X(Tuns64,Tint32): 4136: case X(Tuns64,Tuns32): eop = OP64_32; goto Leop; 4137: case X(Tuns64,Tint64): goto Lpaint; 4138: case X(Tuns64,Tfloat32): 4139: case X(Tuns64,Tfloat64): 4140: case X(Tuns64,Tfloat80): 4141: case X(Tuns64,Tcomplex32): 4142: case X(Tuns64,Tcomplex64): 4143: case X(Tuns64,Tcomplex80): 4144: e = el_una(OPu64_d, TYdouble, e); 4145: fty = Tfloat64; 4146: goto Lagain; 4147: case X(Tuns64,Timaginary32): 4148: case X(Tuns64,Timaginary64): 4149: case X(Tuns64,Timaginary80): goto Lzero; 4150: 4151: /* ============================= */ 4152: 4153: case X(Tfloat32,Tint8): 4154: case X(Tfloat32,Tuns8): 4155: case X(Tfloat32,Tint16): 4156: case X(Tfloat32,Tuns16): 4157: case X(Tfloat32,Tint32): 4158: case X(Tfloat32,Tuns32): 4159: case X(Tfloat32,Tint64): 4160: case X(Tfloat32,Tuns64): 4161: case X(Tfloat32,Tfloat80): e = el_una(OPf_d, TYdouble, e); 4162: fty = Tfloat64; 4163: goto Lagain; 4164: case X(Tfloat32,Tfloat64): eop = OPf_d; goto Leop; 4165: case X(Tfloat32,Timaginary32): goto Lzero; 4166: case X(Tfloat32,Timaginary64): goto Lzero; 4167: case X(Tfloat32,Timaginary80): goto Lzero; 4168: case X(Tfloat32,Tcomplex32): 4169: case X(Tfloat32,Tcomplex64): 4170: case X(Tfloat32,Tcomplex80): 4171: e = el_bin(OPadd,TYcfloat,el_long(TYifloat,0),e); 4172: fty = Tcomplex32; 4173: goto Lagain; 4174: 4175: /* ============================= */ 4176: 4177: case X(Tfloat64,Tint8): 4178: case X(Tfloat64,Tuns8): e = el_una(OPd_s16, TYshort, e); 4179: fty = Tint16; 4180: goto Lagain; 4181: case X(Tfloat64,Tint16): eop = OPd_s16; goto Leop; 4182: case X(Tfloat64,Tuns16): eop = OPd_u16; goto Leop; 4183: case X(Tfloat64,Tint32): eop = OPd_s32; goto Leop; 4184: case X(Tfloat64,Tuns32): eop = OPd_u32; goto Leop; 4185: case X(Tfloat64,Tint64): eop = OPd_s64; goto Leop; 4186: case X(Tfloat64,Tuns64): eop = OPd_u64; goto Leop; 4187: case X(Tfloat64,Tfloat32): eop = OPd_f; goto Leop; 4188: case X(Tfloat64,Tfloat80): eop = OPd_ld; goto Leop; 4189: case X(Tfloat64,Timaginary32): goto Lzero; 4190: case X(Tfloat64,Timaginary64): goto Lzero; 4191: case X(Tfloat64,Timaginary80): goto Lzero; 4192: case X(Tfloat64,Tcomplex32): 4193: case X(Tfloat64,Tcomplex64): 4194: case X(Tfloat64,Tcomplex80): 4195: e = el_bin(OPadd,TYcfloat,el_long(TYidouble,0),e); 4196: fty = Tcomplex64; 4197: goto Lagain; 4198: 4199: /* ============================= */ 4200: 4201: case X(Tfloat80,Tint8): 4202: case X(Tfloat80,Tuns8): 4203: case X(Tfloat80,Tint16): 4204: case X(Tfloat80,Tuns16): 4205: case X(Tfloat80,Tint32): 4206: case X(Tfloat80,Tuns32): 4207: case X(Tfloat80,Tint64): 4208: case X(Tfloat80,Tfloat32): e = el_una(OPld_d, TYdouble, e); 4209: fty = Tfloat64; 4210: goto Lagain; 4211: case X(Tfloat80,Tuns64): 4212: eop = OPld_u64; goto Leop; 4213: case X(Tfloat80,Tfloat64): eop = OPld_d; goto Leop; 4214: case X(Tfloat80,Timaginary32): goto Lzero; 4215: case X(Tfloat80,Timaginary64): goto Lzero; 4216: case X(Tfloat80,Timaginary80): goto Lzero; 4217: case X(Tfloat80,Tcomplex32): 4218: case X(Tfloat80,Tcomplex64): 4219: case X(Tfloat80,Tcomplex80): 4220: e = el_bin(OPadd,TYcldouble,e,el_long(TYildouble,0)); 4221: fty = Tcomplex80; 4222: goto Lagain; 4223: 4224: /* ============================= */ 4225: 4226: case X(Timaginary32,Tint8): 4227: case X(Timaginary32,Tuns8): 4228: case X(Timaginary32,Tint16): 4229: case X(Timaginary32,Tuns16): 4230: case X(Timaginary32,Tint32): 4231: case X(Timaginary32,Tuns32): 4232: case X(Timaginary32,Tint64): 4233: case X(Timaginary32,Tuns64): 4234: case X(Timaginary32,Tfloat32): 4235: case X(Timaginary32,Tfloat64): 4236: case X(Timaginary32,Tfloat80): goto Lzero; 4237: case X(Timaginary32,Timaginary64): eop = OPf_d; goto Leop; 4238: case X(Timaginary32,Timaginary80): 4239: e = el_una(OPf_d, TYidouble, e); 4240: fty = Timaginary64; 4241: goto Lagain; 4242: case X(Timaginary32,Tcomplex32): 4243: case X(Timaginary32,Tcomplex64): 4244: case X(Timaginary32,Tcomplex80): 4245: e = el_bin(OPadd,TYcfloat,el_long(TYfloat,0),e); 4246: fty = Tcomplex32; 4247: goto Lagain; 4248: 4249: /* ============================= */ 4250: 4251: case X(Timaginary64,Tint8): 4252: case X(Timaginary64,Tuns8): 4253: case X(Timaginary64,Tint16): 4254: case X(Timaginary64,Tuns16): 4255: case X(Timaginary64,Tint32): 4256: case X(Timaginary64,Tuns32): 4257: case X(Timaginary64,Tint64): 4258: case X(Timaginary64,Tuns64): 4259: case X(Timaginary64,Tfloat32): 4260: case X(Timaginary64,Tfloat64): 4261: case X(Timaginary64,Tfloat80): goto Lzero; 4262: case X(Timaginary64,Timaginary32): eop = OPd_f; goto Leop; 4263: case X(Timaginary64,Timaginary80): eop = OPd_ld; goto Leop; 4264: case X(Timaginary64,Tcomplex32): 4265: case X(Timaginary64,Tcomplex64): 4266: case X(Timaginary64,Tcomplex80): 4267: e = el_bin(OPadd,TYcdouble,el_long(TYdouble,0),e); 4268: fty = Tcomplex64; 4269: goto Lagain; 4270: 4271: /* ============================= */ 4272: 4273: case X(Timaginary80,Tint8): 4274: case X(Timaginary80,Tuns8): 4275: case X(Timaginary80,Tint16): 4276: case X(Timaginary80,Tuns16): 4277: case X(Timaginary80,Tint32): 4278: case X(Timaginary80,Tuns32): 4279: case X(Timaginary80,Tint64): 4280: case X(Timaginary80,Tuns64): 4281: case X(Timaginary80,Tfloat32): 4282: case X(Timaginary80,Tfloat64): 4283: case X(Timaginary80,Tfloat80): goto Lzero; 4284: case X(Timaginary80,Timaginary32): e = el_una(OPf_d, TYidouble, e); 4285: fty = Timaginary64; 4286: goto Lagain; 4287: case X(Timaginary80,Timaginary64): eop = OPld_d; goto Leop; 4288: case X(Timaginary80,Tcomplex32): 4289: case X(Timaginary80,Tcomplex64): 4290: case X(Timaginary80,Tcomplex80): 4291: e = el_bin(OPadd,TYcldouble,el_long(TYldouble,0),e); 4292: fty = Tcomplex80; 4293: goto Lagain; 4294: 4295: /* ============================= */ 4296: 4297: case X(Tcomplex32,Tint8): 4298: case X(Tcomplex32,Tuns8): 4299: case X(Tcomplex32,Tint16): 4300: case X(Tcomplex32,Tuns16): 4301: case X(Tcomplex32,Tint32): 4302: case X(Tcomplex32,Tuns32): 4303: case X(Tcomplex32,Tint64): 4304: case X(Tcomplex32,Tuns64): 4305: case X(Tcomplex32,Tfloat32): 4306: case X(Tcomplex32,Tfloat64): 4307: case X(Tcomplex32,Tfloat80): 4308: e = el_una(OPc_r, TYfloat, e); 4309: fty = Tfloat32; 4310: goto Lagain; 4311: case X(Tcomplex32,Timaginary32): 4312: case X(Tcomplex32,Timaginary64): 4313: case X(Tcomplex32,Timaginary80): 4314: e = el_una(OPc_i, TYifloat, e); 4315: fty = Timaginary32; 4316: goto Lagain; 4317: case X(Tcomplex32,Tcomplex64): 4318: case X(Tcomplex32,Tcomplex80): 4319: e = el_una(OPf_d, TYcdouble, e); 4320: fty = Tcomplex64; 4321: goto Lagain; 4322: 4323: /* ============================= */ 4324: 4325: case X(Tcomplex64,Tint8): 4326: case X(Tcomplex64,Tuns8): 4327: case X(Tcomplex64,Tint16): 4328: case X(Tcomplex64,Tuns16): 4329: case X(Tcomplex64,Tint32): 4330: case X(Tcomplex64,Tuns32): 4331: case X(Tcomplex64,Tint64): 4332: case X(Tcomplex64,Tuns64): 4333: case X(Tcomplex64,Tfloat32): 4334: case X(Tcomplex64,Tfloat64): 4335: case X(Tcomplex64,Tfloat80): 4336: e = el_una(OPc_r, TYdouble, e); 4337: fty = Tfloat64; 4338: goto Lagain; 4339: case X(Tcomplex64,Timaginary32): 4340: case X(Tcomplex64,Timaginary64): 4341: case X(Tcomplex64,Timaginary80): 4342: e = el_una(OPc_i, TYidouble, e); 4343: fty = Timaginary64; 4344: goto Lagain; 4345: case X(Tcomplex64,Tcomplex32): eop = OPd_f; goto Leop; 4346: case X(Tcomplex64,Tcomplex80): eop = OPd_ld; goto Leop; 4347: 4348: /* ============================= */ 4349: 4350: case X(Tcomplex80,Tint8): 4351: case X(Tcomplex80,Tuns8): 4352: case X(Tcomplex80,Tint16): 4353: case X(Tcomplex80,Tuns16): 4354: case X(Tcomplex80,Tint32): 4355: case X(Tcomplex80,Tuns32): 4356: case X(Tcomplex80,Tint64): 4357: case X(Tcomplex80,Tuns64): 4358: case X(Tcomplex80,Tfloat32): 4359: case X(Tcomplex80,Tfloat64): 4360: case X(Tcomplex80,Tfloat80): 4361: e = el_una(OPc_r, TYldouble, e); 4362: fty = Tfloat80; 4363: goto Lagain; 4364: case X(Tcomplex80,Timaginary32): 4365: case X(Tcomplex80,Timaginary64): 4366: case X(Tcomplex80,Timaginary80): 4367: e = el_una(OPc_i, TYildouble, e); 4368: fty = Timaginary80; 4369: goto Lagain; 4370: case X(Tcomplex80,Tcomplex32): 4371: case X(Tcomplex80,Tcomplex64): 4372: e = el_una(OPld_d, TYcdouble, e); 4373: fty = Tcomplex64; 4374: goto Lagain; 4375: 4376: /* ============================= */ 4377: 4378: default: 4379: if (fty == tty) 4380: goto Lpaint; 4381: //dump(0); 4382: //printf("fty = %d, tty = %d, %d\n", fty, tty, t->ty); 4383: error("e2ir: cannot cast %s of type %s to type %s", e1->toChars(), e1->type->toChars(), t->toChars()); 4384: goto Lzero; 4385: 4386: Lzero: 4387: e = el_long(ttym, 0); 4388: break; 4389: 4390: Lpaint: 4391: e->Ety = ttym; 4392: break; 4393: 4394: Leop: 4395: e = el_una(eop, ttym, e); 4396: break; 4397: } 4398: Lret: 4399: // Adjust for any type paints 4400: t = type->toBasetype(); 4401: e->Ety = t->totym(); 4402: 4403: el_setLoc(e,loc); 4404: return e; 4405: } 4406: 4407: elem *ArrayLengthExp::toElem(IRState *irs) 4408: { 4409: elem *e = e1->toElem(irs); 4410: e = el_una(I64 ? OP128_64 : OP64_32, type->totym(), e); 4411: el_setLoc(e,loc); 4412: return e; 4413: } 4414: 4415: elem *SliceExp::toElem(IRState *irs) 4416: { 4417: //printf("SliceExp::toElem()\n"); 4418: Type *t1 = e1->type->toBasetype(); 4419: elem *e = e1->toElem(irs); 4420: if (lwr) 4421: { 4422: elem *einit = resolveLengthVar(lengthVar, &e, t1); 4423: 4424: int sz = t1->nextOf()->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
4425: 4426: elem *elwr = lwr->toElem(irs); 4427: elem *eupr = upr->toElem(irs); 4428: 4429: elem *elwr2 = el_same(&elwr); 4430: 4431: // Create an array reference where: 4432: // length is (upr - lwr) 4433: // pointer is (ptr + lwr*sz) 4434: // Combine as (length pair ptr) 4435: 4436: if (irs->arrayBoundsCheck()) 4437: { 4438: // Checks (unsigned compares): 4439: // upr <= array.length 4440: // lwr <= upr 4441: 4442: elem *c1; 4443: elem *c2; 4444: elem *ea; 4445: elem *eb; 4446: elem *eupr2; 4447: elem *elength; 4448: 4449: if (t1->ty == Tpointer) 4450: { 4451: // Just do lwr <= upr check 4452: 4453: eupr2 = el_same(&eupr); 4454: eupr2->Ety = TYsize_t; // make sure unsigned comparison 4455: c1 = el_bin(OPle, TYint, elwr2, eupr2); 4456: c1 = el_combine(eupr, c1); 4457: goto L2; 4458: } 4459: else if (t1->ty == Tsarray) 4460: { TypeSArray *tsa = (TypeSArray *)t1; 4461: dinteger_t length = tsa->dim->toInteger(); 4462: 4463: elength = el_long(TYsize_t, length); 4464: goto L1; 4465: } 4466: else if (t1->ty == Tarray) 4467: { 4468: if (lengthVar && !(lengthVar->storage_class & STCconst)) 4469: elength = el_var(lengthVar->toSymbol()); 4470: else 4471: { 4472: elength = e; 4473: e = el_same(&elength); 4474: elength = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, elength); 4475: } 4476: L1: 4477: eupr2 = el_same(&eupr); 4478: c1 = el_bin(OPle, TYint, eupr, elength); 4479: eupr2->Ety = TYsize_t; // make sure unsigned comparison 4480: c2 = el_bin(OPle, TYint, elwr2, eupr2); 4481: c1 = el_bin(OPandand, TYint, c1, c2); // (c1 && c2) 4482: 4483: L2: 4484: // Construct: (c1 || ModuleArray(line)) 4485: Symbol *sassert; 4486: 4487: sassert = irs->blx->module->toModuleArray(); 4488: ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 4489: eb = el_bin(OPoror,TYvoid,c1,ea); 4490: elwr = el_combine(elwr, eb); 4491: 4492: elwr2 = el_copytree(elwr2); 4493: eupr = el_copytree(eupr2); 4494: } 4495: } 4496: 4497: elem *eptr = array_toPtr(e1->type, e); 4498: 4499: elem *elength = el_bin(OPmin, TYsize_t, eupr, elwr2); 4500: eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYsize_t, el_copytree(elwr2), el_long(TYsize_t, sz))); 4501: 4502: e = el_pair(TYdarray, elength, eptr); 4503: e = el_combine(elwr, e); 4504: e = el_combine(einit, e); 4505: } 4506: else if (t1->ty == Tsarray) 4507: { 4508: e = sarray_toDarray(loc, t1, NULL, e); 4509: } 4510: el_setLoc(e,loc); 4511: return e; 4512: } 4513: 4514: elem *IndexExp::toElem(IRState *irs) 4515: { elem *e; 4516: elem *n1 = e1->toElem(irs); 4517: elem *eb = NULL; 4518: 4519: //printf("IndexExp::toElem() %s\n", toChars()); 4520: Type *t1 = e1->type->toBasetype(); 4521: if (t1->ty == Taarray) 4522: { 4523: // set to: 4524: // *aaGetX(aa, keyti, valuesize, &key); 4525: 4526: TypeAArray *taa = (TypeAArray *)t1; 4527: int vsize = taa->next->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'int', possible loss of data
4528: Symbol *s; 4529: 4530: // n2 becomes the index, also known as the key 4531: elem *n2 = e2->toElem(irs); 4532: 4533: if (I64) 4534: { 4535: /* Turn n2 into a pointer to the index. If it's an lvalue, 4536: * take the address of it. If not, copy it to a temp and 4537: * take the address of that. 4538: */ 4539: n2 = addressElem(n2, taa->index); 4540: } 4541: else 4542: { 4543: if (tybasic(n2->Ety) == TYstruct || tybasic(n2->Ety) == TYarray) 4544: { 4545: n2 = el_una(OPstrpar, TYstruct, n2); 4546: n2->ET = n2->E1->ET; 4547: if (taa->index->ty == Tsarray) 4548: { 4549: assert(e2->type->size() == taa->index->size()); 4550: } 4551: //printf("numbytes = %d\n", n2->Enumbytes); 4552: } 4553: } 4554: 4555: elem *valuesize = el_long(TYsize_t, vsize); 4556: //printf("valuesize: "); elem_print(valuesize); 4557: if (modifiable) 4558: { 4559: n1 = el_una(OPaddr, TYnptr, n1); 4560: s = taa->aaGetSymbol(I64 ? "GetX" : "Get", 1); 4561: } 4562: else 4563: { 4564: s = taa->aaGetSymbol(I64 ? "GetRvalueX" : "GetRvalue", 1); 4565: } 4566: //printf("taa->index = %s\n", taa->index->toChars()); 4567: elem* keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 4568: //keyti = taa->index->getTypeInfo(NULL)->toElem(irs); 4569: //printf("keyti:\n"); 4570: //elem_print(keyti); 4571: elem* ep = el_params(n2, valuesize, keyti, n1, NULL); 4572: e = el_bin(OPcall, TYnptr, el_var(s), ep); 4573: if (irs->arrayBoundsCheck()) 4574: { 4575: elem *ea; 4576: 4577: elem *n = el_same(&e); 4578: 4579: // Construct: ((e || ModuleAssert(line)),n) 4580: Symbol *sassert = irs->blx->module->toModuleArray(); 4581: ea = el_bin(OPcall,TYvoid,el_var(sassert), 4582: el_long(TYint, loc.linnum)); 4583: e = el_bin(OPoror,TYvoid,e,ea); 4584: e = el_bin(OPcomma, TYnptr, e, n); 4585: } 4586: e = el_una(OPind, type->totym(), e); 4587: if (tybasic(e->Ety) == TYstruct) 4588: e->ET = type->toCtype(); 4589: } 4590: else 4591: { 4592: elem *einit = resolveLengthVar(lengthVar, &n1, t1); 4593: elem *n2 = e2->toElem(irs); 4594: 4595: if (irs->arrayBoundsCheck()) 4596: { 4597: elem *elength; 4598: elem *n2x; 4599: elem *ea; 4600: 4601: if (t1->ty == Tsarray) 4602: { TypeSArray *tsa = (TypeSArray *)t1; 4603: dinteger_t length = tsa->dim->toInteger(); 4604: 4605: elength = el_long(TYsize_t, length); 4606: goto L1; 4607: } 4608: else if (t1->ty == Tarray) 4609: { 4610: elength = n1; 4611: n1 = el_same(&elength); 4612: elength = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, elength); 4613: L1: 4614: n2x = n2; 4615: n2 = el_same(&n2x); 4616: n2x = el_bin(OPlt, TYint, n2x, elength); 4617: 4618: // Construct: (n2x || ModuleAssert(line)) 4619: Symbol *sassert; 4620: 4621: sassert = irs->blx->module->toModuleArray(); 4622: ea = el_bin(OPcall,TYvoid,el_var(sassert), 4623: el_long(TYint, loc.linnum)); 4624: eb = el_bin(OPoror,TYvoid,n2x,ea); 4625: } 4626: } 4627: 4628: n1 = array_toPtr(t1, n1); 4629: 4630: { 4631: elem *escale = el_long(TYsize_t, t1->nextOf()->size()); 4632: n2 = el_bin(OPmul, TYsize_t, n2, escale); 4633: e = el_bin(OPadd, TYnptr, n1, n2); 4634: e = el_una(OPind, type->totym(), e); 4635: if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray) 4636: { e->Ety = TYstruct; 4637: e->ET = type->toCtype(); 4638: } 4639: } 4640: 4641: eb = el_combine(einit, eb); 4642: e = el_combine(eb, e); 4643: } 4644: el_setLoc(e,loc); 4645: return e; 4646: } 4647: 4648: 4649: elem *TupleExp::toElem(IRState *irs) 4650: { elem *e = NULL; 4651: 4652: //printf("TupleExp::toElem() %s\n", toChars()); 4653: for (size_t i = 0; i < exps->dim; i++) 4654: { Expression *el = exps->tdata()[i]; 4655: elem *ep = el->toElem(irs); 4656: 4657: e = el_combine(e, ep); 4658: } 4659: return e; 4660: } 4661: 4662: #if DMDV2 4663: elem *tree_insert(Elems *args, int low, int high) 4664: { 4665: assert(low < high); 4666: if (low + 1 == high) 4667: return args->tdata()[low]; 4668: int mid = (low + high) >> 1; 4669: return el_param(tree_insert(args, low, mid), 4670: tree_insert(args, mid, high)); 4671: } 4672: #endif 4673: 4674: elem *ArrayLiteralExp::toElem(IRState *irs) 4675: { elem *e; 4676: size_t dim; 4677: elem *earg = NULL; 4678: 4679: //printf("ArrayLiteralExp::toElem() %s, type = %s\n", toChars(), type->toChars()); 4680: Type *tb = type->toBasetype(); 4681: if (elements) 4682: { 4683: if (I64) 4684: { /* Instead of passing the initializers on the stack, allocate the 4685: * array and assign the members inline. 4686: * Avoids the whole variadic arg mess. 4687: */ 4688: dim = elements->dim; 4689: Elems args; 4690: args.setDim(dim); // +1 for number of args parameter 4691: e = el_long(TYsize_t, dim); 4692: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 4693: // call _d_arrayliteralTX(ti, dim) 4694: e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALTX]),e); 4695: Symbol *stmp = symbol_genauto(Type::tvoid->pointerTo()->toCtype()); 4696: e = el_bin(OPeq,TYnptr,el_var(stmp),e); 4697: 4698: targ_size_t sz = tb->nextOf()->size(); // element size
warning C4244: 'initializing' : conversion from 'd_uns64' to 'targ_size_t', possible loss of data
4699: ::type *te = tb->nextOf()->toCtype(); // element type 4700: for (size_t i = 0; i < dim; i++) 4701: { Expression *el = elements->tdata()[i]; 4702: 4703: /* Generate: *(stmp + i * sz) = element[i] 4704: */ 4705: elem *ep = el->toElem(irs); 4706: elem *ev = el_var(stmp); 4707: ev = el_bin(OPadd, TYnptr, ev, el_long(TYsize_t, i * sz)); 4708: ev = el_una(OPind, te->Tty, ev); 4709: elem *eeq = el_bin(OPeq,te->Tty,ev,ep); 4710: 4711: if (tybasic(te->Tty) == TYstruct) 4712: { 4713: eeq->Eoper = OPstreq; 4714: eeq->ET = te; 4715: } 4716: else if (tybasic(te->Tty) == TYarray) 4717: { 4718: eeq->Eoper = OPstreq; 4719: eeq->Ejty = eeq->Ety = TYstruct; 4720: eeq->ET = te; 4721: } 4722: args.tdata()[i] = eeq; 4723: } 4724: e = el_combine(e, el_combines((void **)args.tdata(), dim)); 4725: e = el_combine(e, el_var(stmp)); 4726: } 4727: else 4728: { 4729: Elems args; 4730: dim = elements->dim; 4731: args.setDim(dim + 1); // +1 for number of args parameter 4732: e = el_long(TYsize_t, dim); 4733: args.tdata()[dim] = e; 4734: for (size_t i = 0; i < dim; i++) 4735: { Expression *el = elements->tdata()[i]; 4736: elem *ep = el->toElem(irs); 4737: 4738: if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) 4739: { 4740: ep = el_una(OPstrpar, TYstruct, ep); 4741: ep->ET = el->type->toCtype(); 4742: } 4743: args.tdata()[dim - (i + 1)] = ep; 4744: } 4745: 4746: /* Because the number of parameters can get very large, produce 4747: * a balanced binary tree so we don't blow up the stack in 4748: * the subsequent tree walking code. 4749: */ 4750: e = el_params((void **)args.tdata(), dim + 1); 4751: 4752: e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 4753: 4754: // call _d_arrayliteralT(ti, dim, ...) 4755: e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 4756: e->Eflags |= EFLAGS_variadic; 4757: } 4758: } 4759: else 4760: { dim = 0; 4761: e = el_long(TYsize_t, 0); 4762: } 4763: if (tb->ty == Tarray) 4764: { 4765: e = el_pair(TYdarray, el_long(TYsize_t, dim), e); 4766: } 4767: else if (tb->ty == Tpointer) 4768: { 4769: } 4770: else 4771: { 4772: e = el_una(OPind,TYstruct,e); 4773: e->ET = type->toCtype(); 4774: } 4775: 4776: el_setLoc(e,loc); 4777: e = el_combine(earg, e); 4778: return e; 4779: } 4780: 4781: /************************************************* 4782: * Allocate a static array, and initialize its members with 4783: * exps[]. 4784: * Return the initialization expression, and the symbol for the static array in *psym. 4785: */ 4786: elem *ExpressionsToStaticArray(IRState *irs, Loc loc, Expressions *exps, Type *telem, symbol **psym) 4787: { 4788: // Create a static array of type telem[dim] 4789: size_t dim = exps->dim; 4790: Type *tsarray = new TypeSArray(telem, new IntegerExp(loc, dim, Type::tsize_t)); 4791: tsarray = tsarray->semantic(loc, NULL); 4792: symbol *stmp = symbol_genauto(tsarray->toCtype()); 4793: targ_size_t szelem = telem->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'targ_size_t', possible loss of data
4794: 4795: Elems elems; 4796: elems.setDim(dim); 4797: 4798: ::type *te = telem->toCtype(); // stmp[] element type 4799: 4800: for (size_t i = 0; i < dim; i++) 4801: { Expression *el = exps->tdata()[i]; 4802: 4803: /* Generate: *(&stmp + i * szelem) = element[i] 4804: */ 4805: elem *ep = el->toElem(irs); 4806: elem *ev = el_ptr(stmp); 4807: ev = el_bin(OPadd, TYnptr, ev, el_long(TYsize_t, i * szelem)); 4808: ev = el_una(OPind, te->Tty, ev); 4809: elem *eeq = el_bin(OPeq,te->Tty,ev,ep); 4810: 4811: if (tybasic(te->Tty) == TYstruct) 4812: { 4813: eeq->Eoper = OPstreq; 4814: eeq->ET = te; 4815: } 4816: else if (tybasic(te->Tty) == TYarray) 4817: { 4818: eeq->Eoper = OPstreq; 4819: eeq->Ejty = eeq->Ety = TYstruct; 4820: eeq->ET = te; 4821: } 4822: elems.tdata()[i] = eeq; 4823: } 4824: 4825: *psym = stmp; 4826: return el_combines((void **)elems.tdata(), dim); 4827: } 4828: 4829: elem *AssocArrayLiteralExp::toElem(IRState *irs) 4830: { 4831: //printf("AssocArrayLiteralExp::toElem() %s\n", toChars()); 4832: size_t dim = keys->dim; 4833: elem *e; 4834: 4835: if (I64) 4836: { // call _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values) 4837: // Prefer this to avoid the varargs fiasco in 64 bit code 4838: Type *t = type->toBasetype()->mutableOf(); 4839: assert(t->ty == Taarray); 4840: TypeAArray *ta = (TypeAArray *)t; 4841: 4842: symbol *skeys; 4843: elem *ekeys = ExpressionsToStaticArray(irs, loc, keys, ta->index, &skeys); 4844: 4845: symbol *svalues; 4846: elem *evalues = ExpressionsToStaticArray(irs, loc, values, ta->nextOf(), &svalues); 4847: 4848: e = el_params(el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(svalues)), 4849: el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(skeys )), 4850: ta->getTypeInfo(NULL)->toElem(irs), 4851: NULL); 4852: 4853: // call _d_assocarrayliteralTX(ti, keys, values) 4854: e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALTX]),e); 4855: el_setLoc(e,loc); 4856: 4857: e = el_combine(evalues, e); 4858: e = el_combine(ekeys, e); 4859: } 4860: else // Keep for binary backwards compatibility 4861: { // call _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...) 4862: e = el_long(TYsize_t, dim); 4863: for (size_t i = 0; i < dim; i++) 4864: { Expression *el = keys->tdata()[i]; 4865: 4866: for (int j = 0; j < 2; j++) 4867: { 4868: elem *ep = el->toElem(irs); 4869: 4870: if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) 4871: { 4872: ep = el_una(OPstrpar, TYstruct, ep); 4873: ep->ET = el->type->toCtype(); 4874: } 4875: //printf("[%d] %s\n", i, el->toChars()); 4876: //elem_print(ep); 4877: e = el_param(ep, e); 4878: el = values->tdata()[i]; 4879: } 4880: } 4881: 4882: Type *t = type->toBasetype()->mutableOf(); 4883: assert(t->ty == Taarray); 4884: TypeAArray *ta = (TypeAArray *)t; 4885: 4886: #if 0 4887: /* Unfortunately, the hash function for Aa (array of chars) is custom and 4888: * different from Axa and Aya, which get the generic hash function. 4889: * So, rewrite the type of the AArray so that if it's key type 4890: * is an array of const or invariant, make it an array of mutable. 4891: */ 4892: Type *tkey = ta->index->toBasetype(); 4893: if (tkey->ty == Tarray) 4894: { 4895: tkey = tkey->nextOf()->mutableOf()->arrayOf(); 4896: tkey = tkey->semantic(0, NULL); 4897: ta = new TypeAArray(ta->nextOf(), tkey); 4898: ta = (TypeAArray *)ta->merge(); 4899: } 4900: #endif 4901: 4902: e = el_param(e, ta->getTypeInfo(NULL)->toElem(irs)); 4903: 4904: // call _d_assocarrayliteralT(ti, dim, ...) 4905: e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); 4906: e->Eflags |= EFLAGS_variadic; 4907: el_setLoc(e,loc); 4908: } 4909: 4910: return e; 4911: } 4912: 4913: 4914: /******************************************* 4915: * Generate elem to zero fill contents of Symbol stmp 4916: * from *poffset..offset2. 4917: * May store anywhere from 0..maxoff, as this function 4918: * tries to use aligned int stores whereever possible. 4919: * Update *poffset to end of initialized hole; *poffset will be >= offset2. 4920: */ 4921: 4922: elem *fillHole(Symbol *stmp, size_t *poffset, size_t offset2, size_t maxoff) 4923: { elem *e = NULL; 4924: int basealign = 1; 4925: 4926: while (*poffset < offset2) 4927: { tym_t ty; 4928: elem *e1; 4929: 4930: if (tybasic(stmp->Stype->Tty) == TYnptr) 4931: e1 = el_var(stmp); 4932: else 4933: e1 = el_ptr(stmp); 4934: if (basealign) 4935: *poffset &= ~3; 4936: basealign = 1; 4937: size_t sz = maxoff - *poffset; 4938: switch (sz) 4939: { case 1: ty = TYchar; break; 4940: case 2: ty = TYshort; break; 4941: case 3: 4942: ty = TYshort; 4943: basealign = 0; 4944: break; 4945: default: 4946: ty = TYlong; 4947: break; 4948: } 4949: e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, *poffset)); 4950: e1 = el_una(OPind, ty, e1); 4951: e1 = el_bin(OPeq, ty, e1, el_long(ty, 0)); 4952: e = el_combine(e, e1); 4953: *poffset += tysize[ty]; 4954: } 4955: return e; 4956: } 4957: 4958: elem *StructLiteralExp::toElem(IRState *irs) 4959: { elem *e; 4960: size_t dim; 4961: 4962: //printf("StructLiteralExp::toElem() %s\n", toChars()); 4963: 4964: // struct symbol to initialize with the literal 4965: Symbol *stmp = sym ? sym : symbol_genauto(sd->type->toCtype()); 4966: 4967: e = NULL; 4968: 4969: if (fillHoles) 4970: { 4971: /* Initialize all alignment 'holes' to zero. 4972: * Do before initializing fields, as the hole filling process 4973: * can spill over into the fields. 4974: */ 4975: size_t offset = 0; 4976: for (size_t i = 0; i < sd->fields.dim; i++) 4977: { 4978: Dsymbol *s = sd->fields.tdata()[i]; 4979: VarDeclaration *v = s->isVarDeclaration(); 4980: assert(v); 4981: 4982: e = el_combine(e, fillHole(stmp, &offset, v->offset, sd->structsize)); 4983: size_t vend = v->offset + v->type->size();
warning C4244: 'initializing' : conversion from 'd_uns64' to 'size_t', possible loss of data
4984: if (offset < vend) 4985: offset = vend; 4986: } 4987: e = el_combine(e, fillHole(stmp, &offset, sd->structsize, sd->structsize)); 4988: } 4989: 4990: if (elements) 4991: { 4992: dim = elements->dim; 4993: assert(dim <= sd->fields.dim); 4994: for (size_t i = 0; i < dim; i++) 4995: { Expression *el = elements->tdata()[i]; 4996: if (!el) 4997: continue; 4998: 4999: Dsymbol *s = sd->fields.tdata()[i]; 5000: VarDeclaration *v = s->isVarDeclaration(); 5001: assert(v); 5002: assert(!v->isThisDeclaration()); 5003: 5004: elem *e1; 5005: if (tybasic(stmp->Stype->Tty) == TYnptr) 5006: { e1 = el_var(stmp); 5007: e1->EV.sp.Voffset = soffset; 5008: } 5009: else 5010: { e1 = el_ptr(stmp); 5011: if (soffset) 5012: e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); 5013: } 5014: e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset)); 5015: elem *ec = e1; // pointer to destination 5016: 5017: elem *ep = el->toElem(irs); 5018: 5019: Type *t1b = v->type->toBasetype(); 5020: Type *t2b = el->type->toBasetype(); 5021: if (t1b->ty == Tsarray) 5022: { 5023: if (t2b->implicitConvTo(t1b)) 5024: { 5025: #if DMDV2 5026: // Determine if postblit is needed 5027: int postblit = 0; 5028: if (needsPostblit(t1b)) 5029: postblit = 1; 5030: 5031: if (postblit) 5032: { 5033: /* Generate: 5034: * _d_arrayctor(ti, From: ep, To: e1) 5035: */ 5036: Expression *ti = t1b->nextOf()->toBasetype()->getTypeInfo(NULL); 5037: elem *esize = el_long(TYsize_t, ((TypeSArray *)t1b)->dim->toInteger()); 5038: e1 = el_pair(TYdarray, esize, e1); 5039: ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el->type, ep)); 5040: ep = el_params(e1, ep, ti->toElem(irs), NULL); 5041: int rtl = RTLSYM_ARRAYCTOR; 5042: e1 = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep); 5043: } 5044: else 5045: #endif 5046: { 5047: elem *esize = el_long(TYsize_t, t1b->size()); 5048: ep = array_toPtr(el->type, ep); 5049: e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); 5050: } 5051: } 5052: else 5053: { 5054: elem *edim = el_long(TYsize_t, t1b->size() / t2b->size()); 5055: e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); 5056: } 5057: } 5058: else 5059: { 5060: tym_t ty = v->type->totym(); 5061: e1 = el_una(OPind, ty, e1); 5062: if (tybasic(ty) == TYstruct) 5063: e1->ET = v->type->toCtype(); 5064: e1 = el_bin(OPeq, ty, e1, ep); 5065: if (tybasic(ty) == TYstruct) 5066: { e1->Eoper = OPstreq; 5067: e1->ET = v->type->toCtype(); 5068: } 5069: #if DMDV2 5070: /* Call postblit() on e1 5071: */ 5072: StructDeclaration *sd = needsPostblit(v->type); 5073: if (sd) 5074: { FuncDeclaration *fd = sd->postblit; 5075: ec = el_copytree(ec); 5076: ec = callfunc(loc, irs, 1, Type::tvoid, ec, sd->type->pointerTo(), fd, fd->type, NULL, NULL); 5077: e1 = el_bin(OPcomma, ec->Ety, e1, ec); 5078: } 5079: #endif 5080: } 5081: e = el_combine(e, e1); 5082: } 5083: } 5084: 5085: #if DMDV2 5086: if (sd->isnested) 5087: { // Initialize the hidden 'this' pointer 5088: assert(sd->fields.dim); 5089: Dsymbol *s = sd->fields.tdata()[sd->fields.dim - 1]; 5090: ThisDeclaration *v = s->isThisDeclaration(); 5091: assert(v); 5092: 5093: elem *e1; 5094: if (tybasic(stmp->Stype->Tty) == TYnptr) 5095: { e1 = el_var(stmp); 5096: e1->EV.sp.Voffset = soffset; 5097: } 5098: else 5099: { e1 = el_ptr(stmp); 5100: if (soffset) 5101: e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); 5102: } 5103: e1 = setEthis(loc, irs, e1, sd); 5104: 5105: e = el_combine(e, e1); 5106: } 5107: #endif 5108: 5109: elem *ev = el_var(stmp); 5110: ev->ET = sd->type->toCtype(); 5111: e = el_combine(e, ev); 5112: el_setLoc(e,loc); 5113: return e; 5114: } 5115: 5116: /******************************************** 5117: * Add destructors 5118: */ 5119: 5120: elem *appendDtors(IRState *irs, elem *er, size_t starti, size_t endi) 5121: { 5122: //printf("appendDtors(%d .. %d)\n", starti, endi); 5123: 5124: /* Code gen can be improved by determining if no exceptions can be thrown 5125: * between the OPdctor and OPddtor, and eliminating the OPdctor and OPddtor. 5126: */ 5127: 5128: /* Build edtors, an expression that calls destructors on all the variables 5129: * going out of the scope starti..endi 5130: */ 5131: elem *edtors = NULL; 5132: for (size_t i = starti; i != endi; ++i) 5133: { 5134: VarDeclaration *vd = irs->varsInScope->tdata()[i]; 5135: if (vd) 5136: { 5137: //printf("appending dtor\n"); 5138: irs->varsInScope->tdata()[i] = NULL; 5139: elem *ed = vd->edtor->toElem(irs); 5140: ed = el_ddtor(ed, vd); 5141: edtors = el_combine(ed, edtors); // execute in reverse order 5142: } 5143: } 5144: 5145: if (edtors) 5146: { 5147: /* Append edtors to er, while preserving the value of er 5148: */ 5149: if (tybasic(er->Ety) == TYvoid) 5150: { /* No value to preserve, so simply append 5151: */ 5152: er = el_combine(er, edtors); 5153: } 5154: else 5155: { 5156: elem **pe; 5157: for (pe = &er; (*pe)->Eoper == OPcomma; pe = &(*pe)->E2) 5158: ; 5159: elem *erx = *pe; 5160: 5161: if (erx->Eoper == OPconst || erx->Eoper == OPrelconst) 5162: { 5163: *pe = el_combine(edtors, erx); 5164: } 5165: else if (tybasic(erx->Ety) == TYstruct || tybasic(erx->Ety) == TYarray) 5166: { 5167: /* Expensive to copy, to take a pointer to it instead 5168: */ 5169: elem *ep = el_una(OPaddr, TYnptr, erx); 5170: elem *e = el_same(&ep); 5171: ep = el_combine(ep, edtors); 5172: ep = el_combine(ep, e); 5173: e = el_una(OPind, erx->Ety, ep); 5174: e->ET = erx->ET; 5175: *pe = e; 5176: } 5177: else 5178: { 5179: elem *e = el_same(&erx); 5180: erx = el_combine(erx, edtors); 5181: *pe = el_combine(erx, e); 5182: } 5183: } 5184: } 5185: return er; 5186: } 5187: 5188: