Commits

Anonymous committed 37f27c7

Updated D1 to 1.032-not working

Comments (0)

Files changed (60)

     return FALSE;
 }
 
-#if V2
+//#if V2
 
 int
 AsmStatement::blockExit()
     return BEany;
 }
 
-#endif
+//#endif
 
 /* GCC does not support jumps from asm statements.  When optimization
    is turned on, labels referenced only from asm statements will not

d/dmd/aggregate.h

 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #ifndef DMD_AGGREGATE_H
     void semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     char *mangle();
-    char *kind();
+    const char *kind();
     Expression *cloneMembers();
     void toDocBuffer(OutBuffer *buf);
 
 {
     UnionDeclaration(Loc loc, Identifier *id);
     Dsymbol *syntaxCopy(Dsymbol *s);
-    char *kind();
+    const char *kind();
 
     UnionDeclaration *isUnionDeclaration() { return this; }
 };
 #endif
     int isAbstract();
     virtual int vtblOffset();
-    char *kind();
+    const char *kind();
     char *mangle();
     void toDocBuffer(OutBuffer *buf);
 
     void semantic(Scope *sc);
     int isBaseOf(ClassDeclaration *cd, target_ptrdiff_t *poffset);
     int isBaseOf(BaseClass *bc, target_ptrdiff_t *poffset);
-    char *kind();
+    const char *kind();
     int vtblOffset();
 #if V2
     int isCPPinterface();
 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #include <stdio.h>
     return 0;
 }
 
-char *AttribDeclaration::kind()
+const char *AttribDeclaration::kind()
 {
     return "attribute";
 }
     buf->writestring("}\n");
 }
 
-char *AnonDeclaration::kind()
+const char *AnonDeclaration::kind()
 {
     return (char *)(isunion ? "anonymous union" : "anonymous struct");
 }
     return TRUE;
 }
 
-char *PragmaDeclaration::kind()
+const char *PragmaDeclaration::kind()
 {
     return "pragma";
 }
     }
 }
 
-char *StaticIfDeclaration::kind()
+const char *StaticIfDeclaration::kind()
 {
     return "static if";
 }
 CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
     : AttribDeclaration(NULL)
 {
+	this->loc = loc;
     this->exp = exp;
     this->sd = NULL;
     this->compiled = 0;
     exp = resolveProperties(sc, exp);
     exp = exp->optimize(WANTvalue | WANTinterpret);
     if (exp->op != TOKstring)
-    {	error("argument to mixin must be a string, not (%s)", exp->toChars());
+    {	exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
     }
     else
     {
     p.nextToken();
     decl = p.parseDeclDefs(0);
     if (p.token.value != TOKeof)
-	error("incomplete mixin declaration (%s)", se->toChars());
+	exp->error("incomplete mixin declaration (%s)", se->toChars());
     }
 }
 
     void inlineScan();
     void addComment(unsigned char *comment);
     void emitComment(Scope *sc);
-    char *kind();
+    const char *kind();
     int oneMember(Dsymbol **ps);
     int hasPointers();
     void checkCtorConstInit();
     Dsymbol *syntaxCopy(Dsymbol *s);
     void semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
 };
 
 struct PragmaDeclaration : AttribDeclaration
     void semantic(Scope *sc);
     int oneMember(Dsymbol **ps);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
     void toObjFile(int multiobj);			// compile to .obj file
 };
 
     Dsymbol *syntaxCopy(Dsymbol *s);
     int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
     void semantic(Scope *sc);
-    char *kind();
+    const char *kind();
 };
 
 // Mixin declarations
 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #include <stdio.h>
     if (!ctor && baseClass && baseClass->ctor)
     {
 	//printf("Creating default this(){} for class %s\n", toChars());
-	ctor = new CtorDeclaration(0, 0, NULL, 0);
+	ctor = new CtorDeclaration(loc, 0, NULL, 0);
 	ctor->fbody = new CompoundStatement(0, new Statements());
 	members->push(ctor);
 	ctor->addMember(sc, this, 1);
 /****************************************
  */
 
-char *ClassDeclaration::kind()
+const char *ClassDeclaration::kind()
 {
     return "class";
 }
 /*******************************************
  */
 
-char *InterfaceDeclaration::kind()
+const char *InterfaceDeclaration::kind()
 {
     return "interface";
 }

d/dmd/declaration.c

 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #include <stdio.h>
 {
 }
 
-char *Declaration::kind()
+const char *Declaration::kind()
 {
     return "declaration";
 }
     return NULL;
 }
 
-char *TupleDeclaration::kind()
+const char *TupleDeclaration::kind()
 {
     return "tuple";
 }
 	    attributes = sc->attributes;
 	if (sc->parent->isFuncDeclaration() && init)
 	    semantic2(sc);
+	    storage_class |= sc->stc & STCdeprecated;
     }
     else if (sem == 1)
     {
     }
 }
 
-char *TypedefDeclaration::kind()
+const char *TypedefDeclaration::kind()
 {
     return "typedef";
 }
     }
 }
 
-char *AliasDeclaration::kind()
+const char *AliasDeclaration::kind()
 {
     return "alias";
 }
 	ei = init->isExpInitializer();
     else
     {
-	Expression *e = type->defaultInit();
+	Expression *e = type->defaultInit(loc);
 	if (e)
 	    ei = new ExpInitializer(loc, e);
 	else
     }
 }
 
-char *VarDeclaration::kind()
+const char *VarDeclaration::kind()
 {
     return "variable";
 }

d/dmd/declaration.h

 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #ifndef DMD_DECLARATION_H
 
     Declaration(Identifier *id);
     void semantic(Scope *sc);
-    char *kind();
+    const char *kind();
     target_size_t size(Loc loc);
     void checkModify(Loc loc, Scope *sc, Type *t);
 
 
     TupleDeclaration(Loc loc, Identifier *ident, Objects *objects);
     Dsymbol *syntaxCopy(Dsymbol *);
-    char *kind();
+    const char *kind();
     Type *getType();
     int needThis();
 
     void semantic(Scope *sc);
     void semantic2(Scope *sc);
     char *mangle();
