changeset 68:ee3a9f34dc48

final bits of codegen implementation to compile Phobos
author korDen
date Tue, 24 Aug 2010 16:44:34 +0400
parents f708f0452e81
children c876339731a4
files commands.txt dmd/ArrayLiteralExp.d dmd/AssignExp.d dmd/AssocArrayLiteralExp.d dmd/CaseStatement.d dmd/Declaration.d dmd/FuncDeclaration.d dmd/GotoDefaultStatement.d dmd/Identifier.d dmd/IdentifierExp.d dmd/IntegerExp.d dmd/OutBuffer.d dmd/ReturnStatement.d dmd/String.d dmd/StringExp.d dmd/TypeAArray.d dmd/TypeEnum.d dmd/TypeInfoAssociativeArrayDeclaration.d dmd/TypeInfoStaticArrayDeclaration.d dmd/TypedefDeclaration.d dmd/VarDeclaration.d dmd/VoidInitializer.d dmd/XorAssignExp.d
diffstat 23 files changed, 305 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/commands.txt	Mon Aug 23 21:21:05 2010 +0400
+++ b/commands.txt	Tue Aug 24 16:44:34 2010 +0400
@@ -86,6 +86,7 @@
 dmd\TypeInfoTypedefDeclaration.d
 dmd\TypeInfoPointerDeclaration.d
 dmd\TypeInfoStaticArrayDeclaration.d
+dmd\TypeInfoAssociativeArrayDeclaration.d
 dmd\DsymbolExp.d
 dmd\GlobalExpressions.d
 dmd\NewExp.d
--- a/dmd/ArrayLiteralExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/ArrayLiteralExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -25,9 +25,11 @@
 import dmd.expression.Util;
 import dmd.backend.Util;
 import dmd.backend.RTLSYM;
-import dmd.backend.OPER;
+import dmd.backend.OPER;
+import dmd.backend.Symbol;
 import dmd.backend.TYM;
 import dmd.backend.mTY;
