changeset 1617:6820110de311

Merge DMD r301: a little refactor and harmonize --- dmd/declaration.h | 1 + dmd/func.c | 30 ++++++++++++++++++++++++++++++ dmd/mtype.c | 51 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 68 insertions(+), 14 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:21 -0300
parents c94049033c20
children a87f1d6ff48e
files dmd/declaration.h dmd/func.c dmd/mtype.c
diffstat 3 files changed, 71 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/declaration.h	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/declaration.h	Wed Jan 06 15:18:21 2010 -0300
@@ -763,6 +763,7 @@
     int needsClosure();
     Statement *mergeFrequire(Statement *);
     Statement *mergeFensure(Statement *);
+    Parameters *getParameters(int *pvarargs);
 
 // LDC: give argument types to runtime functions
     static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name);
--- a/dmd/func.c	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/func.c	Wed Jan 06 15:18:21 2010 -0300
@@ -850,6 +850,7 @@
         }
 #endif
 
+#if 0
 	// Propagate storage class from tuple parameters to their element-parameters.
 	if (f->parameters)
 	{
@@ -867,6 +868,7 @@
 		}
 	    }
 	}
+#endif
 
 	/* Declare all the function parameters as variables
 	 * and install them in parameters[]
@@ -2491,6 +2493,34 @@
 }
 #endif
 
+/*********************************************
+ * Return the function's parameter list, and whether
+ * it is variadic or not.
+ */
+
+Parameters *FuncDeclaration::getParameters(int *pvarargs)
+{   Parameters *fparameters;
+    int fvarargs;
+
+    if (type)
+    {
+	assert(type->ty == Tfunction);
+	TypeFunction *fdtype = (TypeFunction *)type;
+	fparameters = fdtype->parameters;
+	fvarargs = fdtype->varargs;
+    }
+    else // Constructors don't have type's
+    {   CtorDeclaration *fctor = isCtorDeclaration();
+	assert(fctor);
+	fparameters = fctor->arguments;
+	fvarargs = fctor->varargs;
+    }
+    if (pvarargs)
+	*pvarargs = fvarargs;
+    return fparameters;
+}
+
+
 /****************************** FuncAliasDeclaration ************************/
 
 // Used as a way to import a set of functions from another scope into this one.
--- a/dmd/mtype.c	Wed Jan 06 15:18:21 2010 -0300
+++ b/dmd/mtype.c	Wed Jan 06 15:18:21 2010 -0300
@@ -2965,7 +2965,12 @@
 	return this;
     }
     //printf("TypeFunction::semantic() this = %p\n", this);
-
+    //printf("TypeFunction::semantic() %s, sc->stc = %x\n", toChars(), sc->stc);
+
+    /* Copy in order to not mess up original.
+     * This can produce redundant copies if inferring return type,
+     * as semantic() will get called again on this.
+     */
     TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
     memcpy(tf, this, sizeof(TypeFunction));
     if (parameters)
@@ -2982,10 +2987,12 @@
     if (tf->next)
     {
 	tf->next = tf->next->semantic(loc,sc);
+#if !SARRAYVALUE
 	if (tf->next->toBasetype()->ty == Tsarray)
 	{   error(loc, "functions cannot return static array %s", tf->next->toChars());
 	    tf->next = Type::terror;
 	}
+#endif
 	if (tf->next->toBasetype()->ty == Tfunction)
 	{   error(loc, "functions cannot return a function");
 	    tf->next = Type::terror;
@@ -3008,44 +3015,60 @@
 
 	size_t dim = Parameter::dim(tf->parameters);
 	for (size_t i = 0; i < dim; i++)
-	{   Parameter *arg = Parameter::getNth(tf->parameters, i);
+	{   Parameter *fparam = Parameter::getNth(tf->parameters, i);
 
 	    tf->inuse++;
-	    arg->type = arg->type->semantic(loc, argsc);
+	    fparam->type = fparam->type->semantic(loc, argsc);
 	    if (tf->inuse == 1) tf->inuse--;
 
 	    // each function needs its own copy of a tuple arg, since
 	    // they mustn't share arg flags like inreg, ...
-	    if (arg->type->ty == Ttuple) {
-		arg->type = arg->type->syntaxCopy();
+	    if (fparam->type->ty == Ttuple) {
+		fparam->type = fparam->type->syntaxCopy();
 		tf->inuse++;
-		arg->type = arg->type->semantic(loc,sc);
+		fparam->type = fparam->type->semantic(loc,sc);
 		if (tf->inuse == 1) tf->inuse--;
 	    }
 
-	    Type *t = arg->type->toBasetype();
-
-	    if (arg->storageClass & (STCout | STCref | STClazy))
+	    Type *t = fparam->type->toBasetype();
+
+	    if (fparam->storageClass & (STCout | STCref | STClazy))
 	    {
 		if (t->ty == Tsarray)
 		    error(loc, "cannot have out or ref parameter of type %s", t->toChars());
 	    }
-	    if (!(arg->storageClass & STClazy) && t->ty == Tvoid)
-		error(loc, "cannot have parameter of type %s", arg->type->toChars());
-
-	    if (arg->defaultArg)
+	    if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
+		error(loc, "cannot have parameter of type %s", fparam->type->toChars());
+
+	    if (fparam->defaultArg)
 	    {
-		arg->defaultArg = arg->defaultArg->semantic(argsc);
-		arg->defaultArg = resolveProperties(argsc, arg->defaultArg);
-		arg->defaultArg = arg->defaultArg->implicitCastTo(argsc, arg->type);
+		fparam->defaultArg = fparam->defaultArg->semantic(argsc);
+		fparam->defaultArg = resolveProperties(argsc, fparam->defaultArg);
+		fparam->defaultArg = fparam->defaultArg->implicitCastTo(argsc, fparam->type);
 	    }
 
 	    /* If arg turns out to be a tuple, the number of parameters may
 	     * change.
 	     */
 	    if (t->ty == Ttuple)
-	    {	dim = Parameter::dim(tf->parameters);
+	    {
+		// Propagate storage class from tuple parameters to their element-parameters.
+		TypeTuple *tt = (TypeTuple *)t;
+		if (tt->arguments)
+		{
+		    size_t tdim = tt->arguments->dim;
+		    for (size_t j = 0; j < tdim; j++)
+		    {   Parameter *narg = (Parameter *)tt->arguments->data[j];
+			narg->storageClass = fparam->storageClass;
+		    }
+		}
+
+		/* Reset number of parameters, and back up one to do this arg again,
+		 * now that it is the first element of a tuple
+		 */
+		dim = Parameter::dim(tf->parameters);
 		i--;
+		continue;
 	    }
 	}
 	argsc->pop();