diff dmd/TypePointer.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 2e2a5c3f943a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypePointer.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,200 @@
+module dmd.TypePointer;
+
+import dmd.Type;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.TypeNext;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.MATCH;
+import dmd.Expression;
+import dmd.NullExp;
+import dmd.TypeInfoDeclaration;
+import dmd.TypeInfoPointerDeclaration;
+import dmd.CppMangleState;
+import dmd.TY;
+import dmd.Util;
+import dmd.MOD;
+import dmd.Global;
+
+import dmd.backend.TYPE;
+import dmd.backend.Util;
+import dmd.backend.TYM;
+
+class TypePointer : TypeNext
+{
+    this(Type t)
+	{
+		super(TY.Tpointer, t);
+	}
+version (DumbClone) {
+} else {		
+	final TypePointer cloneTo(TypePointer t)
+	{
+		super.cloneTo(t);
+		return t;
+	}
+
+	TypePointer clone()
+	{
+		assert(this.classinfo == TypePointer.classinfo);
+		return cloneTo(new TypePointer(next));
+	}
+}
+    Type syntaxCopy()
+	{
+		Type t = next.syntaxCopy();
+		if (t == next)
+			t = this;
+		else
+		{	
+			t = new TypePointer(t);
+			t.mod = mod;
+		}
+		return t;
+	}
+	
+    Type semantic(Loc loc, Scope sc)
+	{
+		//printf("TypePointer.semantic()\n");
+		if (deco)
+			return this;
+		Type n = next.semantic(loc, sc);
+		switch (n.toBasetype().ty)
+		{
+			case TY.Ttuple:
+				error(loc, "can't have pointer to %s", n.toChars());
+				n = tint32;
+				break;
+			default:
+				break;
+		}
+		if (n !is next)
+		{
+			deco = null;
+		}
+		next = n;
+		transitive();
+		return merge();
+	}
+	
+    ulong size(Loc loc)
+	{
+		return PTRSIZE;
+	}
+	
+    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
+	{
+		//printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
+		if (mod != this.mod)
+		{	
+			toCBuffer3(buf, hgs, mod);
+			return;
+		}
+		next.toCBuffer2(buf, hgs, this.mod);
+		if (next.ty != Tfunction)
+			buf.writeByte('*');
+	}
+	
+    MATCH implicitConvTo(Type to)
+	{
+		//printf("TypePointer.implicitConvTo(to = %s) %s\n", to.toChars(), toChars());
+
+		if (equals(to))
+			return MATCH.MATCHexact;
+		if (to.ty == TY.Tpointer)
+		{	
+			TypePointer tp = cast(TypePointer)to;
+			assert(tp.next);
+
+			if (!(next.mod == tp.next.mod || tp.next.mod == MOD.MODconst))
+				return MATCH.MATCHnomatch;        // not const-compatible
+
+			/* Alloc conversion to void[]
+			 */
+			if (next.ty != TY.Tvoid && tp.next.ty == TY.Tvoid)
+			{
+				return MATCH.MATCHconvert;
+			}
+
+			MATCH m = next.constConv(tp.next);
+			if (m != MATCH.MATCHnomatch)
+			{
+				if (m == MATCH.MATCHexact && mod != to.mod)
+					m = MATCH.MATCHconst;
+				return m;
+			}
+
+			/* Conversion of ptr to derived to ptr to base
+			 */
+			int offset = 0;
+			if (tp.next.isBaseOf(next, &offset) && offset == 0)
+				return MATCH.MATCHconvert;
+		}
+		return MATCH.MATCHnomatch;
+	}
+	
+    bool isscalar()
+	{
+		return true;
+	}
+	
+    Expression defaultInit(Loc loc)
+	{
+	version (LOGDEFAULTINIT) {
+		printf("TypePointer::defaultInit() '%s'\n", toChars());
+	}
+		Expression e = new NullExp(loc);
+		e.type = this;
+		return e;
+	}
+	
+    bool isZeroInit(Loc loc)
+	{
+		return true;
+	}
+	
+    TypeInfoDeclaration getTypeInfoDeclaration()
+	{
+		return new TypeInfoPointerDeclaration(this);
+	}
+	
+    bool hasPointers()
+	{
+		return true;
+	}
+	
+version (CPP_MANGLE) {
+    void toCppMangle(OutBuffer buf, CppMangleState* cms)
+	{
+		assert(false);
+	}
+}
+
+    type* toCtype()
+	{
+		type* tn;
+		type* t;
+
+		//printf("TypePointer.toCtype() %s\n", toChars());
+		if (ctype)
+			return ctype;
+
+		if (1 || global.params.symdebug)
+		{	/* Need to always do this, otherwise C++ name mangling
+			 * goes awry.
+			 */
+			t = type_alloc(TYM.TYnptr);
+			ctype = t;
+			tn = next.toCtype();
+			t.Tnext = tn;
+			tn.Tcount++;
+		}
+		else
+			t = type_fake(totym());
+
+		t.Tcount++;
+		ctype = t;
+		return t;
+	}
+}
\ No newline at end of file