-    char *kind();
+    const char *kind();
     Type *getType();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
 #ifdef _DH
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     int overloadInsert(Dsymbol *s);
-    char *kind();
+    const char *kind();
     Type *getType();
     Dsymbol *toAlias();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void semantic2(Scope *sc);
-    char *kind();
+    const char *kind();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
 #ifdef _DH
     Type *htype;
     void inlineScan();
     int canInline(int hasthis, int hdrscan = 0);
     Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments);
-    char *kind();
+    const char *kind();
     void toDocBuffer(OutBuffer *buf);
 
     static FuncDeclaration *genCfunc(Type *treturn, char *name,
     FuncAliasDeclaration(FuncDeclaration *funcalias);
 
     FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
-    char *kind();
+    const char *kind();
     Symbol *toSymbol();
 };
 
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     Dsymbol *syntaxCopy(Dsymbol *);
     int isNested();
+    int isVirtual();
 
     FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
-    char *kind();
+    const char *kind();
 };
 
 struct CtorDeclaration : FuncDeclaration
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
     char *toChars();
     int isVirtual();
     int addPreInvariant();
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
     int isVirtual();
     int addPreInvariant();
     int addPostInvariant();
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
     int isDelete();
     int isVirtual();
     int addPreInvariant();
 
 void ScopeDsymbol::emitMemberComments(Scope *sc)
 {
-    //printf("ScopeDsymbol::emitMemberComments()\n");
+    //printf("ScopeDsymbol::emitMemberComments() %s\n", toChars());
     OutBuffer *buf = sc->docbuf;
 
     if (members)
 	else if (isTemplateDeclaration())
 	    m = "$(DDOC_TEMPLATE_MEMBERS \n";
 
-	// BUG: if no members are actually printed, we should not emit DDOC_MEMBERS
-	buf->writestring(m);
+	unsigned offset1 = buf->offset;		// save starting offset
+  	buf->writestring(m);
+ 	unsigned offset2 = buf->offset;		// to see if we write anything 
+ 	//^possiblely change to target_size_t/target_ptrdiff_t?
 	sc = sc->push(this);
 	for (int i = 0; i < members->dim; i++)
 	{
 	    s->emitComment(sc);
 	}
 	sc->pop();
+	if (buf->offset == offset2)
+ 	{
+ 	    /* Didn't write out any members, so back out last write
++ 	     */
+ 	    buf->offset = offset1;
+ 	}
+ 	else
 	buf->writestring(")\n");
     }
 }
 
 void Dsymbol::emitComment(Scope *sc)		   { }
 void InvariantDeclaration::emitComment(Scope *sc)  { }
-//void PostBlitDeclaration::emitComment(Scope *sc)   { }
+#if V2
+void PostBlitDeclaration::emitComment(Scope *sc)   { }
+#endif
 void DtorDeclaration::emitComment(Scope *sc)	   { }
 void StaticCtorDeclaration::emitComment(Scope *sc) { }
 void StaticDtorDeclaration::emitComment(Scope *sc) { }
     //printf("TemplateDeclaration::emitComment() '%s', kind = %s\n", toChars(), kind());
     if (prot() == PROTprivate)
 	return;
-    if (!comment)
-	return;
 
-    OutBuffer *buf = sc->docbuf;
-    DocComment *dc = DocComment::parse(sc, this, comment);
-    unsigned o;
+    unsigned char *com = comment;
     int hasmembers = 1;
 
     Dsymbol *ss = this;
 	{
 	    ss = onemember->isFuncDeclaration();
 	    if (ss)
-		hasmembers = 0;
+		{	hasmembers = 0;
+ 		if (com != ss->comment)
+ 		    com = Lexer::combineComments(com, ss->comment);
+ 	    }
 	    else
 		ss = this;
 	}
     }
+    
+    if (!com)
+ 	return;
+ 
+     OutBuffer *buf = sc->docbuf;
+     DocComment *dc = DocComment::parse(sc, this, com);
+     unsigned o;
 
     if (!dc)
     {
 	if (parent &&
 	    (td = parent->isTemplateDeclaration()) != NULL &&
 	    td->onemember == this)
-	{   HdrGenState hgs;
+	{   /* It's a function template
+! 	     */
+ 	    HdrGenState hgs;
 	    unsigned o = buf->offset;
 	    TypeFunction *tf = (TypeFunction *)type;
 
     return loc.toChars();
 }
 
-char *Dsymbol::kind()
+const char *Dsymbol::kind()
 {
     return "symbol";
 }
     return sprev;
 }
 
-char *ScopeDsymbol::kind()
+const char *ScopeDsymbol::kind()
 {
     return "ScopeDsymbol";
 }
 
     static Array *arraySyntaxCopy(Array *a);
 
-    virtual char *kind();
+    virtual const char *kind();
     virtual Dsymbol *toAlias();			// resolve real symbol
     virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
     virtual void semantic(Scope *sc);
     void defineRef(Dsymbol *s);
     static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
     Dsymbol *nameCollision(Dsymbol *s);
-    char *kind();
+    const char *kind();
 
     void emitMemberComments(Scope *sc);
 
 /************************************
  */
 
-elem *sarray_toDarray(Type *tfrom, Type *tto, elem *e)
+elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e)
 {
     //printf("sarray_toDarray()\n");
     //elem_print(e);
 	if ((dim * fsize) % tsize != 0)
 	{
 	  Lerr:
-	    error((Loc)0, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars());
+	    error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars());
 	}
 	dim = (dim * fsize) / tsize;
     }
 	    //elem_print(e);
 	    goto Lret;
 	}
