diff dmd/TypeDArray.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 832f71e6f96c 2cc604139636
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypeDArray.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,339 @@
+module dmd.TypeDArray;
+
+import dmd.TypeArray;
+import dmd.MOD;
+import dmd.Id;
+import dmd.TOK;
+import dmd.StringExp;
+import dmd.IntegerExp;
+import dmd.ArrayLengthExp;
+import dmd.Type;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.Expression;
+import dmd.Identifier;
+import dmd.MATCH;
+import dmd.ArrayTypes;
+import dmd.TypeInfoDeclaration;
+import dmd.TypeInfoArrayDeclaration;
+import dmd.NullExp;
+import dmd.TY;
+import dmd.TypeStruct;
+import dmd.Util;
+import dmd.TypePointer;
+import dmd.Global;
+
+import dmd.backend.TYPE;
+import dmd.backend.Symbol;
+import dmd.backend.Classsym;
+import dmd.backend.Util;
+import dmd.backend.SC;
+import dmd.backend.TYM;
+import dmd.backend.LIST;
+
+import core.stdc.stdlib;
+import core.stdc.stdio;
+
+// Dynamic array, no dimension
+class TypeDArray : TypeArray
+{
+    this(Type t)
+	{
+		super(TY.Tarray, t);
+		//printf("TypeDArray(t = %p)\n", t);
+	}
+	
+version (DumbClone) {
+} else {
+	Type clone()
+	{
+		assert(false);
+	}
+}
+    Type syntaxCopy()
+	{
+		Type t = next.syntaxCopy();
+		if (t == next)
+			t = this;
+		else
+		{	
+			t = new TypeDArray(t);
+			t.mod = mod;
+		}
+		return t;
+	}
+	
+    ulong size(Loc loc)
+	{
+		//printf("TypeDArray.size()\n");
+		return PTRSIZE * 2;
+	}
+	
+    uint alignsize()
+	{
+		// A DArray consists of two ptr-sized values, so align it on pointer size
+		// boundary
+		return PTRSIZE;
+	}
+	
+    Type semantic(Loc loc, Scope sc)
+	{
+		Type tn = next;
+
+		tn = next.semantic(loc,sc);
+		Type tbn = tn.toBasetype();
+		switch (tbn.ty)
+		{
+			case TY.Tfunction:
+			case TY.Tnone:
+			case TY.Ttuple:
+				error(loc, "can't have array of %s", tbn.toChars());
+				tn = next = tint32;
+				break;
+			case TY.Tstruct:
+			{   
+				TypeStruct ts = cast(TypeStruct)tbn;
+				if (ts.sym.isnested)
+					error(loc, "cannot have array of inner structs %s", ts.toChars());
+				break;
+			}
+			
+			default:
+				break;	///
+		}
+		if (tn.isauto())
+			error(loc, "cannot have array of auto %s", tn.toChars());
+
+		next = tn;
+		transitive();
+		return merge();
+	}
+	
+    void toDecoBuffer(OutBuffer buf, int flag)
+	{
+		Type.toDecoBuffer(buf, flag);
+		if (next)
+			next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
+	}
+	
+    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
+	{
+		if (mod != this.mod)
+		{
+			toCBuffer3(buf, hgs, mod);
+			return;
+		}
+		next.toCBuffer2(buf, hgs, this.mod);
+		buf.writestring("[]");
+	}
+	
+    Expression dotExp(Scope sc, Expression e, Identifier ident)
+	{
+version (LOGDOTEXP) {
+		printf("TypeDArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
+}
+		if (ident is Id.length)
+		{
+			if (e.op == TOK.TOKstring)
+			{   
+				StringExp se = cast(StringExp)e;
+
+				return new IntegerExp(se.loc, se.len, Type.tindex);
+			}
+			e = new ArrayLengthExp(e.loc, e);
+			e.type = Type.tsize_t;
+			return e;
+		}
+		else if (ident is Id.ptr)
+		{
+			e = e.castTo(sc, next.pointerTo());
+			return e;
+		}
+		else
+		{
+			e = TypeArray.dotExp(sc, e, ident);
+		}
+		return e;
+	}
+	
+    int isString()
+	{
+		assert(false);
+	}
+	
+    bool isZeroInit(Loc loc)
+	{
+		return true;
+	}
+	
+    bool checkBoolean()
+	{
+		return true;
+	}
+	
+    MATCH implicitConvTo(Type to)
+	{
+		//printf("TypeDArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars());
+		if (equals(to))
+			return MATCHexact;
+
+		// Allow implicit conversion of array to pointer
+		if (IMPLICIT_ARRAY_TO_PTR && to.ty == Tpointer)
+		{
+			TypePointer tp = cast(TypePointer)to;
+
+			/* Allow conversion to void*
+			 */
+			if (tp.next.ty == Tvoid &&
+				(next.mod == tp.next.mod || tp.next.mod == MODconst))
+			{
+				return MATCHconvert;
+			}
+
+			return next.constConv(to);
+		}
+
+		if (to.ty == Tarray)
+		{	
+			int offset = 0;
+			TypeDArray ta = cast(TypeDArray)to;
+
+			if (!(next.mod == ta.next.mod || ta.next.mod == MODconst))
+				return MATCHnomatch;	// not const-compatible
+
+			/* Allow conversion to void[]
+			 */
+			if (next.ty != Tvoid && ta.next.ty == Tvoid)
+			{
+				return MATCHconvert;
+			}
+
+			MATCH m = next.constConv(ta.next);
+			if (m != MATCHnomatch)
+			{
+				if (m == MATCHexact && mod != to.mod)
+				m = MATCHconst;
+				return m;
+			}
+
+			/* Allow conversions of T[][] to const(T)[][]
+			 */
+			if (mod == ta.mod && next.ty == Tarray && ta.next.ty == Tarray)
+			{
+				m = next.implicitConvTo(ta.next);
+				if (m == MATCHconst)
+				return m;
+			}
+
+			/* Conversion of array of derived to array of base
+			 */
+			if (ta.next.isBaseOf(next, &offset) && offset == 0)
+				return MATCHconvert;
+		}
+		return Type.implicitConvTo(to);
+	}
+	
+    Expression defaultInit(Loc loc)
+	{
+	version (LOGDEFAULTINIT) {
+		printf("TypeDArray.defaultInit() '%s'\n", toChars());
+	}
+		Expression e = new NullExp(loc);
+		e.type = this;
+		return e;
+	}
+	
+    bool builtinTypeInfo()
+	{
+	version (DMDV2) {
+		return !mod && (next.isTypeBasic() !is null && !next.mod ||
+			// strings are so common, make them builtin
+			next.ty == Tchar && next.mod == MODinvariant);
+	} else {
+		return next.isTypeBasic() !is null;
+	}
+	}
+version (DMDV2) {
+    MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
+	{
+	static if (false) {
+		printf("TypeDArray.deduceType()\n");
+		printf("\tthis   = %d, ", ty); print();
+		printf("\ttparam = %d, ", tparam.ty); tparam.print();
+	}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
+
+	  Lnomatch:
+		return MATCHnomatch;
+	}
+}
+    TypeInfoDeclaration getTypeInfoDeclaration()
+	{
+		return new TypeInfoArrayDeclaration(this);
+	}
+
+    bool hasPointers()
+	{
+		return true;
+	}
+
+version (CPP_MANGLE) {
+    void toCppMangle(OutBuffer buf, CppMangleState* cms);
+}
+
+    type* toCtype()
+	{
+		type *t;
+
+		if (ctype)
+			return ctype;
+
+		if (0 && global.params.symdebug)
+		{
+			/* Create a C type out of:
+			 *	struct _Array_T { size_t length; T* data; }
+			 */
+			Symbol* s;
+			char *id;
+
+			assert(next.deco);
+			id = cast(char*) alloca(7 + next.deco.length + 1);
+			sprintf(id, "_Array_%.*s", next.deco);
+			s = symbol_calloc(id);
+			s.Sclass = SC.SCstruct;
+			s.Sstruct = struct_calloc();
+			s.Sstruct.Sflags |= 0;
+			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("length", SC.SCmember, Type.tsize_t.toCtype());
+			list_append(&s.Sstruct.Sfldlst, s1);
+
+			Symbol* s2 = symbol_name("data", SC.SCmember, next.pointerTo().toCtype());
+			s2.Smemoff = cast(uint)Type.tsize_t.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.TYdarray, next.toCtype());
+			}
+			else
+				t = type_fake(TYM.TYdarray);
+		}
+		t.Tcount++;
+		ctype = t;
+		return t;
+	}
+}
\ No newline at end of file