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()