+	else if (e2->op == TOKadd || e2->op == TOKmin)
+ 	{
+ 	    /* It's ea[] = eb[] +- ec[]
++ 	     */
+ 	    BinExp *e2a = (BinExp *)e2;
+ 	    Type *t = e2->type->toBasetype()->nextOf()->toBasetype();
+ 	    if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80)
+ 	    {
+ 		e2->error("array add/min for %s not supported", t->toChars());
+ 		return el_long(TYint, 0);
+ 	    }
+ 	    elem *ea = e1->toElem(irs);
+ 	    ea = array_toDarray(e1->type, ea);
+ 	    elem *eb = e2a->e1->toElem(irs);
+ 	    eb = array_toDarray(e2a->e1->type, eb);
+ 	    elem *ec = e2a->e2->toElem(irs);
+ 	    ec = array_toDarray(e2a->e2->type, ec);
+ 
+ 	    int rtl = RTLSYM_ARRAYASSADDFLOAT;
+ 	    if (t->ty == Tfloat64)
+ 		rtl = RTLSYM_ARRAYASSADDDOUBLE;
+ 	    else if (t->ty == Tfloat80)
+ 		rtl = RTLSYM_ARRAYASSADDREAL;
+ 	    if (e2->op == TOKmin)
+ 	    {
+ 		rtl = RTLSYM_ARRAYASSMINFLOAT;
+ 		if (t->ty == Tfloat64)
+ 		    rtl = RTLSYM_ARRAYASSMINDOUBLE;
+ 		else if (t->ty == Tfloat80)
+ 		    rtl = RTLSYM_ARRAYASSMINREAL;
+ 	    }
+ 
+ 	    /* Set parameters so the order of evaluation is eb, ec, ea
++ 	     */
+ 	    elem *ep = el_params(eb, ec, ea, NULL);
+ 	    e = el_bin(OPcall, type->totym(), el_var(rtlsym[rtl]), ep);
+ 	    goto Lret;
+ 	}
 	else
 	{
 	    /* It's array1[]=array2[]
 		// If eto is a static array, need to convert it to
 		// a dynamic array.
 		//if (are->e1->type->ty == Tsarray)
-		//    eto = sarray_toDarray(are->e1->type, eto);
+		//    eto = sarray_toDarray(loc, are->e1->type, eto);
 
 		ep = el_params(eto, efrom, esize, NULL);
 		e = el_bin(OPcall, type->totym(), el_var(rtlsym[RTLSYM_ARRAYCOPY]), ep);
     // Convert from static array to dynamic array
     if (tty == Tarray && fty == Tsarray)
     {
-	e = sarray_toDarray(tfrom, t, e);
+	e = sarray_toDarray(loc, tfrom, t, e);
 	goto Lret;
     }
 
     }
     else if (t1->ty == Tsarray)
     {
-	e = sarray_toDarray(t1, NULL, e);
+	e = sarray_toDarray(loc, t1, NULL, e);
     }
     el_setLoc(e,loc);
     return e;
 
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #include <stdio.h>
 #include "enum.h"
 #include "mtype.h"
 #include "scope.h"
+#include "declaration.h"
 
 /********************************* EnumDeclaration ****************************/
 
     minval = 0;
     defaultval = 0;
     sinit = NULL;
+    isdeprecated = 0;
     attributes = NULL;
 }
 
 	return;
     if (!memtype)
 	memtype = Type::tint32;
+	if (sc->stc & STCdeprecated)
+ 	isdeprecated = 1;
     parent = sc->scopesym;
     if (attributes)
 	attributes->append(sc->attributes);
     return type;
 }
 
-char *EnumDeclaration::kind()
+const char *EnumDeclaration::kind()
 {
     return "enum";
 }
 
+int EnumDeclaration::isDeprecated()
+ {
+     return isdeprecated;
+ }
+
 /********************************* EnumMember ****************************/
 
 EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value)
     }
 }
 
-char *EnumMember::kind()
+const char *EnumMember::kind()
 {
     return "enum member";
 }
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2006 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
 /* NOTE: This file has been patched from the original DMD distribution to
    work with the GDC compiler.
 
-   Modified by David Friedman, December 2006
+   Modified by Michael Parrott, September 2009
+   Using David Friedman's code
 */
 
 #ifndef DMD_ENUM_H
 {
     Type *type;			// the TypeEnum
     Type *memtype;		// type of the members
-    integer_t maxval;
-    integer_t minval;
-    integer_t defaultval;	// default initializer
+    #if V1
+      integer_t maxval;
+      integer_t minval;
+      integer_t defaultval;	// default initializer
+ #else
+     Expression *maxval;
+     Expression *minval;
+     Expression *defaultval;	// default initializer
+ 
+     Scope *scope;		// !=NULL means context to use
+ #endif
+     int isdeprecated;
     Expressions * attributes; // GCC decl/type attributes
 
     EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
     int oneMember(Dsymbol **ps);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     Type *getType();
-    char *kind();
+    const char *kind();
+    #if V2
+     Dsymbol *search(Loc, Identifier *ident, int flags);
+ 	#endif
+     int isDeprecated();			// is Dsymbol deprecated?
 
     void emitComment(Scope *sc);
     void toDocBuffer(OutBuffer *buf);
     EnumMember(Loc loc, Identifier *id, Expression *value);
     Dsymbol *syntaxCopy(Dsymbol *s);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
 
     void emitComment(Scope *sc);
     void toDocBuffer(OutBuffer *buf);

d/dmd/expression.c

 #endif
 /* Can't find a path from e1 to ad
 ! 	     */
-	    error("this for %s needs to be type %s not type %s",
+	    e1->error("this for %s needs to be type %s not type %s",
 		var->toChars(), ad->toChars(), t->toChars());
 	}
     }
     return FALSE;
 }
 
+/********************************
++  * Can this expression throw an exception?
++  * Valid only after semantic() pass.
++  */
+ 
+int Expression::canThrow()
+{
+    return TRUE;
+}
+
 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
 {   Expressions *a = NULL;
 
 	    }
 
 	    default:
-		print();
-		type->print();
+		/* This can happen if errors, such as
+! 		 * the type is painted on like in fromConstInitializer().
+! 		 */
+ 		if (!global.errors)
+ 		{   type->print();
 		assert(0);
+		}	
 		break;
 	}
 	break;
 		goto L3;
 
 	    default:
+	    /* This can happen if errors, such as
++ 		 * the type is painted on like in fromConstInitializer().
++ 		 */
+ 		if (!global.errors)
+ 		{
 #ifdef DEBUG
 		t->print();
 #endif
 		assert(0);
 	}
