Mercurial > projects > ldc
comparison dmd2/cast.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 356e65836fb5 |
children | 54b3c1394d62 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Copyright (c) 1999-2008 by Digital Mars | 2 // Copyright (c) 1999-2009 by Digital Mars |
3 // All Rights Reserved | 3 // All Rights Reserved |
4 // written by Walter Bright | 4 // written by Walter Bright |
5 // http://www.digitalmars.com | 5 // http://www.digitalmars.com |
6 // License for redistribution is by either the Artistic License | 6 // License for redistribution is by either the Artistic License |
7 // in artistic.txt, or the GNU General Public License in gnu.txt. | 7 // in artistic.txt, or the GNU General Public License in gnu.txt. |
8 // See the included readme.txt for details. | 8 // See the included readme.txt for details. |
9 | 9 |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <assert.h> | 11 #include <assert.h> |
12 | 12 |
13 #if _WIN32 || IN_GCC || IN_LLVM | 13 #include "rmem.h" |
14 #include "mem.h" | |
15 #else | |
16 #include "../root/mem.h" | |
17 #endif | |
18 | 14 |
19 #include "expression.h" | 15 #include "expression.h" |
20 #include "mtype.h" | 16 #include "mtype.h" |
21 #include "utf.h" | 17 #include "utf.h" |
22 #include "declaration.h" | 18 #include "declaration.h" |
59 */ | 55 */ |
60 ; | 56 ; |
61 } | 57 } |
62 else | 58 else |
63 { | 59 { |
64 warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data", | 60 warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data", |
65 loc.toChars(), toChars(), type->toChars(), t->toChars()); | 61 toChars(), type->toChars(), t->toChars()); |
66 } | 62 } |
67 } | 63 } |
68 #if DMDV2 | 64 #if DMDV2 |
69 if (match == MATCHconst && t == type->constOf()) | 65 if (match == MATCHconst && t == type->constOf()) |
70 { | 66 { |
107 error("cannot implicitly convert expression (%s) of type %s to %s", | 103 error("cannot implicitly convert expression (%s) of type %s to %s", |
108 toChars(), type->toChars(), t->toChars()); | 104 toChars(), type->toChars(), t->toChars()); |
109 return castTo(sc, t); | 105 return castTo(sc, t); |
110 } | 106 } |
111 | 107 |
108 Expression *StringExp::implicitCastTo(Scope *sc, Type *t) | |
109 { | |
110 //printf("StringExp::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); | |
111 unsigned char committed = this->committed; | |
112 Expression *e = Expression::implicitCastTo(sc, t); | |
113 if (e->op == TOKstring) | |
114 { | |
115 // Retain polysemous nature if it started out that way | |
116 ((StringExp *)e)->committed = committed; | |
117 } | |
118 return e; | |
119 } | |
120 | |
112 /******************************************* | 121 /******************************************* |
113 * Return !=0 if we can implicitly convert this to type t. | 122 * Return !=0 if we can implicitly convert this to type t. |
114 * Don't do the actual cast. | 123 * Don't do the actual cast. |
115 */ | 124 */ |
116 | 125 |
231 goto Lno; | 240 goto Lno; |
232 goto Lyes; | 241 goto Lyes; |
233 | 242 |
234 case Tchar: | 243 case Tchar: |
235 case Tuns8: | 244 case Tuns8: |
236 //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value); | 245 //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value); |
237 if ((unsigned char)value != value) | 246 if ((unsigned char)value != value) |
238 goto Lno; | 247 goto Lno; |
239 goto Lyes; | 248 goto Lyes; |
240 | 249 |
241 case Tint16: | 250 case Tint16: |
438 { | 447 { |
439 case Tsarray: | 448 case Tsarray: |
440 if (type->ty == Tsarray) | 449 if (type->ty == Tsarray) |
441 { | 450 { |
442 if (((TypeSArray *)type)->dim->toInteger() != | 451 if (((TypeSArray *)type)->dim->toInteger() != |
452 ((TypeSArray *)t)->dim->toInteger()) | |
453 return MATCHnomatch; | |
454 TY tynto = t->nextOf()->ty; | |
455 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) | |
456 return MATCHexact; | |
457 } | |
458 else if (type->ty == Tarray) | |
459 { | |
460 if (length() > | |
443 ((TypeSArray *)t)->dim->toInteger()) | 461 ((TypeSArray *)t)->dim->toInteger()) |
444 return MATCHnomatch; | 462 return MATCHnomatch; |
445 TY tynto = t->nextOf()->ty; | 463 TY tynto = t->nextOf()->ty; |
446 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) | 464 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar) |
447 return MATCHexact; | 465 return MATCHexact; |
561 FuncDeclaration *f = NULL; | 579 FuncDeclaration *f = NULL; |
562 for (int i = 0; i < eo->vars->a.dim; i++) | 580 for (int i = 0; i < eo->vars->a.dim; i++) |
563 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; | 581 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; |
564 FuncDeclaration *f2 = s->isFuncDeclaration(); | 582 FuncDeclaration *f2 = s->isFuncDeclaration(); |
565 assert(f2); | 583 assert(f2); |
566 if (f2->overloadExactMatch(t->nextOf())) | 584 if (f2->overloadExactMatch(t->nextOf(), m)) |
567 { if (f) | 585 { if (f) |
568 /* Error if match in more than one overload set, | 586 /* Error if match in more than one overload set, |
569 * even if one is a 'better' match than the other. | 587 * even if one is a 'better' match than the other. |
570 */ | 588 */ |
571 ScopeDsymbol::multiplyDefined(loc, f, f2); | 589 ScopeDsymbol::multiplyDefined(loc, f, f2); |
578 | 596 |
579 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction && | 597 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction && |
580 t->ty == Tpointer && t->nextOf()->ty == Tfunction && | 598 t->ty == Tpointer && t->nextOf()->ty == Tfunction && |
581 e1->op == TOKvar) | 599 e1->op == TOKvar) |
582 { | 600 { |
583 // LDC: it happens for us | |
584 #if !IN_LLVM | |
585 /* I don't think this can ever happen - | 601 /* I don't think this can ever happen - |
586 * it should have been | 602 * it should have been |
587 * converted to a SymOffExp. | 603 * converted to a SymOffExp. |
588 */ | 604 */ |
589 assert(0); | 605 assert(0); |
590 #endif | |
591 VarExp *ve = (VarExp *)e1; | 606 VarExp *ve = (VarExp *)e1; |
592 FuncDeclaration *f = ve->var->isFuncDeclaration(); | 607 FuncDeclaration *f = ve->var->isFuncDeclaration(); |
593 if (f && f->overloadExactMatch(t->nextOf())) | 608 if (f && f->overloadExactMatch(t->nextOf(), m)) |
594 result = MATCHexact; | 609 result = MATCHexact; |
595 } | 610 } |
596 } | 611 } |
597 //printf("\tresult = %d\n", result); | 612 //printf("\tresult = %d\n", result); |
598 return result; | 613 return result; |
618 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction && | 633 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction && |
619 (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction) | 634 (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction) |
620 { | 635 { |
621 f = var->isFuncDeclaration(); | 636 f = var->isFuncDeclaration(); |
622 if (f) | 637 if (f) |
623 { f = f->overloadExactMatch(t->nextOf()); | 638 { f = f->overloadExactMatch(t->nextOf(), m); |
624 if (f) | 639 if (f) |
625 { if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) || | 640 { if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) || |
626 (t->ty == Tpointer && !(f->needThis() || f->isNested()))) | 641 (t->ty == Tpointer && !(f->needThis() || f->isNested()))) |
627 { | 642 { |
628 result = MATCHexact; | 643 result = MATCHexact; |
652 | 667 |
653 t = t->toBasetype(); | 668 t = t->toBasetype(); |
654 if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction && | 669 if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction && |
655 t->ty == Tdelegate && t->nextOf()->ty == Tfunction) | 670 t->ty == Tdelegate && t->nextOf()->ty == Tfunction) |
656 { | 671 { |
657 if (func && func->overloadExactMatch(t->nextOf())) | 672 if (func && func->overloadExactMatch(t->nextOf(), m)) |
658 result = MATCHexact; | 673 result = MATCHexact; |
659 } | 674 } |
660 } | 675 } |
661 return result; | 676 return result; |
662 } | 677 } |
714 return toDelegate(sc, tf->nextOf()); | 729 return toDelegate(sc, tf->nextOf()); |
715 } | 730 } |
716 #endif | 731 #endif |
717 else | 732 else |
718 { | 733 { |
734 if (typeb->ty == Tstruct) | |
735 { TypeStruct *ts = (TypeStruct *)typeb; | |
736 if (!(tb->ty == Tstruct && ts->sym == ((TypeStruct *)tb)->sym) && | |
737 ts->sym->aliasthis) | |
738 { /* Forward the cast to our alias this member, rewrite to: | |
739 * cast(to)e1.aliasthis | |
740 */ | |
741 Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident); | |
742 Expression *e = new CastExp(loc, e1, tb); | |
743 e = e->semantic(sc); | |
744 return e; | |
745 } | |
746 } | |
747 else if (typeb->ty == Tclass) | |
748 { TypeClass *ts = (TypeClass *)typeb; | |
749 if (tb->ty != Tclass && | |
750 ts->sym->aliasthis) | |
751 { /* Forward the cast to our alias this member, rewrite to: | |
752 * cast(to)e1.aliasthis | |
753 */ | |
754 Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident); | |
755 Expression *e = new CastExp(loc, e1, tb); | |
756 e = e->semantic(sc); | |
757 return e; | |
758 } | |
759 } | |
719 e = new CastExp(loc, e, tb); | 760 e = new CastExp(loc, e, tb); |
720 } | 761 } |
721 } | 762 } |
722 else | 763 else |
723 { | 764 { |
845 { | 886 { |
846 if (!copied) | 887 if (!copied) |
847 { se = (StringExp *)copy(); | 888 { se = (StringExp *)copy(); |
848 copied = 1; | 889 copied = 1; |
849 } | 890 } |
891 se->type = t; | |
892 return se; | |
893 } | |
894 | |
895 if (committed && tb->ty == Tsarray && typeb->ty == Tarray) | |
896 { | |
897 se = (StringExp *)copy(); | |
898 se->sz = tb->nextOf()->size(); | |
899 se->len = (len * sz) / se->sz; | |
900 se->committed = 1; | |
850 se->type = t; | 901 se->type = t; |
851 return se; | 902 return se; |
852 } | 903 } |
853 | 904 |
854 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) | 905 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) |
1046 FuncDeclaration *f = NULL; | 1097 FuncDeclaration *f = NULL; |
1047 for (int i = 0; i < eo->vars->a.dim; i++) | 1098 for (int i = 0; i < eo->vars->a.dim; i++) |
1048 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; | 1099 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; |
1049 FuncDeclaration *f2 = s->isFuncDeclaration(); | 1100 FuncDeclaration *f2 = s->isFuncDeclaration(); |
1050 assert(f2); | 1101 assert(f2); |
1051 if (f2->overloadExactMatch(t->nextOf())) | 1102 if (f2->overloadExactMatch(t->nextOf(), m)) |
1052 { if (f) | 1103 { if (f) |
1053 /* Error if match in more than one overload set, | 1104 /* Error if match in more than one overload set, |
1054 * even if one is a 'better' match than the other. | 1105 * even if one is a 'better' match than the other. |
1055 */ | 1106 */ |
1056 ScopeDsymbol::multiplyDefined(loc, f, f2); | 1107 ScopeDsymbol::multiplyDefined(loc, f, f2); |
1074 { | 1125 { |
1075 VarExp *ve = (VarExp *)e1; | 1126 VarExp *ve = (VarExp *)e1; |
1076 FuncDeclaration *f = ve->var->isFuncDeclaration(); | 1127 FuncDeclaration *f = ve->var->isFuncDeclaration(); |
1077 if (f) | 1128 if (f) |
1078 { | 1129 { |
1079 // LDC: not in ldc | |
1080 #if !IN_LLVM | |
1081 assert(0); // should be SymOffExp instead | 1130 assert(0); // should be SymOffExp instead |
1082 #endif | 1131 f = f->overloadExactMatch(tb->nextOf(), m); |
1083 f = f->overloadExactMatch(tb->nextOf()); | |
1084 if (f) | 1132 if (f) |
1085 { | 1133 { |
1086 e = new VarExp(loc, f); | 1134 e = new VarExp(loc, f); |
1087 e->type = f->type; | 1135 e->type = f->type; |
1088 e = new AddrExp(loc, e); | 1136 e = new AddrExp(loc, e); |
1142 e->type = t; | 1190 e->type = t; |
1143 return e; | 1191 return e; |
1144 } | 1192 } |
1145 if (tb->ty == Tpointer && typeb->ty == Tsarray) | 1193 if (tb->ty == Tpointer && typeb->ty == Tsarray) |
1146 { | 1194 { |
1147 e = (ArrayLiteralExp *)copy(); | 1195 Type *tp = typeb->nextOf()->pointerTo(); |
1148 e->type = typeb->nextOf()->pointerTo(); | 1196 if (!tp->equals(e->type)) |
1197 { e = (ArrayLiteralExp *)copy(); | |
1198 e->type = tp; | |
1199 } | |
1149 } | 1200 } |
1150 L1: | 1201 L1: |
1151 return e->Expression::castTo(sc, t); | 1202 return e->Expression::castTo(sc, t); |
1152 } | 1203 } |
1153 | 1204 |
1202 (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) | 1253 (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) |
1203 { | 1254 { |
1204 f = var->isFuncDeclaration(); | 1255 f = var->isFuncDeclaration(); |
1205 if (f) | 1256 if (f) |
1206 { | 1257 { |
1207 f = f->overloadExactMatch(tb->nextOf()); | 1258 f = f->overloadExactMatch(tb->nextOf(), m); |
1208 if (f) | 1259 if (f) |
1209 { | 1260 { |
1210 if (tb->ty == Tdelegate && f->needThis() && hasThis(sc)) | 1261 if (tb->ty == Tdelegate && f->needThis() && hasThis(sc)) |
1211 { | 1262 { |
1212 e = new DelegateExp(loc, new ThisExp(loc), f); | 1263 e = new DelegateExp(loc, new ThisExp(loc), f); |
1256 if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && | 1307 if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && |
1257 tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) | 1308 tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) |
1258 { | 1309 { |
1259 if (func) | 1310 if (func) |
1260 { | 1311 { |
1261 f = func->overloadExactMatch(tb->nextOf()); | 1312 f = func->overloadExactMatch(tb->nextOf(), m); |
1262 if (f) | 1313 if (f) |
1263 { int offset; | 1314 { int offset; |
1264 if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset) | 1315 if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset) |
1265 error("%s", msg); | 1316 error("%s", msg); |
1266 f->tookAddressOf++; | 1317 f->tookAddressOf++; |
1319 Type *t = Type::tptrdiff_t; | 1370 Type *t = Type::tptrdiff_t; |
1320 | 1371 |
1321 stride = t1b->nextOf()->size(loc); | 1372 stride = t1b->nextOf()->size(loc); |
1322 if (!t->equals(t2b)) | 1373 if (!t->equals(t2b)) |
1323 e2 = e2->castTo(sc, t); | 1374 e2 = e2->castTo(sc, t); |
1324 // LDC: llvm uses typesafe pointer arithmetic | |
1325 #if !IN_LLVM | |
1326 e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t)); | 1375 e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t)); |
1327 #endif | |
1328 e2->type = t; | 1376 e2->type = t; |
1329 type = e1->type; | 1377 type = e1->type; |
1330 } | 1378 } |
1331 else if (t2b->ty == Tpointer && t1b->isintegral()) | 1379 else if (t2b->ty == Tpointer && t1b->isintegral()) |
1332 { // Need to adjust operator by the stride | 1380 { // Need to adjust operator by the stride |
1337 stride = t2b->nextOf()->size(loc); | 1385 stride = t2b->nextOf()->size(loc); |
1338 if (!t->equals(t1b)) | 1386 if (!t->equals(t1b)) |
1339 e = e1->castTo(sc, t); | 1387 e = e1->castTo(sc, t); |
1340 else | 1388 else |
1341 e = e1; | 1389 e = e1; |
1342 #if !IN_LLVM | |
1343 e = new MulExp(loc, e, new IntegerExp(0, stride, t)); | 1390 e = new MulExp(loc, e, new IntegerExp(0, stride, t)); |
1344 #endif | |
1345 e->type = t; | 1391 e->type = t; |
1346 type = e2->type; | 1392 type = e2->type; |
1347 e1 = e2; | 1393 e1 = e2; |
1348 e2 = e; | 1394 e2 = e; |
1349 } | 1395 } |
1664 return this; | 1710 return this; |
1665 | 1711 |
1666 Lerror: | 1712 Lerror: |
1667 incompatibleTypes(); | 1713 incompatibleTypes(); |
1668 type = Type::terror; | 1714 type = Type::terror; |
1715 e1 = new ErrorExp(); | |
1716 e2 = new ErrorExp(); | |
1669 return this; | 1717 return this; |
1670 } | 1718 } |
1671 | 1719 |
1672 /*********************************** | 1720 /*********************************** |
1673 * Do integral promotions (convertchk). | 1721 * Do integral promotions (convertchk). |
1701 break; | 1749 break; |
1702 } | 1750 } |
1703 return e; | 1751 return e; |
1704 } | 1752 } |
1705 | 1753 |
1754 /*********************************** | |
1755 * See if both types are arrays that can be compared | |
1756 * for equality. Return !=0 if so. | |
1757 * If they are arrays, but incompatible, issue error. | |
1758 * This is to enable comparing things like an immutable | |
1759 * array with a mutable one. | |
1760 */ | |
1761 | |
1762 int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) | |
1763 { | |
1764 t1 = t1->toBasetype(); | |
1765 t2 = t2->toBasetype(); | |
1766 | |
1767 if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && | |
1768 (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) | |
1769 { | |
1770 if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && | |
1771 t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && | |
1772 (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) | |
1773 { | |
1774 error(loc, "array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); | |
1775 } | |
1776 return 1; | |
1777 } | |
1778 return 0; | |
1779 } |