changeset 57:3adbb28755e8

createTypeInfoArray implemented fixed a bug in expandTuples
author korDen
date Sat, 21 Aug 2010 14:46:32 +0400
parents 51605de93870
children ecf732dfe11e
files dmd/expression/Util.d
diffstat 1 files changed, 108 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/expression/Util.d	Sat Aug 21 14:16:53 2010 +0400
+++ b/dmd/expression/Util.d	Sat Aug 21 14:46:32 2010 +0400
@@ -336,7 +336,7 @@
     if (exps)
     {
 		expandTuples(exps);
-
+		
 		for (size_t i = 0; i < exps.dim; i++)
 		{   
 			Expression arg = cast(Expression)exps.data[i];
@@ -344,8 +344,9 @@
 			if (!arg.type)
 			{
 debug {
-				if (!global.gag)
+				if (!global.gag) {
 					writef("1: \n");
+				}
 }
 				arg.error("%s is not an expression", arg.toChars());
 				arg = new IntegerExp(arg.loc, 0, Type.tint32);
@@ -809,7 +810,7 @@
 
 			// Look for tuple with 0 members
 			if (arg.op == TOK.TOKtype)
-			{	
+			{
 				TypeExp e = cast(TypeExp)arg;
 				if (e.type.toBasetype().ty == TY.Ttuple)
 				{   
@@ -832,7 +833,7 @@
 				TupleExp te = cast(TupleExp)arg;
 
 				exps.remove(i);		// remove arg
-				exps.insert(i, cast(void*)te.exps);	// replace with tuple contents
+				exps.insert(i, te.exps);	// replace with tuple contents
 
 				if (i == exps.dim)
 					return;		// empty tuple, no more arguments
@@ -938,7 +939,109 @@
 
 Expression createTypeInfoArray(Scope sc, Expression* exps, int dim)
 {
-	assert(false);
+static if (true) {
+	/* Get the corresponding TypeInfo_Tuple and
+	 * point at its elements[].
+	 */
+
+	/* Create the TypeTuple corresponding to the types of args[]
+	 */
+	Arguments args = new Arguments;
+	args.setDim(dim);
+	for (size_t i = 0; i < dim; i++)
+	{	
+		Argument arg = new Argument(STCin, exps[i].type, null, null);
+		args.data[i] = cast(void*)arg;
+	}
+	TypeTuple tup = new TypeTuple(args);
+	Expression e = tup.getTypeInfo(sc);
+	e = e.optimize(WANTvalue);
+	assert(e.op == TOKsymoff);		// should be SymOffExp
+
+version (BREAKABI) {
+	/*
+	 * Should just pass a reference to TypeInfo_Tuple instead,
+	 * but that would require existing code to be recompiled.
+	 * Source compatibility can be maintained by computing _arguments[]
+	 * at the start of the called function by offseting into the
+	 * TypeInfo_Tuple reference.
+	 */
+
+} else {
+	// Advance to elements[] member of TypeInfo_Tuple
+	SymOffExp se = cast(SymOffExp)e;
+	se.offset += PTRSIZE + PTRSIZE;
+
+	// Set type to TypeInfo[]*
+	se.type = Type.typeinfo.type.arrayOf().pointerTo();
+
+	// Indirect to get the _arguments[] value
+	e = new PtrExp(Loc(0), se);
+	e.type = se.type.next;
+}
+	return e;
+} else {
+	/* Improvements:
+	 * 1) create an array literal instead,
+	 * as it would eliminate the extra dereference of loading the
+	 * static variable.
+	 */
+
+	ArrayInitializer ai = new ArrayInitializer(Loc(0));
+	VarDeclaration v;
+	Type t;
+	Expression e;
+	scope OutBuffer buf = new OutBuffer();
+	Identifier id;
+	string name;
+
+	// Generate identifier for _arguments[]
+	buf.writestring("_arguments_");
+	for (int i = 0; i < dim; i++)
+	{	
+		t = exps[i].type;
+		t.toDecoBuffer(buf);
+	}
+	buf.writeByte(0);
+	id = Lexer.idPool(buf.extractString());
+
+	Module m = sc.module_;
+	Dsymbol s = m.symtab.lookup(id);
+
+	if (s && s.parent == m)
+	{	
+		// Use existing one
+		v = s.isVarDeclaration();
+		assert(v);
+	}
+	else
+	{	
+		// Generate new one
+
+		for (int i = 0; i < dim; i++)
+		{   
+			t = exps[i].type;
+			e = t.getTypeInfo(sc);
+			ai.addInit(new IntegerExp(i), new ExpInitializer(0, e));
+		}
+
+		t = Type.typeinfo.type.arrayOf();
+		ai.type = t;
+		v = new VarDeclaration(0, t, id, ai);
+		m.members.push(v);
+		m.symtab.insert(v);
+		sc = sc.push();
+		sc.linkage = LINKc;
+		sc.stc = STCstatic | STCcomdat;
+		ai.semantic(sc, t);
+		v.semantic(sc);
+		v.parent = m;
+		sc = sc.pop();
+	}
+	e = new VarExp(0, v);
+	e = e.semantic(sc);
+	return e;
+}
 }
 
 /**************************************