+	break;
+	}
     }
     else if (v & 0x8000000000000000LL)
 	buf->printf("0x%"PRIxMAX, v);
 #endif
     typeidType = typeidType->semantic(loc, sc);
     e = typeidType->getTypeInfo(sc);
+    if (e->loc.linnum == 0)
+ 	e->loc = loc;		// so there's at least some line number info
     return e;
 }
 
 	    e1 = getRightThis(loc, sc, ad, e1, var);
 	    if (!sc->noaccesscheck)
 	    accessCheck(loc, sc, e1, var);
+	    VarDeclaration *v = var->isVarDeclaration();
+ 	    if (v && v->isConst())
+ 	    {	ExpInitializer *ei = v->getExpInitializer();
+ 		if (ei)
+ 		{   Expression *e = ei->exp->copy();
+ 		    e = e->semantic(sc);
+ 		    return e;
+ 		}
+ 	    }
 	}
     }
     //printf("-DotVarExp::semantic('%s')\n", toChars());
     return e;
 
 Lerr:
-    return new IntegerExp(0);
+    return new IntegerExp(loc, 0, Type::tint32);
 }
 
 void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 	{
 	    ue->e1 = getRightThis(loc, sc, ad, ue->e1, f);
 	}
+	/* Cannot call public functions from inside invariant
++ 	 * (because then the invariant would have infinite recursion)
++ 	 */
+ 	if (sc->func && sc->func->isInvariantDeclaration() &&
+ 	    ue->e1->op == TOKthis &&
+ 	    f->addPostInvariant()
+ 	   )
+ 	{
+ 	    error("cannot call public/export function %s from invariant", f->toChars());
+ 	}
 
 	checkDeprecated(sc, f);
 	accessCheck(loc, sc, ue->e1, f);

d/dmd/expression.h

 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2007 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
     virtual int isBool(int result);
     virtual int isBit();
     virtual int checkSideEffect(int flag);
+    virtual int canThrow();
 
     virtual int inlineCost(InlineCostState *ics);
     virtual Expression *doInline(InlineDoState *ids);
     StructDeclaration *sd;
     ClassDeclaration *cd;
     InterfaceDeclaration *id;
+    Dsymbol *pd;
 
 #if 0
     printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
 	if (fbody)
 	    error("function body is not abstract in interface %s", id->toChars());
     }
+    /* Template member functions aren't virtual:
++      *   interface TestInterface { void tpl(T)(); }
++      * and so won't work in interfaces
++      */
+     if ((pd = toParent()) != NULL &&
+ 	pd->isTemplateInstance() &&
+ 	(pd = toParent2()) != NULL &&
+ 	(id = pd->isInterfaceDeclaration()) != NULL)
+     {
+ 	error("template member function not allowed in interface %s", id->toChars());
+     }
 
     cd = parent->isClassDeclaration();
     if (cd)
 		f = (TypeFunction *)type;
 	    }
 
-	    int offend = fbody ? fbody->fallOffEnd() : TRUE;
+	    int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE;
+ 	    //int offend = fbody ? fbody->fallOffEnd() : TRUE;
 
 	    if (isStaticCtorDeclaration())
 	    {	/* It's a static constructor. Ensure that all
     return fd;
 }
 
-char *FuncDeclaration::kind()
+const char *FuncDeclaration::kind()
 {
     return "function";
 }
     this->funcalias = funcalias;
 }
 
-char *FuncAliasDeclaration::kind()
+const char *FuncAliasDeclaration::kind()
 {
     return "function alias";
 }
     return (tok == TOKdelegate);
 }
 
-char *FuncLiteralDeclaration::kind()
+int FuncLiteralDeclaration::isVirtual()
+ {
+     return FALSE;
+ }
+ 
+ const char *FuncLiteralDeclaration::kind()
 {
     // GCC requires the (char*) casts
     return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function";
 	cd->defaultCtor = this;
 }
 
-char *CtorDeclaration::kind()
+const char *CtorDeclaration::kind()
 {
     return "constructor";
 }
     FuncDeclaration::semantic(sc);
 }
 
-char *NewDeclaration::kind()
+const char *NewDeclaration::kind()
 {
     return "allocator";
 }
     FuncDeclaration::semantic(sc);
 }
 
-char *DeleteDeclaration::kind()
+const char *DeleteDeclaration::kind()
 {
     return "deallocator";
 }
     { "empty", "" },
     { "p" },
     { "coverage", "__coverage" },
+    { "__vptr" },
+    { "__monitor" },
 
     { "TypeInfo" },
     { "TypeInfo_Class" },
     aliases.push(alias);
 }
 
-char *Import::kind()
+const char *Import::kind()
 {
     return isstatic ? (char *)"static import" : (char *)"import";
 }
 	int isstatic);
     void addAlias(Identifier *name, Identifier *alias);
 
-    char *kind();
+    const char *kind();
     Dsymbol *syntaxCopy(Dsymbol *s);	// copy only syntax trees
     void load(Scope *sc);
     void semantic(Scope *sc);
 	value.data[i] = (void *)val;
 	length++;
 	if (length == 0)
-	    error("array dimension overflow");
+	    error(loc, "array dimension overflow");
 	if (length > dim)
 	    dim = length;
     }
 #include "lib.h"
 #include "melf.h"
 
-#define LOG 1
+#define LOG 0
 
 Library::Library()
 {
 	    for (unsigned offset = 0; offset < section->SHsecsz; offset += sizeof(elf_symtab))
 	    {	elf_symtab *sym = (elf_symtab *)(buf + section->SHfileoff + offset);
 
-		if ((sym->STinfo >> 4) == ST_BIND_GLOBAL &&
+		if (((sym->STinfo >> 4) == ST_BIND_GLOBAL ||
+ 		     (sym->STinfo >> 4) == ST_BIND_WEAK) &&
 		    sym->STdefsht != SHT_UNDEF)	// not extern
 		{
 		    char *name = string_tab + sym->STname;
 
 
-// Copyright (c) 1999-2007 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
 int executecmd(char *cmd, char *args, int useenv);
 int executearg0(char *cmd, char *args);
 
+/****************************************
++  * Write filename to cmdbuf, quoting if necessary.
++  */
+ 
+ void writeFilename(OutBuffer *buf, char *filename, size_t len)
+ {
+     /* Loop and see if we need to quote
++      */
+     for (size_t i = 0; i < len; i++)
+     {	char c = filename[i];
+ 
+ 	if (isalnum(c) || c == '_')
+ 	    continue;
+ 
+ 	/* Need to quote
++ 	 */
+ 	buf->writeByte('"');
+ 	buf->write(filename, len);
+ 	buf->writeByte('"');
+ 	return;
+     }
+ 
+     /* No quoting necessary
++      */
+     buf->write(filename, len);
+ }
+ 
+ void writeFilename(OutBuffer *buf, char *filename)
+ {
+     writeFilename(buf, filename, strlen(filename));
+ }
+
 /*****************************
  * Run the linker.  Return status of execution.
  */
 	p = (char *)global.params.objfiles->data[i];
 	char *ext = FileName::ext(p);
 	if (ext)
-	    cmdbuf.write(p, ext - p - 1);
+	    // Write name sans extension
+ 	    writeFilename(&cmdbuf, p, ext - p - 1);
 	else
-	    cmdbuf.writestring(p);
+	    writeFilename(&cmdbuf, p);
     }
     cmdbuf.writeByte(',');
     if (global.params.exefile)
