Mercurial > projects > ddmd
diff dmd/Type.d @ 135:af1bebfd96a4 dmd2037
dmd 2.038
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 13 Sep 2010 22:19:42 +0100 |
parents | 206db751bd4c |
children | 31c086f76669 |
line wrap: on
line diff
--- a/dmd/Type.d Sat Sep 11 13:03:39 2010 +0100 +++ b/dmd/Type.d Mon Sep 13 22:19:42 2010 +0100 @@ -59,6 +59,8 @@ import dmd.DotIdExp; import dmd.AggregateDeclaration; import dmd.DotTemplateInstanceExp; +import dmd.Token; +import dmd.TypeInfoWildDeclaration; import dmd.expression.Util; @@ -127,6 +129,102 @@ return -1; } +/*************************** + * Return !=0 if modfrom can be implicitly converted to modto + */ +int MODimplicitConv(MOD modfrom, MOD modto) +{ + if (modfrom == modto) + return 1; + + //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto); + static uint X(MOD m, MOD n) + { + return (((m) << 4) | (n)); + } + switch (X(modfrom, modto)) + { + case X(MOD.MODundefined, MOD.MODconst): + case X(MOD.MODimmutable, MOD.MODconst): + case X(MOD.MODwild, MOD.MODconst): + case X(MOD.MODimmutable, MOD.MODconst | MOD.MODshared): + case X(MOD.MODshared, MOD.MODconst | MOD.MODshared): + case X(MOD.MODwild | MOD.MODshared, MOD.MODconst | MOD.MODshared): + return 1; + + default: + return 0; + } +} + +/********************************* + * Mangling for mod. + */ +void MODtoDecoBuffer(OutBuffer buf, MOD mod) +{ + switch (mod) + { + case MOD.MODundefined: + break; + case MOD.MODconst: + buf.writeByte('x'); + break; + case MOD.MODimmutable: + buf.writeByte('y'); + break; + case MOD.MODshared: + buf.writeByte('O'); + break; + case MOD.MODshared | MOD.MODconst: + buf.writestring("Ox"); + break; + case MOD.MODwild: + buf.writestring("Ng"); + break; + case MOD.MODshared | MOD.MODwild: + buf.writestring("ONg"); + break; + default: + assert(0); + } +} + +/********************************* + * Name for mod. + */ +void MODtoBuffer(OutBuffer buf, MOD mod) +{ + switch (mod) + { + case MOD.MODundefined: + break; + + case MOD.MODimmutable: + buf.writestring(Token.tochars[TOK.TOKimmutable]); + break; + + case MOD.MODshared: + buf.writestring(Token.tochars[TOK.TOKshared]); + break; + + case MOD.MODshared | MOD.MODconst: + buf.writestring(Token.tochars[TOK.TOKshared]); + buf.writeByte(' '); + case MOD.MODconst: + buf.writestring(Token.tochars[TOK.TOKconst]); + break; + + case MOD.MODshared | MOD.MODwild: + buf.writestring(Token.tochars[TOK.TOKshared]); + buf.writeByte(' '); + case MOD.MODwild: + buf.writestring(Token.tochars[TOKwild]); + break; + default: + assert(0); + } +} + class Type { TY ty; @@ -143,12 +241,16 @@ * They should not be referenced by anybody but mtype.c. * They can be null if not lazily evaluated yet. * Note that there is no "shared immutable", because that is just immutable + * Naked == no MOD bits */ - Type cto; // MODconst ? mutable version of this type : const version - Type ito; // MODinvariant ? mutable version of this type : invariant version - Type sto; // MODshared ? mutable version of this type : shared mutable version - Type scto; // MODshared|MODconst ? mutable version of this type : shared const version + Type cto; // MODconst ? naked version of this type : const version + Type ito; // MODimmutable ? naked version of this type : immutable version + Type sto; // MODshared ? naked version of this type : shared mutable version + Type scto; // MODshared|MODconst ? naked version of this type : shared const version + Type wto; // MODwild ? naked version of this type : wild version + Type swto; // MODshared|MODwild ? naked version of this type : shared wild version + Type pto; // merged pointer to this type Type rto; // reference to this type @@ -173,6 +275,7 @@ static ClassDeclaration typeinfoconst; static ClassDeclaration typeinfoinvariant; static ClassDeclaration typeinfoshared; + static ClassDeclaration typeinfowild; static Type basic[TY.TMAX]; static ubyte mangleChar[TY.TMAX]; @@ -493,7 +596,7 @@ * forward references. */ if ((cast(TypeClass)t1n).sym == (cast(TypeClass)t2n).sym && - t2n.mod == MOD.MODconst) + MODimplicitConv(t1n.mod, t2n.mod)) goto Lcovariant; // If t1n is forward referenced: @@ -512,6 +615,9 @@ Lcovariant: /* Can convert mutable to const */ + if (!MODimplicitConv(t2.mod, t1.mod)) + goto Lnotcovariant; +static if(false) { if (t1.mod != t2.mod) { if (!(t1.mod & MOD.MODconst) && (t2.mod & MOD.MODconst)) @@ -519,7 +625,7 @@ if (!(t1.mod & MOD.MODshared) && (t2.mod & MOD.MODshared)) goto Lnotcovariant; } - +} /* Can convert pure to impure, and nothrow to throw */ if (!t1.ispure && t2.ispure) @@ -628,6 +734,7 @@ mangleChar[TY.Twchar] = 'u'; mangleChar[TY.Tdchar] = 'w'; + // '@' shouldn't appear anywhere in the deco'd names mangleChar[TY.Tbit] = '@'; mangleChar[TY.Tinstance] = '@'; mangleChar[TY.Terror] = '@'; @@ -736,16 +843,7 @@ { if (flag != mod && flag != 0x100) { - if (mod & MOD.MODshared) - buf.writeByte('O'); - - if (mod & MOD.MODconst) - buf.writeByte('x'); - else if (mod & MOD.MODinvariant) - buf.writeByte('y'); - - // Cannot be both const and invariant - assert((mod & (MOD.MODconst | MOD.MODinvariant)) != (MOD.MODconst | MOD.MODinvariant)); + MODtoDecoBuffer(buf, mod); } buf.writeByte(mangleChar[ty]); } @@ -832,40 +930,35 @@ { if (mod != this.mod) { - string p; - if (this.mod & MOD.MODshared) - buf.writestring("shared("); + { + MODtoBuffer(buf, this.mod & MOD.MODshared); + buf.writeByte('('); + } - switch (this.mod & (MOD.MODconst | MOD.MODinvariant)) - { - case MOD.MODundefined: - toCBuffer2(buf, hgs, this.mod); - break; - case MOD.MODconst: - p = "const("; - goto L1; - case MOD.MODinvariant: - p = "immutable("; - L1: buf.writestring(p); - toCBuffer2(buf, hgs, this.mod); - buf.writeByte(')'); - break; - } - - if (this.mod & MOD.MODshared) - buf.writeByte(')'); + if (this.mod & ~MOD.MODshared) + { + MODtoBuffer(buf, this.mod & ~MOD.MODshared); + buf.writeByte('('); + toCBuffer2(buf, hgs, this.mod); + buf.writeByte(')'); + } + else + toCBuffer2(buf, hgs, this.mod); + if (this.mod & MOD.MODshared) + { + buf.writeByte(')'); + } } } void modToBuffer(OutBuffer buf) { - if (mod & MOD.MODshared) - buf.writestring(" shared"); - if (mod & MOD.MODconst) - buf.writestring(" const"); - if (mod & MOD.MODinvariant) - buf.writestring(" immutable"); + if (mod) + { + buf.writeByte(' '); + MODtoBuffer(buf, mod); + } } version (CPP_MANGLE) { @@ -948,13 +1041,20 @@ bool isConst() { return (mod & MOD.MODconst) != 0; } - int isInvariant() { return mod & MOD.MODinvariant; } + int isImmutable() { return mod & MOD.MODimmutable; } - int isMutable() { return !(mod & (MOD.MODconst | MOD.MODinvariant)); } + int isMutable() { return !(mod & (MOD.MODconst | MOD.MODimmutable | MOD.MODwild)); } int isShared() { return mod & MOD.MODshared; } int isSharedConst() { return mod == (MOD.MODshared | MOD.MODconst); } + + int isWild() { return mod & MOD.MODwild; } + + int isSharedWild() { return mod == (MOD.MODshared | MOD.MODwild); } + + int isNaked() { return mod == 0; } + /******************************** * Convert to 'const'. @@ -982,13 +1082,13 @@ Type invariantOf() { //printf("Type.invariantOf() %p %s\n", this, toChars()); - if (isInvariant()) + if (isImmutable()) { return this; } if (ito) { - assert(ito.isInvariant()); + assert(ito.isImmutable()); return ito; } Type t = makeInvariant(); @@ -1007,51 +1107,29 @@ if (isShared()) t = sto; // shared const => shared else - t = cto; + t = cto; // const => naked assert(!t || t.isMutable()); } - else if (isInvariant()) + else if (isImmutable()) { t = ito; assert(!t || (t.isMutable() && !t.isShared())); } + else if (isWild()) + { + if (isShared()) + t = sto; // shared wild => shared + else + t = wto; // wild => naked + assert(!t || t.isMutable()); + } if (!t) { - uint sz = this.classinfo.init.length; - t = cast(Type)GC.malloc(sz); - memcpy(cast(void*)t, cast(void*)this, sz); - t.mod = mod & MODshared; - t.deco = null; - t.arrayof = null; - t.pto = null; - t.rto = null; - t.cto = null; - t.ito = null; - t.sto = null; - t.scto = null; - t.vtinfo = null; + t = makeMutable(); t = t.merge(); - t.fixTo(this); - - switch (mod) - { - case MODconst: - t.cto = this; - break; - - case MODinvariant: - t.ito = this; - break; - - case MODshared | MODconst: - t.scto = this; - break; - - default: - assert(0); - } } + assert(t.isMutable()); return t; } @@ -1099,6 +1177,13 @@ /******************************** * Make type unshared. + * 0 => 0 + * const => const + * immutable => immutable + * shared => 0 + * shared const => const + * wild => wild + * shared wild => wild */ Type unSharedOf() { @@ -1109,6 +1194,8 @@ { if (isConst()) t = cto; // shared const => const + else if (isWild()) + t = wto; // shared wild => wild else t = sto; assert(!t || !t.isShared()); @@ -1128,37 +1215,68 @@ t.ito = null; t.sto = null; t.scto = null; + t.wto = null; + t.swto = null; t.vtinfo = null; t = t.merge(); t.fixTo(this); - - switch (mod) - { - case MODshared: - t.sto = this; - break; - - case MODshared | MODconst: - t.scto = this; - break; - - default: - assert(0); - } } assert(!t.isShared()); return t; } + + /******************************** + * Convert to 'wild'. + */ + + Type wildOf() + { + //printf("Type::wildOf() %p %s\n", this, toChars()); + if (mod == MOD.MODwild) + { + return this; + } + if (wto) + { + assert(wto.isWild()); + return wto; + } + Type t = makeWild(); + t = t.merge(); + t.fixTo(this); + //printf("\t%p %s\n", t, t->toChars()); + return t; + } + + Type sharedWildOf() + { + //printf("Type::sharedWildOf() %p, %s\n", this, toChars()); + if (mod == (MOD.MODwild)) + { + return this; + } + if (swto) + { + assert(swto.mod == (MOD.MODshared | MOD.MODwild)); + return swto; + } + Type t = makeSharedWild(); + t = t.merge(); + t.fixTo(this); + //printf("\t%p\n", t); + return t; + } + static uint X(MOD m, MOD n) { - return (((m) << 3) | (n)); + return (((m) << 4) | (n)); } /********************************** * For our new type 'this', which is type-constructed from t, - * fill in the cto, ito, sto, scto shortcuts. + * fill in the cto, ito, sto, scto, wto shortcuts. */ void fixTo(Type t) { @@ -1181,7 +1299,7 @@ cto = t; break; - case X(MOD.MODundefined, MOD.MODinvariant): + case X(MOD.MODundefined, MOD.MODimmutable): ito = t; break; @@ -1193,12 +1311,20 @@ scto = t; break; + case X(MOD.MODundefined, MODwild): + wto = t; + break; + + case X(MOD.MODundefined, MODshared | MODwild): + swto = t; + break; + case X(MOD.MODconst, MOD.MODundefined): cto = null; goto L2; - case X(MOD.MODconst, MOD.MODinvariant): + case X(MOD.MODconst, MOD.MODimmutable): ito = t; goto L2; @@ -1208,30 +1334,48 @@ case X(MOD.MODconst, MOD.MODshared | MOD.MODconst): scto = t; + goto L2; + + case X(MOD.MODconst, MOD.MODwild): + wto = t; + goto L2; + + case X(MOD.MODconst, MOD.MODshared | MOD.MODwild): + swto = t; L2: t.cto = this; break; - case X(MOD.MODinvariant, MOD.MODundefined): + case X(MOD.MODimmutable, MOD.MODundefined): ito = null; goto L3; - case X(MOD.MODinvariant, MOD.MODconst): + case X(MOD.MODimmutable, MOD.MODconst): cto = t; goto L3; - case X(MOD.MODinvariant, MOD.MODshared): + case X(MOD.MODimmutable, MOD.MODshared): sto = t; goto L3; - case X(MOD.MODinvariant, MOD.MODshared | MOD.MODconst): + case X(MOD.MODimmutable, MOD.MODshared | MOD.MODconst): scto = t; + goto L3; + + case X(MOD.MODimmutable, MOD.MODwild): + wto = t; + goto L3; + + case X(MOD.MODimmutable, MOD.MODshared | MOD.MODwild): + swto = t; L3: t.ito = this; if (t.cto) t.cto.ito = this; if (t.sto) t.sto.ito = this; if (t.scto) t.scto.ito = this; + if (t.wto) t.wto.ito = this; + if (t.swto) t.swto.ito = this; break; @@ -1243,12 +1387,20 @@ cto = t; goto L4; - case X(MOD.MODshared, MOD.MODinvariant): + case X(MOD.MODshared, MOD.MODimmutable): ito = t; goto L4; case X(MOD.MODshared, MOD.MODshared | MOD.MODconst): scto = t; + goto L4; + + case X(MOD.MODshared, MOD.MODwild): + wto = t; + goto L4; + + case X(MOD.MODshared, MOD.MODshared | MOD.MODwild): + swto = t; L4: t.sto = this; break; @@ -1256,21 +1408,82 @@ case X(MOD.MODshared | MOD.MODconst, MOD.MODundefined): scto = null; - break; + goto L5; case X(MOD.MODshared | MOD.MODconst, MOD.MODconst): cto = t; - break; + goto L5; - case X(MOD.MODshared | MOD.MODconst, MOD.MODinvariant): + case X(MOD.MODshared | MOD.MODconst, MOD.MODimmutable): ito = t; - break; + goto L5; + + case X(MOD.MODshared | MOD.MODconst, MOD.MODwild): + wto = t; + goto L5; case X(MOD.MODshared | MOD.MODconst, MOD.MODshared): sto = t; + goto L5; + + case X(MOD.MODshared | MOD.MODconst, MOD.MODshared | MOD.MODwild): + swto = t; L5: t.scto = this; break; + + case X(MOD.MODwild, MOD.MODundefined): + wto = null; + goto L6; + + case X(MOD.MODwild, MOD.MODconst): + cto = t; + goto L6; + + case X(MOD.MODwild, MOD.MODimmutable): + ito = t; + goto L6; + + case X(MOD.MODwild, MOD.MODshared): + sto = t; + goto L6; + + case X(MOD.MODwild, MOD.MODshared | MOD.MODconst): + scto = t; + goto L6; + + case X(MOD.MODwild, MOD.MODshared | MOD.MODwild): + swto = t; + L6: + t.wto = this; + break; + + + case X(MOD.MODshared | MOD.MODwild, MOD.MODundefined): + swto = null; + goto L7; + + case X(MOD.MODshared | MOD.MODwild, MOD.MODconst): + cto = t; + goto L7; + + case X(MOD.MODshared | MOD.MODwild, MOD.MODimmutable): + ito = t; + goto L7; + + case X(MOD.MODshared | MOD.MODwild, MOD.MODshared): + sto = t; + goto L7; + + case X(MOD.MODshared | MOD.MODwild, MOD.MODshared | MOD.MODconst): + scto = t; + goto L7; + + case X(MOD.MODshared | MOD.MODwild, MOD.MODwild): + wto = t; + L7: + t.swto = this; + break; } check(); @@ -1287,38 +1500,66 @@ { case MOD.MODundefined: if (cto) assert(cto.mod == MOD.MODconst); - if (ito) assert(ito.mod == MOD.MODinvariant); + if (ito) assert(ito.mod == MOD.MODimmutable); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); break; case MOD.MODconst: if (cto) assert(cto.mod == MOD.MODundefined); - if (ito) assert(ito.mod == MOD.MODinvariant); + if (ito) assert(ito.mod == MOD.MODimmutable); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); break; - case MOD.MODinvariant: + case MOD.MODimmutable: if (cto) assert(cto.mod == MOD.MODconst); if (ito) assert(ito.mod == MOD.MODundefined); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); break; case MOD.MODshared: if (cto) assert(cto.mod == MOD.MODconst); - if (ito) assert(ito.mod == MOD.MODinvariant); + if (ito) assert(ito.mod == MOD.MODimmutable); if (sto) assert(sto.mod == MOD.MODundefined); if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); break; case MOD.MODshared | MOD.MODconst: if (cto) assert(cto.mod == MOD.MODconst); - if (ito) assert(ito.mod == MOD.MODinvariant); + if (ito) assert(ito.mod == MOD.MODimmutable); if (sto) assert(sto.mod == MOD.MODshared); if (scto) assert(scto.mod == MOD.MODundefined); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); break; + + case MOD.MODwild: + if (cto) assert(cto.mod == MOD.MODconst); + if (ito) assert(ito.mod == MOD.MODimmutable); + if (sto) assert(sto.mod == MOD.MODshared); + if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODundefined); + if (swto) assert(swto.mod == (MOD.MODshared | MOD.MODwild)); + break; + + case MOD.MODshared | MOD.MODwild: + if (cto) assert(cto.mod == MOD.MODconst); + if (ito) assert(ito.mod == MOD.MODimmutable); + if (sto) assert(sto.mod == MOD.MODshared); + if (scto) assert(scto.mod == (MOD.MODshared | MOD.MODconst)); + if (wto) assert(wto.mod == MOD.MODwild); + if (swto) assert(swto.mod == MOD.MODundefined); + break; } Type tn = nextOf(); @@ -1331,19 +1572,27 @@ break; case MOD.MODconst: - assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODconst); + assert(tn.mod & MOD.MODimmutable || tn.mod & MOD.MODconst); break; - case MOD.MODinvariant: - assert(tn.mod == MOD.MODinvariant); + case MOD.MODimmutable: + assert(tn.mod == MOD.MODimmutable); break; case MOD.MODshared: - assert(tn.mod & MOD.MODinvariant || tn.mod & MOD.MODshared); + assert(tn.mod & MOD.MODimmutable || tn.mod & MOD.MODshared); break; case MOD.MODshared | MOD.MODconst: - assert(tn.mod & MOD.MODinvariant || tn.mod & (MOD.MODshared | MOD.MODconst)); + assert(tn.mod & MOD.MODimmutable || tn.mod & (MOD.MODshared | MOD.MODconst)); + break; + + case MOD.MODwild: + assert(tn.mod); + break; + + case MOD.MODshared | MOD.MODwild: + assert(tn.mod == MOD.MODimmutable || tn.mod == (MOD.MODshared | MOD.MODconst) || tn.mod == (MOD.MODshared | MOD.MODwild)); break; } tn.check(); @@ -1360,23 +1609,31 @@ switch (mod) { case 0: - t = mutableOf(); + t = unSharedOf().mutableOf(); break; case MODconst: - t = constOf(); + t = unSharedOf().constOf(); break; - case MODinvariant: + case MODimmutable: t = invariantOf(); break; case MODshared: - t = sharedOf(); + t = mutableOf().sharedOf(); break; case MODshared | MODconst: t = sharedConstOf(); + break; + + case MODwild: + t = unSharedOf().wildOf(); + break; + + case MODshared | MODwild: + t = sharedWildOf(); break; default: @@ -1396,7 +1653,8 @@ /* Add anything to immutable, and it remains immutable */ - if (!t.isInvariant()) + //printf("addMod(%x) %s\n", mod, toChars()); + if (!t.isImmutable()) { switch (mod) { @@ -1410,13 +1668,15 @@ t = constOf(); break; - case MOD.MODinvariant: + case MOD.MODimmutable: t = invariantOf(); break; case MOD.MODshared: if (isConst()) t = sharedConstOf(); + else if (isWild()) + t = sharedWildOf(); else t = sharedOf(); break; @@ -1424,6 +1684,19 @@ case MOD.MODshared | MOD.MODconst: t = sharedConstOf(); break; + + case MOD.MODwild: + if (isConst()) + {} + else if (isShared()) + t = sharedWildOf(); + else + t = wildOf(); + break; + + case MOD.MODshared | MOD.MODwild: + t = sharedWildOf(); + break; } } return t; @@ -1436,13 +1709,15 @@ MOD mod = MOD.MODundefined; if (stc & STC.STCimmutable) - mod = MOD.MODinvariant; + mod = MOD.MODimmutable; else { if (stc & (STC.STCconst | STC.STCin)) mod = MOD.MODconst; if (stc & STC.STCshared) mod |= MOD.MODshared; + if (stc & STC.STCwild) + mod |= MOD.MODwild; } return addMod(mod); @@ -1514,6 +1789,8 @@ t.ito = null; t.sto = null; t.scto = null; + t.wto = null; + t.swto = null; t.vtinfo = null; //printf("-Type.makeConst() %p, %s\n", t, toChars()); @@ -1527,7 +1804,7 @@ } Type t = clone(); - t.mod = MOD.MODinvariant; + t.mod = MOD.MODimmutable; t.deco = null; t.arrayof = null; @@ -1537,6 +1814,8 @@ t.ito = null; t.sto = null; t.scto = null; + t.wto = null; + t.swto = null; t.vtinfo = null; return t; @@ -1558,6 +1837,8 @@ t.ito = null; t.sto = null; t.scto = null; + t.wto = null; + t.swto = null; t.vtinfo = null; return t; @@ -1579,11 +1860,73 @@ t.ito = null; t.sto = null; t.scto = null; + t.wto = null; + t.swto = null; t.vtinfo = null; return t; } + Type makeWild() + { + if (wto) + return wto; + + Type t = clone(); + t.mod = MOD.MODwild; + t.deco = null; + t.arrayof = null; + t.pto = null; + t.rto = null; + t.cto = null; + t.ito = null; + t.sto = null; + t.scto = null; + t.wto = null; + t.swto = null; + t.vtinfo = null; + return t; + } + + Type makeSharedWild() + { + if (swto) + return swto; + + Type t = clone(); + t.mod = MOD.MODshared | MOD.MODwild; + t.deco = null; + t.arrayof = null; + t.pto = null; + t.rto = null; + t.cto = null; + t.ito = null; + t.sto = null; + t.scto = null; + t.wto = null; + t.swto = null; + t.vtinfo = null; + return t; + } + + Type makeMutable() + { + Type t = clone(); + t.mod = mod & MOD.MODshared; + t.deco = null; + t.arrayof = null; + t.pto = null; + t.rto = null; + t.cto = null; + t.ito = null; + t.sto = null; + t.scto = null; + t.wto = null; + t.swto = null; + t.vtinfo = null; + return t; + } + Dsymbol toDsymbol(Scope sc) { return null; @@ -1627,7 +1970,7 @@ { if (equals(to)) return MATCH.MATCHexact; - if (ty == to.ty && to.mod == MOD.MODconst) + if (ty == to.ty && MODimplicitConv(mod, to.mod)) return MATCH.MATCHconst; return MATCH.MATCHnomatch; } @@ -1883,6 +2226,18 @@ assert(false); } + /*************************************** + * Use when we prefer the default initializer to be a literal, + * rather than a global immutable variable. + */ + Expression defaultInitLiteral(Loc loc = Loc(0)) + { +version(LOGDEFAULTINIT) { + printf("Type::defaultInitLiteral() '%s'\n", toChars()); +} + return defaultInit(loc); + } + ///bool isZeroInit(Loc loc = Loc(0)) // if initializer is 0 bool isZeroInit(Loc loc) // if initializer is 0 { @@ -1995,20 +2350,24 @@ Type at = cast(Type)dedtypes[i]; // 5*5 == 25 cases - static pure int X(int U, int T) { return ((U << 3) | T); } + static pure int X(int U, int T) { return ((U << 4) | T); } switch (X(tparam.mod, mod)) { case X(0, 0): case X(0, MODconst): - case X(0, MODinvariant): + case X(0, MODimmutable): case X(0, MODshared): case X(0, MODconst | MODshared): + case X(0, MODwild): + case X(0, MODwild | MODshared): // foo(U:U) T => T // foo(U:U) const(T) => const(T) // foo(U:U) immutable(T) => immutable(T) // foo(U:U) shared(T) => shared(T) // foo(U:U) const(shared(T)) => const(shared(T)) + // foo(U:U) wild(T) => wild(T) + // foo(U:U) wild(shared(T)) => wild(shared(T)) if (!at) { dedtypes[i] = tt; goto Lexact; @@ -2016,13 +2375,20 @@ break; case X(MODconst, MODconst): - case X(MODinvariant, MODinvariant): + case X(MODimmutable, MODimmutable): case X(MODshared, MODshared): case X(MODconst | MODshared, MODconst | MODshared): + case X(MODwild, MODwild): + case X(MODwild | MODshared, MODwild | MODshared): + case X(MODconst, MODwild): + case X(MODconst, MODwild | MODshared): // foo(U:const(U)) const(T) => T // foo(U:immutable(U)) immutable(T) => T // foo(U:shared(U)) shared(T) => T // foo(U:const(shared(U)) const(shared(T))=> T + // foo(U:wild(U)) wild(T) => T + // foo(U:wild(shared(U)) wild(shared(T)) => T + // foo(U:const(U)) wild(shared(T)) => shared(T) tt = mutableOf().unSharedOf(); if (!at) { @@ -2035,10 +2401,12 @@ case X(MODconst, MODimmutable): case X(MODconst, MODconst | MODshared): case X(MODconst | MODshared, MODimmutable): + case X(MODshared, MODwild | MODshared): // foo(U:const(U)) T => T // foo(U:const(U)) immutable(T) => T // foo(U:const(U)) const(shared(T)) => shared(T) // foo(U:const(shared(U)) immutable(T) => T + // foo(U:shared(U)) wild(shared(T)) => wild(T) tt = mutableOf(); if (!at) { dedtypes[i] = tt; @@ -2067,6 +2435,23 @@ case X(MODshared, MODimmutable): case X(MODconst | MODshared, 0): case X(MODconst | MODshared, MODconst): + case X(MODimmutable, MODwild): + case X(MODshared, MODwild): + case X(MODconst | MODshared, MODwild): + case X(MODwild, 0): + case X(MODwild, MODconst): + case X(MODwild, MODimmutable): + case X(MODwild, MODshared): + case X(MODwild, MODconst | MODshared): + case X(MODwild | MODshared, 0): + case X(MODwild | MODshared, MODconst): + case X(MODwild | MODshared, MODimmutable): + case X(MODwild | MODshared, MODshared): + case X(MODwild | MODshared, MODconst | MODshared): + case X(MODwild | MODshared, MODwild): + case X(MODimmutable, MODwild | MODshared): + case X(MODconst | MODshared, MODwild | MODshared): + case X(MODwild, MODwild | MODshared): // foo(U:immutable(U)) T => nomatch // foo(U:immutable(U)) const(T) => nomatch // foo(U:immutable(U)) shared(T) => nomatch @@ -2077,6 +2462,23 @@ // foo(U:shared(U)) immutable(T) => nomatch // foo(U:const(shared(U)) T => nomatch // foo(U:const(shared(U)) const(T) => nomatch + // foo(U:immutable(U)) wild(T) => nomatch + // foo(U:shared(U)) wild(T) => nomatch + // foo(U:const(shared(U)) wild(T) => nomatch + // foo(U:wild(U)) T => nomatch + // foo(U:wild(U)) const(T) => nomatch + // foo(U:wild(U)) immutable(T) => nomatch + // foo(U:wild(U)) shared(T) => nomatch + // foo(U:wild(U)) const(shared(T)) => nomatch + // foo(U:wild(shared(U)) T => nomatch + // foo(U:wild(shared(U)) const(T) => nomatch + // foo(U:wild(shared(U)) immutable(T) => nomatch + // foo(U:wild(shared(U)) shared(T) => nomatch + // foo(U:wild(shared(U)) const(shared(T)) => nomatch + // foo(U:wild(shared(U)) wild(T) => nomatch + // foo(U:immutable(U)) wild(shared(T)) => nomatch + // foo(U:const(shared(U))) wild(shared(T)) => nomatch + // foo(U:wild(U)) wild(shared(T)) => nomatch //if (!at) goto Lnomatch; break; @@ -2204,8 +2606,11 @@ t.vtinfo = new TypeInfoSharedDeclaration(t); else if (t.isConst()) t.vtinfo = new TypeInfoConstDeclaration(t); - else if (t.isInvariant()) + else if (t.isImmutable()) t.vtinfo = new TypeInfoInvariantDeclaration(t); + else if (t.isWild()) + t.vtinfo = new TypeInfoWildDeclaration(t); + else t.vtinfo = t.getTypeInfoDeclaration(); } else { @@ -2261,6 +2666,24 @@ return null; } + /*************************************** + * Return !=0 if the type or any of its subtypes is wild. + */ + + int hasWild() + { + return mod & MOD.MODwild; + } + + /*************************************** + * Return MOD bits matching argument type (targ) to wild parameter type (this). + */ + + uint wildMatch(Type targ) + { + return 0; + } + Expression toExpression() { assert(false); @@ -2402,14 +2825,16 @@ case MOD.MODundefined: break; case MOD.MODconst: + case MOD.MODwild: t |= mTY.mTYconst; break; - case MOD.MODinvariant: + case MOD.MODimmutable: t |= mTY.mTYimmutable; break; case MOD.MODshared: t |= mTY.mTYshared; break; + case MOD.MODshared | MOD.MODwild: case MOD.MODshared | MOD.MODconst: t |= mTY.mTYshared | mTY.mTYconst; break;