Mercurial > projects > ddmd
comparison dmd/Type.d @ 98:5c859d5fbe27
and more
author | Trass3r |
---|---|
date | Tue, 31 Aug 2010 03:53:49 +0200 |
parents | ae5b11064a9a |
children | 12c0c84d13fd |
comparison
equal
deleted
inserted
replaced
96:acd69f84627e | 98:5c859d5fbe27 |
---|---|
395 } | 395 } |
396 | 396 |
397 DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType() | 397 DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType() |
398 | 398 |
399 /******************************* | 399 /******************************* |
400 * Covariant means that 'this' can substitute for 't'. | |
400 * Returns: | 401 * Returns: |
401 * 0 types are distinct | 402 * 0 types are distinct |
402 * 1 this is covariant with t | 403 * 1 this is covariant with t |
403 * 2 arguments match as far as overloading goes, | 404 * 2 arguments match as far as overloading goes, |
404 * but types are not covariant | 405 * but types are not covariant |
444 | 445 |
445 if (!arg1.type.equals(arg2.type)) | 446 if (!arg1.type.equals(arg2.type)) |
446 { | 447 { |
447 ///static if (false) { | 448 ///static if (false) { |
448 /// // turn on this for contravariant argument types, see bugzilla 3075 | 449 /// // turn on this for contravariant argument types, see bugzilla 3075 |
450 /// // BUG: cannot convert ref to const to ref to immutable | |
449 /// // We can add const, but not subtract it | 451 /// // We can add const, but not subtract it |
450 /// if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst) | 452 /// if (arg2.type.implicitConvTo(arg1.type) < MATCH.MATCHconst) |
451 ///} | 453 ///} |
452 goto Ldistinct; | 454 goto Ldistinct; |
453 } | 455 } |
647 } | 649 } |
648 | 650 |
649 basic[TY.Terror] = basic[TY.Tint32]; | 651 basic[TY.Terror] = basic[TY.Tint32]; |
650 | 652 |
651 tvoidptr = tvoid.pointerTo(); | 653 tvoidptr = tvoid.pointerTo(); |
654 tstring = tchar.invariantOf().arrayOf(); | |
652 | 655 |
653 if (global.params.isX86_64) { | 656 if (global.params.isX86_64) { |
654 PTRSIZE = 8; | 657 PTRSIZE = 8; |
655 if (global.params.isLinux || global.params.isFreeBSD || global.params.isSolaris) | 658 if (global.params.isLinux || global.params.isFreeBSD || global.params.isSolaris) |
656 REALSIZE = 10; | 659 REALSIZE = 10; |
944 /******************************** | 947 /******************************** |
945 * Convert to 'const'. | 948 * Convert to 'const'. |
946 */ | 949 */ |
947 Type constOf() | 950 Type constOf() |
948 { | 951 { |
949 static if (false) { | |
950 //printf("Type.constOf() %p %s\n", this, toChars()); | |
951 if (isConst()) | |
952 return this; | |
953 if (cto) | |
954 return cto; | |
955 Type t = makeConst(); | |
956 t = t.merge(); | |
957 cto = t; | |
958 if (ito) | |
959 ito.cto = t; | |
960 //if (t.nextOf()) assert(t.nextOf().isConst()); | |
961 //printf("-Type.constOf() %p %s\n", t, toChars()); | |
962 return t; | |
963 } else { | |
964 //printf("Type.constOf() %p %s\n", this, toChars()); | 952 //printf("Type.constOf() %p %s\n", this, toChars()); |
965 if (mod == MOD.MODconst) | 953 if (mod == MOD.MODconst) |
966 return this; | 954 return this; |
967 if (cto) | 955 if (cto) |
968 { | 956 { |
972 Type t = makeConst(); | 960 Type t = makeConst(); |
973 t = t.merge(); | 961 t = t.merge(); |
974 t.fixTo(this); | 962 t.fixTo(this); |
975 //printf("-Type.constOf() %p %s\n", t, toChars()); | 963 //printf("-Type.constOf() %p %s\n", t, toChars()); |
976 return t; | 964 return t; |
977 } | |
978 } | 965 } |
979 | 966 |
980 /******************************** | 967 /******************************** |
981 * Convert to 'immutable'. | 968 * Convert to 'immutable'. |
982 */ | 969 */ |
983 Type invariantOf() | 970 Type invariantOf() |
984 { | 971 { |
985 static if (false) { | |
986 //printf("Type.invariantOf() %p %s\n", this, toChars()); | |
987 if (isInvariant()) | |
988 { | |
989 return this; | |
990 } | |
991 if (ito) | |
992 { | |
993 //if (!ito.isInvariant()) printf("\tito is %p %s\n", ito, ito.toChars()); | |
994 assert(ito.isInvariant()); | |
995 return ito; | |
996 } | |
997 Type t = makeInvariant(); | |
998 t = t.merge(); | |
999 ito = t; | |
1000 if (cto) | |
1001 cto.ito = t; | |
1002 static if (false) {// fails for function types | |
1003 if (t.nextOf() && !t.nextOf().isInvariant()) | |
1004 { | |
1005 assert(0); | |
1006 } | |
1007 } | |
1008 //printf("\t%p\n", t); | |
1009 return t; | |
1010 } else { | |
1011 //printf("Type.invariantOf() %p %s\n", this, toChars()); | 972 //printf("Type.invariantOf() %p %s\n", this, toChars()); |
1012 if (isInvariant()) | 973 if (isInvariant()) |
1013 { | 974 { |
1014 return this; | 975 return this; |
1015 } | 976 } |
1021 Type t = makeInvariant(); | 982 Type t = makeInvariant(); |
1022 t = t.merge(); | 983 t = t.merge(); |
1023 t.fixTo(this); | 984 t.fixTo(this); |
1024 //printf("\t%p\n", t); | 985 //printf("\t%p\n", t); |
1025 return t; | 986 return t; |
1026 } | |
1027 } | 987 } |
1028 | 988 |
1029 Type mutableOf() | 989 Type mutableOf() |
1030 { | 990 { |
1031 static if (false) { | |
1032 //printf("Type.mutableOf() %p, %s\n", this, toChars()); | |
1033 Type t = this; | |
1034 if (isConst()) | |
1035 { | |
1036 t = cto; | |
1037 assert(!t || t.isMutable()); | |
1038 } | |
1039 else if (isInvariant()) | |
1040 { | |
1041 t = ito; | |
1042 assert(!t || t.isMutable()); | |
1043 } | |
1044 if (!t) | |
1045 { | |
1046 uint sz = this.classinfo.init.length; | |
1047 t = cast(Type)GC.malloc(sz); | |
1048 memcpy(cast(void*)t, cast(void*)this, sz); | |
1049 t.mod = 0; | |
1050 t.deco = null; | |
1051 t.arrayof = null; | |
1052 t.pto = null; | |
1053 t.rto = null; | |
1054 t.cto = null; | |
1055 t.ito = null; | |
1056 t.sto = null; | |
1057 t.scto = null; | |
1058 t.vtinfo = null; | |
1059 if (ty == Tsarray) | |
1060 { | |
1061 TypeSArray ta = cast(TypeSArray)t; | |
1062 //ta.next = ta.next.mutableOf(); | |
1063 } | |
1064 t = t.merge(); | |
1065 if (isConst()) | |
1066 { cto = t; | |
1067 t.cto = this; | |
1068 if (ito) | |
1069 ito.cto = this; | |
1070 } | |
1071 else if (isInvariant()) | |
1072 { ito = t; | |
1073 t.ito = this; | |
1074 if (cto) | |
1075 cto.ito = this; | |
1076 } | |
1077 } | |
1078 return t; | |
1079 } else { | |
1080 //printf("Type.mutableOf() %p, %s\n", this, toChars()); | 991 //printf("Type.mutableOf() %p, %s\n", this, toChars()); |
1081 Type t = this; | 992 Type t = this; |
1082 if (isConst()) | 993 if (isConst()) |
1083 { | 994 { |
1084 if (isShared()) | 995 if (isShared()) |
1095 if (!t) | 1006 if (!t) |
1096 { | 1007 { |
1097 uint sz = this.classinfo.init.length; | 1008 uint sz = this.classinfo.init.length; |
1098 t = cast(Type)GC.malloc(sz); | 1009 t = cast(Type)GC.malloc(sz); |
1099 memcpy(cast(void*)t, cast(void*)this, sz); | 1010 memcpy(cast(void*)t, cast(void*)this, sz); |
1100 t.mod = MODundefined; | 1011 t.mod = mod & MODshared; |
1101 t.deco = null; | 1012 t.deco = null; |
1102 t.arrayof = null; | 1013 t.arrayof = null; |
1103 t.pto = null; | 1014 t.pto = null; |
1104 t.rto = null; | 1015 t.rto = null; |
1105 t.cto = null; | 1016 t.cto = null; |
1119 | 1030 |
1120 case MODinvariant: | 1031 case MODinvariant: |
1121 t.ito = this; | 1032 t.ito = this; |
1122 break; | 1033 break; |
1123 | 1034 |
1124 case MODshared: | |
1125 t.sto = this; | |
1126 break; | |
1127 | |
1128 case MODshared | MODconst: | 1035 case MODshared | MODconst: |
1129 t.scto = this; | 1036 t.scto = this; |
1130 break; | 1037 break; |
1131 | 1038 |
1132 default: | 1039 default: |
1133 assert(0); | 1040 assert(0); |
1134 } | 1041 } |
1135 } | 1042 } |
1136 return t; | 1043 return t; |
1137 } | |
1138 } | 1044 } |
1139 | 1045 |
1140 Type sharedOf() | 1046 Type sharedOf() |
1141 { | 1047 { |
1142 //printf("Type.sharedOf() %p, %s\n", this, toChars()); | 1048 //printf("Type.sharedOf() %p, %s\n", this, toChars()); |
1176 t.fixTo(this); | 1082 t.fixTo(this); |
1177 //printf("\t%p\n", t); | 1083 //printf("\t%p\n", t); |
1178 | 1084 |
1179 return t; | 1085 return t; |
1180 } | 1086 } |
1181 | 1087 |
1088 /******************************** | |
1089 * Make type unshared. | |
1090 */ | |
1091 Type unSharedOf() | |
1092 { | |
1093 //writef("Type::unSharedOf() %p, %s\n", this, toChars()); | |
1094 Type t = this; | |
1095 | |
1096 if (isShared()) | |
1097 { | |
1098 if (isConst()) | |
1099 t = cto; // shared const => const | |
1100 else | |
1101 t = sto; | |
1102 assert(!t || !t.isShared()); | |
1103 } | |
1104 | |
1105 if (!t) | |
1106 { | |
1107 uint sz = this.classinfo.init.length; | |
1108 t = cast(Type)GC.malloc(sz); | |
1109 memcpy(cast(void*)t, cast(void*)this, sz); | |
1110 t.mod = mod & ~MODshared; | |
1111 t.deco = null; | |
1112 t.arrayof = null; | |
1113 t.pto = null; | |
1114 t.rto = null; | |
1115 t.cto = null; | |
1116 t.ito = null; | |
1117 t.sto = null; | |
1118 t.scto = null; | |
1119 t.vtinfo = null; | |
1120 t = t.merge(); | |
1121 | |
1122 t.fixTo(this); | |
1123 | |
1124 switch (mod) | |
1125 { | |
1126 case MODshared: | |
1127 t.sto = this; | |
1128 break; | |
1129 | |
1130 case MODshared | MODconst: | |
1131 t.scto = this; | |
1132 break; | |
1133 | |
1134 default: | |
1135 assert(0); | |
1136 } | |
1137 } | |
1138 assert(!t.isShared()); | |
1139 return t; | |
1140 } | |
1141 | |
1182 static uint X(MOD m, MOD n) | 1142 static uint X(MOD m, MOD n) |
1183 { | 1143 { |
1184 return (((m) << 3) | (n)); | 1144 return (((m) << 3) | (n)); |
1185 } | 1145 } |
1186 | 1146 |
1904 * Output: | 1864 * Output: |
1905 * dedtypes = [ int ] // Array of Expression/Type's | 1865 * dedtypes = [ int ] // Array of Expression/Type's |
1906 */ | 1866 */ |
1907 MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) | 1867 MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) |
1908 { | 1868 { |
1909 static if (false) { | 1869 static if (false) |
1870 { | |
1910 printf("Type.deduceType()\n"); | 1871 printf("Type.deduceType()\n"); |
1911 printf("\tthis = %d, ", ty); print(); | 1872 printf("\tthis = %d, ", ty); print(); |
1912 printf("\ttparam = %d, ", tparam.ty); tparam.print(); | 1873 printf("\ttparam = %d, ", tparam.ty); tparam.print(); |
1913 } | 1874 } |
1914 if (!tparam) | 1875 if (!tparam) |
1949 if (!tp.isTemplateTypeParameter()) | 1910 if (!tp.isTemplateTypeParameter()) |
1950 goto Lnomatch; | 1911 goto Lnomatch; |
1951 Type tt = this; | 1912 Type tt = this; |
1952 Type at = cast(Type)dedtypes.data[i]; | 1913 Type at = cast(Type)dedtypes.data[i]; |
1953 | 1914 |
1954 // 3*3 == 9 cases | 1915 // 5*5 == 25 cases |
1955 if (tparam.isMutable()) | 1916 static pure int X(int U, int T) { return ((U << 3) | T); } |
1956 { // foo(U:U) T => T | 1917 |
1957 // foo(U:U) const(T) => const(T) | 1918 switch (X(tparam.mod, mod)) |
1958 // foo(U:U) invariant(T) => invariant(T) | 1919 { |
1920 case X(0, 0): | |
1921 case X(0, MODconst): | |
1922 case X(0, MODinvariant): | |
1923 case X(0, MODshared): | |
1924 case X(0, MODconst | MODshared): | |
1925 // foo(U:U) T => T | |
1926 // foo(U:U) const(T) => const(T) | |
1927 // foo(U:U) immutable(T) => immutable(T) | |
1928 // foo(U:U) shared(T) => shared(T) | |
1929 // foo(U:U) const(shared(T)) => const(shared(T)) | |
1959 if (!at) | 1930 if (!at) |
1960 { | 1931 { dedtypes.data[i] = cast(void *)tt; |
1961 dedtypes.data[i] = cast(void*)this; | |
1962 goto Lexact; | 1932 goto Lexact; |
1963 } | 1933 } |
1964 } | 1934 break; |
1965 else if (mod == tparam.mod) | 1935 |
1966 { // foo(U:const(U)) const(T) => T | 1936 case X(MODconst, MODconst): |
1967 // foo(U:invariant(U)) invariant(T) => T | 1937 case X(MODinvariant, MODinvariant): |
1938 case X(MODshared, MODshared): | |
1939 case X(MODconst | MODshared, MODconst | MODshared): | |
1940 // foo(U:const(U)) const(T) => T | |
1941 // foo(U:immutable(U)) immutable(T) => T | |
1942 // foo(U:shared(U)) shared(T) => T | |
1943 // foo(U:const(shared(U)) const(shared(T))=> T | |
1944 tt = mutableOf().unSharedOf(); | |
1945 if (!at) | |
1946 { dedtypes.data[i] = cast(void *)tt; | |
1947 goto Lexact; | |
1948 } | |
1949 break; | |
1950 | |
1951 case X(MODconst, 0): | |
1952 case X(MODconst, MODimmutable): | |
1953 case X(MODconst, MODconst | MODshared): | |
1954 case X(MODconst | MODshared, MODimmutable): | |
1955 // foo(U:const(U)) T => T | |
1956 // foo(U:const(U)) immutable(T) => T | |
1957 // foo(U:const(U)) const(shared(T)) => shared(T) | |
1958 // foo(U:const(shared(U)) immutable(T) => T | |
1968 tt = mutableOf(); | 1959 tt = mutableOf(); |
1969 if (!at) | 1960 if (!at) |
1970 { | 1961 { dedtypes.data[i] = cast(void *)tt; |
1971 dedtypes.data[i] = cast(void*)tt; | |
1972 goto Lexact; | |
1973 } | |
1974 } | |
1975 else if (tparam.isConst()) | |
1976 { // foo(U:const(U)) T => T | |
1977 // foo(U:const(U)) invariant(T) => T | |
1978 tt = mutableOf(); | |
1979 if (!at) | |
1980 { | |
1981 dedtypes.data[i] = cast(void*)tt; | |
1982 goto Lconst; | 1962 goto Lconst; |
1983 } | 1963 } |
1984 } | 1964 break; |
1985 else | 1965 |
1986 { // foo(U:invariant(U)) T => nomatch | 1966 case X(MODshared, MODconst | MODshared): |
1987 // foo(U:invariant(U)) const(T) => nomatch | 1967 case X(MODconst | MODshared, MODshared): |
1968 // foo(U:shared(U)) const(shared(T)) => const(T) | |
1969 // foo(U:const(shared(U)) shared(T) => T | |
1970 tt = unSharedOf(); | |
1988 if (!at) | 1971 if (!at) |
1972 { dedtypes.data[i] = cast(void *)tt; | |
1973 goto Lconst; | |
1974 } | |
1975 break; | |
1976 | |
1977 case X(MODimmutable, 0): | |
1978 case X(MODimmutable, MODconst): | |
1979 case X(MODimmutable, MODshared): | |
1980 case X(MODimmutable, MODconst | MODshared): | |
1981 case X(MODconst, MODshared): | |
1982 case X(MODshared, 0): | |
1983 case X(MODshared, MODconst): | |
1984 case X(MODshared, MODimmutable): | |
1985 case X(MODconst | MODshared, 0): | |
1986 case X(MODconst | MODshared, MODconst): | |
1987 // foo(U:immutable(U)) T => nomatch | |
1988 // foo(U:immutable(U)) const(T) => nomatch | |
1989 // foo(U:immutable(U)) shared(T) => nomatch | |
1990 // foo(U:immutable(U)) const(shared(T)) => nomatch | |
1991 // foo(U:const(U)) shared(T) => nomatch | |
1992 // foo(U:shared(U)) T => nomatch | |
1993 // foo(U:shared(U)) const(T) => nomatch | |
1994 // foo(U:shared(U)) immutable(T) => nomatch | |
1995 // foo(U:const(shared(U)) T => nomatch | |
1996 // foo(U:const(shared(U)) const(T) => nomatch | |
1997 //if (!at) | |
1989 goto Lnomatch; | 1998 goto Lnomatch; |
1999 break; | |
2000 | |
2001 default: | |
2002 assert(0); | |
1990 } | 2003 } |
1991 | 2004 |
1992 if (tt.equals(at)) | 2005 if (tt.equals(at)) |
1993 goto Lexact; | 2006 goto Lexact; |
1994 else if (tt.ty == Tclass && at.ty == Tclass) | 2007 else if (tt.ty == Tclass && at.ty == Tclass) |
2270 case TY.Tclass: | 2283 case TY.Tclass: |
2271 case TY.Treference: | 2284 case TY.Treference: |
2272 case TY.Tpointer: t = TYM.TYnptr; break; | 2285 case TY.Tpointer: t = TYM.TYnptr; break; |
2273 case TY.Tdelegate: t = TYM.TYdelegate; break; | 2286 case TY.Tdelegate: t = TYM.TYdelegate; break; |
2274 case TY.Tarray: t = TYM.TYdarray; break; | 2287 case TY.Tarray: t = TYM.TYdarray; break; |
2275 case TY.Tsarray: t = TYM.TYarray; break; | 2288 version(SARRAYVALUE) |
2289 { case TY.Tsarray: t = TYstruct; break;} | |
2290 else | |
2291 { case TY.Tsarray: t = TYM.TYarray; break;} | |
2276 case TY.Tstruct: t = TYM.TYstruct; break; | 2292 case TY.Tstruct: t = TYM.TYstruct; break; |
2277 | 2293 |
2278 case TY.Tenum: | 2294 case TY.Tenum: |
2279 case TY.Ttypedef: | 2295 case TY.Ttypedef: |
2280 t = toBasetype().totym(); | 2296 t = toBasetype().totym(); |
2483 { | 2499 { |
2484 return tint32; // array/ptr index | 2500 return tint32; // array/ptr index |
2485 } | 2501 } |
2486 | 2502 |
2487 static Type tvoidptr; // void* | 2503 static Type tvoidptr; // void* |
2488 | 2504 static Type tstring; // immutable(char)[] |
2505 | |
2489 static Type terror() | 2506 static Type terror() |
2490 { | 2507 { |
2491 return basic[TY.Terror]; // for error recovery | 2508 return basic[TY.Terror]; // for error recovery |
2492 } | 2509 } |
2493 | 2510 |