diff dmd/TypeDelegate.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/TypeDelegate.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,213 @@
+module dmd.TypeDelegate;
+
+import dmd.Type;
+import dmd.TypeNext;
+import dmd.MOD;
+import dmd.OutBuffer;
+import dmd.Id;
+import dmd.AddExp;
+import dmd.PtrExp;
+import dmd.IntegerExp;
+import dmd.NullExp;
+import dmd.TypeFunction;
+import dmd.HdrGenState;
+import dmd.Expression;
+import dmd.Identifier;
+import dmd.CppMangleState;
+import dmd.Argument;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.TypeInfoDeclaration;
+import dmd.TypeInfoDelegateDeclaration;
+import dmd.TY;
+import dmd.Global;
+
+import dmd.backend.TYPE;
+import dmd.backend.Symbol;
+import dmd.backend.Classsym;
+import dmd.backend.TYM;
+import dmd.backend.SC;
+import dmd.backend.Util;
+import dmd.backend.LIST;
+
+class TypeDelegate : TypeNext
+{
+    // .next is a TypeFunction
+
+    this(Type t)
+	{
+		super(TY.Tfunction, t);
+		ty = TY.Tdelegate;
+	}
+	
+version (DumbClone) {
+} else {
+	Type clone()
+	{
+		assert(false);
+	}
+}
+    Type syntaxCopy()
+	{
+		Type t = next.syntaxCopy();
+		if (t == next)
+			t = this;
+		else
+		{	
+			t = new TypeDelegate(t);
+			t.mod = mod;
+		}
+		return t;
+	}
+	
+    Type semantic(Loc loc, Scope sc)
+	{
+		if (deco)			// if semantic() already run
+		{
+			//printf("already done\n");
+			return this;
+		}
+
+		next = next.semantic(loc, sc);
+		return merge();
+	}
+	
+    ulong size(Loc loc)
+	{
+		return PTRSIZE * 2;
+	}
+	
+    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
+	{
+		if (mod != this.mod)
+		{	
+			toCBuffer3(buf, hgs, mod);
+			return;
+		}
+		TypeFunction tf = cast(TypeFunction)next;
+
+		tf.next.toCBuffer2(buf, hgs, MODundefined);
+		buf.writestring(" delegate");
+		Argument.argsToCBuffer(buf, hgs, tf.parameters, tf.varargs);
+	}
+	
+    Expression defaultInit(Loc loc)
+	{
+	version (LOGDEFAULTINIT) {
+		printf("TypeDelegate.defaultInit() '%s'\n", toChars());
+	}
+		Expression e;
+		e = new NullExp(loc);
+		e.type = this;
+		return e;
+	}
+	
+    bool isZeroInit(Loc loc)
+	{
+		return true;
+	}
+	
+    bool checkBoolean()
+	{
+		return true;
+	}
+	
+    TypeInfoDeclaration getTypeInfoDeclaration()
+	{
+		return new TypeInfoDelegateDeclaration(this);
+	}
+	
+    Expression dotExp(Scope sc, Expression e, Identifier ident)
+	{
+	version (LOGDOTEXP) {
+		printf("TypeDelegate.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
+	}
+		if (ident == Id.ptr)
+		{
+			e.type = tvoidptr;
+			return e;
+		}
+		else if (ident == Id.funcptr)
+		{
+			e = e.addressOf(sc);
+			e.type = tvoidptr;
+			e = new AddExp(e.loc, e, new IntegerExp(PTRSIZE));
+			e.type = tvoidptr;
+			e = new PtrExp(e.loc, e);
+			e.type = next.pointerTo();
+			return e;
+		}
+		else
+		{
+			e = Type.dotExp(sc, e, ident);
+		}
+		return e;
+	}
+	
+    bool hasPointers()
+	{
+		return true;
+	}
+
+version (CPP_MANGLE) {
+    void toCppMangle(OutBuffer buf, CppMangleState* cms)
+	{
+		assert(false);
+	}
+}
+
+    type* toCtype()
+	{
+		type* t;
+
+		if (ctype)
+			return ctype;
+
+		if (0 && global.params.symdebug)
+		{
+			/* A delegate consists of:
+			 *    _Delegate { void* frameptr; Function *funcptr; }
+			 */
+
+			static Symbol* s;
+
+			if (!s)
+			{
+				s = symbol_calloc("_Delegate");
+				s.Sclass = SC.SCstruct;
+				s.Sstruct = struct_calloc();
+				s.Sstruct.Sflags |= 0;	/// huh?
+				s.Sstruct.Salignsize = alignsize();
+				s.Sstruct.Sstructalign = cast(ubyte)global.structalign;
+				s.Sstruct.Sstructsize = cast(uint)size(Loc(0));
+				slist_add(s);
+
+				Symbol* s1 = symbol_name("frameptr", SC.SCmember, Type.tvoidptr.toCtype());
+				list_append(&s.Sstruct.Sfldlst, s1);
+
+				Symbol* s2 = symbol_name("funcptr", SC.SCmember, Type.tvoidptr.toCtype());
+				s2.Smemoff = cast(uint)Type.tvoidptr.size();
+				list_append(&s.Sstruct.Sfldlst, s2);
+			}
+
+			t = type_alloc(TYM.TYstruct);
+			t.Ttag = cast(Classsym*)s;		// structure tag name
+			t.Tcount++;
+			s.Stype = t;
+		}
+		else
+		{
+			if (global.params.symdebug == 1)
+			{
+				// Generate D symbolic debug info, rather than C
+				t = type_allocn(TYM.TYdelegate, next.toCtype());
+			}
+			else
+				t = type_fake(TYM.TYdelegate);
+		}
+
+		t.Tcount++;
+		ctype = t;
+		return t;
+	}
+}
\ No newline at end of file