+import dmd.codegen.Util;
 
 class ArrayLiteralExp : Expression
 {
@@ -329,7 +331,50 @@
 
 	dt_t** toDt(dt_t** pdt)
 	{
-		assert(false);
+		//printf("ArrayLiteralExp.toDt() '%s', type = %s\n", toChars(), type.toChars());
+
+		dt_t *d;
+		dt_t **pdtend;
+
+		d = null;
+		pdtend = &d;
+		for (int i = 0; i < elements.dim; i++)
+		{	
+			Expression e = cast(Expression)elements.data[i];
+
+			pdtend = e.toDt(pdtend);
+		}
+		Type t = type.toBasetype();
+
+		switch (t.ty)
+		{
+			case Tsarray:
+				pdt = dtcat(pdt, d);
+				break;
+
+			case Tpointer:
+			case Tarray:
+				if (t.ty == Tarray)
+					dtdword(pdt, elements.dim);
+				if (d)
+				{
+					// Create symbol, and then refer to it
+					Symbol* s;
+					s = static_sym();
+					s.Sdt = d;
+					outdata(s);
+
+					dtxoff(pdt, s, 0, TYnptr);
+				}
+				else
+					dtdword(pdt, 0);
+
+				break;
+
+			default:
+				assert(0);
+		}
+		return pdt;
 	}
 
 version (DMDV2) {
--- a/dmd/AssignExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/AssignExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -26,6 +26,7 @@
 import dmd.TypeClass;
 import dmd.OutBuffer;
 import dmd.Loc;
+import dmd.TypeNext;
 import dmd.TupleExp;
 import dmd.VarDeclaration;
 import dmd.Scope;
@@ -777,15 +778,18 @@
 		{	
 			CallExp ce = cast(CallExp)e2;
 
-			TypeFunction tf = cast(TypeFunction)ce.e1.type.toBasetype();
-			if (tf.ty == TY.Tfunction && tf.retStyle() == RET.RETstack)
-			{
-				elem* ehidden = e1.toElem(irs);
-				ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden);
-				assert(!irs.ehidden);
-				irs.ehidden = ehidden;
-				e = e2.toElem(irs);
-				goto Lret;
+			Type t = ce.e1.type.toBasetype();
+			if (t.ty == TY.Tfunction) {
+				TypeFunction tf = cast(TypeFunction)t;
+				if (tf.retStyle() == RET.RETstack)
+				{
+					elem* ehidden = e1.toElem(irs);
+					ehidden = el_una(OPER.OPaddr, TYM.TYnptr, ehidden);
+					assert(!irs.ehidden);
+					irs.ehidden = ehidden;
+					e = e2.toElem(irs);
+					goto Lret;
+				}
 			}
 		}
 }
--- a/dmd/AssocArrayLiteralExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/AssocArrayLiteralExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -22,6 +22,11 @@
 import dmd.TOK;
 import dmd.PREC;
 import dmd.expression.Util;
+import dmd.backend.Util;
+import dmd.backend.TYM;
+import dmd.backend.mTY;
+import dmd.backend.OPER;
+import dmd.backend.RTLSYM;
 
 class AssocArrayLiteralExp : Expression
 {
@@ -112,7 +117,57 @@
 
 	elem* toElem(IRState* irs)
 	{
-		assert(false);
+		elem* e;
+		size_t dim;
+
+		//printf("AssocArrayLiteralExp.toElem() %s\n", toChars());
+		dim = keys.dim;
+		e = el_long(TYint, dim);
+		for (size_t i = 0; i < dim; i++)
+		{   
+			Expression el = cast(Expression)keys.data[i];
+
+			for (int j = 0; j < 2; j++)
+			{
+				elem* ep = el.toElem(irs);
+
+				if (tybasic(ep.Ety) == TYstruct || tybasic(ep.Ety) == TYarray)
+				{
+					ep = el_una(OPstrpar, TYstruct, ep);
+					ep.Enumbytes = cast(uint)el.type.size();
+				}
+		//printf("[%d] %s\n", i, el.toChars());
+		//elem_print(ep);
+				e = el_param(ep, e);
+				el = cast(Expression)values.data[i];
+			}
+		}
+
+		Type t = type.toBasetype().mutableOf();
+		assert(t.ty == Taarray);
+		TypeAArray ta = cast(TypeAArray)t;
+
+		/* Unfortunately, the hash function for Aa (array of chars) is custom and
+		 * different from Axa and Aya, which get the generic hash function.
+		 * So, rewrite the type of the AArray so that if it's key type
+		 * is an array of const or invariant, make it an array of mutable.
+		 */
+		Type tkey = ta.index.toBasetype();
+		if (tkey.ty == Tarray)
+		{
+			tkey = tkey.nextOf().mutableOf().arrayOf();
+			tkey = tkey.semantic(Loc(0), null);
+			ta = new TypeAArray(ta.nextOf(), tkey);
+			ta = cast(TypeAArray)ta.merge();
+		}
+
+		e = el_param(e, ta.getTypeInfo(null).toElem(irs));
+
+		// call _d_assocarrayliteralT(ti, dim, ...)
+		e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e);
+
+		el_setLoc(e,loc);
+		return e;
 	}
 
 	bool checkSideEffect(int flag)
--- a/dmd/CaseStatement.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/CaseStatement.d	Tue Aug 24 16:44:34 2010 +0400
@@ -119,9 +119,12 @@
 		return this;
 	}
 	
-    int compare(Object obj)
+    int opCmp(Object obj)
 	{
-		assert(false);
+		// Sort cases so we can do an efficient lookup
+		CaseStatement cs2 = cast(CaseStatement)obj;
+
+		return exp.opCmp(cs2.exp);
 	}
 	
     bool usesEH()
--- a/dmd/Declaration.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/Declaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -266,7 +266,7 @@
 	
     bool isThreadlocal()
 	{
-		assert(false);
+		return false;
 	}
 	
     bool isCodeseg()
--- a/dmd/FuncDeclaration.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/FuncDeclaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -2066,7 +2066,7 @@
 	
     bool isCodeseg()
 	{
-		assert(false);
+		return true;		// functions are always in the code segment
 	}
 	
     bool isOverloadable()
--- a/dmd/GotoDefaultStatement.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/GotoDefaultStatement.d	Tue Aug 24 16:44:34 2010 +0400
@@ -11,6 +11,11 @@
 import dmd.IRState;
 import dmd.BE;
 
