Mercurial > projects > ddmd
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