diff dmd/FuncDeclaration.d @ 135:af1bebfd96a4 dmd2037

dmd 2.038
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Mon, 13 Sep 2010 22:19:42 +0100
parents 206db751bd4c
children bc45b1c53019
line wrap: on
line diff
--- a/dmd/FuncDeclaration.d	Sat Sep 11 13:03:39 2010 +0100
+++ b/dmd/FuncDeclaration.d	Mon Sep 13 22:19:42 2010 +0100
@@ -309,37 +309,59 @@
 			originalType = type;
 		if (!type.deco)
 		{
+    	    sc = sc.push();
+	        sc.stc |= storage_class & STC.STCref;	// forward refness to function type
+	        type = type.semantic(loc, sc);
+	        sc = sc.pop();
+            
 			/* Apply const, immutable and shared storage class
 			 * to the function type
 			 */
-			type = type.semantic(loc, sc);
 			StorageClass stc = storage_class;
-			if (type.isInvariant())
+			if (type.isImmutable())
 				stc |= STC.STCimmutable;
 			if (type.isConst())
 				stc |= STC.STCconst;
 			if (type.isShared() || storage_class & STC.STCsynchronized)
 				stc |= STC.STCshared;
+	        if (type.isWild())
+	            stc |= STC.STCwild;
 			switch (stc & STC.STC_TYPECTOR)
 			{
 				case STC.STCimmutable:
 				case STC.STCimmutable | STC.STCconst:
 				case STC.STCimmutable | STC.STCconst | STC.STCshared:
 				case STC.STCimmutable | STC.STCshared:
+                case STC.STCimmutable | STC.STCwild:
+	            case STC.STCimmutable | STC.STCconst | STC.STCwild:
+	            case STC.STCimmutable | STC.STCconst | STC.STCshared | STC.STCwild:
+	            case STC.STCimmutable | STC.STCshared | STC.STCwild:
 				// Don't use toInvariant(), as that will do a merge()
 				type = type.makeInvariant();
 				goto Lmerge;
 	
 				case STC.STCconst:
+	            case STC.STCconst | STC.STCwild:
 				type = type.makeConst();
 				goto Lmerge;
 	
 				case STC.STCshared | STC.STCconst:
+	            case STC.STCshared | STC.STCconst | STC.STCwild:
 				type = type.makeSharedConst();
 				goto Lmerge;
 	
 				case STC.STCshared:
 				type = type.makeShared();
+		        goto Lmerge;
+
+	            case STC.STCwild:
+		        type = type.makeWild();
+		        goto Lmerge;
+
+	            case STC.STCshared | STC.STCwild:
+		        type = type.makeSharedWild();
+		        goto Lmerge;
+
 				Lmerge:
 					if (!(type.ty == Tfunction && !type.nextOf()))
 						/* Can't do merge if return type is not known yet
@@ -354,7 +376,7 @@
 				assert(0);
 			}
 		}
-		//type.print();
+        storage_class &= ~STC.STCref;
 		if (type.ty != TY.Tfunction)
 		{
 		error("%s must be a function", toChars());
@@ -378,7 +400,7 @@
 		if (isAbstract() && !isVirtual())
 		error("non-virtual functions cannot be abstract");
 
-		if ((f.isConst() || f.isInvariant()) && !isThis())
+		if ((f.isConst() || f.isImmutable()) && !isThis())
 		error("without 'this' cannot be const/immutable");
 
 		if (isAbstract() && isFinal())
@@ -965,7 +987,7 @@
 				thandle = thandle.nextOf().constOf().pointerTo();
 				}
 			}
-			else if (storage_class & STC.STCimmutable || type.isInvariant())
+			else if (storage_class & STC.STCimmutable || type.isImmutable())
 			{
 				if (thandle.ty == TY.Tclass)
 				thandle = thandle.invariantOf();
@@ -1054,7 +1076,7 @@
 			}
 }
 		}
-
+static if(false) {
 		// Propagate storage class from tuple parameters to their element-parameters.
 		if (f.parameters)
 		{
@@ -1072,7 +1094,7 @@
 			}
 			}
 		}
-
+}
 		/* Declare all the function parameters as variables
 		 * and install them in parameters[]
 		 */
@@ -2399,10 +2421,10 @@
 		assert(tb.ty == Tfunction);
 		TypeFunction tf = cast(TypeFunction)tb;
 		Type tret = tf.next.toBasetype();
-		if (tf.varargs)
+		if (tf.varargs && arguments && parameters && arguments.dim != parameters.dim)
 		{	
 			cantInterpret = 1;
-			error("Variadic functions are not yet implemented in CTFE");
+			error("C-style variadic functions are not yet implemented in CTFE");
 			return null;
 		}
 		
@@ -2547,7 +2569,7 @@
 			}
 		}
 		// Don't restore the value of 'this' upon function return
-		if (needThis() && thisarg.op==TOKvar) {
+		if (needThis() && thisarg.op == TOKvar && istate) {
 			VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration();
  			foreach (size_t i, Dsymbol s; istate.vars)
 			{   
@@ -2562,7 +2584,7 @@
 
 		/* Save the values of the local variables used
 		 */
-		scope Expressions valueSaves = new Expressions();
+		scope valueSaves = new Expressions();
 		if (istate && !isNested())
 		{
 			//printf("saving local variables...\n");
@@ -3835,6 +3857,35 @@
 		}
 	}
 
+    /*********************************************
+     * Return the function's parameter list, and whether
+     * it is variadic or not.
+     */
+
+    Parameters getParameters(int *pvarargs)
+    {
+        Parameters fparameters;
+        int fvarargs;
+
+        if (type)
+        {
+	        assert(type.ty == Tfunction);
+	        auto fdtype = cast(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;
+    }
+
     override FuncDeclaration isFuncDeclaration() { return this; }
 }