+import dmd.backend.block;
+import dmd.backend.Blockx;
+import dmd.backend.Util;
+import dmd.backend.BC;
+
 class GotoDefaultStatement : Statement
 {
     SwitchStatement sw;
@@ -52,6 +57,33 @@
 
     void toIR(IRState *irs)
 	{
-		assert(false);
+		block *b;
+		Blockx *blx = irs.blx;
+		block *bdest = irs.getDefaultBlock();
+
+		b = blx.curblock;
+
+		// The rest is equivalent to GotoStatement
+
+		// Adjust exception handler scope index if in different try blocks
+		if (b.Btry != bdest.Btry)
+		{
+		// Check that bdest is in an enclosing try block
+		for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry)
+		{
+			if (!bt)
+			{
+				//printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry);
+				error("cannot goto into try block");
+				break;
+			}
+		}
+
+		//setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1);
+		}
+
+		list_append(&b.Bsucc,bdest);
+		incUsage(irs, loc);
+		block_next(blx,BCgoto,null);
 	}
 }
\ No newline at end of file
--- a/dmd/Identifier.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/Identifier.d	Tue Aug 24 16:44:34 2010 +0400
@@ -28,7 +28,7 @@
 		assert(false);
 	}
 	
-    int compare(Object o)
+    int opCmp(Object o)
 	{
 		assert(false);
 	}
--- a/dmd/IdentifierExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/IdentifierExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -155,7 +155,7 @@
 
 	int isLvalue()
 	{
-		assert(false);
+		return 1;
 	}
 
 	Expression toLvalue(Scope sc, Expression e)
--- a/dmd/IntegerExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/IntegerExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -474,7 +474,8 @@
 					break;
 
 				case TY.Tint64:
-					buf.printf("%jdL", v);
+					//buf.printf("%jdL", v);
+					buf.printf("%sL", v);
 					break;
 
 				case TY.Tuns64:
--- a/dmd/OutBuffer.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/OutBuffer.d	Tue Aug 24 16:44:34 2010 +0400
@@ -95,6 +95,19 @@
     final void writenl()			// write newline
 	{
 		assert(false);
+version (_WIN32) {
+	version (M_UNICODE) {
+		write4(0x000A000D);		// newline is CR,LF on Microsoft OS's
+	} else {
+		writeword(0x0A0D);		// newline is CR,LF on Microsoft OS's
+	}
+} else {
+	version (M_UNICODE) {
+		writeword('\n');
+	} else {
+		writeByte('\n');
+	}
+}
 	}
 	
     final void writeByte(uint b)