-	cmdbuf.writestring(global.params.exefile);
+	writeFilename(&cmdbuf, global.params.exefile);
     else
-    {	// Generate exe file name from first obj name
+    {	/* Generate exe file name from first obj name.
+! 	 * No need to add it to cmdbuf because the linker will default to it.
+! 	 */
 	char *n = (char *)global.params.objfiles->data[0];
 	n = FileName::name(n);
 	FileName *fn = FileName::forceExt(n, "exe");
     {
 	if (i)
 	    cmdbuf.writeByte('+');
-	cmdbuf.writestring((char *) global.params.libfiles->data[i]);
+	writeFilename(&cmdbuf, (char *) global.params.libfiles->data[i]);
     }
 
     if (global.params.deffile)
     {
 	cmdbuf.writeByte(',');
-	cmdbuf.writestring(global.params.deffile);
+	writeFilename(&cmdbuf, global.params.deffile);
     }
 
     /* Eliminate unnecessary trailing commas	*/
     if (global.params.resfile)
     {
 	cmdbuf.writestring("/RC:");
-	cmdbuf.writestring(global.params.resfile);
+	writeFilename(&cmdbuf, global.params.resfile);
     }
 
 #if 0
 
     copyright = "Copyright (c) 1999-2008 by Digital Mars";
     written = "written by Walter Bright";
-    version = "v1.031";
+    version = "v1.032";
     global.structalign = 8;
 
     memset(&params, 0, sizeof(Param));
 int runProgram();
 void inifile(char *argv0, char *inifile);
 void halt();
+void util_progress();
 
 /*** Where to send error messages ***/
 #if IN_GCC
+/*
+ **********************************************************************
+ ** md5.c                                                            **
+ ** RSA Data Security, Inc. MD5 Message Digest Algorithm             **
+ ** Created: 2/17/90 RLR                                             **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** License to copy and use this software is granted provided that   **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message     **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function.                                       **
+ **                                                                  **
+ ** License is also granted to make and use derivative works         **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD5 Message Digest Algorithm" in all         **
+ ** material mentioning or referencing the derived work.             **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+ */
+
+/* -- include the following line if the md5.h header file is separate -- */
+#include "md5.h"
+
+/* forward declaration */
+static void Transform (UINT4 *buf, UINT4 *in);
+
+static unsigned char PADDING[64] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G and H are basic MD5 functions: selection, majority, parity */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z))) 
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) \
+  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) \
+  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) \
+  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+
+void MD5Init (mdContext)
+MD5_CTX *mdContext;
+{
+  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
+
+  /* Load magic initialization constants.
+   */
+  mdContext->buf[0] = (UINT4)0x67452301;
+  mdContext->buf[1] = (UINT4)0xefcdab89;
+  mdContext->buf[2] = (UINT4)0x98badcfe;
+  mdContext->buf[3] = (UINT4)0x10325476;
+}
+
+void MD5Update (mdContext, inBuf, inLen)
+MD5_CTX *mdContext;
+unsigned char *inBuf;
+unsigned int inLen;
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* update number of bits */
+  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+    mdContext->i[1]++;
+  mdContext->i[0] += ((UINT4)inLen << 3);
+  mdContext->i[1] += ((UINT4)inLen >> 29);
+
+  while (inLen--) {
+    /* add new character to buffer, increment mdi */
+    mdContext->in[mdi++] = *inBuf++;
+
+    /* transform if necessary */
+    if (mdi == 0x40) {
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)
+        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+                (((UINT4)mdContext->in[ii+2]) << 16) |
+                (((UINT4)mdContext->in[ii+1]) << 8) |
+                ((UINT4)mdContext->in[ii]);
+      Transform (mdContext->buf, in);
+      mdi = 0;
+    }
+  }
+}
+
+void MD5Final (mdContext)
+MD5_CTX *mdContext;
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+  unsigned int padLen;
+
+  /* save number of bits */
+  in[14] = mdContext->i[0];
+  in[15] = mdContext->i[1];
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* pad out to 56 mod 64 */
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+  MD5Update (mdContext, PADDING, padLen);
+
+  /* append length in bits and transform */
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)
+    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+            (((UINT4)mdContext->in[ii+2]) << 16) |
+            (((UINT4)mdContext->in[ii+1]) << 8) |
+            ((UINT4)mdContext->in[ii]);
+  Transform (mdContext->buf, in);
+
+  /* store buffer in digest */
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+    mdContext->digest[ii+1] =
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+    mdContext->digest[ii+2] =
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+    mdContext->digest[ii+3] =
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+  }
+}
+
+/* Basic MD5 step. Transform buf based on in.
+ */
+static void Transform (buf, in)
+UINT4 *buf;
+UINT4 *in;
+{
+  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+  /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+  FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */
+  FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */
+  FF ( c, d, a, b, in[ 2], S13,  606105819); /* 3 */
+  FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */
+  FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */
+  FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */
+  FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */
+  FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */
+  FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */
+  FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */
+  FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */
+  FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */
+  FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */
+  FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */
+  FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */
+  FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */
+
+  /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+  GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
+  GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
+  GG ( c, d, a, b, in[11], S23,  643717713); /* 19 */
+  GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
+  GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
+  GG ( d, a, b, c, in[10], S22,   38016083); /* 22 */
+  GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
+  GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
+  GG ( a, b, c, d, in[ 9], S21,  568446438); /* 25 */
+  GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
+  GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
+  GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
+  GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
+  GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
+  GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
+  GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */
+
+  /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+  HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */
+  HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */
+  HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */
+  HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
+  HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
+  HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
+  HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
+  HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
+  HH ( a, b, c, d, in[13], S31,  681279174); /* 41 */
+  HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
+  HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
+  HH ( b, c, d, a, in[ 6], S34,   76029189); /* 44 */
+  HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
+  HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
+  HH ( c, d, a, b, in[15], S33,  530742520); /* 47 */
+  HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */
+
+  /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+  II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */
+  II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */
+  II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
+  II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
+  II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
+  II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
+  II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
+  II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
+  II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
+  II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
+  II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
+  II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
+  II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
+  II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
+  II ( c, d, a, b, in[ 2], S43,  718787259); /* 63 */
+  II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+/*
+ **********************************************************************
+ ** End of md5.c                                                     **
+ ******************************* (cut) ********************************
+ */
+
+/*
+ **********************************************************************
+ ** md5.h -- Header file for implementation of MD5                   **
+ ** RSA Data Security, Inc. MD5 Message Digest Algorithm             **
+ ** Created: 2/17/90 RLR                                             **
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version              **
+ ** Revised (for MD5): RLR 4/27/91                                   **
+ **   -- G modified to have y&~z instead of y&z                      **
+ **   -- FF, GG, HH modified to add in last register done            **
+ **   -- Access pattern: round 2 works mod 5, round 3 works mod 3    **
+ **   -- distinct additive constant for each step                    **
+ **   -- round 4 added, working mod 7                                **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** License to copy and use this software is granted provided that   **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message     **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function.                                       **
+ **                                                                  **
+ ** License is also granted to make and use derivative works         **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD5 Message Digest Algorithm" in all         **
+ ** material mentioning or referencing the derived work.             **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+ */
+
+/* typedef a 32 bit type */
+typedef unsigned long int UINT4;
+
+/* Data structure for MD5 (Message Digest) computation */
+typedef struct {
+  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
+  UINT4 buf[4];                                    /* scratch buffer */
+  unsigned char in[64];                              /* input buffer */
+  unsigned char digest[16];     /* actual digest after MD5Final call */
+} MD5_CTX;
+
+void MD5Init (MD5_CTX *mdContext);
+void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned inLen);
+void MD5Final (MD5_CTX *mdContext);
+
+/*
+ **********************************************************************
+ ** End of md5.h                                                     **
+ ******************************* (cut) ********************************
+ */
+
+
 {
 }
 
