diff dmd/TypeFunction.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 010eb8f0e18d
children 206db751bd4c
line wrap: on
line diff
--- a/dmd/TypeFunction.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/TypeFunction.d	Thu Sep 09 22:51:44 2010 +0100
@@ -26,10 +26,11 @@
 import dmd.CppMangleState;
 import dmd.TypeInfoDeclaration;
 import dmd.MATCH;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.Expression;
 import dmd.RET;
 import dmd.TY;
+import dmd.TRUST;
 import dmd.Util;
 import dmd.TemplateInstance : isTuple;
 
@@ -49,7 +50,7 @@
 {
     // .next is the return type
 
-    Arguments parameters;	// function parameters
+    Parameters parameters;	// function parameters
     int varargs;	// 1: T t, ...) style for variable number of arguments
 			// 2: T t ...) style for variable number of arguments
     bool isnothrow;	// true: nothrow
@@ -57,10 +58,11 @@
     bool isproperty;	// can be called without parentheses
     bool isref;		// true: returns a reference
     LINK linkage;	// calling convention
+    TRUST trust;	// level of trust
 
     int inuse;
 
-    this(Arguments parameters, Type treturn, int varargs, LINK linkage)
+    this(Parameters parameters, Type treturn, int varargs, LINK linkage)
 	{
 		super(TY.Tfunction, treturn);
 
@@ -70,18 +72,20 @@
 		this.parameters = parameters;
 		this.varargs = varargs;
 		this.linkage = linkage;
+        this.trust = TRUSTdefault;
 	}
 	
     override Type syntaxCopy()
 	{
 		Type treturn = next ? next.syntaxCopy() : null;
-		Arguments params = Argument.arraySyntaxCopy(parameters);
+		auto params = Parameter.arraySyntaxCopy(parameters);
 		TypeFunction t = new TypeFunction(params, treturn, varargs, linkage);
 		t.mod = mod;
 		t.isnothrow = isnothrow;
 		t.ispure = ispure;
 		t.isproperty = isproperty;
 		t.isref = isref;
+        t.trust = trust;
 
 		return t;
 	}
@@ -145,8 +149,29 @@
 			tf.isnothrow = true;
 		if (sc.stc & STC.STCref)
 			tf.isref = true;
+        if (sc.stc & STCsafe)
+    	    tf.trust = TRUST.TRUSTsafe;
+        if (sc.stc & STCtrusted)
+    	    tf.trust = TRUST.TRUSTtrusted;
+        if (sc.stc & STCproperty)
+	        tf.isproperty = true;
+        
+		tf.linkage = sc.linkage;
+        
+        /* If the parent is @safe, then this function defaults to safe
+         * too.
+         */
+        if (tf.trust == TRUST.TRUSTdefault)
+	        for (Dsymbol p = sc.func; p; p = p.toParent2())
+	        {   FuncDeclaration fd = p.isFuncDeclaration();
+	            if (fd)
+	            {
+    		        if (fd.isSafe())
+		                tf.trust = TRUST.TRUSTsafe;		// default to @safe
+		            break;
+	            }
+	        }
 
-		tf.linkage = sc.linkage;
 		if (tf.next)
 		{
 			tf.next = tf.next.semantic(loc,sc);
@@ -183,7 +208,7 @@
 			size_t dim = Argument.dim(tf.parameters);
 
 			for (size_t i = 0; i < dim; i++)
-			{   Argument arg = Argument.getNth(tf.parameters, i);
+			{   auto arg = Parameter.getNth(tf.parameters, i);
 
 				tf.inuse++;
 				arg.type = arg.type.semantic(loc, argsc);
@@ -220,7 +245,7 @@
 				 * change.
 				 */
 				if (t.ty == TY.Ttuple)
-				{	dim = Argument.dim(tf.parameters);
+				{	dim = Parameter.dim(tf.parameters);
 					i--;
 				}
 			}
@@ -235,7 +260,10 @@
 			return terror;
 		}
 
-		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Argument.dim(tf.parameters) == 0)
+        if (tf.isproperty && (tf.varargs || Parameter.dim(tf.parameters) > 1))
+	    error(loc, "properties can only have zero or one parameter");
+
+		if (tf.varargs == 1 && tf.linkage != LINK.LINKd && Parameter.dim(tf.parameters) == 0)
 			error(loc, "variadic functions with non-D linkage must have at least one parameter");
 
 		/* Don't return merge(), because arg identifiers and default args
@@ -274,7 +302,7 @@
 			case LINK.LINKcpp:		mc = 'R';	break;
 		}
 		buf.writeByte(mc);
-		if (ispure || isnothrow || isproperty || isref)
+		if (ispure || isnothrow || isproperty || isref || trust)
 		{
 			if (ispure)
 				buf.writestring("Na");
@@ -284,9 +312,18 @@
 				buf.writestring("Nc");
 			if (isproperty)
 				buf.writestring("Nd");
+	        switch (trust)
+	        {
+	            case TRUST.TRUSTtrusted:
+		            buf.writestring("Ne");
+		            break;
+	            case TRUST.TRUSTsafe:
+		            buf.writestring("Nd");
+		            break;
+	        }
 		}
 		// Write argument types
-		Argument.argsToDecoBuffer(buf, parameters);
+		Parameter.argsToDecoBuffer(buf, parameters);
 		//if (buf.data[buf.offset - 1] == '@') halt();
 		buf.writeByte('Z' - varargs);	// mark end of arg list
 		assert(next);
@@ -324,6 +361,17 @@
 		if (isref)
 			buf.writestring("ref ");
 
+        switch (trust)
+        {
+	    case TRUST.TRUSTtrusted:
+	        buf.writestring("@trusted ");
+	        break;
+
+	    case TRUST.TRUSTsafe:
+	        buf.writestring("@safe ");
+	        break;
+        }
+
 		if (next && (!ident || ident.toHChars2() == ident.toChars()))
 			next.toCBuffer2(buf, hgs, MODundefined);
 		if (hgs.ddoc != 1)
@@ -347,7 +395,7 @@
 			buf.writeByte(' ');
 			buf.writestring(ident.toHChars2());
 		}
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 		inuse--;
 	}
 	
@@ -382,7 +430,7 @@
 		if (!hgs.hdrgen && p)
 			buf.writestring(p);
 		buf.writestring(" function");
-		Argument.argsToCBuffer(buf, hgs, parameters, varargs);
+		Parameter.argsToCBuffer(buf, hgs, parameters, varargs);
 
 		/* Use postfix style for attributes
 		 */
@@ -400,6 +448,16 @@
 		if (isref)
 			buf.writestring(" ref");
 
+        switch (trust)
+        {
+	    case TRUSTtrusted:
+	        buf.writestring(" @trusted");
+	        break;
+
+	    case TRUSTsafe:
+	        buf.writestring(" @safe");
+	        break;
+        }
 		inuse--;
 	}
 	
@@ -417,8 +475,8 @@
 				linkage != tp.linkage)
 				return MATCHnomatch;
 
