diff dmd/Type.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 347de076ad34
children 206db751bd4c
line wrap: on
line diff
--- a/dmd/Type.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Type.d	Thu Sep 09 22:51:44 2010 +0100
@@ -2,7 +2,7 @@
 
 import dmd.common;
 import dmd.TY;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.TOK;
 import dmd.STC;
 import dmd.TypeArray;
@@ -396,8 +396,8 @@
     DYNCAST dyncast() { return DYNCAST.DYNCAST_TYPE; } // kludge for template.isType()
 
 	/*******************************
-	 * Covariant means that 'this' can substitute for 't'.
-	 * Returns:
+     * Covariant means that 'this' can substitute for 't',
+     * i.e. a pure function is a match for an impure type.	 * Returns:
 	 *	0	types are distinct
 	 *	1	this is covariant with t
 	 *	2	arguments match as far as overloading goes,
@@ -433,14 +433,14 @@
 
 		if (t1.parameters && t2.parameters)
 		{
-			size_t dim = Argument.dim(t1.parameters);
-			if (dim != Argument.dim(t2.parameters))
+			size_t dim = Parameter.dim(t1.parameters);
+			if (dim != Parameter.dim(t2.parameters))
 				goto Ldistinct;
 
 			for (size_t i = 0; i < dim; i++)
 			{   
-				Argument arg1 = Argument.getNth(t1.parameters, i);
-				Argument arg2 = Argument.getNth(t2.parameters, i);
+				auto arg1 = Parameter.getNth(t1.parameters, i);
+				auto arg2 = Parameter.getNth(t2.parameters, i);
 
 				if (!arg1.type.equals(arg2.type))
 				{
@@ -452,7 +452,8 @@
 ///}
 					goto Ldistinct;
 				}
-				if ((arg1.storageClass & ~STC.STCscope) != (arg2.storageClass & ~STC.STCscope))
+                const STC sc = STC.STCref | STC.STCin | STC.STCout | STC.STClazy;
+				if ((arg1.storageClass & sc) != (arg2.storageClass & sc))
 					inoutmismatch = 1;
 				// We can add scope, but not subtract it
 				if (!(arg1.storageClass & STC.STCscope) && (arg2.storageClass & STC.STCscope))
@@ -521,6 +522,11 @@
 			goto Lnotcovariant;
 
 		if (t1.isref != t2.isref)
+	        goto Lnotcovariant;
+
+        /* Can convert safe/trusted to system
+         */
+        if (t1.trust <= TRUST.TRUSTsystem && t2.trust >= TRUSTtrusted)
 			goto Lnotcovariant;
 
 		//printf("\tcovaraint: 1\n");
@@ -1764,11 +1770,11 @@
 			//		    if (!e.isConst())
 			//			error(loc, ".init cannot be evaluated at compile time");
 					}
-					return e;
+					goto Lreturn;
 				}
 }
-				Expression ex = defaultInit(e.loc);
-				return ex;
+				e = defaultInit(e.loc);
+	            goto Lreturn;
 			}
 		}
 		if (ident is Id.typeinfo_)
@@ -1776,19 +1782,89 @@
 			if (!global.params.useDeprecated)
 				error(e.loc, ".typeinfo deprecated, use typeid(type)");
 			e = getTypeInfo(sc);
-			return e;
 		}
-		if (ident is Id.stringof_)
+		else if (ident is Id.stringof_)
 		{		
 			string s = e.toChars();
 			e = new StringExp(e.loc, s, 'c');
-			scope Scope sc2 = new Scope(); ///
-			e = e.semantic(sc2);
-			return e;
 		}
-		return getProperty(e.loc, ident);
+        else
+    	    e = getProperty(e.loc, ident);
+        
+Lreturn:
+        e = e.semantic(sc);
+        return e;
 	}
 	
+    /***************************************
+     * Figures out what to do with an undefined member reference
+     * for classes and structs.
+     */
+    Expression noMember(Scope sc, Expression e, Identifier ident)
+    {
+        assert(ty == TY.Tstruct || ty == TY.Tclass);
+        AggregateDeclaration sym = toDsymbol(sc).isAggregateDeclaration();
+        assert(sym);
+
+        if (ident != Id.__sizeof &&
+	    ident != Id.alignof &&
+	    ident != Id.init &&
+	    ident != Id.mangleof &&
+	    ident != Id.stringof &&
+	    ident != Idoffsetof)
+        {
+	    /* See if we should forward to the alias this.
+	     */
+	    if (sym.aliasthis)
+	    {   /* Rewrite e.ident as:
+	         *	e.aliasthis.ident
+	         */
+	        e = new DotIdExp(e.loc, e, sym.aliasthis.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDot() to see if we should forward request
+	     * to it.
+	     */
+	    Dsymbol fd = search_function(sym, Id.opDot);
+	    if (fd)
+	    {   /* Rewrite e.ident as:
+	         *	e.opDot().ident
+	         */
+	        e = build_overload(e.loc, sc, e, NULL, fd.ident);
+	        e = new DotIdExp(e.loc, e, ident);
+	        return e.semantic(sc);
+	    }
+
+	    /* Look for overloaded opDispatch to see if we should forward request
+	     * to it.
+	     */
+	    fd = search_function(sym, Id.opDispatch);
+	    if (fd)
+	    {
+	        /* Rewrite e.ident as:
+	         *	e.opDispatch!("ident")
+	         */
+	        TemplateDeclaration td = fd.isTemplateDeclaration();
+	        if (!td)
+	        {
+		    fd.error("must be a template opDispatch(string s), not a %s", fd.kind());
+		    return new ErrorExp();
+	        }
+	        auto se = new StringExp(e.loc, ident.toChars());
+	        auto tiargs = new Objects();
+	        tiargs.push(se);
+	        e = new DotTemplateInstanceExp(e.loc, e, Id.opDispatch, tiargs);
+	        (cast(DotTemplateInstanceExp)e).ti.tempdecl = td;
+	        return e;
+	        //return e.semantic(sc);
+	    }
+        }
+
+        return Type.dotExp(sc, e, ident);
+    }
+    
     uint memalign(uint salign)
 	{
 		return salign;