diff dmd/PtrExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 4ae0d790a452
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PtrExp.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,193 @@
+module dmd.PtrExp;
+
+import dmd.Expression;
+import dmd.Identifier;
+import dmd.backend.elem;
+import dmd.UnaExp;
+import dmd.InterState;
+import dmd.Type;
+import dmd.OutBuffer;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.IRState;
+import dmd.HdrGenState;
+import dmd.TOK;
+import dmd.GlobalExpressions;
+import dmd.SymOffExp;
+import dmd.AddrExp;
+import dmd.VarDeclaration;
+import dmd.StructLiteralExp;
+import dmd.TypePointer;
+import dmd.TypeArray;
+import dmd.ErrorExp;
+import dmd.TY;
+import dmd.expression.Ptr;
+import dmd.expression.Util;
+
+import dmd.backend.Util;
+import dmd.backend.TYM;
+import dmd.backend.mTY;
+import dmd.backend.OPER;
+
+class PtrExp : UnaExp
+{
+	this(Loc loc, Expression e)
+	{
+		super(loc, TOK.TOKstar, PtrExp.sizeof, e);
+		//    if (e.type)
+		//		type = ((TypePointer *)e.type).next;
+	}
+
+	this(Loc loc, Expression e, Type t)
+	{
+		super(loc, TOKstar, PtrExp.sizeof, e);
+		type = t;
+	}
+
+	Expression semantic(Scope sc)
+	{
+	version (LOGSEMANTIC) {
+		printf("PtrExp::semantic('%s')\n", toChars());
+	}
+		if (!type)
+		{
+			UnaExp.semantic(sc);
+			e1 = resolveProperties(sc, e1);
+			if (!e1.type)
+				writef("PtrExp.semantic('%s')\n", toChars());
+			Expression e = op_overload(sc);
+			if (e)
+				return e;
+			Type tb = e1.type.toBasetype();
+			switch (tb.ty)
+			{
+				case Tpointer:
+					type = (cast(TypePointer)tb).next;
+					break;
+
+				case Tsarray:
+				case Tarray:
+					type = (cast(TypeArray)tb).next;
+					e1 = e1.castTo(sc, type.pointerTo());
+					break;
+
+				default:
+					error("can only * a pointer, not a '%s'", e1.type.toChars());
+					return new ErrorExp();
+			}
+			rvalue();
+		}
+		return this;
+	}
+
+	int isLvalue()
+	{
+		assert(false);
+	}
+
+	Expression toLvalue(Scope sc, Expression e)
+	{
+static if (false) {
+		tym = tybasic(e1.ET.Tty);
+		if (!(tyscalar(tym) ||
+		  tym == TYstruct ||
+		  tym == TYarray && e.Eoper == TOKaddr)
+		)
+			synerr(EM_lvalue);	// lvalue expected
+}
+		return this;
+	}
+
+version (DMDV2) {
+	Expression modifiableLvalue(Scope sc, Expression e)
+	{
+		//printf("PtrExp.modifiableLvalue() %s, type %s\n", toChars(), type.toChars());
+
+		if (e1.op == TOKsymoff)
+		{	
+			SymOffExp se = cast(SymOffExp)e1;
+			se.var.checkModify(loc, sc, type);
+			//return toLvalue(sc, e);
+		}
+
+		return Expression.modifiableLvalue(sc, e);
+	}
+}
+	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+
+	elem* toElem(IRState* irs)
+	{
+		elem* e;
+
+		//printf("PtrExp::toElem() %s\n", toChars());
+		e = e1.toElem(irs);
+		e = el_una(OPER.OPind, type.totym(), e);
+
+		if (tybasic(e.Ety) == TYM.TYstruct)
+		{
+			e.Enumbytes = cast(uint)type.size();
+		}
+
+		el_setLoc(e,loc);
+		return e;
+	}
+
+	Expression optimize(int result)
+	{
+		//printf("PtrExp.optimize(result = x%x) %s\n", result, toChars());
+		e1 = e1.optimize(result);
+		// Convert *&ex to ex
+		if (e1.op == TOK.TOKaddress)
+		{	
+			Expression e;
+			Expression ex;
+
+			ex = (cast(AddrExp)e1).e1;
+			if (type.equals(ex.type))
+				e = ex;
+			else
+			{
+				e = ex.copy();
+				e.type = type;
+			}
+			return e;
+		}
+		// Constant fold *(&structliteral + offset)
+		if (e1.op == TOK.TOKadd)
+		{
+			Expression e;
+			e = Ptr(type, e1);
+			if (e !is EXP_CANT_INTERPRET)
+				return e;
+		}
+
+		if (e1.op == TOK.TOKsymoff)
+		{	
+			SymOffExp se = cast(SymOffExp)e1;
+			VarDeclaration v = se.var.isVarDeclaration();
+			Expression e = expandVar(result, v);
+			if (e && e.op == TOK.TOKstructliteral)
+			{   
+				StructLiteralExp sle = cast(StructLiteralExp)e;
+				e = sle.getField(type, se.offset);
+				if (e && e !is EXP_CANT_INTERPRET)
+					return e;
+			}
+		}
+		return this;
+	}
+
+	Expression interpret(InterState* istate)
+	{
+		assert(false);
+	}
+
+	Identifier opId()
+	{
+		assert(false);
+	}
+}
+