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