changeset 35:3cfcb944304e trunk

[svn r39] * Updated to DMD 1.022 with the exception of: Bugzilla 278: dmd.conf search path doesn't work This fix was causing crashes for me :/ So for it's the old behaviour
author lindquist
date Tue, 09 Oct 2007 06:21:30 +0200
parents 4648206ca213
children c0967c4b2a74
files dmd/aggregate.h dmd/class.c dmd/constfold.c dmd/expression.c dmd/expression.h dmd/func.c dmd/inifile.c dmd/mars.c dmd/mtype.c dmd/optimize.c dmd/parse.c gen/runtime.c lphobos/internal/objectimpl.d premake.lua tester.sh
diffstat 15 files changed, 281 insertions(+), 118 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/aggregate.h	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/aggregate.h	Tue Oct 09 06:21:30 2007 +0200
@@ -213,6 +213,7 @@
     void interfaceSemantic(Scope *sc);
     int isNested();
     int isCOMclass();
+    virtual int isCOMinterface();
     int isAbstract();
     virtual int vtblOffset();
     char *kind();
@@ -248,6 +249,7 @@
     int isBaseOf(BaseClass *bc, int *poffset);
     char *kind();
     int vtblOffset();
+    virtual int isCOMinterface();
 
     void toObjFile();			// compile to .obj file
     Symbol *toSymbol();
--- a/dmd/class.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/class.c	Tue Oct 09 06:21:30 2007 +0200
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2007 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -146,6 +146,20 @@
 		    Type::typeinfotypelist->error("%s", msg);
 		Type::typeinfotypelist = this;
 	    }
+
+#if V2
+	    if (id == Id::TypeInfo_Const)
+	    {	if (Type::typeinfoconst)
+		    Type::typeinfoconst->error("%s", msg);
+		Type::typeinfoconst = this;
+	    }
+
+	    if (id == Id::TypeInfo_Invariant)
+	    {	if (Type::typeinfoinvariant)
+		    Type::typeinfoinvariant->error("%s", msg);
+		Type::typeinfoinvariant = this;
+	    }
+#endif
 	}
 
 	if (id == Id::Object)
@@ -168,10 +182,6 @@
     }
 
     com = 0;
-#if 0
-    if (id == Id::IUnknown)		// IUnknown is the root of all COM objects
-	com = 1;
-#endif
     isauto = 0;
     isabstract = 0;
     isnested = 0;
@@ -249,6 +259,11 @@
     methods.setDim(0);
 #endif
 
