Mercurial > projects > ddmd
diff dmd/TypeInstance.d @ 16:5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sun, 04 Apr 2010 22:41:11 +0100 |
parents | 10317f0c89a5 |
children | 2e2a5c3f943a |
line wrap: on
line diff
--- a/dmd/TypeInstance.d Sun Apr 04 02:15:33 2010 +0100 +++ b/dmd/TypeInstance.d Sun Apr 04 22:41:11 2010 +0100 @@ -1,7 +1,14 @@ module dmd.TypeInstance; import dmd.TypeQualified; +import dmd.TemplateAliasParameter; +import dmd.TemplateDeclaration; import dmd.TemplateInstance; +import dmd.TemplateParameter; +import dmd.TemplateValueParameter; +import dmd.TemplateTupleParameter; +import dmd.Tuple; +import dmd.VarExp; import dmd.MOD; import dmd.MATCH; import dmd.Loc; @@ -13,43 +20,56 @@ import dmd.Expression; import dmd.Scope; import dmd.ArrayTypes; +import dmd.TOK; import dmd.TY; +import dmd.Util : printf; /* Similar to TypeIdentifier, but with a TemplateInstance as the root */ class TypeInstance : TypeQualified { - TemplateInstance tempinst; + TemplateInstance tempinst; - this(Loc loc, TemplateInstance tempinst) + this(Loc loc, TemplateInstance tempinst) { super(Tinstance, loc); this.tempinst = tempinst; } - -version (DumbClone) { -} else { - Type clone() - { - assert(false); + + version (DumbClone) { + } else { + Type clone() + { + assert(false); + } } -} - - Type syntaxCopy() + + Type syntaxCopy() { - assert(false); + //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim); + TypeInstance t; + + t = new TypeInstance(loc, cast(TemplateInstance)tempinst.syntaxCopy(null)); + t.syntaxCopyHelper(this); + t.mod = mod; + return t; } - - //char *toChars(); - - //void toDecoBuffer(OutBuffer *buf, int flag); - - void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) + + //char *toChars(); + + //void toDecoBuffer(OutBuffer *buf, int flag); + + void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { - assert(false); + if (mod != this.mod) + { toCBuffer3(buf, hgs, mod); + return; + } + tempinst.toCBuffer(buf, hgs); + toCBuffer2Helper(buf, hgs); } - - void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) + + void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { // Note close similarity to TypeIdentifier::resolve() Dsymbol s; @@ -58,13 +78,13 @@ *pt = null; *ps = null; - static if (false) { - if (!idents.dim) - { - error(loc, "template instance '%s' has no identifier", toChars()); - return; + static if (false) { + if (!idents.dim) + { + error(loc, "template instance '%s' has no identifier", toChars()); + return; + } } - } //id = (Identifier *)idents.data[0]; //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); s = tempinst; @@ -75,13 +95,42 @@ *pt = (*pt).addMod(mod); //printf("pt = '%s'\n", (*pt)->toChars()); } - - Type semantic(Loc loc, Scope sc) + + Type semantic(Loc loc, Scope sc) { - assert(false); + Type t; + Expression e; + Dsymbol s; + + //printf("TypeInstance::semantic(%s)\n", toChars()); + + if (sc.parameterSpecialization) + { + uint errors = global.errors; + global.gag++; + + resolve(loc, sc, &e, &t, &s); + + global.gag--; + if (errors != global.errors) + { if (global.gag == 0) + global.errors = errors; + return this; + } + } + else + resolve(loc, sc, &e, &t, &s); + + if (!t) + { + debug printf("2: "); + error(loc, "%s is used as a type", toChars()); + t = tvoid; + } + return t; } - - Dsymbol toDsymbol(Scope sc) + + Dsymbol toDsymbol(Scope sc) { Type t; Expression e; @@ -110,9 +159,225 @@ return s; } - - MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) + + MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { - assert(false); +static if (0) { + printf("TypeInstance::deduceType()\n"); + printf("\tthis = %d, ", ty); print(); + printf("\ttparam = %d, ", tparam.ty); tparam.print(); +} + + // Extra check + if (tparam && tparam.ty == Tinstance) + { + TypeInstance tp = cast(TypeInstance)tparam; + + //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl); + //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl); + if (!tp.tempinst.tempdecl) + { //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars()); + if (!tp.tempinst.name.equals(tempinst.name)) + { + /* Handle case of: + * template Foo(T : sa!(T), alias sa) + */ + int i = templateIdentifierLookup(tp.tempinst.name, parameters); + if (i == -1) + { /* Didn't find it as a parameter identifier. Try looking + * it up and seeing if is an alias. See Bugzilla 1454 + */ + Dsymbol s = tempinst.tempdecl.scope_.search(Loc(0), tp.tempinst.name, null); + if (s) + { + s = s.toAlias(); + TemplateDeclaration td = s.isTemplateDeclaration(); + if (td && td == tempinst.tempdecl) + goto L2; + } + goto Lnomatch; + } + TemplateParameter tpx = cast(TemplateParameter)parameters.data[i]; + // This logic duplicates tpx->matchArg() + TemplateAliasParameter ta = tpx.isTemplateAliasParameter(); + if (!ta) + goto Lnomatch; + Object sa = tempinst.tempdecl; + if (!sa) + goto Lnomatch; + if (ta.specAlias && sa != ta.specAlias) + goto Lnomatch; + if (dedtypes.data[i]) + { // Must match already deduced symbol + Object s = cast(Object)dedtypes.data[i]; + + if (s != sa) + goto Lnomatch; + } + dedtypes.data[i] = cast(void*)sa; + } + } + else if (tempinst.tempdecl != tp.tempinst.tempdecl) + goto Lnomatch; + +L2: + + for (int i = 0; 1; i++) + { + //printf("\ttest: tempinst->tiargs[%d]\n", i); + Object o1; + if (i < tempinst.tiargs.dim) + o1 = cast(Object)tempinst.tiargs.data[i]; + else if (i < tempinst.tdtypes.dim && i < tp.tempinst.tiargs.dim) + // Pick up default arg + o1 = cast(Object)tempinst.tdtypes.data[i]; + else + break; + + if (i >= tp.tempinst.tiargs.dim) + goto Lnomatch; + + Object o2 = cast(Object)tp.tempinst.tiargs.data[i]; + + Type t1 = isType(o1); + Type t2 = isType(o2); + + Expression e1 = isExpression(o1); + Expression e2 = isExpression(o2); + + Dsymbol s1 = isDsymbol(o1); + Dsymbol s2 = isDsymbol(o2); + + Tuple v1 = isTuple(o1); + Tuple v2 = isTuple(o2); +static if (0) { + if (t1) printf("t1 = %s\n", t1.toChars()); + if (t2) printf("t2 = %s\n", t2.toChars()); + if (e1) printf("e1 = %s\n", e1.toChars()); + if (e2) printf("e2 = %s\n", e2.toChars()); + if (s1) printf("s1 = %s\n", s1.toChars()); + if (s2) printf("s2 = %s\n", s2.toChars()); + if (v1) printf("v1 = %s\n", v1.toChars()); + if (v2) printf("v2 = %s\n", v2.toChars()); +} + + TemplateTupleParameter ttp; + int j; + if (t2 && + t2.ty == Tident && + i == tp.tempinst.tiargs.dim - 1 && + i == tempinst.tempdecl.parameters.dim - 1 && + (ttp = tempinst.tempdecl.isVariadic()) !is null) + { + /* Given: + * struct A(B...) {} + * alias A!(int, float) X; + * static if (!is(X Y == A!(Z), Z)) + * deduce that Z is a tuple(int, float) + */ + + j = templateParameterLookup(t2, parameters); + if (j == -1) + goto Lnomatch; + + /* Create tuple from remaining args + */ + Tuple vt = new Tuple(); + int vtdim = tempinst.tiargs.dim - i; + vt.objects.setDim(vtdim); + for (size_t k = 0; k < vtdim; k++) + vt.objects.data[k] = cast(void *)tempinst.tiargs.data[i + k]; + + Tuple v = cast(Tuple)dedtypes.data[j]; + if (v) + { + if (!match(v, vt, tempinst.tempdecl, sc)) + goto Lnomatch; + } + else + dedtypes.data[j] = cast(void*)vt; + break; //return MATCHexact; + } + + if (t1 && t2) + { + if (!t1.deduceType(sc, t2, parameters, dedtypes)) + goto Lnomatch; + } + else if (e1 && e2) + { + if (!e1.equals(e2)) + { if (e2.op == TOKvar) + { + /* + * (T:Number!(e2), int e2) + */ + j = templateIdentifierLookup((cast(VarExp)e2).var.ident, parameters); + goto L1; + } + goto Lnomatch; + } + } + else if (e1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); +L1: + if (j == -1) + goto Lnomatch; + TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j]; + // BUG: use tp->matchArg() instead of the following + TemplateValueParameter tv = tp_.isTemplateValueParameter(); + if (!tv) + goto Lnomatch; + Expression e = cast(Expression)dedtypes.data[j]; + if (e) + { + if (!e1.equals(e)) + goto Lnomatch; + } + else + { Type vt = tv.valType.semantic(Loc(0), sc); + MATCH m = cast(MATCH)e1.implicitConvTo(vt); + if (!m) + goto Lnomatch; + dedtypes.data[j] = cast(void*)e1; + } + } + else if (s1 && t2 && t2.ty == Tident) + { + j = templateParameterLookup(t2, parameters); + if (j == -1) + goto Lnomatch; + TemplateParameter tp_ = cast(TemplateParameter)parameters.data[j]; + // BUG: use tp->matchArg() instead of the following + TemplateAliasParameter ta = tp_.isTemplateAliasParameter(); + if (!ta) + goto Lnomatch; + Dsymbol s = cast(Dsymbol)dedtypes.data[j]; + if (s) + { + if (!s1.equals(s)) + goto Lnomatch; + } + else + { + dedtypes.data[j] = cast(void*)s1; + } + } + else if (s1 && s2) + { + if (!s1.equals(s2)) + goto Lnomatch; + } + // BUG: Need to handle tuple parameters + else + goto Lnomatch; + } + } + return Type.deduceType(sc, tparam, parameters, dedtypes); + +Lnomatch: + //printf("no match\n"); + return MATCHnomatch; } -} \ No newline at end of file +}