--- a/dmd/ReturnStatement.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/ReturnStatement.d	Tue Aug 24 16:44:34 2010 +0400
@@ -399,10 +399,11 @@
     void toIR(IRState* irs)
 	{
 		Blockx* blx = irs.blx;
-
+		
 		incUsage(irs, loc);
 		if (exp)
 		{	
+			//printf("%.*s %.*s\n", exp.classinfo.name, exp.toChars());
 			elem *e;
 
 			FuncDeclaration func = irs.getFunc();
@@ -420,7 +421,7 @@
 				 */
 				if (exp.op == TOK.TOKstructliteral)
 				{	
-					scope StructLiteralExp se = cast(StructLiteralExp)exp;
+					StructLiteralExp se = cast(StructLiteralExp)exp;
 					enum objectSize = __traits(classInstanceSize, StructLiteralExp);
 					ubyte save[objectSize];
 					memcpy(save.ptr, cast(void*)se, objectSize);
@@ -461,7 +462,8 @@
 					//if (tb.ty == TY.Tstruct) exp.dump(0);
 					if ((exp.op == TOK.TOKvar || exp.op == TOK.TOKdotvar || exp.op == TOK.TOKstar) &&
 						tb.ty == TY.Tstruct)
-					{   StructDeclaration sd = (cast(TypeStruct)tb).sym;
+					{   
+						StructDeclaration sd = (cast(TypeStruct)tb).sym;
 						if (sd.postblit)
 						{	
 							FuncDeclaration fd = sd.postblit;
--- a/dmd/String.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/String.d	Tue Aug 24 16:44:34 2010 +0400
@@ -73,7 +73,7 @@
 		return str == (cast(String)obj).str;
 	}
 
-    int compare(Object obj)
+    int opCmp(Object obj)
 	{
 		return cmp(str, (cast(String)obj).str);
 	}
--- a/dmd/StringExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/StringExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -70,7 +70,7 @@
 		{
 			if (e.op == TOKstring)
 			{
-				return compare(o) == 0;
+				return opCmp(o) == 0;
 			}
 		}
 		
@@ -577,7 +577,7 @@
 		return e;
 	}
 
-	int compare(Object obj)
+	int opCmp(Object obj)
 	{
 		// Used to sort case statement expressions so we can do an efficient lookup
 		StringExp se2 = cast(StringExp)(obj);
--- a/dmd/TypeAArray.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/TypeAArray.d	Tue Aug 24 16:44:34 2010 +0400
@@ -4,6 +4,7 @@
 import dmd.MOD;
 import dmd.ArrayTypes;
 import dmd.TypeInfoDeclaration;
+import dmd.TypeInfoAssociativeArrayDeclaration;
 import dmd.Expression;
 import dmd.Scope;
 import dmd.Loc;
@@ -183,7 +184,15 @@
 	
     void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
-		assert(false);
+		if (mod != this.mod)
+		{	
+			toCBuffer3(buf, hgs, mod);
+			return;
+		}
+		next.toCBuffer2(buf, hgs, this.mod);
+		buf.writeByte('[');
+		index.toCBuffer2(buf, hgs, MODundefined);
+		buf.writeByte(']');
 	}
 	
     Expression dotExp(Scope sc, Expression e, Identifier ident)
@@ -300,7 +309,7 @@
 	
     TypeInfoDeclaration getTypeInfoDeclaration()
 	{
-		assert(false);
+		return new TypeInfoAssociativeArrayDeclaration(this);
 	}
 	
     bool hasPointers()
--- a/dmd/TypeEnum.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/TypeEnum.d	Tue Aug 24 16:44:34 2010 +0400
@@ -19,6 +19,7 @@
 import dmd.TypeInfoEnumDeclaration;
 import dmd.ArrayTypes;
 import dmd.TY;
+import dmd.MOD;
 import dmd.Util;
 
 import dmd.backend.TYPE;
@@ -84,9 +85,14 @@
 		buf.printf("%s", name);
 	}
 	
-    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, int mod)
+    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
 	{
-		assert(false);
+		if (mod != this.mod)
+		{	
+			toCBuffer3(buf, hgs, mod);
+			return;
+		}
+		buf.writestring(sym.toChars());
 	}
 
     Expression dotExp(Scope sc, Expression e, Identifier ident)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypeInfoAssociativeArrayDeclaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -0,0 +1,35 @@
+module dmd.TypeInfoAssociativeArrayDeclaration;
+
+import dmd.Type;
+import dmd.TypeAArray;
+import dmd.TY;
+import dmd.TypeInfoDeclaration;
+import dmd.backend.dt_t;
+import dmd.backend.TYM;
+import dmd.backend.Util;
+
+class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
+{
+	this(Type tinfo)
+	{
+		super(tinfo, 0);
+	}
+
+	void toDt(dt_t** pdt)
+	{
+		//printf("TypeInfoAssociativeArrayDeclaration.toDt()\n");
+		dtxoff(pdt, Type.typeinfoassociativearray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
+		dtdword(pdt, 0);			    // monitor
+
+		assert(tinfo.ty == Taarray);
+
+		TypeAArray tc = cast(TypeAArray)tinfo;
+
+		tc.next.getTypeInfo(null);
+		dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type
+
+		tc.index.getTypeInfo(null);
+		dtxoff(pdt, tc.index.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type
+	}
+}
+
--- a/dmd/TypeInfoStaticArrayDeclaration.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/TypeInfoStaticArrayDeclaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -2,6 +2,11 @@
 
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
+import dmd.TypeSArray;
+import dmd.TY;
+
+import dmd.backend.Util;
+import dmd.backend.TYM;
 import dmd.backend.dt_t;
 
 class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
@@ -11,8 +16,19 @@
 		super(tinfo, 0);
 	}
 
-    void toDt(dt_t **pdt)
+    void toDt(dt_t** pdt)
 	{
-		assert(false);
+		//printf("TypeInfoStaticArrayDeclaration.toDt()\n");
+		dtxoff(pdt, Type.typeinfostaticarray.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
+		dtdword(pdt, 0);			    // monitor
+
+		assert(tinfo.ty == Tsarray);
+
+		TypeSArray tc = cast(TypeSArray)tinfo;
+
+		tc.next.getTypeInfo(null);
+		dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for array of type
+
+		dtdword(pdt, cast(int)tc.dim.toInteger());		// length
 	}
 }
\ No newline at end of file
--- a/dmd/TypedefDeclaration.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/TypedefDeclaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -14,11 +14,16 @@
 import dmd.TypeTypedef;
 import dmd.Global;
 import dmd.STC;
+import dmd.Id;
 
 import dmd.backend.SC;
 import dmd.backend.FL;
+import dmd.backend.SFL;
 import dmd.backend.Symbol;
 import dmd.backend.Util;
+import dmd.backend.LIST;
+import dmd.backend.Classsym;
+import dmd.codegen.Util;
 
 class TypedefDeclaration : Declaration
 {
@@ -175,6 +180,18 @@
     Symbol* sinit;
     Symbol* toInitializer()
 	{
-		assert(false);
+		Symbol* s;
+		Classsym* stag;
+
+		if (!sinit)
+		{
+			stag = fake_classsym(Id.ClassInfo);
+			s = toSymbolX("__init", SCextern, stag.Stype, "Z");
+			s.Sfl = FLextern;
+			s.Sflags |= SFLnodebug;
+			slist_add(s);
+			sinit = s;
+		}
+		return sinit;
 	}
 }
--- a/dmd/VarDeclaration.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/VarDeclaration.d	Tue Aug 24 16:44:34 2010 +0400
@@ -13,6 +13,7 @@
 import dmd.CastExp;
 import dmd.WANT;
 import dmd.StructDeclaration;
+import dmd.StorageClassDeclaration;
 import dmd.DsymbolExp;
 import dmd.TypeSArray;
 import dmd.IntegerExp;
@@ -673,7 +674,28 @@
 	
     void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		StorageClassDeclaration.stcToCBuffer(buf, storage_class);
+
+		/* If changing, be sure and fix CompoundDeclarationStatement.toCBuffer()
+		 * too.
+		 */
+		if (type)
+			type.toCBuffer(buf, ident, hgs);
+		else
+			buf.writestring(ident.toChars());
+		if (init)
+		{	
+			buf.writestring(" = ");
+///version (DMDV2) {
+			ExpInitializer ie = init.isExpInitializer();
+			if (ie && (ie.exp.op == TOKconstruct || ie.exp.op == TOKblit))
+				(cast(AssignExp)ie.exp).e2.toCBuffer(buf, hgs);
+			else
+///}
+				init.toCBuffer(buf, hgs);
+		}
+		buf.writeByte(';');
+		buf.writenl();
 	}
 	
 version (_DH) {
--- a/dmd/VoidInitializer.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/VoidInitializer.d	Tue Aug 24 16:44:34 2010 +0400
@@ -9,6 +9,7 @@
 import dmd.HdrGenState;
 
 import dmd.backend.dt_t;
+import dmd.backend.Util;
 
 class VoidInitializer : Initializer
 {
@@ -43,7 +44,13 @@
 
     dt_t* toDt()
 	{
-		assert(false);
+		/* Void initializers are set to 0, just because we need something
+		 * to set them to in the static data segment.
+		 */
+		dt_t *dt = null;
+
+		dtnzeros(&dt, cast(uint)type.size());
+		return dt;
 	}
 
     VoidInitializer isVoidInitializer() { return this; }
--- a/dmd/XorAssignExp.d	Mon Aug 23 21:21:05 2010 +0400
+++ b/dmd/XorAssignExp.d	Tue Aug 24 16:44:34 2010 +0400
@@ -12,6 +12,7 @@
 import dmd.Id;
 import dmd.TOK;
 import dmd.backend.elem;
+import dmd.backend.OPER;
 
 class XorAssignExp : BinExp
 {
@@ -47,6 +48,6 @@
 
     elem* toElem(IRState* irs)
 	{
-		assert(false);
+		return toElemBin(irs,OPxorass);
 	}
 }