+    if (sc->stc & STCdeprecated)
+    {	//printf("test1: %s is deprecated\n", toChars());
+	isdeprecated = 1;
+    }
+
     // Expand any tuples in baseclasses[]
     for (i = 0; i < baseclasses.dim; )
     {	BaseClass *b = (BaseClass *)baseclasses.data[i];
@@ -286,6 +301,17 @@
 	else
 	{
 	    tc = (TypeClass *)(tb);
+	    if (tc->sym->isDeprecated())
+	    {
+		if (!isDeprecated())
+		{
+		    // Deriving from deprecated class makes this one deprecated too
+		    isdeprecated = 1;
+
+		    tc->checkDeprecated(loc, sc);
+		}
+	    }
+
 	    if (tc->sym->isInterfaceDeclaration())
 		;
 	    else
@@ -340,6 +366,17 @@
 	}
 	else
 	{
+	    if (tc->sym->isDeprecated())
+	    {
+		if (!isDeprecated())
+		{
+		    // Deriving from deprecated class makes this one deprecated too
+		    isdeprecated = 1;
+
+		    tc->checkDeprecated(loc, sc);
+		}
+	    }
+
 	    // Check for duplicate interfaces
 	    for (size_t j = (baseClass ? 1 : 0); j < i; j++)
 	    {
@@ -480,8 +517,6 @@
 	isauto = 1;
     if (storage_class & STCabstract)
 	isabstract = 1;
-    if (storage_class & STCdeprecated)
-	isdeprecated = 1;
 
     sc = sc->push(this);
     sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic |
@@ -567,7 +602,7 @@
 	ctor->fbody = new CompoundStatement(0, new Statements());
 	members->push(ctor);
 	ctor->addMember(sc, this, 1);
-	*sc = scsave;
+	*sc = scsave;	// why? What about sc->nofree?
 	sc->offset = structsize;
 	ctor->semantic(sc);
 	defaultCtor = ctor;
@@ -754,6 +789,35 @@
     return s;
 }
 
+/**********************************************************
+ * fd is in the vtbl[] for this class.
+ * Return 1 if function is hidden (not findable through search).
+ */
+
+#if V2
+int isf(void *param, FuncDeclaration *fd)
+{
+    //printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
+    return param == fd;
+}
+
+int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
+{
+    //printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars());
+    Dsymbol *s = search(0, fd->ident, 4|2);
+    if (!s)
+    {	//printf("not found\n");
+	/* Because, due to a hack, if there are multiple definitions
+	 * of fd->ident, NULL is returned.
+	 */
+	return 0;
+    }
+    FuncDeclaration *fdstart = s->toAlias()->isFuncDeclaration();
+    //printf("%s fdstart = %p\n", s->kind(), fdstart);
+    return !overloadApply(fdstart, &isf, fd);
+}
+#endif
+
 /****************
  * Find virtual function matching identifier and type.
  * Used to build virtual function tables for interface implementations.
@@ -802,7 +866,7 @@
 
 	// If this is an interface, and it derives from a COM interface,
 	// then this is a COM interface too.
-	if (b->base->isCOMclass())
+	if (b->base->isCOMinterface())
 	    com = 1;
 
 	vtblInterfaces->push(b);
@@ -818,6 +882,11 @@
     return com;
 }
 
+int ClassDeclaration::isCOMinterface()
+{
+    return 0;
+}
+
 
 /****************************************
  */
@@ -927,6 +996,11 @@
 	scope = NULL;
     }
 
+    if (sc->stc & STCdeprecated)
+    {
+	isdeprecated = 1;
+    }
+
     // Expand any tuples in baseclasses[]
     for (i = 0; i < baseclasses.dim; )
     {	BaseClass *b = (BaseClass *)baseclasses.data[0];
@@ -1044,7 +1118,7 @@
 
     sc = sc->push(this);
     sc->parent = this;
-    if (isCOMclass())
+    if (isCOMinterface())
 	sc->linkage = LINKwindows;
     sc->structalign = 8;
     structalign = sc->structalign;
@@ -1134,18 +1208,23 @@
 
 /****************************************
  * Determine if slot 0 of the vtbl[] is reserved for something else.
- * For class objects, yes, this is where the classinfo ptr goes.
+ * For class objects, yes, this is where the ClassInfo ptr goes.
  * For COM interfaces, no.
  * For non-COM interfaces, yes, this is where the Interface ptr goes.
  */
 
 int InterfaceDeclaration::vtblOffset()
 {
-    if (isCOMclass())
+    if (isCOMinterface())
 	return 0;
     return 1;
 }
 
+int InterfaceDeclaration::isCOMinterface()
+{
+    return com;
+}
+
 /*******************************************
  */
 
--- a/dmd/constfold.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/constfold.c	Tue Oct 09 06:21:30 2007 +0200
@@ -733,6 +733,36 @@
 	    }
 	}
     }
+    else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
+    {	// Swap operands and use common code
+	Expression *e = e1;
+	e1 = e2;
+	e2 = e;
+	goto Lsa;
+    }
+    else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
+    {
+     Lsa:
+	StringExp *es1 = (StringExp *)e1;
+	ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
+	size_t dim1 = es1->len;
+	size_t dim2 = es2->elements ? es2->elements->dim : 0;
+	if (dim1 != dim2)
+	    cmp = 0;
+	else
+	{
+	    for (size_t i = 0; i < dim1; i++)
+	    {
+		uinteger_t c = es1->charAt(i);
+		Expression *ee2 = (Expression *)es2->elements->data[i];
+		if (ee2->isConst() != 1)
+		    return EXP_CANT_INTERPRET;
+		cmp = (c == ee2->toInteger());
+		if (cmp == 0)
+		    break;
+	    }
+	}
+    }
     else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
     {   StructLiteralExp *es1 = (StructLiteralExp *)e1;
 	StructLiteralExp *es2 = (StructLiteralExp *)e2;
@@ -1132,26 +1162,7 @@
 	if (i >= es1->len)
 	    e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len);
 	else