-char *Module::kind()
+const char *Module::kind()
 {
     return "module";
 }
 }
 
 
-char *Package::kind()
+const char *Package::kind()
 {
     return "package";
 }
 struct Package : ScopeDsymbol
 {
     Package(Identifier *ident);
-    char *kind();
+    const char *kind();
 
     static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);
 
     static Module *load(Loc loc, Array *packages, Identifier *ident);
 
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *kind();
+    const char *kind();
     void setDocfile();	// set docfile member
     void read(Loc loc);	// read file
 #if IN_GCC
     if (s)
     {
 	//printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
+	s->checkDeprecated(loc, sc);		// check for deprecated aliases
 	s = s->toAlias();
 	//printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
 	for (i = 0; i < idents.dim; i++)
 {
     Type *t;
 
-    t = semantic(0, sc);
+    t = semantic(loc, sc);
     if (t == this)
 	return NULL;
     return t->toDsymbol(sc);
 	sc->intypeof++;
 	exp = exp->semantic(sc);
 	sc->intypeof--;
+	if (exp->op == TOKtype)
+ 	{
+ 	    error(loc, "argument %s to typeof is not an expression", exp->toChars());
+ 	}
 	t = exp->type;
 	if (!t)
 	{
 	//return getProperty(e->loc, ident);
 	return Type::dotExp(sc, e, ident);
     }
+    s->checkDeprecated(e->loc, sc);
     s = s->toAlias();
 
     v = s->isVarDeclaration();
 	    }
 	    return e;
 	}
+	
+	if (ident == Id::__vptr)
+ 	{   /* The pointer to the vtbl[]
++ 	     * *cast(void***)e
++ 	     */
+ 	    e = e->castTo(sc, tvoidptr->pointerTo()->pointerTo());
+ 	    e = new PtrExp(e->loc, e);
+ 	    e = e->semantic(sc);
+ 	    return e;
+ 	}
+ 
+ 	if (ident == Id::__monitor)
+ 	{   /* The handle to the monitor (call it a void*)
++ 	     * *(cast(void**)e + 1)
++ 	     */
+ 	    e = e->castTo(sc, tvoidptr->pointerTo());
+ 	    e = new AddExp(e->loc, e, new IntegerExp(1));
+ 	    e = new PtrExp(e->loc, e);
+ 	    e = e->semantic(sc);
+ 	    return e;
+ 	}
 
 	if (ident == Id::typeinfo)
 	{
 	    return Type::dotExp(sc, e, ident);
 	}
     }
+    s->checkDeprecated(e->loc, sc);
     s = s->toAlias();
     v = s->isVarDeclaration();
     if (v && v->isConst())
 	integer_t i2 = e->e2->toInteger();
 	target_size_t sz = e->e1->type->size() * 8;
 	if (i2 < 0 || i2 > sz)
