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 }