-	{   integer_t value;
-
-	    switch (es1->sz)
-	    {
-		case 1:
-		    value = ((unsigned char *)es1->string)[i];
-		    break;
-
-		case 2:
-		    value = ((unsigned short *)es1->string)[i];
-		    break;
-
-		case 4:
-		    value = ((unsigned int *)es1->string)[i];
-		    break;
-
-		default:
-		    assert(0);
-		    break;
-	    }
+	{   unsigned value = es1->charAt(i);
 	    e = new IntegerExp(loc, value, type);
 	}
     }
--- a/dmd/expression.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/expression.c	Tue Oct 09 06:21:30 2007 +0200
@@ -2354,26 +2354,36 @@
     return result ? TRUE : FALSE;
 }
 
+unsigned StringExp::charAt(size_t i)
+{   unsigned value;
+
+    switch (sz)
+    {
+	case 1:
+	    value = ((unsigned char *)string)[i];
+	    break;
+
+	case 2:
+	    value = ((unsigned short *)string)[i];
+	    break;
+
+	case 4:
+	    value = ((unsigned int *)string)[i];
+	    break;
+
+	default:
+	    assert(0);
+	    break;
+    }
+    return value;
+}
+
 void StringExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 {
     buf->writeByte('"');
     for (size_t i = 0; i < len; i++)
-    {	unsigned c;
-
-	switch (sz)
-	{
-	    case 1:
-		c = ((unsigned char *)string)[i];
-		break;
-	    case 2:
-		c = ((unsigned short *)string)[i];
-		break;
-	    case 4:
-		c = ((unsigned *)string)[i];
-		break;
-	    default:
-		assert(0);
-	}
+    {	unsigned c = charAt(i);
+
 	switch (c)
 	{
 	    case '"':
@@ -4933,7 +4943,7 @@
 	{
 	    AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration();
 	L1:
-	    Type *t = e1->type;
+	    Type *t = e1->type->toBasetype();
 
 	    if (ad &&
 		!(t->ty == Tpointer && t->next->ty == Tstruct &&
@@ -5467,6 +5477,7 @@
 	     */
 	    Expression *e = new StructLiteralExp(loc, (StructDeclaration *)ad, arguments);
 	    e = e->semantic(sc);
+	    e->type = e1->type;		// in case e1->type was a typedef
 	    return e;
 	}
 	else if (t1->ty == Tclass)
@@ -6087,8 +6098,11 @@
 	{   TypeClass *tc = (TypeClass *)tb;
 	    ClassDeclaration *cd = tc->sym;
 
-	    if (cd->isInterfaceDeclaration() && cd->isCOMclass())
+	    if (cd->isCOMinterface())
+	    {	/* Because COM classes are deleted by IUnknown.Release()
+		 */
 		error("cannot delete instance of COM interface %s", cd->toChars());
+	    }
 	    break;
 	}
 	case Tpointer:
--- a/dmd/expression.h	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/expression.h	Tue Oct 09 06:21:30 2007 +0200
@@ -321,6 +321,7 @@
     Expression *castTo(Scope *sc, Type *t);
     int compare(Object *obj);
     int isBool(int result);
+    unsigned charAt(size_t i);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     void toMangleBuffer(OutBuffer *buf);
     elem *toElem(IRState *irs);
--- a/dmd/func.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/func.c	Tue Oct 09 06:21:30 2007 +0200
@@ -929,12 +929,19 @@
 		 * ctor consts were initialized.
 		 */
 
-		ScopeDsymbol *ad = toParent()->isScopeDsymbol();
-		assert(ad);
-		for (int i = 0; i < ad->members->dim; i++)
-		{   Dsymbol *s = (Dsymbol *)ad->members->data[i];
-
-		    s->checkCtorConstInit();
+		Dsymbol *p = toParent();
+		ScopeDsymbol *ad = p->isScopeDsymbol();
+		if (!ad)
+		{
+		    error("static constructor can only be member of struct/class/module, not %s %s", p->kind(), p->toChars());
+		}
+		else
+		{
+		    for (int i = 0; i < ad->members->dim; i++)
+		    {   Dsymbol *s = (Dsymbol *)ad->members->data[i];
+
+			s->checkCtorConstInit();
+		    }
 		}
 	    }
 
@@ -2249,7 +2256,7 @@
 void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 {
     if (hgs->hdrgen)
-    {	buf->writestring("static this(){}\n");
+    {	buf->writestring("static this();\n");
 	return;
     }
     buf->writestring("static this()");
--- a/dmd/inifile.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/inifile.c	Tue Oct 09 06:21:30 2007 +0200
@@ -76,6 +76,28 @@
 		if (!FileName::exists(filename))
 		{
 #if linux
+
+#if 0
+#if __GLIBC__	    // This fix by Thomas Kuehne
+		    /* argv0 might be a symbolic link,
+		     * so try again looking past it to the real path
+		     */
+		    char* real_argv0 = realpath(argv0, NULL);
+		    if (real_argv0)
+		    {
+			filename = FileName::replaceName(real_argv0, inifile);
+			free(real_argv0);
+			if (FileName::exists(filename))
+			    goto Ldone;
+		    }
+#else
+#error use of glibc non-standard extension realpath(char*, NULL)
+#endif
+#endif
+
+	// old way; problem is that argv0 might not be on the PATH at all
+	// and some other instance might be found
+
 		    // Search PATH for argv0
 		    const char *p = getenv("PATH");
 		    Array *paths = FileName::splitPath(p);
--- a/dmd/mars.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/mars.c	Tue Oct 09 06:21:30 2007 +0200
@@ -67,8 +67,8 @@
 
     copyright = "Copyright (c) 1999-2007 by Digital Mars and Tomas Lindquist Olsen";
     written = "written by Walter Bright and Tomas Lindquist Olsen";
-    llvmdc_version = "0.0.1";
-    version = "v1.021";
+    llvmdc_version = "0.1";
+    version = "v1.022";
     global.structalign = 8;
 
     memset(&params, 0, sizeof(Param));
@@ -173,6 +173,8 @@
   -debug         compile in debug code\n\
   -debug=level   compile in debug code <= level\n\
   -debug=ident   compile in debug code identified by ident\n\
+  -debuglib=name    set symbolic debug library to name\n\
+  -defaultlib=name  set default library to name\n\
   -g             add symbolic debug info\n\
   -gc            add symbolic debug info, pretend to be C\n\
   -H             generate 'header' file\n\
--- a/dmd/mtype.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/mtype.c	Tue Oct 09 06:21:30 2007 +0200
@@ -554,6 +554,8 @@
     }
     else if (ident == Id::init)
     {
+	if (ty == Tvoid)
+	    error(loc, "void does not have an initializer");
 	e = defaultInit();
 	e->loc = loc;
     }
@@ -642,7 +644,9 @@
 		return e;
 	    }
 #endif
-	    return defaultInit();
+	    Expression *ex = defaultInit();
+	    ex->loc = e->loc;
+	    return ex;
 	}
     }
     if (ident == Id::typeinfo)
@@ -3760,6 +3764,8 @@
 #if LOGDOTEXP
     printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars());
 #endif
+    if (!sym->symtab)
+	goto Lfwd;
     s = sym->symtab->lookup(ident);
     if (!s)
     {
@@ -3769,6 +3775,10 @@
     em = m->value->copy();
     em->loc = e->loc;
     return em;
+
+Lfwd:
+    error(e->loc, "forward reference of %s.%s", toChars(), ident->toChars());
+    return new IntegerExp(0, 0, this);
 }
 
 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident)
@@ -4472,6 +4482,9 @@
 	    t = ClassDeclaration::classinfo->type;
 	    if (e->op == TOKtype || e->op == TOKdottype)
 	    {
+		/* For type.classinfo, we know the classinfo
+		 * at compile time.
+		 */
 		if (!sym->vclassinfo)
 		    sym->vclassinfo = new ClassInfoDeclaration(sym);
 		e = new VarExp(e->loc, sym->vclassinfo);
@@ -4479,13 +4492,25 @@
 		e->type = t;	// do this so we don't get redundant dereference
 	    }
 	    else
-	    {
+	    {	/* For class objects, the classinfo reference is the first
+		 * entry in the vtbl[]
+		 */
 		e = new PtrExp(e->loc, e);
 		e->type = t->pointerTo();
 		if (sym->isInterfaceDeclaration())
 		{
-		    if (sym->isCOMclass())
+		    if (sym->isCOMinterface())
+		    {	/* COM interface vtbl[]s are different in that the
+			 * first entry is always pointer to QueryInterface().
+			 * We can't get a .classinfo for it.
+			 */
 			error(e->loc, "no .classinfo for COM interface objects");
+		    }
+		    /* For an interface, the first entry in the vtbl[]
+		     * is actually a pointer to an instance of struct Interface.
+		     * The first member of Interface is the .classinfo,
+		     * so add an extra pointer indirection.
+		     */
 		    e->type = e->type->pointerTo();
 		    e = new PtrExp(e->loc, e);
 		    e->type = t->pointerTo();
--- a/dmd/optimize.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/optimize.c	Tue Oct 09 06:21:30 2007 +0200
@@ -371,6 +371,18 @@
     //printf("BinExp::optimize(result = %d) %s\n", result, toChars());
     e1 = e1->optimize(result);
     e2 = e2->optimize(result);
+    if (op == TOKshlass || op == TOKshrass || op == TOKushrass)
+    {
+	if (e2->isConst() == 1)
+	{
+	    integer_t i2 = e2->toInteger();
+	    d_uns64 sz = e1->type->size() * 8;
+	    if (i2 < 0 || i2 > sz)
+	    {   error("shift assign by %jd is outside the range 0..%zu", i2, sz);
+		e2 = new IntegerExp(0);
+	    }
+	}
+    }
     return this;
 }
 
@@ -451,55 +463,41 @@
     return e;
 }
 
+Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, Expression *, Expression *))
+{   Expression *ex = e;
+
+    e->e1 = e->e1->optimize(result);
+    e->e2 = e->e2->optimize(result);
+    if (e->e2->isConst() == 1)
+    {
+	integer_t i2 = e->e2->toInteger();
+	d_uns64 sz = e->e1->type->size() * 8;
+	if (i2 < 0 || i2 > sz)
+	{   error("shift by %jd is outside the range 0..%zu", i2, sz);
+	    e->e2 = new IntegerExp(0);
+	}
+	if (e->e1->isConst() == 1)
+	    ex = (*shift)(e->type, e->e1, e->e2);
+    }
+    return ex;
+}
+
 Expression *ShlExp::optimize(int result)
-{   Expression *e;
-
+{
     //printf("ShlExp::optimize(result = %d) %s\n", result, toChars());
-    e1 = e1->optimize(result);
-    e2 = e2->optimize(result);
-    e = this;
-    if (e2->isConst() == 1)
-    {
-	integer_t i2 = e2->toInteger();
-	if (i2 < 0 || i2 > e1->type->size() * 8)
-	{   error("shift left by %jd exceeds %zu", i2, e2->type->size() * 8);
-	    e2 = new IntegerExp(0);
-	}
-	if (e1->isConst() == 1)
-	    e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
-    }
-    return e;
+    return shift_optimize(result, this, Shl);
 }
 
 Expression *ShrExp::optimize(int result)
-{   Expression *e;
-
-    e1 = e1->optimize(result);
-    e2 = e2->optimize(result);
-
-    if (e1->isConst() == 1 && e2->isConst() == 1)
-    {
-	e = Shr(type, e1, e2);
-    }
-    else
-	e = this;
-    return e;
+{
+    //printf("ShrExp::optimize(result = %d) %s\n", result, toChars());
+    return shift_optimize(result, this, Shr);
 }
 
 Expression *UshrExp::optimize(int result)
-{   Expression *e;
-
-    //printf("UshrExp::optimize() %s\n", toChars());
-    e1 = e1->optimize(result);
-    e2 = e2->optimize(result);
-
-    if (e1->isConst() == 1 && e2->isConst() == 1)
-    {
-	e = Ushr(type, e1, e2);
-    }
-    else
-	e = this;
-    return e;
+{
+    //printf("UshrExp::optimize(result = %d) %s\n", result, toChars());
+    return shift_optimize(result, this, Ushr);
 }
 
 Expression *AndExp::optimize(int result)
--- a/dmd/parse.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/dmd/parse.c	Tue Oct 09 06:21:30 2007 +0200
@@ -1835,7 +1835,6 @@
 	    case TOKlparen:
 	    {	Arguments *arguments;
 		int varargs;
-		Type **pt;
 
 		if (tpl)
 		{
@@ -1852,7 +1851,8 @@
 		}
 
 		arguments = parseParameters(&varargs);
-		ta = new TypeFunction(arguments, t, varargs, linkage);
+		Type *ta = new TypeFunction(arguments, t, varargs, linkage);
+		Type **pt;
 		for (pt = &ts; *pt != t; pt = &(*pt)->next)
 		    ;
 		*pt = ta;
--- a/gen/runtime.c	Tue Oct 09 02:50:00 2007 +0200
+++ b/gen/runtime.c	Tue Oct 09 06:21:30 2007 +0200
@@ -18,6 +18,10 @@
     Logger::println("*** Loading D runtime ***");
     LOG_SCOPE;
 
+    if (!global.params.runtimeImppath) {
+        error("You must set the runtime import path with -E");
+        fatal();
+    }
     std::string filename(global.params.runtimeImppath);
     filename.append("/llvmdcore.bc");
     llvm::MemoryBuffer* buffer = llvm::MemoryBuffer::getFile(filename.c_str(), filename.length());
--- a/lphobos/internal/objectimpl.d	Tue Oct 09 02:50:00 2007 +0200
+++ b/lphobos/internal/objectimpl.d	Tue Oct 09 06:21:30 2007 +0200
@@ -109,7 +109,7 @@
     char[] toString()
     {
     //return this.classinfo.name;
-    return "classinfo.name not yet implemented";
+    return "Object.toString: classinfo not yet implemented";
     }
 
     /**
@@ -135,9 +135,9 @@
     // BUG: this prevents a compacting GC from working, needs to be fixed
     //return cast(int)cast(void *)this - cast(int)cast(void *)o;
 
+    assert(0, "need opCmp for class <no classinfo yet>");
+    return 0;
     //throw new Error("need opCmp for class " ~ this.classinfo.name);
-    assert(0);
-    return 0;
     }
 
     /**
@@ -257,7 +257,6 @@
     }
 }
 
-
 /**
  * Information about an interface.
  * A pointer to this appears as the first entry in the interface's vtbl[].
@@ -342,7 +341,6 @@
     TypeInfo ti;    /// TypeInfo for this member
 }
 
-
 /**
  * Runtime type information about a type.
  * Can be retrieved for any type using a
@@ -1024,6 +1022,7 @@
         assert(0);
     }
 }
++/
 
 /**
  * All recoverable exceptions should be derived from class Exception.
@@ -1042,7 +1041,8 @@
 
     void print()
     {
-    printf("%.*s\n", toString());
+    auto str = toString();
+    printf("%.*s\n", str.length, str.ptr);
     }
 
     char[] toString() { return msg; }
@@ -1071,5 +1071,3 @@
 }
 
 //extern (C) int nullext = 0;
-
-+/
--- a/premake.lua	Tue Oct 09 02:50:00 2007 +0200
+++ b/premake.lua	Tue Oct 09 06:21:30 2007 +0200
@@ -1,5 +1,4 @@
 project.name = llvmdc
-project.bindir = "bin"
 
 package = newpackage()
 package.name = "idgen"
@@ -7,7 +6,7 @@
 package.language = "c++"
 package.files = { "dmd/idgen.c" }
 package.buildoptions = { "-x c++" }
-package.postbuildcommands = { "bin/idgen", "mv -f id.c id.h dmd" }
+package.postbuildcommands = { "./idgen", "mv -f id.c id.h dmd" }
 
 package = newpackage()
 package.name = "impcnvgen"
@@ -15,9 +14,10 @@
 package.language = "c++"
 package.files = { "dmd/impcnvgen.c" }
 package.buildoptions = { "-x c++" }
-package.postbuildcommands = { "bin/impcnvgen", "mv -f impcnvtab.c dmd" }
+package.postbuildcommands = { "./impcnvgen", "mv -f impcnvtab.c dmd" }
 
 package = newpackage()
+package.bindir = "bin"
 package.name = "llvmdc"
 package.kind = "exe"
 package.language = "c++"
--- a/tester.sh	Tue Oct 09 02:50:00 2007 +0200
+++ b/tester.sh	Tue Oct 09 06:21:30 2007 +0200
@@ -24,10 +24,10 @@
     llvmdc $1 -Itest -odtest -c
     exit $?
 elif [ "$2" = "gdb" ]; then
-    gdb --args llvmdc $1 -Itest -odtest '-c'
+    gdb --args llvmdc $1 -Itest -odtest -c
     exit $?
 elif [ "$2" = "gdbrun" ]; then
-    llvmdc $1 -Itest -odtest '-c' &&
+    llvmdc $1 -Itest -odtest -c &&
     gdb $1
     exit $?
 else