-	{   error("shift left by %"PRIdMAX" exceeds %"PRIuTSIZE, i2, sz);
+	{   e->error("shift by %"PRIdMAX" is outside the range 0..%"PRIuTSIZE, i2, sz);
 	    e->e2 = new IntegerExp(0);
 	}
 	if (e->e1->isConst() == 1)
 	if (token.value != TOKidentifier)
 	{
 	    error("identifier expected, not %s", token.toChars());
-	    goto Lerr;
+	    id = Id::empty;
 	}
-	id = token.ident;
+	else
+		id = token.ident;
 	nextToken();
     }
 
 
     return tm;
 
-Lerr:
-    return NULL;
 }
 
 /******************************************
 	    exp = parseExpression();
 	    check(TOKrparen);
 	    t = new TypeTypeof(loc, exp);
-	    if (token.value == TOKdot)
-		goto L1;
 	    e = new TypeExp(loc, t);
 	    break;
 	}

d/dmd/statement.c

 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2007 by Digital Mars
+// Copyright (c) 1999-2008 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
     return FALSE;
 }
 
+/* Only valid after semantic analysis
++  */
+ int Statement::blockExit()
+ {
+     printf("Statement::blockExit(%p)\n", this);
+     printf("%s\n", toChars());
+     //assert(0); //commented out for gdc
+     return BEany;
+ }
+
 // TRUE if statement may fall off the end without a throw or return
 
 int Statement::fallOffEnd()
     return this;
 }
 
+int ExpStatement::blockExit()
+ {   int result = BEfallthru;
+ 
+     if (exp)
+     {
+ 	if (exp->op == TOKhalt)
+ 	    return BEhalt;
+ 	if (exp->op == TOKassert)
+ 	{   AssertExp *a = (AssertExp *)exp;
+ 
+ 	    if (a->e1->isBool(FALSE))	// if it's an assert(0)
+ 		return BEhalt;
+ 	}
+ 	if (exp->canThrow())
+ 	    result |= BEthrow;
+     }
+     return result;
+ }
+
 int ExpStatement::fallOffEnd()
 {
     if (exp)
 
 Statement *CompileStatement::semantic(Scope *sc)
  {
-     printf("CompileStatement::semantic() %s\n", exp->toChars());
-     /* Shouldn't happen unless errors, as CompileStatement::flatten()
-+      * should have replaced it.
-+      * Return NULL so no further errors happen.
-+      */
-     assert(global.errors);
-     return NULL;
+     //printf("CompileStatement::semantic() %s\n", exp->toChars());
+     Statements *a = flatten(sc);
+     if (!a)
+     return NULL;
+     Statement *s = new CompoundStatement(loc, a);
+     return s->semantic(sc);
  }
 
 
 }
 
 ReturnStatement *CompoundStatement::isReturnStatement()
