Mercurial > projects > ddmd
diff dmd/TypeFunction.d @ 123:9e39c7de8438
Make dmd test suite compile
author | korDen |
---|---|
date | Fri, 03 Sep 2010 20:46:58 +0400 |
parents | e28b18c23469 |
children | 1765f3ef917d |
line wrap: on
line diff
--- a/dmd/TypeFunction.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/TypeFunction.d Fri Sep 03 20:46:58 2010 +0400 @@ -4,6 +4,7 @@ import dmd.TypeNext; import dmd.TypeSArray; import dmd.TypeArray; +import dmd.TemplateTupleParameter; import dmd.ArrayTypes; import dmd.LINK; import dmd.StructDeclaration; @@ -12,6 +13,9 @@ import dmd.STC; import dmd.MOD; import dmd.PROT; +import dmd.TypeIdentifier; +import dmd.TemplateParameter; +import dmd.Tuple; import dmd.Type; import dmd.Loc; import dmd.Scope; @@ -26,6 +30,7 @@ import dmd.RET; import dmd.TY; import dmd.Util; +import dmd.TemplateInstance : isTuple; import dmd.backend.TYPE; import dmd.backend.PARAM; @@ -395,7 +400,100 @@ override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { - assert(false); + //printf("TypeFunction.deduceType()\n"); + //printf("\tthis = %d, ", ty); print(); + //printf("\ttparam = %d, ", tparam.ty); tparam.print(); + + // Extra check that function characteristics must match + if (tparam && tparam.ty == Tfunction) + { + TypeFunction tp = cast(TypeFunction)tparam; + if (varargs != tp.varargs || + linkage != tp.linkage) + return MATCHnomatch; + + size_t nfargs = Argument.dim(this.parameters); + size_t nfparams = Argument.dim(tp.parameters); + + /* See if tuple match + */ + if (nfparams > 0 && nfargs >= nfparams - 1) + { + /* See if 'A' of the template parameter matches 'A' + * of the type of the last function parameter. + */ + Argument fparam = Argument.getNth(tp.parameters, nfparams - 1); + assert(fparam); + assert(fparam.type); + if (fparam.type.ty != Tident) + goto L1; + TypeIdentifier tid = cast(TypeIdentifier)fparam.type; + if (tid.idents.dim) + goto L1; + + /* Look through parameters to find tuple matching tid.ident + */ + size_t tupi = 0; + for (; 1; tupi++) + { + if (tupi == parameters.dim) + goto L1; + TemplateParameter t = parameters[tupi]; + TemplateTupleParameter tup = t.isTemplateTupleParameter(); + if (tup && tup.ident.equals(tid.ident)) + break; + } + + /* The types of the function arguments [nfparams - 1 .. nfargs] + * now form the tuple argument. + */ + int tuple_dim = nfargs - (nfparams - 1); + + /* See if existing tuple, and whether it matches or not + */ + Object o = dedtypes[tupi]; + if (o) + { + // Existing deduced argument must be a tuple, and must match + Tuple t = isTuple(o); + if (!t || t.objects.dim != tuple_dim) + return MATCHnomatch; + for (size_t i = 0; i < tuple_dim; i++) + { + Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + if (!arg.type.equals(t.objects[i])) + return MATCHnomatch; + } + } + else + { // Create new tuple + Tuple t = new Tuple(); + t.objects.setDim(tuple_dim); + for (size_t i = 0; i < tuple_dim; i++) + { + Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + t.objects[i] = arg.type; + } + dedtypes[tupi] = t; + } + nfparams--; // don't consider the last parameter for type deduction + goto L2; + } + + L1: + if (nfargs != nfparams) + return MATCHnomatch; + L2: + for (size_t i = 0; i < nfparams; i++) + { + Argument a = Argument.getNth(this.parameters, i); + Argument ap = Argument.getNth(tp.parameters, i); + if (a.storageClass != ap.storageClass || + !a.type.deduceType(sc, ap.type, parameters, dedtypes)) + return MATCHnomatch; + } + } + return Type.deduceType(sc, tparam, parameters, dedtypes); } override TypeInfoDeclaration getTypeInfoDeclaration()