diff dmd/TemplateDeclaration.d @ 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents e6e542f37b94
children 206db751bd4c
line wrap: on
line diff
--- a/dmd/TemplateDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TemplateDeclaration.d	Thu Sep 09 22:51:44 2010 +0100
@@ -19,7 +19,7 @@
 import dmd.TypeSArray;
 import dmd.StringExp;
 import dmd.TOK;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.CtorDeclaration;
 import dmd.TypeFunction;
 import dmd.TY;
@@ -544,6 +544,7 @@
 		if (m && constraint && !(flag & 1))
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -687,7 +688,7 @@
 		int tuple_dim = 0;
 		MATCH match = MATCHexact;
 		FuncDeclaration fd = onemember.toAlias().isFuncDeclaration();
-		Arguments fparameters;		// function parameter list
+		Parameters fparameters;		// function parameter list
 		int fvarargs;			// function varargs
 		scope Objects dedtypes = new Objects();	// for T:T*, the dedargs is the T*, dedtypes is the T
 
@@ -717,6 +718,7 @@
 		Scope paramscope = scope_.push(paramsym);
 
 		TemplateTupleParameter tp = isVariadic();
+        int tp_is_declared = 0;
 
 	static if (false)
 	{
@@ -757,6 +759,7 @@
 					t.objects[i] = targsi[n + i];
 				}
 				declareParameter(paramscope, tp, t);
+                tp_is_declared = 1;
 			}
 			else
 				n = nargsi;
@@ -808,7 +811,7 @@
 			fvarargs = fctor.varargs;
 		}
 
-		nfparams = Argument.dim(fparameters);	// number of function parameters
+		nfparams = Parameter.dim(fparameters);	// number of function parameters
 		nfargs = fargs ? fargs.dim : 0;		// number of function arguments
 
 		/* Check for match of function arguments with variadic template
@@ -821,6 +824,8 @@
 		{
 			if (nfparams == 0 && nfargs != 0)		// if no function parameters
 			{
+	            if (tp_is_declared)
+		            goto L2;
 				auto t = new Tuple();
 				//printf("t = %p\n", t);
 				dedargs[parameters.dim - 1] = t;
@@ -848,6 +853,9 @@
 					if (fvarargs)		// variadic function doesn't
 						goto Lnomatch;	// go with variadic template
 
+            		if (tp_is_declared)
+            		    goto L2;
+                    
 					/* The types of the function arguments
 					 * now form the tuple argument.
 					 */
@@ -915,7 +923,7 @@
 				continue;
 			}
 
-			Argument fparam = Argument.getNth(fparameters, i);
+			auto fparam = Parameter.getNth(fparameters, i);
 
 			if (i >= nfargs)		// if not enough arguments
 			{
@@ -963,7 +971,7 @@
 					TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype();
 					TypeFunction tf = cast(TypeFunction)td.next;
 
-					if (!tf.varargs && Argument.dim(tf.parameters) == 0)
+					if (!tf.varargs && Parameter.dim(tf.parameters) == 0)
 					{
 						m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes);
 						if (!m && tf.next.toBasetype().ty == Tvoid)
@@ -1100,6 +1108,7 @@
 		if (constraint)
 		{	/* Check to see if constraint is satisfied.
 			 */
+            makeParamNamesVisibleInConstraint(paramscope);
 			Expression e = constraint.syntaxCopy();
 			paramscope.flags |= SCOPE.SCOPEstaticif;
 			e = e.semantic(paramscope);
@@ -1366,4 +1375,60 @@
 	{
 		return true;
 	}
+    
+    /****************************
+     * Declare all the function parameters as variables
+     * and add them to the scope
+     */
+    void makeParamNamesVisibleInConstraint(Scope paramscope)
+    {
+        /* We do this ONLY if there is only one function in the template.
+         */	 
+        FuncDeclaration fd = onemember && onemember.toAlias() ?
+	    onemember.toAlias().isFuncDeclaration() : NULL;
+        if (fd)
+        {
+	        paramscope.parent = fd;
+	        Parameters fparameters;		// function parameter list
+	        int fvarargs;				// function varargs
+	        if (fd.type)
+	        {
+	            assert(fd.type.ty == Tfunction);
+	            TypeFunction fdtype = cast(TypeFunction )fd.type;
+	            fparameters = fdtype.parameters;
+	            fvarargs = fdtype.varargs;
+	        }
+	        else // Constructors don't have type's
+	        {   CtorDeclaration fctor = fd.isCtorDeclaration();
+	            assert(fctor);
+	            fparameters = fctor.arguments;
+	            fvarargs = fctor.varargs;
+	        }
+	        size_t nfparams = Parameter.dim(fparameters); // Num function parameters
+	        for (int i = 0; i < nfparams; i++)
+	        {
+	            Parameter fparam = Parameter.getNth(fparameters, i).syntaxCopy();
+	            if (!fparam.ident)
+		            continue;			// don't add it, if it has no name
+	            Type vtype = fparam.type.syntaxCopy();
+	            // isPure will segfault if called on a ctor, because fd->type is null.
+	            if (fd.type && fd.isPure())
+		        vtype = vtype.addMod(MODconst);
+	            VarDeclaration v = new VarDeclaration(loc, vtype, fparam.ident, null);
+	            v.storage_class |= STCparameter;
+	            // Not sure if this condition is correct/necessary.
+	            //   It's from func.c
+	            if (//fd->type && fd->type->ty == Tfunction &&
+	                fvarargs == 2 && i + 1 == nfparams)
+		            v.storage_class |= STCvariadic;
+		
+	            v.storage_class |= fparam.storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor);
+	            v.semantic(paramscope);
+	            if (!paramscope.insert(v))
+		            error("parameter %s.%s is already defined", toChars(), v.toChars());
+	            else
+		            v.parent = this;
+	        }
+        }
+    }
 }