-			size_t nfargs = Argument.dim(this.parameters);
-			size_t nfparams = Argument.dim(tp.parameters);
+			size_t nfargs = Parameter.dim(this.parameters);
+			size_t nfparams = Parameter.dim(tp.parameters);
 
 			/* See if tuple match
 			 */
@@ -427,7 +485,7 @@
 				/* 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);
+				auto fparam = Parameter.getNth(tp.parameters, nfparams - 1);
 				assert(fparam);
 				assert(fparam.type);
 				if (fparam.type.ty != Tident)
@@ -465,7 +523,7 @@
 						return MATCHnomatch;
 					for (size_t i = 0; i < tuple_dim; i++)
 					{   
-						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
 						if (!arg.type.equals(t.objects[i]))
 							return MATCHnomatch;
 					}
@@ -476,7 +534,7 @@
 					t.objects.setDim(tuple_dim);
 					for (size_t i = 0; i < tuple_dim; i++)
 					{   
-						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						auto arg = Parameter.getNth(this.parameters, nfparams - 1 + i);
 						t.objects[i] = arg.type;
 					}
 					dedtypes[tupi] = t;
@@ -491,8 +549,8 @@
 			L2:
 			for (size_t i = 0; i < nfparams; i++)
 			{
-				Argument a = Argument.getNth(this.parameters, i);
-				Argument ap = Argument.getNth(tp.parameters, i);
+				auto a = Parameter.getNth(this.parameters, i);
+				auto ap = Parameter.getNth(tp.parameters, i);
 				if (a.storageClass != ap.storageClass ||
 					!a.type.deduceType(sc, ap.type, parameters, dedtypes))
 				return MATCHnomatch;
@@ -531,7 +589,7 @@
 	 * Examine function signature for parameter p and see if
 	 * p can 'escape' the scope of the function.
 	 */
-    bool parameterEscapes(Argument p)
+    bool parameterEscapes(Parameter p)
 	{
 		/* Scope parameters do not escape.
 		 * Allow 'lazy' to imply 'scope' -
@@ -586,7 +644,7 @@
 			}
 		}
 
-		size_t nparams = Argument.dim(parameters);
+		size_t nparams = Parameter.dim(parameters);
 		size_t nargs = args ? args.dim : 0;
 		if (nparams == nargs) {
 			;
@@ -604,7 +662,7 @@
 
 			// BUG: what about out and ref?
 
-			Argument p = Argument.getNth(parameters, u);
+			auto p = Parameter.getNth(parameters, u);
 			assert(p);
 			if (u >= nargs)
 			{
@@ -745,10 +803,10 @@
 			type* tp;
 
 			paramtypes = null;
-			size_t nparams = Argument.dim(parameters);
+			size_t nparams = Parameter.dim(parameters);
 			for (size_t i = 0; i < nparams; i++)
 			{   
-				Argument arg = Argument.getNth(parameters, i);
+				auto arg = Parameter.getNth(parameters, i);
 				tp = arg.type.toCtype();
 				if (arg.storageClass & (STC.STCout | STC.STCref))
 				{