-{   int i;
+{   
     ReturnStatement *rs = NULL;
 
-    for (i = 0; i < statements->dim; i++)
-    {	Statement *s;
-
-	s = (Statement *) statements->data[i];
+    for (int i = 0; i < statements->dim; i++)
+     {	Statement *s = (Statement *) statements->data[i];
 	if (s)
 	{
 	    rs = s->isReturnStatement();
 }
 
 void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{   int i;
-
-    for (i = 0; i < statements->dim; i++)
-    {	Statement *s;
-
-	s = (Statement *) statements->data[i];
+{   
+
+    for (int i = 0; i < statements->dim; i++)
+     {	Statement *s = (Statement *) statements->data[i];
 	if (s)
 	    s->toCBuffer(buf, hgs);
     }
 int CompoundStatement::usesEH()
 {
     for (int i = 0; i < statements->dim; i++)
-    {	Statement *s;
-
-	s = (Statement *) statements->data[i];
+    {	Statement *s = (Statement *) statements->data[i];
 	if (s && s->usesEH())
 	    return TRUE;
     }
     return FALSE;
 }
 
+int CompoundStatement::blockExit()
 {
+     //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim);
+     int result = BEfallthru;
+     for (size_t i = 0; i < statements->dim; i++)
     {	Statement *s = (Statement *) statements->data[i];
 	if (s)
+ 	{
+ //printf("result = x%x\n", result);
+ //printf("%s\n", s->toChars());
+ 	    if (!(result & BEfallthru) && !s->comeFrom())
+	    {
+ 		if (global.params.warnings)
+ 		{   fprintf(stdmsg, "warning - ");
+ 		    s->error("statement is not reachable");
+ 		}
+ 	    }
+ 
+ 	    result &= ~BEfallthru;
+ 	    result |= s->blockExit();
+ 	}
+     }
+     return result;
+ }
+
 int CompoundStatement::fallOffEnd()
 {   int falloff = TRUE;
 
 int UnrolledLoopStatement::usesEH()
 {
     for (size_t i = 0; i < statements->dim; i++)
-    {	Statement *s;
-
-	s = (Statement *) statements->data[i];
+    {	Statement *s = (Statement *) statements->data[i];
 	if (s && s->usesEH())
 	    return TRUE;
     }
     return FALSE;
 }
 
+int UnrolledLoopStatement::blockExit()
+ {
+     int result = BEfallthru;
+     for (size_t i = 0; i < statements->dim; i++)
+     {	Statement *s = (Statement *) statements->data[i];
+ 	if (s)
+ 	{
+ 	    int r = s->blockExit();
+ 	    result |= r & ~(BEbreak | BEcontinue);
+ 	}
+     }
+     return result;
+ }
+
 int UnrolledLoopStatement::fallOffEnd()
 {
     //printf("UnrolledLoopStatement::fallOffEnd()\n");
     return statement ? statement->usesEH() : FALSE;
 }
 
+int ScopeStatement::blockExit()
+ {
+     //printf("ScopeStatement::blockExit(%p)\n", statement);
+     return statement ? statement->blockExit() : BEfallthru;
+ }
+
 int ScopeStatement::fallOffEnd()
 {
     return statement ? statement->fallOffEnd() : TRUE;
     return body ? body->usesEH() : 0;
 }
 
+int WhileStatement::blockExit()
+ {
+     //printf("WhileStatement::blockExit(%p)\n", this);
+ 
+     int result = BEnone;
+     if (condition->canThrow())
+ 	result |= BEthrow;
+     if (condition->isBool(TRUE))
+     {
+ 	if (body)
+ 	{   result |= body->blockExit();
+ 	    if (result & BEbreak)
+ 		result |= BEfallthru;
+ 	}
+     }
+     else if (condition->isBool(FALSE))
+     {
+ 	result |= BEfallthru;
+     }
+     else
+     {
+ 	if (body)
+ 	    result |= body->blockExit();
+ 	result |= BEfallthru;
+     }
+     result &= ~(BEbreak | BEcontinue);
+     return result;
+ }
+
 int WhileStatement::fallOffEnd()
 {
     if (body)
     return body ? body->usesEH() : 0;
 }
 
+int DoStatement::blockExit()
+ {   int result;
+ 
+     if (body)
+     {	result = body->blockExit();
+ 	if (result == BEbreak)
+ 	    return BEfallthru;
+ 	if (result & BEcontinue)
+ 	    result |= BEfallthru;
+     }
+     else
+ 	result = BEfallthru;
+     if (result & BEfallthru)
+     {	if (condition->canThrow())
+ 	    result |= BEthrow;
+ 	if (!(result & BEbreak) && condition->isBool(TRUE))
+ 	    result &= ~BEfallthru;
+     }
+     result &= ~(BEbreak | BEcontinue);
+     return result;
+ }
+
 int DoStatement::fallOffEnd()
 {
     if (body)
     return (init && init->usesEH()) || body->usesEH();
 }
 
+int ForStatement::blockExit()
+ {   int result = BEfallthru;
+ 
+     if (init)
+     {	result = init->blockExit();
+ 	if (!(result & BEfallthru))
+ 	    return result;
+     }
+     if (condition)
+     {	if (condition->canThrow())
+ 	    result |= BEthrow;
+     }
+     else
+ 	result &= ~BEfallthru;	// the body must do the exiting
+     if (body)
+     {	int r = body->blockExit();
+ 	if (r & BEbreak)
+ 	    result |= BEfallthru;
+ 	result |= r & ~(BEbreak | BEcontinue);
+     }
+     if (increment && increment->canThrow())
+ 	result |= BEthrow;
+     return result;
+ }
+
 int ForStatement::fallOffEnd()
 {
     if (body)
 		    VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
 		    if (e->isConst())
 			v->storage_class |= STCconst;
-#if V2
-		    else
-			v->storage_class |= STCfinal;
-#endif
 		    var = v;
 		}
 	    }
     return body->usesEH();
 }
 
+int ForeachStatement::blockExit()
+ {   int result = BEfallthru;
+ 
+     if (aggr->canThrow())
+ 	result |= BEthrow;
+ 
+     if (body)
+     {
+ 	result |= body->blockExit() & ~(BEbreak | BEcontinue);
+     }
+     return result;
+ }
+
 int ForeachStatement::fallOffEnd()
 {
     if (body)
 {
     buf->writestring(Token::toChars(op));
     buf->writestring(" (");
-    int i;
     for (int i = 0; i < arguments->dim; i++)
     {
 	Argument *a = (Argument *)arguments->data[i];
     return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH());
 }
 
+int IfStatement::blockExit()
+ {
+     //printf("IfStatement::blockExit(%p)\n", this);
+ 
+     int result = BEnone;
+     if (condition->canThrow())
+ 	result |= BEthrow;
+     if (condition->isBool(TRUE))
+     {
+ 	if (ifbody)
+ 	    result |= ifbody->blockExit();
+ 	else
+ 	    result |= BEfallthru;
+     }
+     else if (condition->isBool(FALSE))
+     {
+ 	if (elsebody)
+ 	    result |= elsebody->blockExit();
+ 	else
+ 	    result |= BEfallthru;
+     }
+     else
+     {
+ 	if (ifbody)
+ 	    result |= ifbody->blockExit();
+ 	else
+ 	    result |= BEfallthru;
+ 	if (elsebody)
+ 	    result |= elsebody->blockExit();
+ 	else
+ 	    result |= BEfallthru;
+     }
+     //printf("IfStatement::blockExit(%p) = x%x\n", this, result);
+     return result;
+ }
+
 int IfStatement::fallOffEnd()
 {
     if (!ifbody || ifbody->fallOffEnd() ||
     return body && body->usesEH();
 }
 
+int PragmaStatement::blockExit()
+ {
+     int result = BEfallthru;
+ #if 0 // currently, no code is generated for Pragma's, so it's just fallthru
+     if (arrayExpressionCanThrow(args))
+ 	result |= BEthrow;
+     if (body)
+ 	result |= body->blockExit();
+ #endif
+    return result;
+ }
+
 int PragmaStatement::fallOffEnd()
 {
     if (body)
     return body ? body->usesEH() : 0;
 }
 
+int SwitchStatement::blockExit()
+ {   int result = BEnone;
+     if (condition->canThrow())
+ 	result |= BEthrow;
+ 
+     if (body)
+     {	result |= body->blockExit();
+ 	if (result & BEbreak)
+ 	{   result |= BEfallthru;
+ 	    result &= ~BEbreak;
+ 	}
+     }
+     else
+ 	result |= BEfallthru;
+ 
+     return result;
+ }
+
 int SwitchStatement::fallOffEnd()
 {
     if (body)
     return statement->usesEH();
 }
 
+int CaseStatement::blockExit()
+ {
+     return statement->blockExit();
+ }
+
 int CaseStatement::fallOffEnd()
 {
     return statement->fallOffEnd();
 
 Statement *DefaultStatement::semantic(Scope *sc)
 {
+	//printf("DefaultStatement::semantic()\n");
     if (sc->sw)
     {
 	if (sc->sw->sdefault)
     return statement->usesEH();
 }
 
+int DefaultStatement::blockExit()
+ {