comparison dmd/codegen/Util.d @ 174:af724d3510d7

lot os toCBuffer methods implemented moved shared Type.* stuff into Global
author korDen
date Sun, 10 Oct 2010 03:47:23 +0400
parents 31c086f76669
children 1475fd394c9e
comparison
equal deleted inserted replaced
173:d237b38b5858 174:af724d3510d7
76 76
77 77
78 /************************************ 78 /************************************
79 * Call a function. 79 * Call a function.
80 */ 80 */
81 elem* callfunc(Loc loc, 81 elem* callfunc(Loc loc,
82 IRState* irs, 82 IRState* irs,
83 int directcall, // 1: don't do virtual call 83 int directcall, // 1: don't do virtual call
84 Type tret, // return type 84 Type tret, // return type
85 elem *ec, // evaluates to function address 85 elem *ec, // evaluates to function address
86 Type ectype, // original type of ec 86 Type ectype, // original type of ec
122 ethis = el_una(OPER.OP64_32, TYM.TYnptr, ethis); // get this 122 ethis = el_una(OPER.OP64_32, TYM.TYnptr, ethis); // get this
123 ec = array_toPtr(t, ec); // get funcptr 123 ec = array_toPtr(t, ec); // get funcptr
124 ec = el_una(OPER.OPind, tf.totym(), ec); 124 ec = el_una(OPER.OPind, tf.totym(), ec);
125 } 125 }
126 else 126 else
127 { 127 {
128 assert(t.ty == TY.Tfunction); 128 assert(t.ty == TY.Tfunction);
129 tf = cast(TypeFunction)t; 129 tf = cast(TypeFunction)t;
130 } 130 }
131 131
132 retmethod = tf.retStyle(); 132 retmethod = tf.retStyle();
139 { 139 {
140 // j=1 if _arguments[] is first argument 140 // j=1 if _arguments[] is first argument
141 int j = (tf.linkage == LINK.LINKd && tf.varargs == 1); 141 int j = (tf.linkage == LINK.LINKd && tf.varargs == 1);
142 142
143 foreach (size_t i, Expression arg; arguments) 143 foreach (size_t i, Expression arg; arguments)
144 { 144 {
145 elem* ea; 145 elem* ea;
146 146
147 //writef("\targ[%d]: %s\n", i, arg.toChars()); 147 //writef("\targ[%d]: %s\n", i, arg.toChars());
148 148
149 size_t nparams = Parameter.dim(tf.parameters); 149 size_t nparams = Parameter.dim(tf.parameters);
176 } 176 }
177 177
178 if (retmethod == RET.RETstack) 178 if (retmethod == RET.RETstack)
179 { 179 {
180 if (!ehidden) 180 if (!ehidden)
181 { 181 {
182 // Don't have one, so create one 182 // Don't have one, so create one
183 type* tt; 183 type* tt;
184 184
185 Type tret2 = tf.next; // in dmd tret is shadowed here, so -> tret2 185 Type tret2 = tf.next; // in dmd tret is shadowed here, so -> tret2
186 if (tret2.toBasetype().ty == Tstruct || 186 if (tret2.toBasetype().ty == Tstruct ||
334 /************************************** 334 /**************************************
335 * Fake a struct symbol. 335 * Fake a struct symbol.
336 */ 336 */
337 337
338 Classsym* fake_classsym(Identifier id) 338 Classsym* fake_classsym(Identifier id)
339 { 339 {
340 TYPE* t; 340 TYPE* t;
341 Classsym* scc; 341 Classsym* scc;
342 342
343 scc = cast(Classsym*)symbol_calloc(toStringz(id.toChars())); 343 scc = cast(Classsym*)symbol_calloc(toStringz(id.toChars()));
344 scc.Sclass = SC.SCstruct; 344 scc.Sclass = SC.SCstruct;
376 /* These two are compiler generated functions for the in and out contracts, 376 /* These two are compiler generated functions for the in and out contracts,
377 * and are called from an overriding function, not just the one they're 377 * and are called from an overriding function, not just the one they're
378 * nested inside, so this hack is so they'll pass 378 * nested inside, so this hack is so they'll pass
379 */ 379 */
380 fd.ident == Id.require || fd.ident == Id.ensure) 380 fd.ident == Id.require || fd.ident == Id.ensure)
381 { 381 {
382 /* Going down one nesting level, i.e. we're calling 382 /* Going down one nesting level, i.e. we're calling
383 * a nested function from its enclosing function. 383 * a nested function from its enclosing function.
384 */ 384 */
385 ///version (DMDV2) { 385 ///version (DMDV2) {
386 if (irs.sclosure) 386 if (irs.sclosure)
387 ethis = el_var(irs.sclosure); 387 ethis = el_var(irs.sclosure);
388 else 388 else
389 ///} 389 ///}
390 if (irs.sthis) 390 if (irs.sthis)
391 { 391 {
392 // We have a 'this' pointer for the current function 392 // We have a 'this' pointer for the current function
393 ethis = el_var(irs.sthis); 393 ethis = el_var(irs.sthis);
394 394
395 /* If no variables in the current function's frame are 395 /* If no variables in the current function's frame are
396 * referenced by nested functions, then we can 'skip' 396 * referenced by nested functions, then we can 'skip'
401 bool cond = (thisfd.closureVars.dim != 0); 401 bool cond = (thisfd.closureVars.dim != 0);
402 } else { 402 } else {
403 bool cond = thisfd.nestedFrameRef; 403 bool cond = thisfd.nestedFrameRef;
404 } 404 }
405 if (cond) 405 if (cond)
406 { 406 {
407 /* Local variables are referenced, can't skip. 407 /* Local variables are referenced, can't skip.
408 * Address of 'this' gives the 'this' for the nested 408 * Address of 'this' gives the 'this' for the nested
409 * function 409 * function
410 */ 410 */
411 ethis = el_una(OPER.OPaddr, TYM.TYnptr, ethis); 411 ethis = el_una(OPER.OPaddr, TYM.TYnptr, ethis);
412 } 412 }
413 } 413 }
414 else 414 else
415 { 415 {
416 /* No 'this' pointer for current function, 416 /* No 'this' pointer for current function,
417 * use null if no references to the current function's frame 417 * use null if no references to the current function's frame
418 */ 418 */
419 ethis = el_long(TYM.TYnptr, 0); 419 ethis = el_long(TYM.TYnptr, 0);
420 version (DMDV2) { 420 version (DMDV2) {
421 bool cond = (thisfd.closureVars.dim != 0); 421 bool cond = (thisfd.closureVars.dim != 0);
422 } else { 422 } else {
423 bool cond = thisfd.nestedFrameRef; 423 bool cond = thisfd.nestedFrameRef;
424 } 424 }
425 if (cond) 425 if (cond)
426 { 426 {
427 /* OPframeptr is an operator that gets the frame pointer 427 /* OPframeptr is an operator that gets the frame pointer
428 * for the current function, i.e. for the x86 it gets 428 * for the current function, i.e. for the x86 it gets
429 * the value of EBP 429 * the value of EBP
430 */ 430 */
431 ethis.Eoper = OPER.OPframeptr; 431 ethis.Eoper = OPER.OPframeptr;
432 } 432 }
433 } 433 }
434 434
435 //if (fdparent != thisfd) ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, 0x18)); 435 //if (fdparent != thisfd) ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, 0x18));
436 } 436 }
437 else 437 else
438 { 438 {
439 if (!irs.sthis) // if no frame pointer for this function 439 if (!irs.sthis) // if no frame pointer for this function
444 else 444 else
445 { 445 {
446 ethis = el_var(irs.sthis); 446 ethis = el_var(irs.sthis);
447 Dsymbol s = thisfd; 447 Dsymbol s = thisfd;
448 while (fd != s) 448 while (fd != s)
449 { 449 {
450 /* Go up a nesting level, i.e. we need to find the 'this' 450 /* Go up a nesting level, i.e. we need to find the 'this'
451 * of an enclosing function. 451 * of an enclosing function.
452 * Our 'enclosing function' may also be an inner class. 452 * Our 'enclosing function' may also be an inner class.
453 */ 453 */
454 454
455 //printf("\ts = '%s'\n", s.toChars()); 455 //printf("\ts = '%s'\n", s.toChars());
456 thisfd = s.isFuncDeclaration(); 456 thisfd = s.isFuncDeclaration();
457 if (thisfd) 457 if (thisfd)
458 { 458 {
459 /* Enclosing function is a function. 459 /* Enclosing function is a function.
460 */ 460 */
461 if (fdparent == s.toParent2()) 461 if (fdparent == s.toParent2())
462 break; 462 break;
463 463
482 // Error should have been caught by front end 482 // Error should have been caught by front end
483 assert(0); 483 assert(0);
484 } 484 }
485 } 485 }
486 else 486 else
487 { 487 {
488 /* Enclosed by an aggregate. That means the current 488 /* Enclosed by an aggregate. That means the current
489 * function must be a member function of that aggregate. 489 * function must be a member function of that aggregate.
490 */ 490 */
491 ClassDeclaration cd; 491 ClassDeclaration cd;
492 StructDeclaration sd; 492 StructDeclaration sd;
525 * of frames. 525 * of frames.
526 */ 526 */
527 version (DMDV2) { 527 version (DMDV2) {
528 bool cond = (fdd.closureVars.dim != 0); 528 bool cond = (fdd.closureVars.dim != 0);
529 } else { 529 } else {
530 bool cond = fdd.nestedFrameRef; 530 bool cond = fdd.nestedFrameRef;
531 } 531 }
532 if (cond) { 532 if (cond) {
533 ethis = el_una(OPER.OPind, TYM.TYnptr, ethis); 533 ethis = el_una(OPER.OPind, TYM.TYnptr, ethis);
534 } 534 }
535 break; 535 break;
656 //extern (C++) extern int intrinsic_op(char* name); 656 //extern (C++) extern int intrinsic_op(char* name);
657 657
658 OPER intrinsic_oper(const(char)* name) 658 OPER intrinsic_oper(const(char)* name)
659 { 659 {
660 version(DMDV1) 660 version(DMDV1)
661 static const(char) *namearray[] = 661 enum const(char) *namearray[] =
662 [ 662 [
663 "4math3cosFeZe", 663 "4math3cosFeZe",
664 "4math3sinFeZe", 664 "4math3sinFeZe",
665 "4math4fabsFeZe", 665 "4math4fabsFeZe",
666 "4math4rintFeZe", 666 "4math4rintFeZe",
685 "9intrinsic5bswapFkZk", 685 "9intrinsic5bswapFkZk",
686 "9intrinsic5outplFkkZk", 686 "9intrinsic5outplFkkZk",
687 "9intrinsic5outpwFktZt", 687 "9intrinsic5outpwFktZt",
688 ]; 688 ];
689 else 689 else
690 static const(char) *namearray[] = 690 enum const(char) *namearray[] =
691 [ 691 [
692 /* The names are mangled differently because of the pure and 692 /* The names are mangled differently because of the pure and
693 * nothrow attributes. 693 * nothrow attributes.
694 */ 694 */
695 "4math3cosFNaNbNfeZe", 695 "4math3cosFNaNbNfeZe",
717 "9intrinsic5bswapFNaNbkZk", 717 "9intrinsic5bswapFNaNbkZk",
718 "9intrinsic5outplFNbkkZk", 718 "9intrinsic5outplFNbkkZk",
719 "9intrinsic5outpwFNbktZt", 719 "9intrinsic5outpwFNbktZt",
720 ]; 720 ];
721 721
722 static const OPER ioptab[] = 722 enum OPER ioptab[] =
723 [ 723 [
724 OPcos, 724 OPcos,
725 OPsin, 725 OPsin,
726 OPabs, 726 OPabs,
727 OPrint, 727 OPrint,
746 OPbswap, 746 OPbswap,
747 OPoutp, 747 OPoutp,
748 OPoutp, 748 OPoutp,
749 ]; 749 ];
750 750
751 debug 751 debug
752 { 752 {
753 assert(namearray.length == ioptab.length); 753 assert(namearray.length == ioptab.length);
754 // assume sorted namearray 754 // assume sorted namearray
755 for (int i = 0; i < namearray.length - 1; i++) 755 for (int i = 0; i < namearray.length - 1; i++)
756 { 756 {
843 } 843 }
844 } 844 }
845 else if ((td = s.isTupleDeclaration()) !is null) 845 else if ((td = s.isTupleDeclaration()) !is null)
846 { 846 {
847 for (size_t i = 0; i < td.objects.dim; i++) 847 for (size_t i = 0; i < td.objects.dim; i++)
848 { 848 {
849 auto o = td.objects[i]; 849 auto o = td.objects[i];
850 ///if (o.dyncast() == DYNCAST_EXPRESSION) 850 ///if (o.dyncast() == DYNCAST_EXPRESSION)
851 if (auto eo = cast(Expression)o) 851 if (auto eo = cast(Expression)o)
852 { 852 {
853 if (eo.op == TOK.TOKdsymbol) 853 if (eo.op == TOK.TOKdsymbol)
854 { 854 {
855 auto se = cast(DsymbolExp)eo; 855 auto se = cast(DsymbolExp)eo;
856 e = el_combine(e, Dsymbol_toElem(se.s, irs)); 856 e = el_combine(e, Dsymbol_toElem(se.s, irs));
857 } 857 }
858 } 858 }
859 } 859 }
883 { 883 {
884 //printf("resolveLengthVar()\n"); 884 //printf("resolveLengthVar()\n");
885 elem* einit = null; 885 elem* einit = null;
886 886
887 if (lengthVar && !(lengthVar.storage_class & STC.STCconst)) 887 if (lengthVar && !(lengthVar.storage_class & STC.STCconst))
888 { 888 {
889 elem* elength; 889 elem* elength;
890 Symbol* slength; 890 Symbol* slength;
891 891
892 if (t1.ty == TY.Tsarray) 892 if (t1.ty == TY.Tsarray)
893 { 893 {
894 TypeSArray tsa = cast(TypeSArray)t1; 894 TypeSArray tsa = cast(TypeSArray)t1;
895 long length = tsa.dim.toInteger(); 895 long length = tsa.dim.toInteger();
896 896
897 elength = el_long(TYM.TYuint, length); 897 elength = el_long(TYM.TYuint, length);
898 goto L3; 898 goto L3;
921 * evalue value to write 921 * evalue value to write
922 * edim number of times to write evalue to eptr[] 922 * edim number of times to write evalue to eptr[]
923 * tb type of evalue 923 * tb type of evalue
924 */ 924 */
925 elem* setArray(elem* eptr, elem* edim, Type tb, elem* evalue, IRState* irs, int op) 925 elem* setArray(elem* eptr, elem* edim, Type tb, elem* evalue, IRState* irs, int op)
926 { 926 {
927 int r; 927 int r;
928 elem* e; 928 elem* e;
929 int sz = cast(int)tb.size(); 929 int sz = cast(int)tb.size();
930 930
931 if (tb.ty == TY.Tfloat80 || tb.ty == TY.Timaginary80) 931 if (tb.ty == TY.Tfloat80 || tb.ty == TY.Timaginary80)
949 */ 949 */
950 if (op != TOK.TOKblit) 950 if (op != TOK.TOKblit)
951 { 951 {
952 StructDeclaration sd = needsPostblit(tb); 952 StructDeclaration sd = needsPostblit(tb);
953 if (sd) 953 if (sd)
954 { 954 {
955 /* Need to do postblit. 955 /* Need to do postblit.
956 * void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti); 956 * void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti);
957 */ 957 */
958 r = (op == TOK.TOKconstruct) ? RTLSYM.RTLSYM_ARRAYSETCTOR : RTLSYM.RTLSYM_ARRAYSETASSIGN; 958 r = (op == TOK.TOKconstruct) ? RTLSYM.RTLSYM_ARRAYSETCTOR : RTLSYM.RTLSYM_ARRAYSETASSIGN;
959 evalue = el_una(OPER.OPaddr, TYM.TYnptr, evalue); 959 evalue = el_una(OPER.OPaddr, TYM.TYnptr, evalue);
1017 Dsymbol cdp = ad.toParent2(); // class/func we're nested in 1017 Dsymbol cdp = ad.toParent2(); // class/func we're nested in
1018 1018
1019 //printf("setEthis(ad = %s, cdp = %s, thisfd = %s)\n", ad.toChars(), cdp.toChars(), thisfd.toChars()); 1019 //printf("setEthis(ad = %s, cdp = %s, thisfd = %s)\n", ad.toChars(), cdp.toChars(), thisfd.toChars());
1020 1020
1021 if (cdp is thisfd) 1021 if (cdp is thisfd)
1022 { 1022 {
1023 /* Class we're new'ing is a local class in this function: 1023 /* Class we're new'ing is a local class in this function:
1024 * void thisfd() { class ad { } } 1024 * void thisfd() { class ad { } }
1025 */ 1025 */
1026 if (irs.sclosure) 1026 if (irs.sclosure)
1027 ethis = el_var(irs.sclosure); 1027 ethis = el_var(irs.sclosure);
1055 cdp == thisfd.toParent2() || ( 1055 cdp == thisfd.toParent2() || (
1056 cdp.isClassDeclaration() && cdp.isClassDeclaration().isBaseOf(thisfd.toParent2().isClassDeclaration(), &offset) 1056 cdp.isClassDeclaration() && cdp.isClassDeclaration().isBaseOf(thisfd.toParent2().isClassDeclaration(), &offset)
1057 ) 1057 )
1058 ) 1058 )
1059 ) 1059 )
1060 { 1060 {
1061 /* Class we're new'ing is at the same level as thisfd 1061 /* Class we're new'ing is at the same level as thisfd
1062 */ 1062 */
1063 assert(offset == 0); // BUG: should handle this case 1063 assert(offset == 0); // BUG: should handle this case
1064 ethis = el_var(irs.sthis); 1064 ethis = el_var(irs.sthis);
1065 } 1065 }
1086 1086
1087 while (t.ty == TY.Tsarray) 1087 while (t.ty == TY.Tsarray)
1088 t = t.nextOf().toBasetype(); 1088 t = t.nextOf().toBasetype();
1089 1089
1090 if (t.ty == TY.Tstruct) 1090 if (t.ty == TY.Tstruct)
1091 { 1091 {
1092 StructDeclaration sd = (cast(TypeStruct)t).sym; 1092 StructDeclaration sd = (cast(TypeStruct)t).sym;
1093 if (sd.postblit) 1093 if (sd.postblit)
1094 return sd; 1094 return sd;
1095 } 1095 }
1096 1096
1130 size_t len = tysize[tybasic(e.Ety)]; 1130 size_t len = tysize[tybasic(e.Ety)];
1131 elem* es = el_calloc(); 1131 elem* es = el_calloc();
1132 es.Eoper = OPER.OPstring; 1132 es.Eoper = OPER.OPstring;
1133 1133
1134 // Match MEM_PH_FREE for OPstring in ztc\el.c 1134 // Match MEM_PH_FREE for OPstring in ztc\el.c
1135 es.EV.ss.Vstring = cast(char*)malloc(len); /// ! 1135 es.EV.ss.Vstring = cast(char*)GC.malloc(len); /// !
1136 memcpy(es.EV.ss.Vstring, &e.EV, len); 1136 memcpy(es.EV.ss.Vstring, &e.EV, len);
1137 1137
1138 es.EV.ss.Vstrlen = len; 1138 es.EV.ss.Vstrlen = len;
1139 es.Ety = TYM.TYnptr; 1139 es.Ety = TYM.TYnptr;
1140 e = es; 1140 e = es;
1274 return null; 1274 return null;
1275 } 1275 }
1276 1276
1277 s = label.statement; 1277 s = label.statement;
1278 if (!s.lblock) 1278 if (!s.lblock)
1279 { 1279 {
1280 s.lblock = block_calloc(blx); 1280 s.lblock = block_calloc(blx);
1281 if (s.isReturnLabel) 1281 if (s.isReturnLabel)
1282 s.lblock.Btry = null; 1282 s.lblock.Btry = null;
1283 } 1283 }
1284 return s.lblock; 1284 return s.lblock;
1291 * tries to use aligned int stores whereever possible. 1291 * tries to use aligned int stores whereever possible.
1292 * Update *poffset to end of initialized hole; *poffset will be >= offset2. 1292 * Update *poffset to end of initialized hole; *poffset will be >= offset2.
1293 */ 1293 */
1294 1294
1295 elem* fillHole(Symbol* stmp, size_t* poffset, size_t offset2, size_t maxoff) 1295 elem* fillHole(Symbol* stmp, size_t* poffset, size_t offset2, size_t maxoff)
1296 { 1296 {
1297 elem* e = null; 1297 elem* e = null;
1298 int basealign = 1; 1298 int basealign = 1;
1299 1299
1300 while (*poffset < offset2) 1300 while (*poffset < offset2)
1301 { 1301 {
1302 tym_t ty; 1302 tym_t ty;
1303 elem* e1; 1303 elem* e1;
1304 1304
1305 if (tybasic(stmp.Stype.Tty) == TYnptr) 1305 if (tybasic(stmp.Stype.Tty) == TYnptr)
1306 e1 = el_var(stmp); 1306 e1 = el_var(stmp);
1307 else 1307 else
1308 e1 = el_ptr(stmp); 1308 e1 = el_ptr(stmp);
1309 1309
1310 if (basealign) 1310 if (basealign)
1311 *poffset &= ~3; 1311 *poffset &= ~3;
1312 1312
1313 basealign = 1; 1313 basealign = 1;
1314 size_t sz = maxoff - *poffset; 1314 size_t sz = maxoff - *poffset;
1315 switch (sz) 1315 switch (sz)
1316 { 1316 {
1317 case 1: ty = TYchar; break; 1317 case 1: ty = TYchar; break;
1318 case 2: ty = TYshort; break; 1318 case 2: ty = TYshort; break;
1319 case 3: 1319 case 3:
1320 ty = TYshort; 1320 ty = TYshort;
1321 basealign = 0; 1321 basealign = 0;