changeset 1587:def7a1d494fd

Merge DMD 1.051
author Christian Kamm <kamm incasoftware de>
date Fri, 06 Nov 2009 23:58:01 +0100
parents 7f728c52e63c
children 71ad691baeb2
files dmd/aggregate.h dmd/arrayop.c dmd/attrib.c dmd/attrib.h dmd/cast.c dmd/class.c dmd/constfold.c dmd/declaration.c dmd/declaration.h dmd/doc.c dmd/dsymbol.c dmd/dsymbol.h dmd/enum.h dmd/expression.c dmd/expression.h dmd/func.c dmd/idgen.c dmd/import.c dmd/import.h dmd/init.c dmd/inline.c dmd/interpret.c dmd/lexer.c dmd/lexer.h dmd/mangle.c dmd/mars.c dmd/mars.h dmd/module.c dmd/module.h dmd/mtype.c dmd/mtype.h dmd/opover.c dmd/optimize.c dmd/parse.c dmd/root/async.c dmd/root/man.c dmd/root/root.c dmd/scope.c dmd/scope.h dmd/statement.c dmd/statement.h dmd/struct.c dmd/template.c dmd/template.h gen/classes.cpp gen/main.cpp
diffstat 46 files changed, 19570 insertions(+), 16602 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/aggregate.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/aggregate.h	Fri Nov 06 23:58:01 2009 +0100
@@ -62,13 +62,19 @@
 				// 1: size is correct
 				// 2: cannot determine size; fwd referenced
     int isdeprecated;		// !=0 if deprecated
-    Scope *scope;		// !=NULL means context to use
 
     // Special member functions
     InvariantDeclaration *inv;		// invariant
     NewDeclaration *aggNew;		// allocator
     DeleteDeclaration *aggDelete;	// deallocator
 
+#if DMDV2
+    //CtorDeclaration *ctor;
+    Dsymbol *ctor;			// CtorDeclaration or TemplateDeclaration
+    CtorDeclaration *defaultCtor;	// default constructor
+    Dsymbol *aliasthis;			// forward unresolved lookups to aliasthis
+#endif
+
     FuncDeclarations dtors;	// Array of destructors
     FuncDeclaration *dtor;	// aggregate destructor
 
@@ -88,6 +94,7 @@
     FuncDeclaration *buildDtor(Scope *sc);
 
     void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
     void toDocBuffer(OutBuffer *buf);
 
     // For access checking
--- a/dmd/arrayop.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/arrayop.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,5 +1,5 @@
 
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -31,6 +31,14 @@
 
 Expression *BinExp::arrayOp(Scope *sc)
 {
+    //printf("BinExp::arrayOp() %s\n", toChars());
+
+    if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid)
+    {
+        error("Cannot perform array operations on void[] arrays");
+        return new ErrorExp();
+    }
+
     Expressions *arguments = new Expressions();
 
     /* The expression to generate an array operation for is mangled
@@ -288,6 +296,8 @@
         sc->stc = 0;
         sc->linkage = LINKd;
         fd->semantic(sc);
+	    fd->semantic2(sc);
+	    fd->semantic3(sc);
         sc->pop();
 //     }
 //     else
@@ -318,6 +328,17 @@
     arguments->shift(this);
 }
 
+void CastExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments)
+{
+    Type *tb = type->toBasetype();
+    if (tb->ty == Tarray || tb->ty == Tsarray)
+    {
+	e1->buildArrayIdent(buf, arguments);
+    }
+    else
+	Expression::buildArrayIdent(buf, arguments);
+}
+
 void SliceExp::buildArrayIdent(OutBuffer *buf, Expressions *arguments)
 {
     buf->writestring("Slice");
@@ -402,6 +423,17 @@
     return e;
 }
 
+Expression *CastExp::buildArrayLoop(Arguments *fparams)
+{
+    Type *tb = type->toBasetype();
+    if (tb->ty == Tarray || tb->ty == Tsarray)
+    {
+	return e1->buildArrayLoop(fparams);
+    }
+    else
+	return Expression::buildArrayLoop(fparams);
+}
+
 Expression *SliceExp::buildArrayLoop(Arguments *fparams)
 {
     Identifier *id = Identifier::generateId("p", fparams->dim);
@@ -420,6 +452,14 @@
     /* Evaluate assign expressions right to left
      */
     Expression *ex2 = e2->buildArrayLoop(fparams);
+#if DMDV2
+    /* Need the cast because:
+     *   b = c + p[i];
+     * where b is a byte fails because (c + p[i]) is an int
+     * which cannot be implicitly cast to byte.
+     */
+    ex2 = new CastExp(0, ex2, e1->type->nextOf());
+#endif
     Expression *ex1 = e1->buildArrayLoop(fparams);
     Argument *param = (Argument *)fparams->data[0];
     param->storageClass = 0;
@@ -488,3 +528,34 @@
 #undef X
 
 
+/***********************************************
+ * Test if operand is a valid array op operand.
+ */
+
+int Expression::isArrayOperand()
+{
+    //printf("Expression::isArrayOperand() %s\n", toChars());
+    if (op == TOKslice)
+	return 1;
+    if (type->toBasetype()->ty == Tarray)
+    {
+	switch (op)
+	{
+	    case TOKadd:
+	    case TOKmin:
+	    case TOKmul:
+	    case TOKdiv:
+	    case TOKmod:
+	    case TOKxor:
+	    case TOKand:
+	    case TOKor:
+	    case TOKneg:
+	    case TOKtilde:
+		return 1;
+
+	    default:
+		break;
+	}
+    }
+    return 0;
+}
--- a/dmd/attrib.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/attrib.c	Fri Nov 06 23:58:01 2009 +0100
@@ -26,6 +26,9 @@
 #include "module.h"
 #include "parse.h"
 #include "template.h"
+#if TARGET_NET
+ #include "frontend.net/pragma.h"
+#endif
 
 #if IN_LLVM
 #include "../gen/enums.h"
@@ -74,6 +77,76 @@
     return m;
 }
 
+void AttribDeclaration::setScopeNewSc(Scope *sc,
+	unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
+	unsigned structalign)
+{
+    if (decl)
+    {
+	Scope *newsc = sc;
+	if (stc != sc->stc ||
+	    linkage != sc->linkage ||
+	    protection != sc->protection ||
+	    explicitProtection != sc->explicitProtection ||
+	    structalign != sc->structalign)
+	{
+	    // create new one for changes
+	    newsc = new Scope(*sc);
+	    newsc->flags &= ~SCOPEfree;
+	    newsc->stc = stc;
+	    newsc->linkage = linkage;
+	    newsc->protection = protection;
+	    newsc->explicitProtection = explicitProtection;
+	    newsc->structalign = structalign;
+	}
+	for (unsigned i = 0; i < decl->dim; i++)
+	{   Dsymbol *s = (Dsymbol *)decl->data[i];
+
+	    s->setScope(newsc);	// yes, the only difference from semanticNewSc()
+	}
+	if (newsc != sc)
+	{
+	    sc->offset = newsc->offset;
+	    newsc->pop();
+	}
+    }
+}
+
+void AttribDeclaration::semanticNewSc(Scope *sc,
+	unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
+	unsigned structalign)
+{
+    if (decl)
+    {
+	Scope *newsc = sc;
+	if (stc != sc->stc ||
+	    linkage != sc->linkage ||
+	    protection != sc->protection ||
+	    explicitProtection != sc->explicitProtection ||
+	    structalign != sc->structalign)
+	{
+	    // create new one for changes
+	    newsc = new Scope(*sc);
+	    newsc->flags &= ~SCOPEfree;
+	    newsc->stc = stc;
+	    newsc->linkage = linkage;
+	    newsc->protection = protection;
+	    newsc->explicitProtection = explicitProtection;
+	    newsc->structalign = structalign;
+	}
+	for (unsigned i = 0; i < decl->dim; i++)
+	{   Dsymbol *s = (Dsymbol *)decl->data[i];
+
+	    s->semantic(newsc);
+	}
+	if (newsc != sc)
+	{
+	    sc->offset = newsc->offset;
+	    newsc->pop();
+	}
+    }
+}
+
 void AttribDeclaration::semantic(Scope *sc)
 {
     Array *d = include(sc, NULL);
@@ -302,24 +375,50 @@
     return scd;
 }
 
+void StorageClassDeclaration::setScope(Scope *sc)
+{
+    if (decl)
+    {
+	unsigned scstc = sc->stc;
+
+	/* These sets of storage classes are mutually exclusive,
+	 * so choose the innermost or most recent one.
+	 */
+	if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest))
+	    scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest);
+	if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared))
+	    scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared);
+	if (stc & (STCconst | STCimmutable | STCmanifest))
+	    scstc &= ~(STCconst | STCimmutable | STCmanifest);
+	if (stc & (STCgshared | STCshared | STCtls))
+	    scstc &= ~(STCgshared | STCshared | STCtls);
+	scstc |= stc;
+
+	setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign);
+    }
+}
+
 void StorageClassDeclaration::semantic(Scope *sc)
 {
     if (decl)
-    {	unsigned stc_save = sc->stc;
+    {
+	unsigned scstc = sc->stc;
 
-	if (stc & (STCauto | STCscope | STCstatic | STCextern))
-	    sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern);
-	sc->stc |= stc;
-	for (unsigned i = 0; i < decl->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)decl->data[i];
+	/* These sets of storage classes are mutually exclusive,
+	 * so choose the innermost or most recent one.
+	 */
+	if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest))
+	    scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest);
+	if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared))
+	    scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared);
+	if (stc & (STCconst | STCimmutable | STCmanifest))
+	    scstc &= ~(STCconst | STCimmutable | STCmanifest);
+	if (stc & (STCgshared | STCshared | STCtls))
+	    scstc &= ~(STCgshared | STCshared | STCtls);
+	scstc |= stc;
 
-	    s->semantic(sc);
-	}
-	sc->stc = stc_save;
+	semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign);
     }
-    else
-	sc->stc = stc;
 }
 
 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
@@ -337,17 +436,11 @@
 	{ STCstatic,       TOKstatic },
 	{ STCextern,       TOKextern },
 	{ STCconst,        TOKconst },
-//	{ STCinvariant,    TOKimmutable },
-//	{ STCshared,       TOKshared },
 	{ STCfinal,        TOKfinal },
 	{ STCabstract,     TOKabstract },
 	{ STCsynchronized, TOKsynchronized },
 	{ STCdeprecated,   TOKdeprecated },
 	{ STCoverride,     TOKoverride },
-//	{ STCnothrow,      TOKnothrow },
-//	{ STCpure,         TOKpure },
-//	{ STCref,          TOKref },
-//	{ STCtls,          TOKtls },
     };
 
     for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
@@ -384,24 +477,21 @@
     return ld;
 }
 
+void LinkDeclaration::setScope(Scope *sc)
+{
+    //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl);
+    if (decl)
+    {
+	setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign);
+    }
+}
+
 void LinkDeclaration::semantic(Scope *sc)
 {
     //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl);
     if (decl)
-    {	enum LINK linkage_save = sc->linkage;
-
-	sc->linkage = linkage;
-	for (unsigned i = 0; i < decl->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)decl->data[i];
-
-	    s->semantic(sc);
-	}
-	sc->linkage = linkage_save;
-    }
-    else
     {
-	sc->linkage = linkage;
+	semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign);
     }
 }
 
@@ -473,31 +563,48 @@
     return pd;
 }
 
+void ProtDeclaration::setScope(Scope *sc)
+{
+    if (decl)
+    {
+	setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign);
+    }
+}
+
+void ProtDeclaration::importAll(Scope *sc)
+{
+    Scope *newsc = sc;
+    if (sc->protection != protection ||
+       sc->explicitProtection != 1)
+    {
+       // create new one for changes
+       newsc = new Scope(*sc);
+       newsc->flags &= ~SCOPEfree;
+       newsc->protection = protection;
+       newsc->explicitProtection = 1;
+    }
+
+    for (int i = 0; i < decl->dim; i++)
+    {
+       Dsymbol *s = (Dsymbol *)decl->data[i];
+       s->importAll(newsc);
+    }
+
+    if (newsc != sc)
+       newsc->pop();
+}
+
 void ProtDeclaration::semantic(Scope *sc)
 {
     if (decl)
-    {	enum PROT protection_save = sc->protection;
-	int explicitProtection_save = sc->explicitProtection;
-
-	sc->protection = protection;
-	sc->explicitProtection = 1;
-	for (unsigned i = 0; i < decl->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)decl->data[i];
-
-	    s->semantic(sc);
-	}
-	sc->protection = protection_save;
-	sc->explicitProtection = explicitProtection_save;
-    }
-    else
-    {	sc->protection = protection;
-	sc->explicitProtection = 1;
+    {
+	semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign);
     }
 }
 
-void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{   const char *p;
+void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection)
+{
+    const char *p;
 
     switch (protection)
     {
@@ -511,6 +618,12 @@
 	    break;
     }
     buf->writestring(p);
+    buf->writeByte(' ');
+}
+
+void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+    protectionToCBuffer(buf, protection);
     AttribDeclaration::toCBuffer(buf, hgs);
 }
 
@@ -532,35 +645,23 @@
     return ad;
 }
 
+void AlignDeclaration::setScope(Scope *sc)
+{
+    //printf("\tAlignDeclaration::setScope '%s'\n",toChars());
+    if (decl)
+    {
+	setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign);
+    }
+}
+
 void AlignDeclaration::semantic(Scope *sc)
 {
 // LDC
 // we only support packed structs, as from the spec: align(1) struct Packed { ... }
 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ...
-
-    //printf("\tAlignDeclaration::semantic '%s'\n",toChars());
-    if (decl)
-    {	unsigned salign_save = sc->structalign;
-
-	for (unsigned i = 0; i < decl->dim; i++)
-	{
-	    Dsymbol *s = (Dsymbol *)decl->data[i];
-
-        if (s->isStructDeclaration() && salign == 1)
-        {
-            sc->structalign = salign;
-            s->semantic(sc);
-            sc->structalign = salign_save;
-        }
-        else
-        {
-            s->semantic(sc);
-        }
-	}
-	sc->structalign = salign_save;
+    {
+	semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign);
     }
-    else
-    assert(0 && "what kind of align use triggers this?");
 }
 
 
@@ -577,7 +678,6 @@
 {
     this->loc = loc;
     this->isunion = isunion;
-    this->scope = NULL;
     this->sem = 0;
 }
 
@@ -780,6 +880,39 @@
     return pd;
 }
 
+void PragmaDeclaration::setScope(Scope *sc)
+{
+#if TARGET_NET
+    if (ident == Lexer::idPool("assembly"))
+    {
+        if (!args || args->dim != 1)
+        {
+            error("pragma has invalid number of arguments");
+        }
+        else
+        {
+            Expression *e = (Expression *)args->data[0];
+            e = e->semantic(sc);
+            e = e->optimize(WANTvalue | WANTinterpret);
+            args->data[0] = (void *)e;
+            if (e->op != TOKstring)
+            {
+                error("string expected, not '%s'", e->toChars());
+            }
+            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e));
+
+            assert(sc);
+            pragma->setScope(sc);
+
+            //add to module members
+            assert(sc->module);
+            assert(sc->module->members);
+            sc->module->members->push(pragma);
+        }
+    }
+#endif // TARGET_NET
+}
+
 void PragmaDeclaration::semantic(Scope *sc)
 {   // Should be merged with PragmaStatement
 
@@ -803,10 +936,10 @@
 		if (e->op == TOKstring)
 		{
 		    StringExp *se = (StringExp *)e;
-		    fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string);
+		    fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
 		}
 		else
-		    error("string expected for message, not '%s'", e->toChars());
+		    fprintf(stdmsg, e->toChars());
 	    }
 	    fprintf(stdmsg, "\n");
 	}
@@ -873,6 +1006,27 @@
 	goto Lnodecl;
     }
 #endif
+#if TARGET_NET
+    else if (ident == Lexer::idPool("assembly"))
+    {
+        if (!args || args->dim != 1)
+	        error("pragma has invalid number of arguments");
+	    else
+	    {
+	        Expression *e = (Expression *)args->data[0];
+	        e = e->semantic(sc);
+	        e = e->optimize(WANTvalue | WANTinterpret);
+	        args->data[0] = (void *)e;
+	        if (e->op != TOKstring)
+		    {
+		        error("string expected, not '%s'", e->toChars());
+	        }
+            PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e));
+            decl = new Array;
+            decl->push(pragma);
+        }
+    }
+#endif // TARGET_NET
 
 // LDC
 #if IN_LLVM
@@ -1001,6 +1155,7 @@
 
 #endif // LDC
 
+
     else if (ignoreUnsupportedPragmas)
     {
 	if (global.params.verbose)
@@ -1298,6 +1453,37 @@
     return condition->include(sc, sd) ? decl : elsedecl;
 }
 
+void ConditionalDeclaration::setScope(Scope *sc)
+{
+    Array *d = include(sc, NULL);
+
+    //printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
+    if (d)
+    {
+       for (unsigned i = 0; i < d->dim; i++)
+       {
+           Dsymbol *s = (Dsymbol *)d->data[i];
+
+           s->setScope(sc);
+       }
+    }
+}
+
+void ConditionalDeclaration::importAll(Scope *sc)
+{
+    Array *d = include(sc, NULL);
+
+    //printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d);
+    if (d)
+    {
+       for (unsigned i = 0; i < d->dim; i++)
+       {
+           Dsymbol *s = (Dsymbol *)d->data[i];
+
+           s->importAll(sc);
+       }
+    }
+}
 
 void ConditionalDeclaration::addComment(unsigned char *comment)
 {
@@ -1418,6 +1604,16 @@
 }
 
 
+void StaticIfDeclaration::importAll(Scope *sc)
+{
+    // do not evaluate condition before semantic pass
+}
+
+void StaticIfDeclaration::setScope(Scope *sc)
+{
+    // do not evaluate condition before semantic pass
+}
+
 void StaticIfDeclaration::semantic(Scope *sc)
 {
     Array *d = include(sc, sd);
--- a/dmd/attrib.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/attrib.h	Fri Nov 06 23:58:01 2009 +0100
@@ -1,183 +1,202 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2007 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef DMD_ATTRIB_H
-#define DMD_ATTRIB_H
-
-#ifdef __DMC__
-#pragma once
-#endif /* __DMC__ */
-
-#include "dsymbol.h"
-
-struct Expression;
-struct Statement;
-struct LabelDsymbol;
-struct Initializer;
-struct Module;
-struct Condition;
-#ifdef _DH
-struct HdrGenState;
-#endif
-
-/**************************************************************/
-
-struct AttribDeclaration : Dsymbol
-{
-    Array *decl;	// array of Dsymbol's
-
-    AttribDeclaration(Array *decl);
-    virtual Array *include(Scope *sc, ScopeDsymbol *s);
-    int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
-    void semantic(Scope *sc);
-    void semantic2(Scope *sc);
-    void semantic3(Scope *sc);
-    void inlineScan();
-    void addComment(unsigned char *comment);
-    void emitComment(Scope *sc);
-    const char *kind();
-    int oneMember(Dsymbol **ps);
-    int hasPointers();
-    void checkCtorConstInit();
-    void addLocalClass(ClassDeclarations *);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    AttribDeclaration *isAttribDeclaration() { return this; }
-
-#if IN_DMD
-    virtual void toObjFile(int multiobj);			// compile to .obj file
-    int cvMember(unsigned char *p);
-#endif
-
-#if IN_LLVM
-    virtual void codegen(Ir*);
-#endif
-};
-
-struct StorageClassDeclaration: AttribDeclaration
-{
-    unsigned stc;
-
-    StorageClassDeclaration(unsigned stc, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-
-    static void stcToCBuffer(OutBuffer *buf, int stc);
-};
-
-struct LinkDeclaration : AttribDeclaration
-{
-    enum LINK linkage;
-
-    LinkDeclaration(enum LINK p, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    void semantic3(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    char *toChars();
-};
-
-struct ProtDeclaration : AttribDeclaration
-{
-    enum PROT protection;
-
-    ProtDeclaration(enum PROT p, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-};
-
-struct AlignDeclaration : AttribDeclaration
-{
-    unsigned salign;
-
-    AlignDeclaration(Loc loc, unsigned sa, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-};
-
-struct AnonDeclaration : AttribDeclaration
-{
-    int isunion;
-    Scope *scope;		// !=NULL means context to use
-    int sem;			// 1 if successful semantic()
-
-    AnonDeclaration(Loc loc, int isunion, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-};
-
-struct PragmaDeclaration : AttribDeclaration
-{
-    Expressions *args;		// array of Expression's
-
-    PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    int oneMember(Dsymbol **ps);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-
-#if IN_DMD
-    void toObjFile(int multiobj);			// compile to .obj file
-#endif
-
-#if IN_LLVM
-    void codegen(Ir*);
-#endif
-};
-
-struct ConditionalDeclaration : AttribDeclaration
-{
-    Condition *condition;
-    Array *elsedecl;	// array of Dsymbol's for else block
-
-    ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    int oneMember(Dsymbol **ps);
-    void emitComment(Scope *sc);
-    Array *include(Scope *sc, ScopeDsymbol *s);
-    void addComment(unsigned char *comment);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-};
-
-struct StaticIfDeclaration : ConditionalDeclaration
-{
-    ScopeDsymbol *sd;
-    int addisdone;
-
-    StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
-    void semantic(Scope *sc);
-    const char *kind();
-};
-
-// Mixin declarations
-
-struct CompileDeclaration : AttribDeclaration
-{
-    Expression *exp;
-
-    ScopeDsymbol *sd;
-    int compiled;
-
-    CompileDeclaration(Loc loc, Expression *exp);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
-    void compileIt(Scope *sc);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-};
-
-#endif /* DMD_ATTRIB_H */
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-2009 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#ifndef DMD_ATTRIB_H
+#define DMD_ATTRIB_H
+
+#ifdef __DMC__
+#pragma once
+#endif /* __DMC__ */
+
+#include "dsymbol.h"
+
+struct Expression;
+struct Statement;
+struct LabelDsymbol;
+struct Initializer;
+struct Module;
+struct Condition;
+#ifdef _DH
+struct HdrGenState;
+#endif
+
+/**************************************************************/
+
+struct AttribDeclaration : Dsymbol
+{
+    Array *decl;	// array of Dsymbol's
+
+    AttribDeclaration(Array *decl);
+    virtual Array *include(Scope *sc, ScopeDsymbol *s);
+    int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
+    void setScopeNewSc(Scope *sc,
+	unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
+	unsigned structalign);
+    void semanticNewSc(Scope *sc,
+	unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
+	unsigned structalign);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    void semantic3(Scope *sc);
+    void inlineScan();
+    void addComment(unsigned char *comment);
+    void emitComment(Scope *sc);
+    const char *kind();
+    int oneMember(Dsymbol **ps);
+    int hasPointers();
+    void checkCtorConstInit();
+    void addLocalClass(ClassDeclarations *);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    void toJsonBuffer(OutBuffer *buf);
+    AttribDeclaration *isAttribDeclaration() { return this; }
+
+#if IN_DMD
+    virtual void toObjFile(int multiobj);			// compile to .obj file
+    int cvMember(unsigned char *p);
+#endif
+
+#if IN_LLVM
+    virtual void codegen(Ir*);
+#endif
+};
+
+struct StorageClassDeclaration: AttribDeclaration
+{
+    unsigned stc;
+
+    StorageClassDeclaration(unsigned stc, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void setScope(Scope *sc);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    static void stcToCBuffer(OutBuffer *buf, int stc);
+};
+
+struct LinkDeclaration : AttribDeclaration
+{
+    enum LINK linkage;
+
+    LinkDeclaration(enum LINK p, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void setScope(Scope *sc);
+    void semantic(Scope *sc);
+    void semantic3(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    char *toChars();
+};
+
+struct ProtDeclaration : AttribDeclaration
+{
+    enum PROT protection;
+
+    ProtDeclaration(enum PROT p, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void importAll(Scope *sc);
+    void setScope(Scope *sc);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    static void protectionToCBuffer(OutBuffer *buf, enum PROT protection);
+};
+
+struct AlignDeclaration : AttribDeclaration
+{
+    unsigned salign;
+
+    AlignDeclaration(Loc loc, unsigned sa, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void setScope(Scope *sc);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+};
+
+struct AnonDeclaration : AttribDeclaration
+{
+    int isunion;
+    int sem;			// 1 if successful semantic()
+
+    AnonDeclaration(Loc loc, int isunion, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+};
+
+struct PragmaDeclaration : AttribDeclaration
+{
+    Expressions *args;		// array of Expression's
+
+    PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void semantic(Scope *sc);
+    void setScope(Scope *sc);
+    int oneMember(Dsymbol **ps);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+
+#if IN_DMD
+    void toObjFile(int multiobj);			// compile to .obj file
+#endif
+
+#if IN_LLVM
+    void codegen(Ir*);
+#endif
+};
+
+struct ConditionalDeclaration : AttribDeclaration
+{
+    Condition *condition;
+    Array *elsedecl;	// array of Dsymbol's for else block
+
+    ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    int oneMember(Dsymbol **ps);
+    void emitComment(Scope *sc);
+    Array *include(Scope *sc, ScopeDsymbol *s);
+    void addComment(unsigned char *comment);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    void toJsonBuffer(OutBuffer *buf);
+    void importAll(Scope *sc);
+    void setScope(Scope *sc);
+};
+
+struct StaticIfDeclaration : ConditionalDeclaration
+{
+    ScopeDsymbol *sd;
+    int addisdone;
+
+    StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
+    void semantic(Scope *sc);
+    void importAll(Scope *sc);
+    void setScope(Scope *sc);
+    const char *kind();
+};
+
+// Mixin declarations
+
+struct CompileDeclaration : AttribDeclaration
+{
+    Expression *exp;
+
+    ScopeDsymbol *sd;
+    int compiled;
+
+    CompileDeclaration(Loc loc, Expression *exp);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
+    void compileIt(Scope *sc);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+};
+
+#endif /* DMD_ATTRIB_H */
--- a/dmd/cast.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/cast.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1078,22 +1078,20 @@
 
 Expression *SymOffExp::castTo(Scope *sc, Type *t)
 {
-    Type *tb;
-
 #if 0
     printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
 	toChars(), type->toChars(), t->toChars());
 #endif
     Expression *e = this;
 
-    tb = t->toBasetype();
-    type = type->toBasetype();
-    if (tb != type)
+    Type *tb = t->toBasetype();
+    Type *typeb = type->toBasetype();
+    if (tb != typeb)
     {
 	// Look for pointers to functions where the functions are overloaded.
 	FuncDeclaration *f;
 
-	if (type->ty == Tpointer && type->next->ty == Tfunction &&
+	if (typeb->ty == Tpointer && typeb->next->ty == Tfunction &&
 	    tb->ty == Tpointer && tb->next->ty == Tfunction)
 	{
 	    f = var->isFuncDeclaration();
@@ -1102,15 +1100,47 @@
 		f = f->overloadExactMatch(tb->next, m);
 		if (f)
 		{
-		    e = new SymOffExp(loc, f, 0);
-		    e->type = t;
+#if DMDV2
+		    if (tb->ty == Tdelegate)
+		    {
+			if (f->needThis() && hasThis(sc))
+			{
+			    e = new DelegateExp(loc, new ThisExp(loc), f);
+			    e = e->semantic(sc);
+			}
+			else if (f->isNested())
+			{
+			    e = new DelegateExp(loc, new IntegerExp(0), f);
+			    e = e->semantic(sc);
+			}
+			else if (f->needThis())
+			{   error("no 'this' to create delegate for %s", f->toChars());
+			    e = new ErrorExp();
+			}
+			else
+			{   error("cannot cast from function pointer to delegate");
+			    e = new ErrorExp();
+			}
+		    }
+		    else
+#endif
+		    {
+			e = new SymOffExp(loc, f, 0);
+			e->type = t;
+		    }
+#if DMDV2
+		    f->tookAddressOf++;
+#endif
 		    return e;
 		}
 	    }
 	}
 	e = Expression::castTo(sc, t);
     }
-    e->type = t;
+    else
+    {
+	e->type = t;
+    }
     return e;
 }
 
@@ -1484,13 +1514,13 @@
     {
 	assert(0);
     }
-    else if (e1->op == TOKslice && t1->ty == Tarray &&
+    else if (e1->isArrayOperand() && t1->ty == Tarray &&
 	     e2->implicitConvTo(t1->nextOf()))
     {	// T[] op T
 	e2 = e2->castTo(sc, t1->nextOf());
 	t = t1->nextOf()->arrayOf();
     }
-    else if (e2->op == TOKslice && t2->ty == Tarray &&
+    else if (e2->isArrayOperand() && t2->ty == Tarray &&
 	     e1->implicitConvTo(t2->nextOf()))
     {	// T op T[]
 	e1 = e1->castTo(sc, t2->nextOf());
--- a/dmd/class.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/class.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -161,6 +161,12 @@
 		    Type::typeinfoinvariant->error("%s", msg);
 		Type::typeinfoinvariant = this;
 	    }
+
+	    if (id == Id::TypeInfo_Shared)
+	    {	if (Type::typeinfoshared)
+		    Type::typeinfoshared->error("%s", msg);
+		Type::typeinfoshared = this;
+	    }
 #endif
 	}
 
@@ -226,19 +232,19 @@
     //{ static int n;  if (++n == 20) *(char*)0=0; }
 
     if (!ident)		// if anonymous class
-    {	char *id = "__anonclass";
+    {	const char *id = "__anonclass";
 
 	ident = Identifier::generateId(id);
     }
 
-    if (!scope)
-    {
-	if (!parent && sc->parent && !sc->parent->isModule())
-	    parent = sc->parent;
+    if (!sc)
+	sc = scope;
+    if (!parent && sc->parent && !sc->parent->isModule())
+	parent = sc->parent;
 
-	type = type->semantic(loc, sc);
-	handle = handle->semantic(loc, sc);
-    }
+    type = type->semantic(loc, sc);
+    handle = type;
+
     if (!members)			// if forward reference
     {	//printf("\tclass '%s' is forward referenced\n", toChars());
 	return;
@@ -329,13 +335,21 @@
 			goto L7;
 		    }
 		}
+		if (!tc->sym->symtab || tc->sym->sizeok == 0)
+		{   // Try to resolve forward reference
+		    if (sc->mustsemantic && tc->sym->scope)
+			tc->sym->semantic(NULL);
+		}
 		if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
 		{
+		    //printf("%s: forward reference of base class %s\n", toChars(), tc->sym->toChars());
 		    //error("forward reference of base class %s", baseClass->toChars());
 		    // Forward reference of base class, try again later
 		    //printf("\ttry later, forward reference of base class %s\n", tc->sym->toChars());
 		    scope = scx ? scx : new Scope(*sc);
 		    scope->setNoFree();
+		    if (tc->sym->scope)
+		        tc->sym->scope->module->addDeferredSemantic(tc->sym);
 		    scope->module->addDeferredSemantic(this);
 		    return;
 		}
@@ -389,6 +403,12 @@
 		    error("inherits from duplicate interface %s", b2->base->toChars());
 	    }
 
+	    if (!tc->sym->symtab)
+	    {   // Try to resolve forward reference
+		if (sc->mustsemantic && tc->sym->scope)
+		    tc->sym->semantic(NULL);
+	    }
+
 	    b->base = tc->sym;
 	    if (!b->base->symtab || b->base->scope)
 	    {
@@ -397,6 +417,8 @@
 		//printf("\ttry later, forward reference of base %s\n", baseClass->toChars());
 		scope = scx ? scx : new Scope(*sc);
 		scope->setNoFree();
+		if (tc->sym->scope)
+		    tc->sym->scope->module->addDeferredSemantic(tc->sym);
 		scope->module->addDeferredSemantic(this);
 		return;
 	    }
@@ -500,15 +522,15 @@
 	{   Dsymbol *s = toParent2();
 	    if (s)
 	    {
-		ClassDeclaration *cd = s->isClassDeclaration();
+		AggregateDeclaration *ad = s->isClassDeclaration();
 		FuncDeclaration *fd = s->isFuncDeclaration();
 
 
-		if (cd || fd)
+		if (ad || fd)
 		{   isnested = 1;
 		    Type *t;
-		    if (cd)
-			t = cd->type;
+		    if (ad)
+			t = ad->handle;
 		    else if (fd)
 		    {	AggregateDeclaration *ad = fd->isMember2();
 			if (ad)
@@ -564,7 +586,7 @@
 //	    sc->offset += PTRSIZE;	// room for uplevel context pointer
     }
     else
-    {	sc->offset = PTRSIZE * 2;	// allow room for vptr[] and monitor
+    {	sc->offset = PTRSIZE * 2;	// allow room for __vptr and __monitor
 	alignsize = PTRSIZE;
     }
     structsize = sc->offset;
@@ -703,17 +725,22 @@
 	//buf->writestring(b->base->ident->toChars());
 	b->type->toCBuffer(buf, NULL, hgs);
     }
-    buf->writenl();
-    buf->writeByte('{');
-    buf->writenl();
-    for (int i = 0; i < members->dim; i++)
+    if (members)
     {
-	Dsymbol *s = (Dsymbol *)members->data[i];
+	buf->writenl();
+	buf->writeByte('{');
+	buf->writenl();
+	for (int i = 0; i < members->dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)members->data[i];
 
-	buf->writestring("    ");
-	s->toCBuffer(buf, hgs);
+	    buf->writestring("    ");
+	    s->toCBuffer(buf, hgs);
+	}
+	buf->writestring("}");
     }
-    buf->writestring("}");
+    else
+	buf->writeByte(';');
     buf->writenl();
 }
 
@@ -777,13 +804,18 @@
 Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
 {
     Dsymbol *s;
+    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars());
 
-    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars());
     if (scope)
-	semantic(scope);
+    {	Scope *sc = scope;
+	sc->mustsemantic++;
+	semantic(sc);
+	sc->mustsemantic--;
+    }
 
     if (!members || !symtab || scope)
-    {	error("is forward referenced when looking for '%s'", ident->toChars());
+    {
+	error("is forward referenced when looking for '%s'", ident->toChars());
 	//*(char*)0=0;
 	return NULL;
     }
@@ -831,7 +863,7 @@
 
 int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
 {
-    //printf("ClassDeclaration::isFuncHidden(%s)\n", fd->toChars());
+    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
     Dsymbol *s = search(0, fd->ident, 4|2);
     if (!s)
     {	//printf("not found\n");
@@ -916,6 +948,13 @@
     return 0;
 }
 
+#if DMDV2
+int ClassDeclaration::isCPPinterface()
+{
+    return 0;
+}
+#endif
+
 
 /****************************************
  */
@@ -1006,10 +1045,15 @@
     //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
     if (inuse)
 	return;
-    if (!scope)
-    {	type = type->semantic(loc, sc);
-	handle = handle->semantic(loc, sc);
-    }
+
+    if (!sc)
+	sc = scope;
+    if (!parent && sc->parent && !sc->parent->isModule())
+	parent = sc->parent;
+
+    type = type->semantic(loc, sc);
+    handle = type;
+
     if (!members)			// if forward reference
     {	//printf("\tinterface '%s' is forward referenced\n", toChars());
 	return;
@@ -1090,6 +1134,11 @@
 		baseclasses.remove(i);
 		continue;
 	    }
+	    if (!b->base->symtab)
+	    {   // Try to resolve forward reference
+		if (sc->mustsemantic && b->base->scope)
+		    b->base->semantic(NULL);
+	    }
 	    if (!b->base->symtab || b->base->scope || b->base->inuse)
 	    {
 		//error("forward reference of base class %s", baseClass->toChars());
@@ -1262,6 +1311,13 @@
     return com;
 }
 
+#if DMDV2
+int InterfaceDeclaration::isCPPinterface()
+{
+    return cpp;
+}
+#endif
+
 /*******************************************
  */
 
--- a/dmd/constfold.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/constfold.c	Fri Nov 06 23:58:01 2009 +0100
@@ -74,6 +74,11 @@
     return 1;
 }
 
+int NullExp::isConst()
+{
+    return 1;
+}
+
 int SymOffExp::isConst()
 {
     return 2;
@@ -845,7 +850,7 @@
     {
 	cmp = e1->toComplex() == e2->toComplex();
     }
-    else if (e1->type->isintegral())
+    else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer)
     {
 	cmp = (e1->toInteger() == e2->toInteger());
     }
@@ -862,9 +867,13 @@
     Loc loc = e1->loc;
     int cmp;
 
-    if (e1->op == TOKnull && e2->op == TOKnull)
+    if (e1->op == TOKnull)
     {
-	cmp = 1;
+	cmp = (e2->op == TOKnull);
+    }
+    else if (e2->op == TOKnull)
+    {
+	cmp = 0;
     }
     else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
     {
@@ -1046,11 +1055,12 @@
 	return e1;
 
     Type *tb = to->toBasetype();
-    Type *typeb = type->toBasetype();
 
-    // LDC: ported from D2 to allow char[] ~ char[n] arguments in CTFE
+    /* Allow casting from one string type to another
+     */
     if (e1->op == TOKstring)
     {
+	Type *typeb = type->toBasetype();
 	if (tb->ty == Tarray && typeb->ty == Tarray &&
 	    tb->nextOf()->size() == typeb->nextOf()->size())
 	{
@@ -1069,7 +1079,7 @@
 	{   dinteger_t result;
 	    real_t r = e1->toReal();
 
-	    switch (typeb->ty)
+	    switch (type->toBasetype()->ty)
 	    {
 		case Tint8:	result = (d_int8)r;	break;
 		case Tchar:
--- a/dmd/declaration.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/declaration.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,1453 +1,1616 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2009 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "init.h"
-#include "declaration.h"
-#include "attrib.h"
-#include "mtype.h"
-#include "template.h"
-#include "scope.h"
-#include "aggregate.h"
-#include "module.h"
-#include "id.h"
-#include "expression.h"
-#include "hdrgen.h"
-
-/********************************* Declaration ****************************/
-
-Declaration::Declaration(Identifier *id)
-    : Dsymbol(id)
-{
-    type = NULL;
-    originalType = NULL;
-    storage_class = STCundefined;
-    protection = PROTundefined;
-    linkage = LINKdefault;
-    inuse = 0;
-}
-
-void Declaration::semantic(Scope *sc)
-{
-}
-
-const char *Declaration::kind()
-{
-    return "declaration";
-}
-
-unsigned Declaration::size(Loc loc)
-{
-    assert(type);
-    return type->size();
-}
-
-int Declaration::isStaticConstructor()
-{
-    return FALSE;
-}
-
-int Declaration::isStaticDestructor()
-{
-    return FALSE;
-}
-
-int Declaration::isDelete()
-{
-    return FALSE;
-}
-
-int Declaration::isDataseg()
-{
-    return FALSE;
-}
-
-int Declaration::isCodeseg()
-{
-    return FALSE;
-}
-
-enum PROT Declaration::prot()
-{
-    return protection;
-}
-
-/*************************************
- * Check to see if declaration can be modified in this context (sc).
- * Issue error if not.
- */
-
-#if DMDV2
-void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
-{
-    if (sc->incontract && isParameter())
-	error(loc, "cannot modify parameter '%s' in contract", toChars());
-
-    if (isCtorinit())
-    {	// It's only modifiable if inside the right constructor
-	Dsymbol *s = sc->func;
-	while (1)
-	{
-	    FuncDeclaration *fd = NULL;
-	    if (s)
-		fd = s->isFuncDeclaration();
-	    if (fd &&
-		((fd->isCtorDeclaration() && storage_class & STCfield) ||
-		 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
-		fd->toParent() == toParent()
-	       )
-	    {
-		VarDeclaration *v = isVarDeclaration();
-		assert(v);
-		v->ctorinit = 1;
-		//printf("setting ctorinit\n");
-	    }
-	    else
-	    {
-		if (s)
-		{   s = s->toParent2();
-		    continue;
-		}
-		else
-		{
-		    const char *p = isStatic() ? "static " : "";
-		    error(loc, "can only initialize %sconst %s inside %sconstructor",
-			p, toChars(), p);
-		}
-	    }
-	    break;
-	}
-    }
-    else
-    {
-	VarDeclaration *v = isVarDeclaration();
-	if (v && v->canassign == 0)
-	{
-	    char *p = NULL;
-	    if (isConst())
-		p = "const";
-	    else if (isInvariant())
-		p = "invariant";
-	    else if (storage_class & STCmanifest)
-		p = "manifest constant";
-	    else if (!t->isAssignable())
-		p = "struct with immutable members";
-	    if (p)
-	    {	error(loc, "cannot modify %s", p);
-		halt();
-	    }
-	}
-    }
-}
-#endif
-
-
-/********************************* TupleDeclaration ****************************/
-
-TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
-    : Declaration(id)
-{
-    this->type = NULL;
-    this->objects = objects;
-    this->isexp = 0;
-    this->tupletype = NULL;
-}
-
-Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(0);
-    return NULL;
-}
-
-const char *TupleDeclaration::kind()
-{
-    return "tuple";
-}
-
-Type *TupleDeclaration::getType()
-{
-    /* If this tuple represents a type, return that type
-     */
-
-    //printf("TupleDeclaration::getType() %s\n", toChars());
-    if (isexp)
-	return NULL;
-    if (!tupletype)
-    {
-	/* It's only a type tuple if all the Object's are types
-	 */
-	for (size_t i = 0; i < objects->dim; i++)
-	{   Object *o = (Object *)objects->data[i];
-
-	    if (o->dyncast() != DYNCAST_TYPE)
-	    {
-		//printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
-		return NULL;
-	    }
-	}
-
-	/* We know it's a type tuple, so build the TypeTuple
-	 */
-	Arguments *args = new Arguments();
-	args->setDim(objects->dim);
-	OutBuffer buf;
-	for (size_t i = 0; i < objects->dim; i++)
-	{   Type *t = (Type *)objects->data[i];
-
-	    //printf("type = %s\n", t->toChars());
-#if 0
-	    buf.printf("_%s_%d", ident->toChars(), i);
-	    char *name = (char *)buf.extractData();
-	    Identifier *id = new Identifier(name, TOKidentifier);
-	    Argument *arg = new Argument(STCin, t, id, NULL);
-#else
-	    Argument *arg = new Argument(STCin, t, NULL, NULL);
-#endif
-	    args->data[i] = (void *)arg;
-	}
-
-	tupletype = new TypeTuple(args);
-    }
-
-    return tupletype;
-}
-
-int TupleDeclaration::needThis()
-{
-    //printf("TupleDeclaration::needThis(%s)\n", toChars());
-    for (size_t i = 0; i < objects->dim; i++)
-    {   Object *o = (Object *)objects->data[i];
-	if (o->dyncast() == DYNCAST_EXPRESSION)
-	{   Expression *e = (Expression *)o;
-	    if (e->op == TOKdsymbol)
-	    {	DsymbolExp *ve = (DsymbolExp *)e;
-		Declaration *d = ve->s->isDeclaration();
-		if (d && d->needThis())
-		{
-		    return 1;
-		}
-	    }
-	}
-    }
-    return 0;
-}
-
-/********************************* TypedefDeclaration ****************************/
-
-TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init)
-    : Declaration(id)
-{
-    this->type = new TypeTypedef(this);
-    this->basetype = basetype->toBasetype();
-    this->init = init;
-#ifdef _DH
-    this->htype = NULL;
-    this->hbasetype = NULL;
-#endif
-    this->sem = 0;
-    this->loc = loc;
-#if IN_DMD
-    this->sinit = NULL;
-#endif
-}
-
-Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
-{
-    Type *basetype = this->basetype->syntaxCopy();
-
-    Initializer *init = NULL;
-    if (this->init)
-	init = this->init->syntaxCopy();
-
-    assert(!s);
-    TypedefDeclaration *st;
-    st = new TypedefDeclaration(loc, ident, basetype, init);
-#ifdef _DH
-    // Syntax copy for header file
-    if (!htype)      // Don't overwrite original
-    {	if (type)    // Make copy for both old and new instances
-	{   htype = type->syntaxCopy();
-	    st->htype = type->syntaxCopy();
-	}
-    }
-    else            // Make copy of original for new instance
-        st->htype = htype->syntaxCopy();
-    if (!hbasetype)
-    {	if (basetype)
-	{   hbasetype = basetype->syntaxCopy();
-	    st->hbasetype = basetype->syntaxCopy();
-	}
-    }
-    else
-        st->hbasetype = hbasetype->syntaxCopy();
-#endif
-    return st;
-}
-
-void TypedefDeclaration::semantic(Scope *sc)
-{
-    //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
-    if (sem == 0)
-    {	sem = 1;
-	basetype = basetype->semantic(loc, sc);
-	sem = 2;
-	type = type->semantic(loc, sc);
-	if (sc->parent->isFuncDeclaration() && init)
-	    semantic2(sc);
-	storage_class |= sc->stc & STCdeprecated;
-    }
-    else if (sem == 1)
-    {
-	error("circular definition");
-    }
-}
-
-void TypedefDeclaration::semantic2(Scope *sc)
-{
-    //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
-    if (sem == 2)
-    {	sem = 3;
-	if (init)
-	{
-	    init = init->semantic(sc, basetype);
-
-	    ExpInitializer *ie = init->isExpInitializer();
-	    if (ie)
-	    {
-		if (ie->exp->type == basetype)
-		    ie->exp->type = type;
-	    }
-	}
-    }
-}
-
-const char *TypedefDeclaration::kind()
-{
-    return "typedef";
-}
-
-Type *TypedefDeclaration::getType()
-{
-    return type;
-}
-
-void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    buf->writestring("typedef ");
-    basetype->toCBuffer(buf, ident, hgs);
-    if (init)
-    {
-	buf->writestring(" = ");
-	init->toCBuffer(buf, hgs);
-    }
-    buf->writeByte(';');
-    buf->writenl();
-}
-
-/********************************* AliasDeclaration ****************************/
-
-AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
-    : Declaration(id)
-{
-    //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
-    //printf("type = '%s'\n", type->toChars());
-    this->loc = loc;
-    this->type = type;
-    this->aliassym = NULL;
-#ifdef _DH
-    this->htype = NULL;
-    this->haliassym = NULL;
-#endif
-    this->overnext = NULL;
-    this->inSemantic = 0;
-    this->importprot = PROTundefined;
-    assert(type);
-}
-
-AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
-    : Declaration(id)
-{
-    //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
-    assert(s != this);
-    this->loc = loc;
-    this->type = NULL;
-    this->aliassym = s;
-#ifdef _DH
-    this->htype = NULL;
-    this->haliassym = NULL;
-#endif
-    this->overnext = NULL;
-    this->inSemantic = 0;
-    assert(s);
-}
-
-Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
-{
-    //printf("AliasDeclaration::syntaxCopy()\n");
-    assert(!s);
-    AliasDeclaration *sa;
-    if (type)
-	sa = new AliasDeclaration(loc, ident, type->syntaxCopy());
-    else
-	sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
-#ifdef _DH
-    // Syntax copy for header file
-    if (!htype)	    // Don't overwrite original
-    {	if (type)	// Make copy for both old and new instances
-	{   htype = type->syntaxCopy();
-	    sa->htype = type->syntaxCopy();
-	}
-    }
-    else			// Make copy of original for new instance
-	sa->htype = htype->syntaxCopy();
-    if (!haliassym)
-    {	if (aliassym)
-	{   haliassym = aliassym->syntaxCopy(s);
-	    sa->haliassym = aliassym->syntaxCopy(s);
-	}
-    }
-    else
-	sa->haliassym = haliassym->syntaxCopy(s);
-#endif
-    return sa;
-}
-
-void AliasDeclaration::semantic(Scope *sc)
-{
-    //printf("AliasDeclaration::semantic() %s\n", toChars());
-    if (aliassym)
-    {
-	if (aliassym->isTemplateInstance())
-	    aliassym->semantic(sc);
-	return;
-    }
-    this->inSemantic = 1;
-
-    if (storage_class & STCconst)
-	error("cannot be const");
-
-    storage_class |= sc->stc & STCdeprecated;
-
-    // Given:
-    //	alias foo.bar.abc def;
-    // it is not knowable from the syntax whether this is an alias
-    // for a type or an alias for a symbol. It is up to the semantic()
-    // pass to distinguish.
-    // If it is a type, then type is set and getType() will return that
-    // type. If it is a symbol, then aliassym is set and type is NULL -
-    // toAlias() will return aliasssym.
-
-    Dsymbol *s;
-    Type *t;
-    Expression *e;
-
-    /* This section is needed because resolve() will:
-     *   const x = 3;
-     *   alias x y;
-     * try to alias y to 3.
-     */
-    s = type->toDsymbol(sc);
-    if (s)
-	goto L2;			// it's a symbolic alias
-
-    //printf("alias type is %s\n", type->toChars());
-    type->resolve(loc, sc, &e, &t, &s);
-    if (s)
-    {
-	goto L2;
-    }
-    else if (e)
-    {
-	// Try to convert Expression to Dsymbol
-        if (e->op == TOKvar)
-	{   s = ((VarExp *)e)->var;
-	    goto L2;
-	}
-        else if (e->op == TOKfunction)
-	{   s = ((FuncExp *)e)->fd;
-	    goto L2;
-	}
-        else
-	{   error("cannot alias an expression %s", e->toChars());
-	    t = e->type;
-	}
-    }
-    else if (t)
-    {
-	type = t;
-    }
-    if (overnext)
-	ScopeDsymbol::multiplyDefined(0, this, overnext);
-    this->inSemantic = 0;
-    return;
-
-  L2:
-    //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
-    type = NULL;
-    VarDeclaration *v = s->isVarDeclaration();
-    if (v && v->linkage == LINKdefault)
-    {
-	error("forward reference of %s", v->toChars());
-	s = NULL;
-    }
-    else
-    {
-	FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
-	if (f)
-	{
-	    if (overnext)
-	    {
-		FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
-		fa->importprot = importprot;
-		if (!fa->overloadInsert(overnext))
-		    ScopeDsymbol::multiplyDefined(0, f, overnext);
-		overnext = NULL;
-		s = fa;
-		s->parent = sc->parent;
-	    }
-	}
-	if (overnext)
-	    ScopeDsymbol::multiplyDefined(0, s, overnext);
-	if (s == this)
-	{
-	    assert(global.errors);
-	    s = NULL;
-	}
-    }
-    aliassym = s;
-    this->inSemantic = 0;
-}
-
-int AliasDeclaration::overloadInsert(Dsymbol *s)
-{
-    /* Don't know yet what the aliased symbol is, so assume it can
-     * be overloaded and check later for correctness.
-     */
-
-    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
-    if (overnext == NULL)
-    {	overnext = s;
-	return TRUE;
-    }
-    else
-    {
-	return overnext->overloadInsert(s);
-    }
-}
-
-const char *AliasDeclaration::kind()
-{
-    return "alias";
-}
-
-Type *AliasDeclaration::getType()
-{
-    return type;
-}
-
-Dsymbol *AliasDeclaration::toAlias()
-{
-    //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
-    assert(this != aliassym);
-    //static int count; if (++count == 10) *(char*)0=0;
-    if (inSemantic)
-    {	error("recursive alias declaration");
-	aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
-    }
-    Dsymbol *s = aliassym ? aliassym->toAlias() : this;
-    return s;
-}
-
-void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    buf->writestring("alias ");
-#if 0 && _DH
-    if (hgs->hdrgen)
-    {
-	if (haliassym)
-	{
-	    buf->writestring(haliassym->toChars());
-	    buf->writeByte(' ');
-	    buf->writestring(ident->toChars());
-	}
-	else
-	    htype->toCBuffer(buf, ident, hgs);
-    }
-    else
-#endif
-    {
-	if (aliassym)
-	{
-	    buf->writestring(aliassym->toChars());
-	    buf->writeByte(' ');
-	    buf->writestring(ident->toChars());
-	}
-	else
-	    type->toCBuffer(buf, ident, hgs);
-    }
-    buf->writeByte(';');
-    buf->writenl();
-}
-
-/********************************* VarDeclaration ****************************/
-
-VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
-    : Declaration(id)
-{
-    //printf("VarDeclaration('%s')\n", id->toChars());
-#ifdef DEBUG
-    if (!type && !init)
-    {	printf("VarDeclaration('%s')\n", id->toChars());
-	//*(char*)0=0;
-    }
-#endif
-    assert(type || init);
-    this->type = type;
-    this->init = init;
-#ifdef _DH
-    this->htype = NULL;
-    this->hinit = NULL;
-#endif
-    this->loc = loc;
-    offset = 0;
-    noscope = 0;
-    nestedref = 0;
-    ctorinit = 0;
-    aliassym = NULL;
-    onstack = 0;
-    canassign = 0;
-    value = NULL;
-
-#if IN_LLVM
-    aggrIndex = 0;
-
-    // LDC
-    anonDecl = NULL;
-    offset2 = 0;
-
-    nakedUse = false;
-
-    availableExternally = true; // assume this unless proven otherwise
-#endif
-}
-
-Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
-{
-    //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
-
-    VarDeclaration *sv;
-    if (s)
-    {	sv = (VarDeclaration *)s;
-    }
-    else
-    {
-	Initializer *init = NULL;
-	if (this->init)
-	{   init = this->init->syntaxCopy();
-	    //init->isExpInitializer()->exp->print();
-	    //init->isExpInitializer()->exp->dump(0);
-	}
-
-	sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
-	sv->storage_class = storage_class;
-    }
-#ifdef _DH
-    // Syntax copy for header file
-    if (!htype)      // Don't overwrite original
-    {	if (type)    // Make copy for both old and new instances
-	{   htype = type->syntaxCopy();
-	    sv->htype = type->syntaxCopy();
-	}
-    }
-    else            // Make copy of original for new instance
-        sv->htype = htype->syntaxCopy();
-    if (!hinit)
-    {	if (init)
-	{   hinit = init->syntaxCopy();
-	    sv->hinit = init->syntaxCopy();
-	}
-    }
-    else
-        sv->hinit = hinit->syntaxCopy();
-#endif
-    return sv;
-}
-
-void VarDeclaration::semantic(Scope *sc)
-{
-    //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
-    //printf(" type = %s\n", type ? type->toChars() : "null");
-    //printf(" stc = x%x\n", sc->stc);
-    //printf(" storage_class = x%x\n", storage_class);
-    //printf("linkage = %d\n", sc->linkage);
-    //if (strcmp(toChars(), "mul") == 0) halt();
-
-    storage_class |= sc->stc;
-    if (storage_class & STCextern && init)
-	error("extern symbols cannot have initializers");
-
-    /* If auto type inference, do the inference
-     */
-    int inferred = 0;
-    if (!type)
-    {	inuse++;
-	type = init->inferType(sc);
-	inuse--;
-	inferred = 1;
-
-	/* This is a kludge to support the existing syntax for RAII
-	 * declarations.
-	 */
-	storage_class &= ~STCauto;
-	originalType = type;
-    }
-    else
-    {	if (!originalType)
-	    originalType = type;
-	type = type->semantic(loc, sc);
-    }
-    //printf(" semantic type = %s\n", type ? type->toChars() : "null");
-
-    type->checkDeprecated(loc, sc);
-    linkage = sc->linkage;
-    this->parent = sc->parent;
-    //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
-    protection = sc->protection;
-    //printf("sc->stc = %x\n", sc->stc);
-    //printf("storage_class = x%x\n", storage_class);
-
-    Dsymbol *parent = toParent();
-    FuncDeclaration *fd = parent->isFuncDeclaration();
-
-    Type *tb = type->toBasetype();
-    if (tb->ty == Tvoid && !(storage_class & STClazy))
-    {	error("voids have no value");
-	type = Type::terror;
-	tb = type;
-    }
-    if (tb->ty == Tfunction)
-    {	error("cannot be declared to be a function");
-	type = Type::terror;
-	tb = type;
-    }
-    if (tb->ty == Tstruct)
-    {	TypeStruct *ts = (TypeStruct *)tb;
-
-	if (!ts->sym->members)
-	{
-	    error("no definition of struct %s", ts->toChars());
-	}
-    }
-    if ((storage_class & STCauto) && !inferred)
-	error("both auto and explicit type given");
-
-    if (tb->ty == Ttuple)
-    {   /* Instead, declare variables for each of the tuple elements
-	 * and add those.
-	 */
-	TypeTuple *tt = (TypeTuple *)tb;
-	size_t nelems = Argument::dim(tt->arguments);
-	Objects *exps = new Objects();
-	exps->setDim(nelems);
-	Expression *ie = init ? init->toExpression() : NULL;
-
-	for (size_t i = 0; i < nelems; i++)
-	{   Argument *arg = Argument::getNth(tt->arguments, i);
-
-	    OutBuffer buf;
-	    buf.printf("_%s_field_%zu", ident->toChars(), i);
-	    buf.writeByte(0);
-	    char *name = (char *)buf.extractData();
-	    Identifier *id = new Identifier(name, TOKidentifier);
-
-	    Expression *einit = ie;
-	    if (ie && ie->op == TOKtuple)
-	    {	einit = (Expression *)((TupleExp *)ie)->exps->data[i];
-	    }
-	    Initializer *ti = init;
-	    if (einit)
-	    {	ti = new ExpInitializer(einit->loc, einit);
-	    }
-
-	    VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
-	    //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
-	    v->semantic(sc);
-            
-/*
-// removed for LDC since TupleDeclaration::toObj already creates the fields;
-// adding them to the scope again leads to duplicates
-	    if (sc->scopesym)
-	    {	//printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
-		if (sc->scopesym->members)
-		    sc->scopesym->members->push(v);
-	    }
-*/
-	    Expression *e = new DsymbolExp(loc, v);
-	    exps->data[i] = e;
-	}
-	TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
-	v2->isexp = 1;
-	aliassym = v2;
-	return;
-    }
-
-    if (storage_class & STCconst && !init && !fd)
-	// Initialize by constructor only
-	storage_class = (storage_class & ~STCconst) | STCctorinit;
-
-    if (isConst())
-    {
-    }
-    else if (isStatic())
-    {
-    }
-    else if (isSynchronized())
-    {
-	error("variable %s cannot be synchronized", toChars());
-    }
-    else if (isOverride())
-    {
-	error("override cannot be applied to variable");
-    }
-    else if (isAbstract())
-    {
-	error("abstract cannot be applied to variable");
-    }
-    else if (storage_class & STCtemplateparameter)
-    {
-    }
-    else
-    {
-	AggregateDeclaration *aad = sc->anonAgg;
-	if (!aad)
-	    aad = parent->isAggregateDeclaration();
-	if (aad)
-	{
-	    aad->addField(sc, this);
-	}
-
-	InterfaceDeclaration *id = parent->isInterfaceDeclaration();
-	if (id)
-	{
-	    error("field not allowed in interface");
-	}
-
-	/* Templates cannot add fields to aggregates
-	 */
-	TemplateInstance *ti = parent->isTemplateInstance();
-	if (ti)
-	{
-	    // Take care of nested templates
-	    while (1)
-	    {
-		TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
-		if (!ti2)
-		    break;
-		ti = ti2;
-	    }
-
-	    // If it's a member template
-	    AggregateDeclaration *ad = ti->tempdecl->isMember();
-	    if (ad && storage_class != STCundefined)
-	    {
-		error("cannot use template to add field to aggregate '%s'", ad->toChars());
-	    }
-	}
-    }
-
-    if (type->isscope() && !noscope)
-    {
-	if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd)
-	{
-	    error("globals, statics, fields, ref and out parameters cannot be scope");
-	}
-
-	if (!(storage_class & STCscope))
-	{
-	    if (!(storage_class & STCparameter) && ident != Id::withSym)
-		error("reference to scope class must be scope");
-	}
-    }
-
-    if (!init && !sc->inunion && !isStatic() && !isConst() && fd &&
-	!(storage_class & (STCfield | STCin | STCforeach)) &&
-	type->size() != 0)
-    {
-	// Provide a default initializer
-	//printf("Providing default initializer for '%s'\n", toChars());
-	if (type->ty == Tstruct &&
-	    ((TypeStruct *)type)->sym->zeroInit == 1)
-	{   /* If a struct is all zeros, as a special case
-	     * set it's initializer to the integer 0.
-	     * In AssignExp::toElem(), we check for this and issue
-	     * a memset() to initialize the struct.
-	     * Must do same check in interpreter.
-	     */
-	    Expression *e = new IntegerExp(loc, 0, Type::tint32);
-	    Expression *e1;
-	    e1 = new VarExp(loc, this);
-	    e = new AssignExp(loc, e1, e);
-	    e->type = e1->type;
-	    init = new ExpInitializer(loc, e/*->type->defaultInit()*/);
-	    return;
-	}
-	else if (type->ty == Ttypedef)
-	{   TypeTypedef *td = (TypeTypedef *)type;
-	    if (td->sym->init)
-	    {	init = td->sym->init;
-		ExpInitializer *ie = init->isExpInitializer();
-		if (ie)
-		    // Make copy so we can modify it
-		    init = new ExpInitializer(ie->loc, ie->exp);
-	    }
-	    else
-		init = getExpInitializer();
-	}
-	else
-	{
-	    init = getExpInitializer();
-	}
-    }
-
-    if (init)
-    {
-	sc = sc->push();
-	sc->stc &= ~(STCconst | STCinvariant | STCpure);
-
-	ArrayInitializer *ai = init->isArrayInitializer();
-	if (ai && tb->ty == Taarray)
-	{
-	    init = ai->toAssocArrayInitializer();
-	}
-
-	StructInitializer *si = init->isStructInitializer();
-	ExpInitializer *ei = init->isExpInitializer();
-
-	// See if we can allocate on the stack
-	if (ei && isScope() && ei->exp->op == TOKnew)
-	{   NewExp *ne = (NewExp *)ei->exp;
-	    if (!(ne->newargs && ne->newargs->dim))
-	    {	ne->onstack = 1;
-		onstack = 1;
-		if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
-		    onstack = 2;
-	    }
-	}
-
-	// If inside function, there is no semantic3() call
-	if (sc->func)
-	{
-	    // If local variable, use AssignExp to handle all the various
-	    // possibilities.
-	    if (fd && !isStatic() && !isConst() && !init->isVoidInitializer())
-	    {
-		//printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
-		if (!ei)
-		{
-		    Expression *e = init->toExpression();
-		    if (!e)
-		    {
-			init = init->semantic(sc, type);
-			e = init->toExpression();
-			if (!e)
-			{   error("is not a static and cannot have static initializer");
-			    return;
-			}
-		    }
-		    ei = new ExpInitializer(init->loc, e);
-		    init = ei;
-		}
-
-		Expression *e1 = new VarExp(loc, this);
-
-		Type *t = type->toBasetype();
-		if (t->ty == Tsarray)
-		{
-		    ei->exp = ei->exp->semantic(sc);
-		    if (!ei->exp->implicitConvTo(type))
-		    {
-			int dim = ((TypeSArray *)t)->dim->toInteger();
-			// If multidimensional static array, treat as one large array
-			while (1)
-			{
-			    t = t->nextOf()->toBasetype();
-			    if (t->ty != Tsarray)
-				break;
-			    dim *= ((TypeSArray *)t)->dim->toInteger();
-			    e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
-			}
-		    }
-		    e1 = new SliceExp(loc, e1, NULL, NULL);
-		}
-		else if (t->ty == Tstruct)
-		{
-		    ei->exp = ei->exp->semantic(sc);
-		    if (!ei->exp->implicitConvTo(type))
-			ei->exp = new CastExp(loc, ei->exp, type);
-		}
-		ei->exp = new AssignExp(loc, e1, ei->exp);
-		ei->exp->op = TOKconstruct;
-		canassign++;
-		ei->exp = ei->exp->semantic(sc);
-		canassign--;
-		ei->exp->optimize(WANTvalue);
-	    }
-	    else
-	    {
-		init = init->semantic(sc, type);
-		if (fd && isConst() && !isStatic())
-		{   // Make it static
-		    storage_class |= STCstatic;
-		}
-	    }
-	}
-	else if (isConst() || isFinal())
-	{
-	    /* Because we may need the results of a const declaration in a
-	     * subsequent type, such as an array dimension, before semantic2()
-	     * gets ordinarily run, try to run semantic2() now.
-	     * Ignore failure.
-	     */
-
-	    if (!global.errors && !inferred)
-	    {
-		unsigned errors = global.errors;
-		global.gag++;
-		//printf("+gag\n");
-		Expression *e;
-		Initializer *i2 = init;
-		inuse++;
-		if (ei)
-		{
-		    e = ei->exp->syntaxCopy();
-		    e = e->semantic(sc);
-		    e = e->implicitCastTo(sc, type);
-		}
-		else if (si || ai)
-		{   i2 = init->syntaxCopy();
-		    i2 = i2->semantic(sc, type);
-		}
-		inuse--;
-		global.gag--;
-		//printf("-gag\n");
-		if (errors != global.errors)	// if errors happened
-		{
-		    if (global.gag == 0)
-			global.errors = errors;	// act as if nothing happened
-		}
-		else if (ei)
-		{
-		    e = e->optimize(WANTvalue | WANTinterpret);
-		    if (e->op == TOKint64 || e->op == TOKstring)
-		    {
-			ei->exp = e;		// no errors, keep result
-		    }
-		}
-		else
-		    init = i2;		// no errors, keep result
-	    }
-	}
-	sc = sc->pop();
-    }
-}
-
-ExpInitializer *VarDeclaration::getExpInitializer()
-{
-    ExpInitializer *ei;
-
-    if (init)
-	ei = init->isExpInitializer();
-    else
-    {
-	Expression *e = type->defaultInit(loc);
-	if (e)
-	    ei = new ExpInitializer(loc, e);
-	else
-	    ei = NULL;
-    }
-    return ei;
-}
-
-void VarDeclaration::semantic2(Scope *sc)
-{
-    //printf("VarDeclaration::semantic2('%s')\n", toChars());
-    if (init && !toParent()->isFuncDeclaration())
-    {	inuse++;
-#if 0
-	ExpInitializer *ei = init->isExpInitializer();
-	if (ei)
-	{
-	    ei->exp->dump(0);
-	    printf("type = %p\n", ei->exp->type);
-	}
-#endif
-	init = init->semantic(sc, type);
-	inuse--;
-    }
-}
-
-void VarDeclaration::semantic3(Scope *sc)
-{
-    // LDC
-    if (!global.params.useAvailableExternally)
-        availableExternally = false;
-
-    // Preserve call chain
-    Declaration::semantic3(sc);
-}
-
-const char *VarDeclaration::kind()
-{
-    return "variable";
-}
-
-Dsymbol *VarDeclaration::toAlias()
-{
-    //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
-    assert(this != aliassym);
-    Dsymbol *s = aliassym ? aliassym->toAlias() : this;
-    return s;
-}
-
-void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    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(" = ");
-	init->toCBuffer(buf, hgs);
-    }
-    buf->writeByte(';');
-    buf->writenl();
-}
-
-int VarDeclaration::needThis()
-{
-    //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
-    return storage_class & STCfield;
-}
-
-int VarDeclaration::isImportedSymbol()
-{
-    if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule()))
-	return TRUE;
-    return FALSE;
-}
-
-void VarDeclaration::checkCtorConstInit()
-{
-    if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
-	error("missing initializer in static constructor for const variable");
-}
-
-/************************************
- * Check to see if this variable is actually in an enclosing function
- * rather than the current one.
- */
-
-void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
-{
-    //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
-    if (parent && !isDataseg() && parent != sc->parent)
-    {
-	// The function that this variable is in
-	FuncDeclaration *fdv = toParent()->isFuncDeclaration();
-	// The current function
-	FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
-
-	if (fdv && fdthis)
-	{
-	    if (loc.filename)
-		fdthis->getLevel(loc, fdv);
-	    nestedref = 1;
-	    fdv->nestedFrameRef = 1;
-#if IN_LLVM
-#if DMDV1
-        fdv->nestedVars.insert(this);
-#endif
-#endif
-	    //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
-	}
-    }
-}
-
-/*******************************
- * Does symbol go into data segment?
- * Includes extern variables.
- */
-
-int VarDeclaration::isDataseg()
-{
-#if 0
-    printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
-    printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
-    printf("parent = '%s'\n", parent->toChars());
-#endif
-    Dsymbol *parent = this->toParent();
-    if (!parent && !(storage_class & (STCstatic | STCconst)))
-    {	error("forward referenced");
-	type = Type::terror;
-	return 0;
-    }
-    return (storage_class & (STCstatic | STCconst) ||
-	   parent->isModule() ||
-	   parent->isTemplateInstance());
-}
-
-int VarDeclaration::hasPointers()
-{
-    return (!isDataseg() && type->hasPointers());
-}
-
-int VarDeclaration::isSameAsInitializer()
-{
-    if (init && init->isExpInitializer() && 
-        init->isExpInitializer()->exp->op == TOKstructliteral)
-        return 0;
-    return isConst();
-}
-
-/******************************************
- * If a variable has an scope destructor call, return call for it.
- * Otherwise, return NULL.
- */
-
-Expression *VarDeclaration::callScopeDtor()
-{   Expression *e = NULL;
-
-    //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
-    if (storage_class & STCscope && !noscope)
-    {
-	for (ClassDeclaration *cd = type->isClassHandle();
-	     cd;
-	     cd = cd->baseClass)
-	{
-	    /* We can do better if there's a way with onstack
-	     * classes to determine if there's no way the monitor
-	     * could be set.
-	     */
-	    //if (cd->isInterfaceDeclaration())
-		//error("interface %s cannot be scope", cd->toChars());
-	    if (1 || onstack || cd->dtors.dim)	// if any destructors
-	    {
-		// delete this;
-		Expression *ec;
-
-		ec = new VarExp(loc, this);
-		e = new DeleteExp(loc, ec);
-		e->type = Type::tvoid;
-		break;
-	    }
-	}
-    }
-    return e;
-}
-
-
-/********************************* ClassInfoDeclaration ****************************/
-
-ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
-    : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
-{
-    this->cd = cd;
-    storage_class = STCstatic;
-}
-
-Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(0);		// should never be produced by syntax
-    return NULL;
-}
-
-void ClassInfoDeclaration::semantic(Scope *sc)
-{
-}
-
-/********************************* ModuleInfoDeclaration ****************************/
-
-ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
-    : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
-{
-    this->mod = mod;
-    storage_class = STCstatic;
-}
-
-Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(0);		// should never be produced by syntax
-    return NULL;
-}
-
-void ModuleInfoDeclaration::semantic(Scope *sc)
-{
-}
-
-/********************************* TypeInfoDeclaration ****************************/
-
-TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
-    : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
-{
-    this->tinfo = tinfo;
-    storage_class = STCstatic;
-    protection = PROTpublic;
-    linkage = LINKc;
-}
-
-Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(0);		// should never be produced by syntax
-    return NULL;
-}
-
-void TypeInfoDeclaration::semantic(Scope *sc)
-{
-    assert(linkage == LINKc);
-    // LDC
-    if (!global.params.useAvailableExternally)
-        availableExternally = false;
-}
-
-/***************************** TypeInfoConstDeclaration **********************/
-
-#if DMDV2
-TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-#endif
-
-/***************************** TypeInfoInvariantDeclaration **********************/
-
-#if DMDV2
-TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-#endif
-
-/***************************** TypeInfoStructDeclaration **********************/
-
-TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoClassDeclaration ***********************/
-
-TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoInterfaceDeclaration *******************/
-
-TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoTypedefDeclaration *********************/
-
-TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoPointerDeclaration *********************/
-
-TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoArrayDeclaration ***********************/
-
-TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoStaticArrayDeclaration *****************/
-
-TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoAssociativeArrayDeclaration ************/
-
-TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoEnumDeclaration ***********************/
-
-TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoFunctionDeclaration ********************/
-
-TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoDelegateDeclaration ********************/
-
-TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/***************************** TypeInfoTupleDeclaration **********************/
-
-TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
-    : TypeInfoDeclaration(tinfo, 0)
-{
-}
-
-/********************************* ThisDeclaration ****************************/
-
-// For the "this" parameter to member functions
-
-ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
-   : VarDeclaration(loc, t, Id::This, NULL)
-{
-    noscope = 1;
-}
-
-Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(0);		// should never be produced by syntax
-    return NULL;
-}
-
-/********************** StaticStructInitDeclaration ***************************/
-
-StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym)
-    : Declaration(new Identifier("", TOKidentifier))
-{
-    this->loc = loc;
-    this->dsym = dsym;
-    storage_class |= STCconst;
-}
-
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-2009 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "init.h"
+#include "declaration.h"
+#include "attrib.h"
+#include "mtype.h"
+#include "template.h"
+#include "scope.h"
+#include "aggregate.h"
+#include "module.h"
+#include "id.h"
+#include "expression.h"
+#include "hdrgen.h"
+
+/********************************* Declaration ****************************/
+
+Declaration::Declaration(Identifier *id)
+    : Dsymbol(id)
+{
+    type = NULL;
+    originalType = NULL;
+    storage_class = STCundefined;
+    protection = PROTundefined;
+    linkage = LINKdefault;
+    inuse = 0;
+}
+
+void Declaration::semantic(Scope *sc)
+{
+}
+
+const char *Declaration::kind()
+{
+    return "declaration";
+}
+
+unsigned Declaration::size(Loc loc)
+{
+    assert(type);
+    return type->size();
+}
+
+int Declaration::isStaticConstructor()
+{
+    return FALSE;
+}
+
+int Declaration::isStaticDestructor()
+{
+    return FALSE;
+}
+
+int Declaration::isDelete()
+{
+    return FALSE;
+}
+
+int Declaration::isDataseg()
+{
+    return FALSE;
+}
+
+int Declaration::isThreadlocal()
+{
+    return FALSE;
+}
+
+int Declaration::isCodeseg()
+{
+    return FALSE;
+}
+
+enum PROT Declaration::prot()
+{
+    return protection;
+}
+
+/*************************************
+ * Check to see if declaration can be modified in this context (sc).
+ * Issue error if not.
+ */
+
+#if DMDV2
+void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
+{
+    if (sc->incontract && isParameter())
+	error(loc, "cannot modify parameter '%s' in contract", toChars());
+
+    if (isCtorinit())
+    {	// It's only modifiable if inside the right constructor
+	Dsymbol *s = sc->func;
+	while (1)
+	{
+	    FuncDeclaration *fd = NULL;
+	    if (s)
+		fd = s->isFuncDeclaration();
+	    if (fd &&
+		((fd->isCtorDeclaration() && storage_class & STCfield) ||
+		 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
+		fd->toParent() == toParent()
+	       )
+	    {
+		VarDeclaration *v = isVarDeclaration();
+		assert(v);
+		v->ctorinit = 1;
+		//printf("setting ctorinit\n");
+	    }
+	    else
+	    {
+		if (s)
+		{   s = s->toParent2();
+		    continue;
+		}
+		else
+		{
+		    const char *p = isStatic() ? "static " : "";
+		    error(loc, "can only initialize %sconst %s inside %sconstructor",
+			p, toChars(), p);
+		}
+	    }
+	    break;
+	}
+    }
+    else
+    {
+	VarDeclaration *v = isVarDeclaration();
+	if (v && v->canassign == 0)
+	{
+	    const char *p = NULL;
+	    if (isConst())
+		p = "const";
+	    else if (isInvariant())
+		p = "immutable";
+	    else if (storage_class & STCmanifest)
+		p = "enum";
+	    else if (!t->isAssignable())
+		p = "struct with immutable members";
+	    if (p)
+	    {	error(loc, "cannot modify %s", p);
+	    }
+	}
+    }
+}
+#endif
+
+
+/********************************* TupleDeclaration ****************************/
+
+TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
+    : Declaration(id)
+{
+    this->type = NULL;
+    this->objects = objects;
+    this->isexp = 0;
+    this->tupletype = NULL;
+}
+
+Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
+{
+    assert(0);
+    return NULL;
+}
+
+const char *TupleDeclaration::kind()
+{
+    return "tuple";
+}
+
+Type *TupleDeclaration::getType()
+{
+    /* If this tuple represents a type, return that type
+     */
+
+    //printf("TupleDeclaration::getType() %s\n", toChars());
+    if (isexp)
+	return NULL;
+    if (!tupletype)
+    {
+	/* It's only a type tuple if all the Object's are types
+	 */
+	for (size_t i = 0; i < objects->dim; i++)
+	{   Object *o = (Object *)objects->data[i];
+
+	    if (o->dyncast() != DYNCAST_TYPE)
+	    {
+		//printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
+		return NULL;
+	    }
+	}
+
+	/* We know it's a type tuple, so build the TypeTuple
+	 */
+	Arguments *args = new Arguments();
+	args->setDim(objects->dim);
+	OutBuffer buf;
+	int hasdeco = 1;
+	for (size_t i = 0; i < objects->dim; i++)
+	{   Type *t = (Type *)objects->data[i];
+
+	    //printf("type = %s\n", t->toChars());
+#if 0
+	    buf.printf("_%s_%d", ident->toChars(), i);
+	    char *name = (char *)buf.extractData();
+	    Identifier *id = new Identifier(name, TOKidentifier);
+	    Argument *arg = new Argument(STCin, t, id, NULL);
+#else
+	    Argument *arg = new Argument(STCin, t, NULL, NULL);
+#endif
+	    args->data[i] = (void *)arg;
+	    if (!t->deco)
+		hasdeco = 0;
+	}
+
+	tupletype = new TypeTuple(args);
+	if (hasdeco)
+	    return tupletype->semantic(0, NULL);
+    }
+
+    return tupletype;
+}
+
+int TupleDeclaration::needThis()
+{
+    //printf("TupleDeclaration::needThis(%s)\n", toChars());
+    for (size_t i = 0; i < objects->dim; i++)
+    {   Object *o = (Object *)objects->data[i];
+	if (o->dyncast() == DYNCAST_EXPRESSION)
+	{   Expression *e = (Expression *)o;
+	    if (e->op == TOKdsymbol)
+	    {	DsymbolExp *ve = (DsymbolExp *)e;
+		Declaration *d = ve->s->isDeclaration();
+		if (d && d->needThis())
+		{
+		    return 1;
+		}
+	    }
+	}
+    }
+    return 0;
+}
+
+/********************************* TypedefDeclaration ****************************/
+
+TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init)
+    : Declaration(id)
+{
+    this->type = new TypeTypedef(this);
+    this->basetype = basetype->toBasetype();
+    this->init = init;
+#ifdef _DH
+    this->htype = NULL;
+    this->hbasetype = NULL;
+#endif
+    this->sem = 0;
+    this->loc = loc;
+#if IN_DMD
+    this->sinit = NULL;
+#endif
+}
+
+Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
+{
+    Type *basetype = this->basetype->syntaxCopy();
+
+    Initializer *init = NULL;
+    if (this->init)
+	init = this->init->syntaxCopy();
+
+    assert(!s);
+    TypedefDeclaration *st;
+    st = new TypedefDeclaration(loc, ident, basetype, init);
+#ifdef _DH
+    // Syntax copy for header file
+    if (!htype)      // Don't overwrite original
+    {	if (type)    // Make copy for both old and new instances
+	{   htype = type->syntaxCopy();
+	    st->htype = type->syntaxCopy();
+	}
+    }
+    else            // Make copy of original for new instance
+        st->htype = htype->syntaxCopy();
+    if (!hbasetype)
+    {	if (basetype)
+	{   hbasetype = basetype->syntaxCopy();
+	    st->hbasetype = basetype->syntaxCopy();
+	}
+    }
+    else
+        st->hbasetype = hbasetype->syntaxCopy();
+#endif
+    return st;
+}
+
+void TypedefDeclaration::semantic(Scope *sc)
+{
+    //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
+    if (sem == 0)
+    {	sem = 1;
+	basetype = basetype->semantic(loc, sc);
+	sem = 2;
+	type = type->semantic(loc, sc);
+	if (sc->parent->isFuncDeclaration() && init)
+	    semantic2(sc);
+	storage_class |= sc->stc & STCdeprecated;
+    }
+    else if (sem == 1)
+    {
+	error("circular definition");
+    }
+}
+
+void TypedefDeclaration::semantic2(Scope *sc)
+{
+    //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
+    if (sem == 2)
+    {	sem = 3;
+	if (init)
+	{
+	    init = init->semantic(sc, basetype);
+
+	    ExpInitializer *ie = init->isExpInitializer();
+	    if (ie)
+	    {
+		if (ie->exp->type == basetype)
+		    ie->exp->type = type;
+	    }
+	}
+    }
+}
+
+const char *TypedefDeclaration::kind()
+{
+    return "typedef";
+}
+
+Type *TypedefDeclaration::getType()
+{
+    return type;
+}
+
+void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+    buf->writestring("typedef ");
+    basetype->toCBuffer(buf, ident, hgs);
+    if (init)
+    {
+	buf->writestring(" = ");
+	init->toCBuffer(buf, hgs);
+    }
+    buf->writeByte(';');
+    buf->writenl();
+}
+
+/********************************* AliasDeclaration ****************************/
+
+AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type)
+    : Declaration(id)
+{
+    //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
+    //printf("type = '%s'\n", type->toChars());
+    this->loc = loc;
+    this->type = type;
+    this->aliassym = NULL;
+#ifdef _DH
+    this->htype = NULL;
+    this->haliassym = NULL;
+#endif
+    this->overnext = NULL;
+    this->inSemantic = 0;
+    this->importprot = PROTundefined;
+    assert(type);
+}
+
+AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
+    : Declaration(id)
+{
+    //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
+    assert(s != this);
+    this->loc = loc;
+    this->type = NULL;
+    this->aliassym = s;
+#ifdef _DH
+    this->htype = NULL;
+    this->haliassym = NULL;
+#endif
+    this->overnext = NULL;
+    this->inSemantic = 0;
+    assert(s);
+}
+
+Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
+{
+    //printf("AliasDeclaration::syntaxCopy()\n");
+    assert(!s);
+    AliasDeclaration *sa;
+    if (type)
+	sa = new AliasDeclaration(loc, ident, type->syntaxCopy());
+    else
+	sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL));
+#ifdef _DH
+    // Syntax copy for header file
+    if (!htype)	    // Don't overwrite original
+    {	if (type)	// Make copy for both old and new instances
+	{   htype = type->syntaxCopy();
+	    sa->htype = type->syntaxCopy();
+	}
+    }
+    else			// Make copy of original for new instance
+	sa->htype = htype->syntaxCopy();
+    if (!haliassym)
+    {	if (aliassym)
+	{   haliassym = aliassym->syntaxCopy(s);
+	    sa->haliassym = aliassym->syntaxCopy(s);
+	}
+    }
+    else
+	sa->haliassym = haliassym->syntaxCopy(s);
+#endif
+    return sa;
+}
+
+void AliasDeclaration::semantic(Scope *sc)
+{
+    //printf("AliasDeclaration::semantic() %s\n", toChars());
+    if (aliassym)
+    {
+	if (aliassym->isTemplateInstance())
+	    aliassym->semantic(sc);
+	return;
+    }
+    this->inSemantic = 1;
+
+    if (storage_class & STCconst)
+	error("cannot be const");
+
+    storage_class |= sc->stc & STCdeprecated;
+
+    // Given:
+    //	alias foo.bar.abc def;
+    // it is not knowable from the syntax whether this is an alias
+    // for a type or an alias for a symbol. It is up to the semantic()
+    // pass to distinguish.
+    // If it is a type, then type is set and getType() will return that
+    // type. If it is a symbol, then aliassym is set and type is NULL -
+    // toAlias() will return aliasssym.
+
+    Dsymbol *s;
+    Type *t;
+    Expression *e;
+
+    /* This section is needed because resolve() will:
+     *   const x = 3;
+     *   alias x y;
+     * try to alias y to 3.
+     */
+    s = type->toDsymbol(sc);
+    if (s
+#if DMDV2
+`	&& ((s->getType() && type->equals(s->getType())) || s->isEnumMember())
+#endif
+	)
+	goto L2;			// it's a symbolic alias
+
+#if DMDV2
+    if (storage_class & (STCref | STCnothrow | STCpure))
+    {	// For 'ref' to be attached to function types, and picked
+	// up by Type::resolve(), it has to go into sc.
+	sc = sc->push();
+	sc->stc |= storage_class & (STCref | STCnothrow | STCpure);
+	type->resolve(loc, sc, &e, &t, &s);
+	sc = sc->pop();
+    }
+    else
+#endif
+	type->resolve(loc, sc, &e, &t, &s);
+    if (s)
+    {
+	goto L2;
+    }
+    else if (e)
+    {
+	// Try to convert Expression to Dsymbol
+        if (e->op == TOKvar)
+	{   s = ((VarExp *)e)->var;
+	    goto L2;
+	}
+        else if (e->op == TOKfunction)
+	{   s = ((FuncExp *)e)->fd;
+	    goto L2;
+	}
+        else
+	{   error("cannot alias an expression %s", e->toChars());
+	    t = e->type;
+	}
+    }
+    else if (t)
+    {
+	type = t;
+    }
+    if (overnext)
+	ScopeDsymbol::multiplyDefined(0, this, overnext);
+    this->inSemantic = 0;
+    return;
+
+  L2:
+    //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
+    type = NULL;
+    VarDeclaration *v = s->isVarDeclaration();
+    if (v && v->linkage == LINKdefault)
+    {
+	error("forward reference of %s", v->toChars());
+	s = NULL;
+    }
+    else
+    {
+	FuncDeclaration *f = s->toAlias()->isFuncDeclaration();
+	if (f)
+	{
+	    if (overnext)
+	    {
+		FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
+		fa->importprot = importprot;
+		if (!fa->overloadInsert(overnext))
+		    ScopeDsymbol::multiplyDefined(0, f, overnext);
+		overnext = NULL;
+		s = fa;
+		s->parent = sc->parent;
+	    }
+	}
+	if (overnext)
+	    ScopeDsymbol::multiplyDefined(0, s, overnext);
+	if (s == this)
+	{
+	    assert(global.errors);
+	    s = NULL;
+	}
+    }
+    if (!aliassym)
+	aliassym = s;
+    this->inSemantic = 0;
+}
+
+int AliasDeclaration::overloadInsert(Dsymbol *s)
+{
+    /* Don't know yet what the aliased symbol is, so assume it can
+     * be overloaded and check later for correctness.
+     */
+
+    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
+    if (overnext == NULL)
+    {
+	if (s == this)
+	{
+	    return TRUE;
+	}
+	overnext = s;
+	return TRUE;
+    }
+    else
+    {
+	return overnext->overloadInsert(s);
+    }
+}
+
+const char *AliasDeclaration::kind()
+{
+    return "alias";
+}
+
+Type *AliasDeclaration::getType()
+{
+    //printf("AliasDeclaration::getType() %s\n", type->toChars());
+#if 0
+    if (!type->deco && scope)
+	semantic(scope);
+    if (type && !type->deco)
+	error("forward reference to alias %s\n", toChars());
+#endif
+    return type;
+}
+
+Dsymbol *AliasDeclaration::toAlias()
+{
+    //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
+    assert(this != aliassym);
+    //static int count; if (++count == 75) exit(0); //*(char*)0=0;
+    if (inSemantic)
+    {	error("recursive alias declaration");
+	aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
+    }
+    Dsymbol *s = aliassym ? aliassym->toAlias() : this;
+    return s;
+}
+
+void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+    buf->writestring("alias ");
+#if 0 && _DH
+    if (hgs->hdrgen)
+    {
+	if (haliassym)
+	{
+	    buf->writestring(haliassym->toChars());
+	    buf->writeByte(' ');
+	    buf->writestring(ident->toChars());
+	}
+	else
+	    htype->toCBuffer(buf, ident, hgs);
+    }
+    else
+#endif
+    {
+	if (aliassym)
+	{
+	    buf->writestring(aliassym->toChars());
+	    buf->writeByte(' ');
+	    buf->writestring(ident->toChars());
+	}
+	else
+	    type->toCBuffer(buf, ident, hgs);
+    }
+    buf->writeByte(';');
+    buf->writenl();
+}
+
+/********************************* VarDeclaration ****************************/
+
+VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init)
+    : Declaration(id)
+{
+    //printf("VarDeclaration('%s')\n", id->toChars());
+#ifdef DEBUG
+    if (!type && !init)
+    {	printf("VarDeclaration('%s')\n", id->toChars());
+	//*(char*)0=0;
+    }
+#endif
+    assert(type || init);
+    this->type = type;
+    this->init = init;
+#ifdef _DH
+    this->htype = NULL;
+    this->hinit = NULL;
+#endif
+    this->loc = loc;
+    offset = 0;
+    noscope = 0;
+#if DMDV1
+    nestedref = 0;
+#endif
+    ctorinit = 0;
+    aliassym = NULL;
+    onstack = 0;
+    canassign = 0;
+    value = NULL;
+
+#if IN_LLVM
+    aggrIndex = 0;
+
+    // LDC
+    anonDecl = NULL;
+    offset2 = 0;
+
+    nakedUse = false;
+
+    availableExternally = true; // assume this unless proven otherwise
+#endif
+}
+
+Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
+{
+    //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
+
+    VarDeclaration *sv;
+    if (s)
+    {	sv = (VarDeclaration *)s;
+    }
+    else
+    {
+	Initializer *init = NULL;
+	if (this->init)
+	{   init = this->init->syntaxCopy();
+	    //init->isExpInitializer()->exp->print();
+	    //init->isExpInitializer()->exp->dump(0);
+	}
+
+	sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init);
+	sv->storage_class = storage_class;
+    }
+#ifdef _DH
+    // Syntax copy for header file
+    if (!htype)      // Don't overwrite original
+    {	if (type)    // Make copy for both old and new instances
+	{   htype = type->syntaxCopy();
+	    sv->htype = type->syntaxCopy();
+	}
+    }
+    else            // Make copy of original for new instance
+        sv->htype = htype->syntaxCopy();
+    if (!hinit)
+    {	if (init)
+	{   hinit = init->syntaxCopy();
+	    sv->hinit = init->syntaxCopy();
+	}
+    }
+    else
+        sv->hinit = hinit->syntaxCopy();
+#endif
+    return sv;
+}
+
+void VarDeclaration::semantic(Scope *sc)
+{
+#if 0
+    printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
+    printf(" type = %s\n", type ? type->toChars() : "null");
+    printf(" stc = x%x\n", sc->stc);
+    printf(" storage_class = x%x\n", storage_class);
+    printf("linkage = %d\n", sc->linkage);
+    //if (strcmp(toChars(), "mul") == 0) halt();
+#endif
+
+    storage_class |= sc->stc;
+    if (storage_class & STCextern && init)
+	error("extern symbols cannot have initializers");
+
+    /* If auto type inference, do the inference
+     */
+    int inferred = 0;
+    if (!type)
+    {	inuse++;
+	type = init->inferType(sc);
+	inuse--;
+	inferred = 1;
+
+	/* This is a kludge to support the existing syntax for RAII
+	 * declarations.
+	 */
+	storage_class &= ~STCauto;
+	originalType = type;
+    }
+    else
+    {	if (!originalType)
+	    originalType = type;
+	type = type->semantic(loc, sc);
+    }
+    //printf(" semantic type = %s\n", type ? type->toChars() : "null");
+
+    type->checkDeprecated(loc, sc);
+    linkage = sc->linkage;
+    this->parent = sc->parent;
+    //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
+    protection = sc->protection;
+    //printf("sc->stc = %x\n", sc->stc);
+    //printf("storage_class = x%x\n", storage_class);
+
+#if DMDV2
+    if (storage_class & STCgshared && global.params.safe && !sc->module->safe)
+    {
+	error("__gshared not allowed in safe mode; use shared");
+    }
+#endif
+
+    Dsymbol *parent = toParent();
+    FuncDeclaration *fd = parent->isFuncDeclaration();
+
+    Type *tb = type->toBasetype();
+    if (tb->ty == Tvoid && !(storage_class & STClazy))
+    {	error("voids have no value");
+	type = Type::terror;
+	tb = type;
+    }
+    if (tb->ty == Tfunction)
+    {	error("cannot be declared to be a function");
+	type = Type::terror;
+	tb = type;
+    }
+    if (tb->ty == Tstruct)
+    {	TypeStruct *ts = (TypeStruct *)tb;
+
+	if (!ts->sym->members)
+	{
+	    error("no definition of struct %s", ts->toChars());
+	}
+    }
+    if ((storage_class & STCauto) && !inferred)
+	error("both auto and explicit type given");
+
+    if (tb->ty == Ttuple)
+    {   /* Instead, declare variables for each of the tuple elements
+	 * and add those.
+	 */
+	TypeTuple *tt = (TypeTuple *)tb;
+	size_t nelems = Argument::dim(tt->arguments);
+	Objects *exps = new Objects();
+	exps->setDim(nelems);
+	Expression *ie = init ? init->toExpression() : NULL;
+
+	for (size_t i = 0; i < nelems; i++)
+	{   Argument *arg = Argument::getNth(tt->arguments, i);
+
+	    OutBuffer buf;
+	    buf.printf("_%s_field_%zu", ident->toChars(), i);
+	    buf.writeByte(0);
+	    char *name = (char *)buf.extractData();
+	    Identifier *id = new Identifier(name, TOKidentifier);
+
+	    Expression *einit = ie;
+	    if (ie && ie->op == TOKtuple)
+	    {	einit = (Expression *)((TupleExp *)ie)->exps->data[i];
+	    }
+	    Initializer *ti = init;
+	    if (einit)
+	    {	ti = new ExpInitializer(einit->loc, einit);
+	    }
+
+	    VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
+	    //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
+	    v->semantic(sc);
+            
+/*
+// removed for LDC since TupleDeclaration::toObj already creates the fields;
+// adding them to the scope again leads to duplicates
+	    if (sc->scopesym)
+	    {	//printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
+		if (sc->scopesym->members)
+		    sc->scopesym->members->push(v);
+	    }
+*/
+	    Expression *e = new DsymbolExp(loc, v);
+	    exps->data[i] = e;
+	}
+	TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
+	v2->isexp = 1;
+	aliassym = v2;
+	return;
+    }
+
+    if (storage_class & STCconst && !init && !fd)
+	// Initialize by constructor only
+	storage_class = (storage_class & ~STCconst) | STCctorinit;
+
+    if (isConst())
+    {
+    }
+    else if (isStatic())
+    {
+    }
+    else if (isSynchronized())
+    {
+	error("variable %s cannot be synchronized", toChars());
+    }
+    else if (isOverride())
+    {
+	error("override cannot be applied to variable");
+    }
+    else if (isAbstract())
+    {
+	error("abstract cannot be applied to variable");
+    }
+    else if (storage_class & STCtemplateparameter)
+    {
+    }
+    else
+    {
+	AggregateDeclaration *aad = sc->anonAgg;
+	if (!aad)
+	    aad = parent->isAggregateDeclaration();
+	if (aad)
+	{
+#if DMDV2
+	    assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared)));
+
+	    if (storage_class & (STCconst | STCimmutable) && init)
+	    {
+		if (!type->toBasetype()->isTypeBasic())
+		    storage_class |= STCstatic;
+	    }
+	    else
+#endif
+		aad->addField(sc, this);
+	}
+
+	InterfaceDeclaration *id = parent->isInterfaceDeclaration();
+	if (id)
+	{
+	    error("field not allowed in interface");
+	}
+
+	/* Templates cannot add fields to aggregates
+	 */
+	TemplateInstance *ti = parent->isTemplateInstance();
+	if (ti)
+	{
+	    // Take care of nested templates
+	    while (1)
+	    {
+		TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
+		if (!ti2)
+		    break;
+		ti = ti2;
+	    }
+
+	    // If it's a member template
+	    AggregateDeclaration *ad = ti->tempdecl->isMember();
+	    if (ad && storage_class != STCundefined)
+	    {
+		error("cannot use template to add field to aggregate '%s'", ad->toChars());
+	    }
+	}
+    }
+
+#if DMDV2
+    if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref &&
+	ident != Id::This)
+    {
+	error("only parameters or foreach declarations can be ref");
+    }
+#endif
+
+    if (type->isscope() && !noscope)
+    {
+	if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd)
+	{
+	    error("globals, statics, fields, ref and out parameters cannot be scope");
+	}
+
+	if (!(storage_class & STCscope))
+	{
+	    if (!(storage_class & STCparameter) && ident != Id::withSym)
+		error("reference to scope class must be scope");
+	}
+    }
+
+    enum TOK op = TOKconstruct;
+    if (!init && !sc->inunion && !isStatic() && !isConst() && fd &&
+	!(storage_class & (STCfield | STCin | STCforeach)) &&
+	type->size() != 0)
+    {
+	// Provide a default initializer
+	//printf("Providing default initializer for '%s'\n", toChars());
+	if (type->ty == Tstruct &&
+	    ((TypeStruct *)type)->sym->zeroInit == 1)
+	{   /* If a struct is all zeros, as a special case
+	     * set it's initializer to the integer 0.
+	     * In AssignExp::toElem(), we check for this and issue
+	     * a memset() to initialize the struct.
+	     * Must do same check in interpreter.
+	     */
+	    Expression *e = new IntegerExp(loc, 0, Type::tint32);
+	    Expression *e1;
+	    e1 = new VarExp(loc, this);
+	    e = new AssignExp(loc, e1, e);
+	    e->op = TOKconstruct;
+	    e->type = e1->type;		// don't type check this, it would fail
+	    init = new ExpInitializer(loc, e);
+	    return;
+	}
+	else if (type->ty == Ttypedef)
+	{   TypeTypedef *td = (TypeTypedef *)type;
+	    if (td->sym->init)
+	    {	init = td->sym->init;
+		ExpInitializer *ie = init->isExpInitializer();
+		if (ie)
+		    // Make copy so we can modify it
+		    init = new ExpInitializer(ie->loc, ie->exp);
+	    }
+	    else
+		init = getExpInitializer();
+	}
+	else
+	{
+	    init = getExpInitializer();
+	}
+	// Default initializer is always a blit
+	op = TOKblit;
+    }
+
+    if (init)
+    {
+	sc = sc->push();
+	sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref);
+
+	ArrayInitializer *ai = init->isArrayInitializer();
+	if (ai && tb->ty == Taarray)
+	{
+	    init = ai->toAssocArrayInitializer();
+	}
+
+	StructInitializer *si = init->isStructInitializer();
+	ExpInitializer *ei = init->isExpInitializer();
+
+	// See if initializer is a NewExp that can be allocated on the stack
+	if (ei && isScope() && ei->exp->op == TOKnew)
+	{   NewExp *ne = (NewExp *)ei->exp;
+	    if (!(ne->newargs && ne->newargs->dim))
+	    {	ne->onstack = 1;
+		onstack = 1;
+		if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
+		    onstack = 2;
+	    }
+	}
+
+	// If inside function, there is no semantic3() call
+	if (sc->func)
+	{
+	    // If local variable, use AssignExp to handle all the various
+	    // possibilities.
+	    if (fd && !isStatic() && !isConst() && !init->isVoidInitializer())
+	    {
+		//printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
+		if (!ei)
+		{
+		    Expression *e = init->toExpression();
+		    if (!e)
+		    {
+			init = init->semantic(sc, type);
+			e = init->toExpression();
+			if (!e)
+			{   error("is not a static and cannot have static initializer");
+			    return;
+			}
+		    }
+		    ei = new ExpInitializer(init->loc, e);
+		    init = ei;
+		}
+
+		Expression *e1 = new VarExp(loc, this);
+
+		Type *t = type->toBasetype();
+		if (t->ty == Tsarray && !(storage_class & (STCref | STCout)))
+		{
+		    ei->exp = ei->exp->semantic(sc);
+		    if (!ei->exp->implicitConvTo(type))
+		    {
+			int dim = ((TypeSArray *)t)->dim->toInteger();
+			// If multidimensional static array, treat as one large array
+			while (1)
+			{
+			    t = t->nextOf()->toBasetype();
+			    if (t->ty != Tsarray)
+				break;
+			    dim *= ((TypeSArray *)t)->dim->toInteger();
+			    e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex));
+			}
+		    }
+		    e1 = new SliceExp(loc, e1, NULL, NULL);
+		}
+		else if (t->ty == Tstruct)
+		{
+		    ei->exp = ei->exp->semantic(sc);
+		    ei->exp = resolveProperties(sc, ei->exp);
+		    StructDeclaration *sd = ((TypeStruct *)t)->sym;
+#if DMDV2
+		    /* Look to see if initializer is a call to the constructor
+		     */
+		    if (sd->ctor &&		// there are constructors
+			ei->exp->type->ty == Tstruct &&	// rvalue is the same struct
+			((TypeStruct *)ei->exp->type)->sym == sd &&
+			ei->exp->op == TOKstar)
+		    {
+			/* Look for form of constructor call which is:
+			 *    *__ctmp.ctor(arguments...)
+			 */
+			PtrExp *pe = (PtrExp *)ei->exp;
+			if (pe->e1->op == TOKcall)
+			{   CallExp *ce = (CallExp *)pe->e1;
+			    if (ce->e1->op == TOKdotvar)
+			    {	DotVarExp *dve = (DotVarExp *)ce->e1;
+				if (dve->var->isCtorDeclaration())
+				{   /* It's a constructor call, currently constructing
+				     * a temporary __ctmp.
+				     */
+				    /* Before calling the constructor, initialize
+				     * variable with a bit copy of the default
+				     * initializer
+				     */
+				    Expression *e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
+				    e->op = TOKblit;
+				    e->type = t;
+				    ei->exp = new CommaExp(loc, e, ei->exp);
+
+				    /* Replace __ctmp being constructed with e1
+				     */
+				    dve->e1 = e1;
+				    return;
+				}
+			    }
+			}
+		    }
+#endif
+		    if (!ei->exp->implicitConvTo(type))
+		    {
+			/* Look for opCall
+			 * See bugzilla 2702 for more discussion
+			 */
+			Type *ti = ei->exp->type->toBasetype();
+			// Don't cast away invariant or mutability in initializer
+			if (search_function(sd, Id::call) &&
+			    /* Initializing with the same type is done differently
+			     */
+			    !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc)))
+			{   // Rewrite as e1.call(arguments)
+			    Expression * eCall = new DotIdExp(loc, e1, Id::call);
+			    ei->exp = new CallExp(loc, eCall, ei->exp);
+			}
+		    }
+		}
+		ei->exp = new AssignExp(loc, e1, ei->exp);
+		ei->exp->op = TOKconstruct;
+		canassign++;
+		ei->exp = ei->exp->semantic(sc);
+		canassign--;
+		ei->exp->optimize(WANTvalue);
+	    }
+	    else
+	    {
+		init = init->semantic(sc, type);
+		if (fd && isConst() && !isStatic())
+		{   // Make it static
+		    storage_class |= STCstatic;
+		}
+	    }
+	}
+	else if (isConst() || isFinal() ||
+		 parent->isAggregateDeclaration())
+	{
+	    /* Because we may need the results of a const declaration in a
+	     * subsequent type, such as an array dimension, before semantic2()
+	     * gets ordinarily run, try to run semantic2() now.
+	     * Ignore failure.
+	     */
+
+	    if (!global.errors && !inferred)
+	    {
+		unsigned errors = global.errors;
+		global.gag++;
+		//printf("+gag\n");
+		Expression *e;
+		Initializer *i2 = init;
+		inuse++;
+		if (ei)
+		{
+		    e = ei->exp->syntaxCopy();
+		    e = e->semantic(sc);
+		    e = e->implicitCastTo(sc, type);
+		}
+		else if (si || ai)
+		{   i2 = init->syntaxCopy();
+		    i2 = i2->semantic(sc, type);
+		}
+		inuse--;
+		global.gag--;
+		//printf("-gag\n");
+		if (errors != global.errors)	// if errors happened
+		{
+		    if (global.gag == 0)
+			global.errors = errors;	// act as if nothing happened
+#if DMDV2
+		    /* Save scope for later use, to try again
+		     */
+		    scope = new Scope(*sc);
+		    scope->setNoFree();
+#endif
+		}
+		else if (ei)
+		{
+		    e = e->optimize(WANTvalue | WANTinterpret);
+		    if (e->op == TOKint64 || e->op == TOKstring || e->op == TOKfloat64)
+		    {
+			ei->exp = e;		// no errors, keep result
+		    }
+#if DMDV2
+		    else
+		    {
+			/* Save scope for later use, to try again
+			 */
+			scope = new Scope(*sc);
+			scope->setNoFree();
+		    }
+#endif
+		}
+		else
+		    init = i2;		// no errors, keep result
+	    }
+	}
+	sc = sc->pop();
+    }
+}
+
+ExpInitializer *VarDeclaration::getExpInitializer()
+{
+    ExpInitializer *ei;
+
+    if (init)
+	ei = init->isExpInitializer();
+    else
+    {
+	Expression *e = type->defaultInit(loc);
+	if (e)
+	    ei = new ExpInitializer(loc, e);
+	else
+	    ei = NULL;
+    }
+    return ei;
+}
+
+void VarDeclaration::semantic2(Scope *sc)
+{
+    //printf("VarDeclaration::semantic2('%s')\n", toChars());
+    if (init && !toParent()->isFuncDeclaration())
+    {	inuse++;
+#if 0
+	ExpInitializer *ei = init->isExpInitializer();
+	if (ei)
+	{
+	    ei->exp->dump(0);
+	    printf("type = %p\n", ei->exp->type);
+	}
+#endif
+	init = init->semantic(sc, type);
+	inuse--;
+    }
+}
+
+void VarDeclaration::semantic3(Scope *sc)
+{
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
+
+    // Preserve call chain
+    Declaration::semantic3(sc);
+}
+
+const char *VarDeclaration::kind()
+{
+    return "variable";
+}
+
+Dsymbol *VarDeclaration::toAlias()
+{
+    //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
+    assert(this != aliassym);
+    Dsymbol *s = aliassym ? aliassym->toAlias() : this;
+    return s;
+}
+
+void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+    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(" = ");
+#if DMDV2
+	ExpInitializer *ie = init->isExpInitializer();
+	if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
+	    ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
+	else
+#endif
+	    init->toCBuffer(buf, hgs);
+    }
+    buf->writeByte(';');
+    buf->writenl();
+}
+
+int VarDeclaration::needThis()
+{
+    //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
+    return storage_class & STCfield;
+}
+
+int VarDeclaration::isImportedSymbol()
+{
+    if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule()))
+	return TRUE;
+    return FALSE;
+}
+
+void VarDeclaration::checkCtorConstInit()
+{
+    if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield))
+	error("missing initializer in static constructor for const variable");
+}
+
+/************************************
+ * Check to see if this variable is actually in an enclosing function
+ * rather than the current one.
+ */
+
+void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
+{
+    //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
+    if (parent && !isDataseg() && parent != sc->parent)
+    {
+	// The function that this variable is in
+	FuncDeclaration *fdv = toParent()->isFuncDeclaration();
+	// The current function
+	FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
+
+	if (fdv && fdthis)
+	{
+	    if (loc.filename)
+		fdthis->getLevel(loc, fdv);
+	    nestedref = 1;
+	    fdv->nestedFrameRef = 1;
+#if IN_LLVM
+#if DMDV1
+        fdv->nestedVars.insert(this);
+#endif
+#endif
+	    //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
+	}
+    }
+}
+
+/*******************************
+ * Does symbol go into data segment?
+ * Includes extern variables.
+ */
+
+int VarDeclaration::isDataseg()
+{
+#if 0
+    printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
+    printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance());
+    printf("parent = '%s'\n", parent->toChars());
+#endif
+    Dsymbol *parent = this->toParent();
+    if (!parent && !(storage_class & (STCstatic | STCconst)))
+    {	error("forward referenced");
+	type = Type::terror;
+	return 0;
+    }
+    return (storage_class & (STCstatic | STCconst) ||
+	   parent->isModule() ||
+	   parent->isTemplateInstance());
+}
+
+/************************************
+ * Does symbol go into thread local storage?
+ */
+
+int VarDeclaration::isThreadlocal()
+{
+    return 0;
+}
+
+int VarDeclaration::hasPointers()
+{
+    //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
+    return (!isDataseg() && type->hasPointers());
+}
+
+int VarDeclaration::isSameAsInitializer()
+{
+    if (init && init->isExpInitializer() && 
+        init->isExpInitializer()->exp->op == TOKstructliteral)
+        return 0;
+    return isConst();
+}
+
+/******************************************
+ * If a variable has an scope destructor call, return call for it.
+ * Otherwise, return NULL.
+ */
+
+Expression *VarDeclaration::callScopeDtor(Scope *sc)
+{   Expression *e = NULL;
+
+    //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
+    if (storage_class & STCscope && !noscope)
+    {
+	for (ClassDeclaration *cd = type->isClassHandle();
+	     cd;
+	     cd = cd->baseClass)
+	{
+	    /* We can do better if there's a way with onstack
+	     * classes to determine if there's no way the monitor
+	     * could be set.
+	     */
+	    //if (cd->isInterfaceDeclaration())
+		//error("interface %s cannot be scope", cd->toChars());
+	    if (1 || onstack || cd->dtors.dim)	// if any destructors
+	    {
+		// delete this;
+		Expression *ec;
+
+		ec = new VarExp(loc, this);
+		e = new DeleteExp(loc, ec);
+		e->type = Type::tvoid;
+		break;
+	    }
+	}
+    }
+    return e;
+}
+
+
+/********************************* ClassInfoDeclaration ****************************/
+
+ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd)
+    : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL)
+{
+    this->cd = cd;
+    storage_class = STCstatic;
+}
+
+Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s)
+{
+    assert(0);		// should never be produced by syntax
+    return NULL;
+}
+
+void ClassInfoDeclaration::semantic(Scope *sc)
+{
+}
+
+/********************************* ModuleInfoDeclaration ****************************/
+
+ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod)
+    : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL)
+{
+    this->mod = mod;
+    storage_class = STCstatic;
+}
+
+Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s)
+{
+    assert(0);		// should never be produced by syntax
+    return NULL;
+}
+
+void ModuleInfoDeclaration::semantic(Scope *sc)
+{
+}
+
+/********************************* TypeInfoDeclaration ****************************/
+
+TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal)
+    : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL)
+{
+    this->tinfo = tinfo;
+    storage_class = STCstatic;
+    protection = PROTpublic;
+    linkage = LINKc;
+}
+
+Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s)
+{
+    assert(0);		// should never be produced by syntax
+    return NULL;
+}
+
+void TypeInfoDeclaration::semantic(Scope *sc)
+{
+    assert(linkage == LINKc);
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
+}
+
+/***************************** TypeInfoConstDeclaration **********************/
+
+#if DMDV2
+TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+#endif
+
+/***************************** TypeInfoInvariantDeclaration **********************/
+
+#if DMDV2
+TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+#endif
+
+/***************************** TypeInfoSharedDeclaration **********************/
+
+#if DMDV2
+TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+#endif
+
+/***************************** TypeInfoStructDeclaration **********************/
+
+TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoClassDeclaration ***********************/
+
+TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoInterfaceDeclaration *******************/
+
+TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoTypedefDeclaration *********************/
+
+TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoPointerDeclaration *********************/
+
+TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoArrayDeclaration ***********************/
+
+TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoStaticArrayDeclaration *****************/
+
+TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoAssociativeArrayDeclaration ************/
+
+TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoEnumDeclaration ***********************/
+
+TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoFunctionDeclaration ********************/
+
+TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoDelegateDeclaration ********************/
+
+TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/***************************** TypeInfoTupleDeclaration **********************/
+
+TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
+    : TypeInfoDeclaration(tinfo, 0)
+{
+}
+
+/********************************* ThisDeclaration ****************************/
+
+// For the "this" parameter to member functions
+
+ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
+   : VarDeclaration(loc, t, Id::This, NULL)
+{
+    noscope = 1;
+}
+
+Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
+{
+    assert(0);		// should never be produced by syntax
+    return NULL;
+}
+
+/********************** StaticStructInitDeclaration ***************************/
+
+StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym)
+    : Declaration(new Identifier("", TOKidentifier))
+{
+    this->loc = loc;
+    this->dsym = dsym;
+    storage_class |= STCconst;
+}
--- a/dmd/declaration.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/declaration.h	Fri Nov 06 23:58:01 2009 +0100
@@ -1,951 +1,1004 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef DMD_DECLARATION_H
-#define DMD_DECLARATION_H
-
-#ifdef __DMC__
-#pragma once
-#endif /* __DMC__ */
-
-#include <set>
-#include <map>
-#include <string>
-
-#include "dsymbol.h"
-#include "lexer.h"
-#include "mtype.h"
-
-struct Expression;
-struct Statement;
-struct LabelDsymbol;
-struct LabelStatement;
-struct Initializer;
-struct Module;
-struct InlineScanState;
-struct ForeachStatement;
-struct FuncDeclaration;
-struct ExpInitializer;
-struct StructDeclaration;
-struct TupleType;
-struct InterState;
-struct IRState;
-struct AnonDeclaration;
-
-enum PROT;
-enum LINK;
-enum TOK;
-enum MATCH;
-
-enum STC
-{
-    STCundefined    = 0,
-    STCstatic	    = 1,
-    STCextern	    = 2,
-    STCconst	    = 4,
-    STCfinal	    = 8,
-    STCabstract     = 0x10,
-    STCparameter    = 0x20,
-    STCfield	    = 0x40,
-    STCoverride	    = 0x80,
-    STCauto         = 0x100,
-    STCsynchronized = 0x200,
-    STCdeprecated   = 0x400,
-    STCin           = 0x800,		// in parameter
-    STCout          = 0x1000,		// out parameter
-    STClazy	    = 0x2000,		// lazy parameter
-    STCforeach      = 0x4000,		// variable for foreach loop
-    STCcomdat       = 0x8000,		// should go into COMDAT record
-    STCvariadic     = 0x10000,		// variadic function argument
-    STCctorinit     = 0x20000,		// can only be set inside constructor
-    STCtemplateparameter = 0x40000,	// template parameter
-    STCscope	    = 0x80000,		// template parameter
-    STCinvariant    = 0x100000,
-    STCimmutable    = 0x100000,
-    STCref	    = 0x200000,
-    STCinit	    = 0x400000,		// has explicit initializer
-    STCmanifest	    = 0x800000,		// manifest constant
-    STCnodtor	    = 0x1000000,	// don't run destructor
-    STCnothrow	    = 0x2000000,	// never throws exceptions
-    STCpure	    = 0x4000000,	// pure function
-    STCtls	    = 0x8000000,	// thread local
-    STCalias	    = 0x10000000,	// alias parameter
-    STCshared       = 0x20000000,	// accessible from multiple threads
-    STCgshared      = 0x40000000,	// accessible from multiple threads
-					// but not typed as "shared"
-    STC_TYPECTOR    = (STCconst | STCimmutable | STCshared),
-};
-
-struct Match
-{
-    int count;			// number of matches found
-    MATCH last;			// match level of lastf
-    FuncDeclaration *lastf;	// last matching function we found
-    FuncDeclaration *nextf;	// current matching function
-    FuncDeclaration *anyf;	// pick a func, any func, to use for error recovery
-};
-
-void overloadResolveX(Match *m, FuncDeclaration *f, Expressions *arguments, Module* from);
-int overloadApply(Module* from, FuncDeclaration *fstart,
-	int (*fp)(void *, FuncDeclaration *),
-	void *param);
-
-/**************************************************************/
-
-struct Declaration : Dsymbol
-{
-    Type *type;
-    Type *originalType;		// before semantic analysis
-    unsigned storage_class;
-    enum PROT protection;
-    enum LINK linkage;
-    int inuse;			// used to detect cycles
-
-    Declaration(Identifier *id);
-    void semantic(Scope *sc);
-    const char *kind();
-    unsigned size(Loc loc);
-    void checkModify(Loc loc, Scope *sc, Type *t);
-
-    void emitComment(Scope *sc);
-    void toDocBuffer(OutBuffer *buf);
-
-    char *mangle();
-    int isStatic() { return storage_class & STCstatic; }
-    virtual int isStaticConstructor();
-    virtual int isStaticDestructor();
-    virtual int isDelete();
-    virtual int isDataseg();
-    virtual int isCodeseg();
-    int isCtorinit()     { return storage_class & STCctorinit; }
-    int isFinal()        { return storage_class & STCfinal; }
-    int isAbstract()     { return storage_class & STCabstract; }
-    int isConst()        { return storage_class & STCconst; }
-    int isInvariant()    { return 0; }
-    int isAuto()         { return storage_class & STCauto; }
-    int isScope()        { return storage_class & STCscope; }
-    int isSynchronized() { return storage_class & STCsynchronized; }
-    int isParameter()    { return storage_class & STCparameter; }
-    int isDeprecated()   { return storage_class & STCdeprecated; }
-    int isOverride()     { return storage_class & STCoverride; }
-    
-    virtual int isSameAsInitializer() { return isConst(); };
-
-    int isIn()    { return storage_class & STCin; }
-    int isOut()   { return storage_class & STCout; }
-    int isRef()   { return storage_class & STCref; }
-
-    enum PROT prot();
-
-    Declaration *isDeclaration() { return this; }
-
-#if IN_LLVM
-    /// Codegen traversal
-    virtual void codegen(Ir* ir);
-#endif
-};
-
-/**************************************************************/
-
-struct TupleDeclaration : Declaration
-{
-    Objects *objects;
-    int isexp;			// 1: expression tuple
-
-    TypeTuple *tupletype;	// !=NULL if this is a type tuple
-
-    TupleDeclaration(Loc loc, Identifier *ident, Objects *objects);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    const char *kind();
-    Type *getType();
-    int needThis();
-
-    TupleDeclaration *isTupleDeclaration() { return this; }
-
-#if IN_LLVM
-    /// Codegen traversal
-    void codegen(Ir* ir);
-#endif
-};
-
-/**************************************************************/
-
-struct TypedefDeclaration : Declaration
-{
-    Type *basetype;
-    Initializer *init;
-    int sem;			// 0: semantic() has not been run
-				// 1: semantic() is in progress
-				// 2: semantic() has been run
-				// 3: semantic2() has been run
-
-    TypedefDeclaration(Loc loc, Identifier *ident, Type *basetype, Initializer *init);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void semantic2(Scope *sc);
-    char *mangle();
-    const char *kind();
-    Type *getType();
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-#ifdef _DH
-    Type *htype;
-    Type *hbasetype;
-#endif
-
-    void toDocBuffer(OutBuffer *buf);
-
-#if IN_DMD
-    void toObjFile(int multiobj);			// compile to .obj file
-    void toDebug();
-    int cvMember(unsigned char *p);
-#endif
-
-    TypedefDeclaration *isTypedefDeclaration() { return this; }
-
-#if IN_DMD
-    Symbol *sinit;
-    Symbol *toInitializer();
-#endif
-
-#if IN_LLVM
-    /// Codegen traversal
-    void codegen(Ir* ir);
-#endif
-};
-
-/**************************************************************/
-
-struct AliasDeclaration : Declaration
-{
-    Dsymbol *aliassym;
-    Dsymbol *overnext;		// next in overload list
-    int inSemantic;
-    PROT importprot;	// if generated by import, store its protection
-
-    AliasDeclaration(Loc loc, Identifier *ident, Type *type);
-    AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    int overloadInsert(Dsymbol *s);
-    const char *kind();
-    Type *getType();
-    Dsymbol *toAlias();
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-#ifdef _DH
-    Type *htype;
-    Dsymbol *haliassym;
-#endif
-
-    void toDocBuffer(OutBuffer *buf);
-
-    AliasDeclaration *isAliasDeclaration() { return this; }
-};
-
-/**************************************************************/
-
-struct VarDeclaration : Declaration
-{
-    Initializer *init;
-    unsigned offset;
-    int noscope;		// no scope semantics
-    int nestedref;		// referenced by a lexically nested function
-    int ctorinit;		// it has been initialized in a ctor
-    int onstack;		// 1: it has been allocated on the stack
-				// 2: on stack, run destructor anyway
-    int canassign;		// it can be assigned to
-    Dsymbol *aliassym;		// if redone as alias to another symbol
-    Expression *value;		// when interpreting, this is the value
-				// (NULL if value not determinable)
-    Scope *scope;		// !=NULL means context to use
-
-    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void semantic2(Scope *sc);
-    const char *kind();
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-#ifdef _DH
-    Type *htype;
-    Initializer *hinit;
-#endif
-    int needThis();
-    int isImportedSymbol();
-    int isDataseg();
-    int hasPointers();
-    Expression *callScopeDtor();
-    ExpInitializer *getExpInitializer();
-    void checkCtorConstInit();
-    void checkNestedReference(Scope *sc, Loc loc);
-    Dsymbol *toAlias();
-    
-    virtual int isSameAsInitializer();
-
-#if IN_DMD
-    void toObjFile(int multiobj);			// compile to .obj file
-    Symbol *toSymbol();
-    int cvMember(unsigned char *p);
-#endif
-
-    // Eliminate need for dynamic_cast
-    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
-
-#if IN_LLVM
-    /// Codegen traversal
-    virtual void codegen(Ir* ir);
-
-    /// Index into parent aggregate.
-    /// Set during type generation.
-    unsigned aggrIndex;
-
-    /// Variables that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
-    bool availableExternally;
-    /// Override added to set above flag.
-    void semantic3(Scope *sc);
-
-    // FIXME: we're not using these anymore!
-    AnonDeclaration* anonDecl;
-    unsigned offset2;
-
-    /// This var is used by a naked function.
-    bool nakedUse;
-#endif
-};
-
-/**************************************************************/
-
-// LDC uses this to denote static struct initializers
-
-struct StaticStructInitDeclaration : Declaration
-{
-    StructDeclaration *dsym;
-
-    StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym);
-
-#if IN_DMD
-    Symbol *toSymbol();
-#endif
-
-    // Eliminate need for dynamic_cast
-    StaticStructInitDeclaration *isStaticStructInitDeclaration() { return (StaticStructInitDeclaration *)this; }
-};
-
-struct ClassInfoDeclaration : VarDeclaration
-{
-    ClassDeclaration *cd;
-
-    ClassInfoDeclaration(ClassDeclaration *cd);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-
-    void emitComment(Scope *sc);
-
-#if IN_DMD
-    Symbol *toSymbol();
-#endif
-
-    ClassInfoDeclaration* isClassInfoDeclaration() { return this; }
-};
-
-struct ModuleInfoDeclaration : VarDeclaration
-{
-    Module *mod;
-
-    ModuleInfoDeclaration(Module *mod);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-
-    void emitComment(Scope *sc);
-
-#if IN_DMD
-    Symbol *toSymbol();
-#endif
-};
-
-struct TypeInfoDeclaration : VarDeclaration
-{
-    Type *tinfo;
-
-    TypeInfoDeclaration(Type *tinfo, int internal);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-
-    void emitComment(Scope *sc);
-
-#if IN_DMD
-    void toObjFile(int multiobj);			// compile to .obj file
-    Symbol *toSymbol();
-    virtual void toDt(dt_t **pdt);
-#endif
-
-    virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return this; }
-
-#if IN_LLVM
-    /// Codegen traversal
-    void codegen(Ir* ir);
-    virtual void llvmDefine();
-#endif
-};
-
-struct TypeInfoStructDeclaration : TypeInfoDeclaration
-{
-    TypeInfoStructDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoClassDeclaration : TypeInfoDeclaration
-{
-    TypeInfoClassDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoInterfaceDeclaration : TypeInfoDeclaration
-{
-    TypeInfoInterfaceDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoTypedefDeclaration : TypeInfoDeclaration
-{
-    TypeInfoTypedefDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoPointerDeclaration : TypeInfoDeclaration
-{
-    TypeInfoPointerDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoArrayDeclaration : TypeInfoDeclaration
-{
-    TypeInfoArrayDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
-{
-    TypeInfoStaticArrayDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
-{
-    TypeInfoAssociativeArrayDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoEnumDeclaration : TypeInfoDeclaration
-{
-    TypeInfoEnumDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoFunctionDeclaration : TypeInfoDeclaration
-{
-    TypeInfoFunctionDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoDelegateDeclaration : TypeInfoDeclaration
-{
-    TypeInfoDelegateDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoTupleDeclaration : TypeInfoDeclaration
-{
-    TypeInfoTupleDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-#if DMDV2
-struct TypeInfoConstDeclaration : TypeInfoDeclaration
-{
-    TypeInfoConstDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoInvariantDeclaration : TypeInfoDeclaration
-{
-    TypeInfoInvariantDeclaration(Type *tinfo);
-
-#if IN_DMD
-    void toDt(dt_t **pdt);
-#endif
-
-#if IN_LLVM
-    void llvmDefine();
-#endif
-};
-
-struct TypeInfoSharedDeclaration : TypeInfoDeclaration
-{
-    TypeInfoSharedDeclaration(Type *tinfo);
-
-    void toDt(dt_t **pdt);
-};
-#endif
-
-/**************************************************************/
-
-struct ThisDeclaration : VarDeclaration
-{
-    ThisDeclaration(Loc loc, Type *t);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    ThisDeclaration *isThisDeclaration() { return this; }
-};
-
-enum ILS
-{
-    ILSuninitialized,	// not computed yet
-    ILSno,		// cannot inline
-    ILSyes,		// can inline
-};
-
-/**************************************************************/
-#if DMDV2
-
-enum BUILTIN
-{
-    BUILTINunknown = -1,	// not known if this is a builtin
-    BUILTINnot,			// this is not a builtin
-    BUILTINsin,			// std.math.sin
-    BUILTINcos,			// std.math.cos
-    BUILTINtan,			// std.math.tan
-    BUILTINsqrt,		// std.math.sqrt
-    BUILTINfabs,		// std.math.fabs
-};
-
-Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments);
-
-#endif
-
-struct FuncDeclaration : Declaration
-{
-    Array *fthrows;			// Array of Type's of exceptions (not used)
-    Statement *frequire;
-    Statement *fensure;
-    Statement *fbody;
-
-    Identifier *outId;			// identifier for out statement
-    VarDeclaration *vresult;		// variable corresponding to outId
-    LabelDsymbol *returnLabel;		// where the return goes
-
-    DsymbolTable *localsymtab;		// used to prevent symbols in different
-					// scopes from having the same name
-    VarDeclaration *vthis;		// 'this' parameter (member and nested)
-    VarDeclaration *v_arguments;	// '_arguments' parameter
-#if IN_GCC
-    VarDeclaration *v_argptr;	        // '_argptr' variable
-#endif
-    Dsymbols *parameters;		// Array of VarDeclaration's for parameters
-    DsymbolTable *labtab;		// statement label symbol table
-    Declaration *overnext;		// next in overload list
-    Loc endloc;				// location of closing curly bracket
-    int vtblIndex;			// for member functions, index into vtbl[]
-    int naked;				// !=0 if naked
-    int inlineAsm;			// !=0 if has inline assembler
-    ILS inlineStatus;
-    int inlineNest;			// !=0 if nested inline
-    int cantInterpret;			// !=0 if cannot interpret function
-    int semanticRun;			// 1 semantic() run
-					// 2 semantic2() run
-					// 3 semantic3() started
-					// 4 semantic3() done
-					// 5 toObjFile() run
-					// this function's frame ptr
-    ForeachStatement *fes;		// if foreach body, this is the foreach
-    int introducing;			// !=0 if 'introducing' function
-    Type *tintro;			// if !=NULL, then this is the type
-					// of the 'introducing' function
-					// this one is overriding
-    int inferRetType;			// !=0 if return type is to be inferred
-    Scope *scope;			// !=NULL means context to use
-
-    // Things that should really go into Scope
-    int hasReturnExp;			// 1 if there's a return exp; statement
-					// 2 if there's a throw statement
-					// 4 if there's an assert(0)
-					// 8 if there's inline asm
-
-    // Support for NRVO (named return value optimization)
-    int nrvo_can;			// !=0 means we can do it
-    VarDeclaration *nrvo_var;		// variable to replace with shidden
-#if IN_DMD
-    Symbol *shidden;			// hidden pointer passed to function
-#endif
-
-#if DMDV2
-    enum BUILTIN builtin;		// set if this is a known, builtin
-					// function we can evaluate at compile
-					// time
-
-    int tookAddressOf;			// set if someone took the address of
-					// this function
-    Dsymbols closureVars;		// local variables in this function
-					// which are referenced by nested
-					// functions
-#else
-    int nestedFrameRef;			// !=0 if nested variables referenced
-#endif
-
-    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void semantic2(Scope *sc);
-    void semantic3(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    int overrides(FuncDeclaration *fd);
-    int findVtblIndex(Array *vtbl, int dim);
-    int overloadInsert(Dsymbol *s);
-    FuncDeclaration *overloadExactMatch(Type *t, Module* from);
-    FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments, Module* from);
-    LabelDsymbol *searchLabel(Identifier *ident);
-    AggregateDeclaration *isThis();
-    AggregateDeclaration *isMember2();
-    int getLevel(Loc loc, FuncDeclaration *fd);	// lexical nesting level difference
-    void appendExp(Expression *e);
-    void appendState(Statement *s);
-    char *mangle();
-    int isMain();
-    int isWinMain();
-    int isDllMain();
-    int isExport();
-    int isImportedSymbol();
-    int isAbstract();
-    int isCodeseg();
-    virtual int isNested();
-    int needThis();
-    virtual int isVirtual();
-    virtual int isFinal();
-    virtual int addPreInvariant();
-    virtual int addPostInvariant();
-    Expression *interpret(InterState *istate, Expressions *arguments);
-    void inlineScan();
-    int canInline(int hasthis, int hdrscan = 0);
-    Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments);
-    const char *kind();
-    void toDocBuffer(OutBuffer *buf);
-
-// LDC: give argument types to runtime functions
-    static FuncDeclaration *genCfunc(Arguments *args, Type *treturn, const char *name);
-    static FuncDeclaration *genCfunc(Arguments *args, Type *treturn, Identifier *id);
-
-#if IN_DMD
-    Symbol *toSymbol();
-    Symbol *toThunkSymbol(int offset);	// thunk version
-    void toObjFile(int multiobj);			// compile to .obj file
-    int cvMember(unsigned char *p);
-#endif
-
-    FuncDeclaration *isFuncDeclaration() { return this; }
-
-#if IN_LLVM
-    // LDC stuff
-
-    /// Codegen traversal
-    void codegen(Ir* ir);
-
-    // vars declared in this function that nested funcs reference
-    // is this is not empty, nestedFrameRef is set and these VarDecls
-    // probably have nestedref set too, see VarDeclaration::checkNestedReference
-    std::set<VarDeclaration*> nestedVars;
-
-    std::string intrinsicName;
-
-    bool isIntrinsic();
-    bool isVaIntrinsic();
-
-    // we keep our own table of label statements as LabelDsymbolS
-    // don't always carry their corresponding statement along ...
-    typedef std::map<const char*, LabelStatement*> LabelMap;
-    LabelMap labmap;
-
-    // if this is an array operation it gets a little special attention
-    bool isArrayOp;
-
-    // Functions that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
-    bool availableExternally;
-
-    // true if overridden with the pragma(allow_inline); stmt
-    bool allowInlining;
-#endif
-};
-
-struct FuncAliasDeclaration : FuncDeclaration
-{
-    FuncDeclaration *funcalias;
-    PROT importprot;	// if generated by import, store its protection
-    
-    FuncAliasDeclaration(FuncDeclaration *funcalias);
-
-    FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
-    const char *kind();
-#if IN_DMD
-    Symbol *toSymbol();
-#endif
-};
-
-struct FuncLiteralDeclaration : FuncDeclaration
-{
-    enum TOK tok;			// TOKfunction or TOKdelegate
-
-    FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok,
-	ForeachStatement *fes);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    int isNested();
-    int isVirtual();
-
-    FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
-    const char *kind();
-};
-
-struct CtorDeclaration : FuncDeclaration
-{   Arguments *arguments;
-    int varargs;
-
-    CtorDeclaration(Loc loc, Loc endloc, Arguments *arguments, int varargs);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-    char *toChars();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    void toDocBuffer(OutBuffer *buf);
-
-    CtorDeclaration *isCtorDeclaration() { return this; }
-};
-
-#if DMDV2
-struct PostBlitDeclaration : FuncDeclaration
-{
-    PostBlitDeclaration(Loc loc, Loc endloc);
-    PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    int overloadInsert(Dsymbol *s);
-    void emitComment(Scope *sc);
-
-    PostBlitDeclaration *isPostBlitDeclaration() { return this; }
-};
-#endif
-
-struct DtorDeclaration : FuncDeclaration
-{
-    DtorDeclaration(Loc loc, Loc endloc);
-    DtorDeclaration(Loc loc, Loc endloc, Identifier *id);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    int overloadInsert(Dsymbol *s);
-    void emitComment(Scope *sc);
-
-    DtorDeclaration *isDtorDeclaration() { return this; }
-};
-
-struct StaticCtorDeclaration : FuncDeclaration
-{
-    StaticCtorDeclaration(Loc loc, Loc endloc);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    AggregateDeclaration *isThis();
-    int isStaticConstructor();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    void emitComment(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-
-    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
-};
-
-struct StaticDtorDeclaration : FuncDeclaration
-{   VarDeclaration *vgate;	// 'gate' variable
-
-    StaticDtorDeclaration(Loc loc, Loc endloc);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    AggregateDeclaration *isThis();
-    int isStaticDestructor();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    void emitComment(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-
-    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
-};
-
-struct InvariantDeclaration : FuncDeclaration
-{
-    InvariantDeclaration(Loc loc, Loc endloc);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    void emitComment(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-
-    InvariantDeclaration *isInvariantDeclaration() { return this; }
-};
-
-
-struct UnitTestDeclaration : FuncDeclaration
-{
-    UnitTestDeclaration(Loc loc, Loc endloc);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    AggregateDeclaration *isThis();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-
-    UnitTestDeclaration *isUnitTestDeclaration() { return this; }
-};
-
-struct NewDeclaration : FuncDeclaration
-{   Arguments *arguments;
-    int varargs;
-
-    NewDeclaration(Loc loc, Loc endloc, Arguments *arguments, int varargs);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-
-    NewDeclaration *isNewDeclaration() { return this; }
-};
-
-
-struct DeleteDeclaration : FuncDeclaration
-{   Arguments *arguments;
-
-    DeleteDeclaration(Loc loc, Loc endloc, Arguments *arguments);
-    Dsymbol *syntaxCopy(Dsymbol *);
-    void semantic(Scope *sc);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-    int isDelete();
-    int isVirtual();
-    int addPreInvariant();
-    int addPostInvariant();
-#ifdef _DH
-    DeleteDeclaration *isDeleteDeclaration() { return this; }
-#endif
-};
-
-#endif /* DMD_DECLARATION_H */
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-2009 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#ifndef DMD_DECLARATION_H
+#define DMD_DECLARATION_H
+
+#ifdef __DMC__
+#pragma once
+#endif /* __DMC__ */
+
+#include <set>
+#include <map>
+#include <string>
+
+#include "dsymbol.h"
+#include "lexer.h"
+#include "mtype.h"
+
+struct Expression;
+struct Statement;
+struct LabelDsymbol;
+struct LabelStatement;
+struct Initializer;
+struct Module;
+struct InlineScanState;
+struct ForeachStatement;
+struct FuncDeclaration;
+struct ExpInitializer;
+struct StructDeclaration;
+struct TupleType;
+struct InterState;
+struct IRState;
+struct AnonDeclaration;
+
+enum PROT;
+enum LINK;
+enum TOK;
+enum MATCH;
+
+enum STC
+{
+    STCundefined    = 0,
+    STCstatic	    = 1,
+    STCextern	    = 2,
+    STCconst	    = 4,
+    STCfinal	    = 8,
+    STCabstract     = 0x10,
+    STCparameter    = 0x20,
+    STCfield	    = 0x40,
+    STCoverride	    = 0x80,
+    STCauto         = 0x100,
+    STCsynchronized = 0x200,
+    STCdeprecated   = 0x400,
+    STCin           = 0x800,		// in parameter
+    STCout          = 0x1000,		// out parameter
+    STClazy	    = 0x2000,		// lazy parameter
+    STCforeach      = 0x4000,		// variable for foreach loop
+    STCcomdat       = 0x8000,		// should go into COMDAT record
+    STCvariadic     = 0x10000,		// variadic function argument
+    STCctorinit     = 0x20000,		// can only be set inside constructor
+    STCtemplateparameter = 0x40000,	// template parameter
+    STCscope	    = 0x80000,		// template parameter
+    STCinvariant    = 0x100000,
+    STCimmutable    = 0x100000,
+    STCref	    = 0x200000,
+    STCinit	    = 0x400000,		// has explicit initializer
+    STCmanifest	    = 0x800000,		// manifest constant
+    STCnodtor	    = 0x1000000,	// don't run destructor
+    STCnothrow	    = 0x2000000,	// never throws exceptions
+    STCpure	    = 0x4000000,	// pure function
+    STCtls	    = 0x8000000,	// thread local
+    STCalias	    = 0x10000000,	// alias parameter
+    STCshared       = 0x20000000,	// accessible from multiple threads
+    STCgshared      = 0x40000000,	// accessible from multiple threads
+					// but not typed as "shared"
+    STC_TYPECTOR    = (STCconst | STCimmutable | STCshared),
+};
+
+struct Match
+{
+    int count;			// number of matches found
+    MATCH last;			// match level of lastf
+    FuncDeclaration *lastf;	// last matching function we found
+    FuncDeclaration *nextf;	// current matching function
+    FuncDeclaration *anyf;	// pick a func, any func, to use for error recovery
+};
+
+void overloadResolveX(Match *m, FuncDeclaration *f,
+	Expression *ethis, Expressions *arguments, Module *from);
+int overloadApply(Module* from, FuncDeclaration *fstart,
+	int (*fp)(void *, FuncDeclaration *),
+	void *param);
+
+/**************************************************************/
+
+struct Declaration : Dsymbol
+{
+    Type *type;
+    Type *originalType;		// before semantic analysis
+    unsigned storage_class;
+    enum PROT protection;
+    enum LINK linkage;
+    int inuse;			// used to detect cycles
+
+    Declaration(Identifier *id);
+    void semantic(Scope *sc);
+    const char *kind();
+    unsigned size(Loc loc);
+    void checkModify(Loc loc, Scope *sc, Type *t);
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toDocBuffer(OutBuffer *buf);
+
+    char *mangle();
+    int isStatic() { return storage_class & STCstatic; }
+    virtual int isStaticConstructor();
+    virtual int isStaticDestructor();
+    virtual int isDelete();
+    virtual int isDataseg();
+    virtual int isThreadlocal();
+    virtual int isCodeseg();
+    int isCtorinit()     { return storage_class & STCctorinit; }
+    int isFinal()        { return storage_class & STCfinal; }
+    int isAbstract()     { return storage_class & STCabstract; }
+    int isConst()        { return storage_class & STCconst; }
+    int isInvariant()    { return storage_class & STCinvariant; }
+    int isAuto()         { return storage_class & STCauto; }
+    int isScope()        { return storage_class & STCscope; }
+    int isSynchronized() { return storage_class & STCsynchronized; }
+    int isParameter()    { return storage_class & STCparameter; }
+    int isDeprecated()   { return storage_class & STCdeprecated; }
+    int isOverride()     { return storage_class & STCoverride; }
+    
+    virtual int isSameAsInitializer() { return isConst(); };
+
+    int isIn()    { return storage_class & STCin; }
+    int isOut()   { return storage_class & STCout; }
+    int isRef()   { return storage_class & STCref; }
+
+    enum PROT prot();
+
+    Declaration *isDeclaration() { return this; }
+
+#if IN_LLVM
+    /// Codegen traversal
+    virtual void codegen(Ir* ir);
+#endif
+};
+
+/**************************************************************/
+
+struct TupleDeclaration : Declaration
+{
+    Objects *objects;
+    int isexp;			// 1: expression tuple
+
+    TypeTuple *tupletype;	// !=NULL if this is a type tuple
+
+    TupleDeclaration(Loc loc, Identifier *ident, Objects *objects);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    const char *kind();
+    Type *getType();
+    int needThis();
+
+    TupleDeclaration *isTupleDeclaration() { return this; }
+
+#if IN_LLVM
+    /// Codegen traversal
+    void codegen(Ir* ir);
+#endif
+};
+
+/**************************************************************/
+
+struct TypedefDeclaration : Declaration
+{
+    Type *basetype;
+    Initializer *init;
+    int sem;			// 0: semantic() has not been run
+				// 1: semantic() is in progress
+				// 2: semantic() has been run
+				// 3: semantic2() has been run
+
+    TypedefDeclaration(Loc loc, Identifier *ident, Type *basetype, Initializer *init);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    char *mangle();
+    const char *kind();
+    Type *getType();
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+#ifdef _DH
+    Type *htype;
+    Type *hbasetype;
+#endif
+
+    void toDocBuffer(OutBuffer *buf);
+
+#if IN_DMD
+    void toObjFile(int multiobj);			// compile to .obj file
+    void toDebug();
+    int cvMember(unsigned char *p);
+#endif
+
+    TypedefDeclaration *isTypedefDeclaration() { return this; }
+
+#if IN_DMD
+    Symbol *sinit;
+    Symbol *toInitializer();
+#endif
+
+#if IN_LLVM
+    /// Codegen traversal
+    void codegen(Ir* ir);
+#endif
+};
+
+/**************************************************************/
+
+struct AliasDeclaration : Declaration
+{
+    Dsymbol *aliassym;
+    Dsymbol *overnext;		// next in overload list
+    int inSemantic;
+    PROT importprot;	// if generated by import, store its protection
+
+    AliasDeclaration(Loc loc, Identifier *ident, Type *type);
+    AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    int overloadInsert(Dsymbol *s);
+    const char *kind();
+    Type *getType();
+    Dsymbol *toAlias();
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+#ifdef _DH
+    Type *htype;
+    Dsymbol *haliassym;
+#endif
+
+    void toDocBuffer(OutBuffer *buf);
+
+    AliasDeclaration *isAliasDeclaration() { return this; }
+};
+
+/**************************************************************/
+
+struct VarDeclaration : Declaration
+{
+    Initializer *init;
+    unsigned offset;
+    int noscope;		// no scope semantics
+#if DMDV2
+    FuncDeclarations nestedrefs; // referenced by these lexically nested functions
+#else
+    int nestedref;		// referenced by a lexically nested function
+#endif
+    int ctorinit;		// it has been initialized in a ctor
+    int onstack;		// 1: it has been allocated on the stack
+				// 2: on stack, run destructor anyway
+    int canassign;		// it can be assigned to
+    Dsymbol *aliassym;		// if redone as alias to another symbol
+    Expression *value;		// when interpreting, this is the value
+				// (NULL if value not determinable)
+#if DMDV2
+    VarDeclaration *rundtor;	// if !NULL, rundtor is tested at runtime to see
+				// if the destructor should be run. Used to prevent
+				// dtor calls on postblitted vars
+#endif
+
+    VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    const char *kind();
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+#ifdef _DH
+    Type *htype;
+    Initializer *hinit;
+#endif
+    int needThis();
+    int isImportedSymbol();
+    int isDataseg();
+    int isThreadlocal();
+    int hasPointers();
+#if DMDV2
+    int canTakeAddressOf();
+    int needsAutoDtor();
+#endif
+    Expression *callScopeDtor(Scope *sc);
+    ExpInitializer *getExpInitializer();
+    Expression *getConstInitializer();
+    void checkCtorConstInit();
+    void checkNestedReference(Scope *sc, Loc loc);
+    Dsymbol *toAlias();
+    
+    virtual int isSameAsInitializer();
+
+#if IN_DMD
+    void toObjFile(int multiobj);			// compile to .obj file
+    Symbol *toSymbol();
+    int cvMember(unsigned char *p);
+#endif
+
+    // Eliminate need for dynamic_cast
+    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
+
+#if IN_LLVM
+    /// Codegen traversal
+    virtual void codegen(Ir* ir);
+
+    /// Index into parent aggregate.
+    /// Set during type generation.
+    unsigned aggrIndex;
+
+    /// Variables that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
+    bool availableExternally;
+    /// Override added to set above flag.
+    void semantic3(Scope *sc);
+
+    // FIXME: we're not using these anymore!
+    AnonDeclaration* anonDecl;
+    unsigned offset2;
+
+    /// This var is used by a naked function.
+    bool nakedUse;
+#endif
+};
+
+/**************************************************************/
+
+// LDC uses this to denote static struct initializers
+
+struct StaticStructInitDeclaration : Declaration
+{
+    StructDeclaration *dsym;
+
+    StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym);
+
+#if IN_DMD
+    Symbol *toSymbol();
+#endif
+
+    // Eliminate need for dynamic_cast
+    StaticStructInitDeclaration *isStaticStructInitDeclaration() { return (StaticStructInitDeclaration *)this; }
+};
+
+struct ClassInfoDeclaration : VarDeclaration
+{
+    ClassDeclaration *cd;
+
+    ClassInfoDeclaration(ClassDeclaration *cd);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+
+#if IN_DMD
+    Symbol *toSymbol();
+#endif
+
+    ClassInfoDeclaration* isClassInfoDeclaration() { return this; }
+};
+
+struct ModuleInfoDeclaration : VarDeclaration
+{
+    Module *mod;
+
+    ModuleInfoDeclaration(Module *mod);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+
+#if IN_DMD
+    Symbol *toSymbol();
+#endif
+};
+
+struct TypeInfoDeclaration : VarDeclaration
+{
+    Type *tinfo;
+
+    TypeInfoDeclaration(Type *tinfo, int internal);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+
+#if IN_DMD
+    void toObjFile(int multiobj);			// compile to .obj file
+    Symbol *toSymbol();
+    virtual void toDt(dt_t **pdt);
+#endif
+
+    virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return this; }
+
+#if IN_LLVM
+    /// Codegen traversal
+    void codegen(Ir* ir);
+    virtual void llvmDefine();
+#endif
+};
+
+struct TypeInfoStructDeclaration : TypeInfoDeclaration
+{
+    TypeInfoStructDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoClassDeclaration : TypeInfoDeclaration
+{
+    TypeInfoClassDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoInterfaceDeclaration : TypeInfoDeclaration
+{
+    TypeInfoInterfaceDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoTypedefDeclaration : TypeInfoDeclaration
+{
+    TypeInfoTypedefDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoPointerDeclaration : TypeInfoDeclaration
+{
+    TypeInfoPointerDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoArrayDeclaration : TypeInfoDeclaration
+{
+    TypeInfoArrayDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
+{
+    TypeInfoStaticArrayDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
+{
+    TypeInfoAssociativeArrayDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoEnumDeclaration : TypeInfoDeclaration
+{
+    TypeInfoEnumDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoFunctionDeclaration : TypeInfoDeclaration
+{
+    TypeInfoFunctionDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoDelegateDeclaration : TypeInfoDeclaration
+{
+    TypeInfoDelegateDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoTupleDeclaration : TypeInfoDeclaration
+{
+    TypeInfoTupleDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+#if DMDV2
+struct TypeInfoConstDeclaration : TypeInfoDeclaration
+{
+    TypeInfoConstDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoInvariantDeclaration : TypeInfoDeclaration
+{
+    TypeInfoInvariantDeclaration(Type *tinfo);
+
+#if IN_DMD
+    void toDt(dt_t **pdt);
+#endif
+
+#if IN_LLVM
+    void llvmDefine();
+#endif
+};
+
+struct TypeInfoSharedDeclaration : TypeInfoDeclaration
+{
+    TypeInfoSharedDeclaration(Type *tinfo);
+
+    void toDt(dt_t **pdt);
+};
+#endif
+
+/**************************************************************/
+
+struct ThisDeclaration : VarDeclaration
+{
+    ThisDeclaration(Loc loc, Type *t);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    ThisDeclaration *isThisDeclaration() { return this; }
+};
+
+enum ILS
+{
+    ILSuninitialized,	// not computed yet
+    ILSno,		// cannot inline
+    ILSyes,		// can inline
+};
+
+/**************************************************************/
+#if DMDV2
+
+enum BUILTIN
+{
+    BUILTINunknown = -1,	// not known if this is a builtin
+    BUILTINnot,			// this is not a builtin
+    BUILTINsin,			// std.math.sin
+    BUILTINcos,			// std.math.cos
+    BUILTINtan,			// std.math.tan
+    BUILTINsqrt,		// std.math.sqrt
+    BUILTINfabs,		// std.math.fabs
+};
+
+Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments);
+
+#else
+enum BUILTIN { };
+#endif
+
+struct FuncDeclaration : Declaration
+{
+    Array *fthrows;			// Array of Type's of exceptions (not used)
+    Statement *frequire;
+    Statement *fensure;
+    Statement *fbody;
+
+    FuncDeclarations foverrides;	// functions this function overrides
+    FuncDeclaration *fdrequire;		// function that does the in contract
+    FuncDeclaration *fdensure;		// function that does the out contract
+
+    Identifier *outId;			// identifier for out statement
+    VarDeclaration *vresult;		// variable corresponding to outId
+    LabelDsymbol *returnLabel;		// where the return goes
+
+    DsymbolTable *localsymtab;		// used to prevent symbols in different
+					// scopes from having the same name
+    VarDeclaration *vthis;		// 'this' parameter (member and nested)
+    VarDeclaration *v_arguments;	// '_arguments' parameter
+#if IN_GCC
+    VarDeclaration *v_argptr;	        // '_argptr' variable
+#endif
+    Dsymbols *parameters;		// Array of VarDeclaration's for parameters
+    DsymbolTable *labtab;		// statement label symbol table
+    Declaration *overnext;		// next in overload list
+    Loc endloc;				// location of closing curly bracket
+    int vtblIndex;			// for member functions, index into vtbl[]
+    int naked;				// !=0 if naked
+    int inlineAsm;			// !=0 if has inline assembler
+    ILS inlineStatus;
+    int inlineNest;			// !=0 if nested inline
+    int cantInterpret;			// !=0 if cannot interpret function
+    int semanticRun;			// 1 semantic() run
+					// 2 semantic2() run
+					// 3 semantic3() started
+					// 4 semantic3() done
+					// 5 toObjFile() run
+					// this function's frame ptr
+    ForeachStatement *fes;		// if foreach body, this is the foreach
+    int introducing;			// !=0 if 'introducing' function
+    Type *tintro;			// if !=NULL, then this is the type
+					// of the 'introducing' function
+					// this one is overriding
+    int inferRetType;			// !=0 if return type is to be inferred
+
+    // Things that should really go into Scope
+    int hasReturnExp;			// 1 if there's a return exp; statement
+					// 2 if there's a throw statement
+					// 4 if there's an assert(0)
+					// 8 if there's inline asm
+
+    // Support for NRVO (named return value optimization)
+    int nrvo_can;			// !=0 means we can do it
+    VarDeclaration *nrvo_var;		// variable to replace with shidden
+#if IN_DMD
+    Symbol *shidden;			// hidden pointer passed to function
+#endif
+
+#if DMDV2
+    enum BUILTIN builtin;		// set if this is a known, builtin
+					// function we can evaluate at compile
+					// time
+
+    int tookAddressOf;			// set if someone took the address of
+					// this function
+    Dsymbols closureVars;		// local variables in this function
+					// which are referenced by nested
+					// functions
+#else
+    int nestedFrameRef;			// !=0 if nested variables referenced
+#endif
+
+    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void semantic2(Scope *sc);
+    void semantic3(Scope *sc);
+    // called from semantic3
+    void varArgs(Scope *sc, TypeFunction*, VarDeclaration *&, VarDeclaration *&);
+
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int overrides(FuncDeclaration *fd);
+    int findVtblIndex(Array *vtbl, int dim);
+    int overloadInsert(Dsymbol *s);
+    FuncDeclaration *overloadExactMatch(Type *t, Module* from);
+    FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags = 0);
+    MATCH leastAsSpecialized(FuncDeclaration *g);
+    LabelDsymbol *searchLabel(Identifier *ident);
+    AggregateDeclaration *isThis();
+    AggregateDeclaration *isMember2();
+    int getLevel(Loc loc, FuncDeclaration *fd);	// lexical nesting level difference
+    void appendExp(Expression *e);
+    void appendState(Statement *s);
+    char *mangle();
+    const char *toPrettyChars();
+    int isMain();
+    int isWinMain();
+    int isDllMain();
+    enum BUILTIN isBuiltin();
+    int isExport();
+    int isImportedSymbol();
+    int isAbstract();
+    int isCodeseg();
+    int isOverloadable();
+    int isPure();
+    virtual int isNested();
+    int needThis();
+    virtual int isVirtual();
+    virtual int isFinal();
+    virtual int addPreInvariant();
+    virtual int addPostInvariant();
+    Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL);
+    void inlineScan();
+    int canInline(int hasthis, int hdrscan = 0);
+    Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments);
+    const char *kind();
+    void toDocBuffer(OutBuffer *buf);
+    FuncDeclaration *isUnique();
+    int needsClosure();
+    Statement *mergeFrequire(Statement *);
+    Statement *mergeFensure(Statement *);
+
+// LDC: give argument types to runtime functions
+    static FuncDeclaration *genCfunc(Arguments *args, Type *treturn, const char *name);
+    static FuncDeclaration *genCfunc(Arguments *args, Type *treturn, Identifier *id);
+
+#if IN_DMD
+    Symbol *toSymbol();
+    Symbol *toThunkSymbol(int offset);	// thunk version
+    void toObjFile(int multiobj);			// compile to .obj file
+    int cvMember(unsigned char *p);
+    void buildClosure(IRState *irs);
+#endif
+
+    FuncDeclaration *isFuncDeclaration() { return this; }
+
+#if IN_LLVM
+    // LDC stuff
+
+    /// Codegen traversal
+    void codegen(Ir* ir);
+
+    // vars declared in this function that nested funcs reference
+    // is this is not empty, nestedFrameRef is set and these VarDecls
+    // probably have nestedref set too, see VarDeclaration::checkNestedReference
+    std::set<VarDeclaration*> nestedVars;
+
+    std::string intrinsicName;
+
+    bool isIntrinsic();
+    bool isVaIntrinsic();
+
+    // we keep our own table of label statements as LabelDsymbolS
+    // don't always carry their corresponding statement along ...
+    typedef std::map<const char*, LabelStatement*> LabelMap;
+    LabelMap labmap;
+
+    // if this is an array operation it gets a little special attention
+    bool isArrayOp;
+
+    // Functions that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
+    bool availableExternally;
+
+    // true if overridden with the pragma(allow_inline); stmt
+    bool allowInlining;
+#endif
+};
+
+#if DMDV2
+FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
+	Objects *tiargs,
+	Expression *ethis,
+	Expressions *arguments,
+	int flags);
+#endif
+
+struct FuncAliasDeclaration : FuncDeclaration
+{
+    FuncDeclaration *funcalias;
+    PROT importprot;	// if generated by import, store its protection
+    
+    FuncAliasDeclaration(FuncDeclaration *funcalias);
+
+    FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
+    const char *kind();
+#if IN_DMD
+    Symbol *toSymbol();
+#endif
+};
+
+struct FuncLiteralDeclaration : FuncDeclaration
+{
+    enum TOK tok;			// TOKfunction or TOKdelegate
+
+    FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok,
+	ForeachStatement *fes);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    int isNested();
+    int isVirtual();
+
+    FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
+    const char *kind();
+};
+
+struct CtorDeclaration : FuncDeclaration
+{   Arguments *arguments;
+    int varargs;
+
+    CtorDeclaration(Loc loc, Loc endloc, Arguments *arguments, int varargs);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+    char *toChars();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    void toDocBuffer(OutBuffer *buf);
+
+    CtorDeclaration *isCtorDeclaration() { return this; }
+};
+
+#if DMDV2
+struct PostBlitDeclaration : FuncDeclaration
+{
+    PostBlitDeclaration(Loc loc, Loc endloc);
+    PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    int overloadInsert(Dsymbol *s);
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+
+    PostBlitDeclaration *isPostBlitDeclaration() { return this; }
+};
+#endif
+
+struct DtorDeclaration : FuncDeclaration
+{
+    DtorDeclaration(Loc loc, Loc endloc);
+    DtorDeclaration(Loc loc, Loc endloc, Identifier *id);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+    char *toChars();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    int overloadInsert(Dsymbol *s);
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+
+    DtorDeclaration *isDtorDeclaration() { return this; }
+};
+
+struct StaticCtorDeclaration : FuncDeclaration
+{
+    StaticCtorDeclaration(Loc loc, Loc endloc);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    AggregateDeclaration *isThis();
+    int isStaticConstructor();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
+};
+
+struct StaticDtorDeclaration : FuncDeclaration
+{   VarDeclaration *vgate;	// 'gate' variable
+
+    StaticDtorDeclaration(Loc loc, Loc endloc);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    AggregateDeclaration *isThis();
+    int isStaticDestructor();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
+};
+
+struct InvariantDeclaration : FuncDeclaration
+{
+    InvariantDeclaration(Loc loc, Loc endloc);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    InvariantDeclaration *isInvariantDeclaration() { return this; }
+};
+
+
+struct UnitTestDeclaration : FuncDeclaration
+{
+    UnitTestDeclaration(Loc loc, Loc endloc);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    AggregateDeclaration *isThis();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+
+    UnitTestDeclaration *isUnitTestDeclaration() { return this; }
+};
+
+struct NewDeclaration : FuncDeclaration
+{   Arguments *arguments;
+    int varargs;
+
+    NewDeclaration(Loc loc, Loc endloc, Arguments *arguments, int varargs);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+
+    NewDeclaration *isNewDeclaration() { return this; }
+};
+
+
+struct DeleteDeclaration : FuncDeclaration
+{   Arguments *arguments;
+
+    DeleteDeclaration(Loc loc, Loc endloc, Arguments *arguments);
+    Dsymbol *syntaxCopy(Dsymbol *);
+    void semantic(Scope *sc);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+    int isDelete();
+    int isVirtual();
+    int addPreInvariant();
+    int addPostInvariant();
+#ifdef _DH
+    DeleteDeclaration *isDeleteDeclaration() { return this; }
+#endif
+};
+
+#endif /* DMD_DECLARATION_H */
--- a/dmd/doc.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/doc.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -33,6 +33,7 @@
 #include "hdrgen.h"
 #include "doc.h"
 #include "mtype.h"
+#include "utf.h"
 
 struct Escape
 {
@@ -89,14 +90,18 @@
 int icmp(const char *stringz, void *s, size_t slen);
 int isDitto(unsigned char *comment);
 unsigned char *skipwhitespace(unsigned char *p);
-unsigned skiptoident(OutBuffer *buf, unsigned i);
-unsigned skippastident(OutBuffer *buf, unsigned i);
-unsigned skippastURL(OutBuffer *buf, unsigned i);
+unsigned skiptoident(OutBuffer *buf, size_t i);
+unsigned skippastident(OutBuffer *buf, size_t i);
+unsigned skippastURL(OutBuffer *buf, size_t i);
 void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
 void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
 void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
 Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len);
 
+int isIdStart(unsigned char *p);
+int isIdTail(unsigned char *p);
+int utfStride(unsigned char *p);
+
 static unsigned char ddoc_default[] = "\
 DDOC =	<html><head>\n\
 	<META http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\n\
@@ -238,7 +243,7 @@
     // Generate predefined macros
 
     // Set the title to be the name of the module
-    {	char *p = toPrettyChars();
+    {	const char *p = toPrettyChars();
 	Macro::define(&macrotable, (unsigned char *)"TITLE", 5, (unsigned char *)p, strlen(p));
     }
 
@@ -674,7 +679,7 @@
 	    buf->writestring("const ");
 #if DMDV2
 	if (d->isInvariant())
-	    buf->writestring("invariant ");
+	    buf->writestring("immutable ");
 #endif
 	if (d->isFinal())
 	    buf->writestring("final ");
@@ -948,7 +953,6 @@
 {   unsigned char *p;
     unsigned char *pstart;
     unsigned char *pend;
-    unsigned char *q;
     unsigned char *idstart;
     unsigned idlen;
 
@@ -963,17 +967,32 @@
 	pstart = p;
 
 	/* Find end of section, which is ended by one of:
-	 *	'identifier:'
+	 *	'identifier:' (but not inside a code section)
 	 *	'\0'
 	 */
 	idlen = 0;
+	int inCode = 0;
 	while (1)
 	{
-	    if (isalpha(*p) || *p == '_')
+	    // Check for start/end of a code section
+	    if (*p == '-')
 	    {
-		q = p + 1;
-		while (isalnum(*q) || *q == '_')
-		    q++;
+		int numdash = 0;
+		while (*p == '-')
+		{
+		    ++numdash;
+		    p++;
+		}
+		// BUG: handle UTF PS and LS too
+		if (!*p || *p == '\r' || *p == '\n' && numdash >= 3)
+		    inCode ^= 1;
+	    }
+
+	    if (!inCode && isIdStart(p))
+	    {
+		unsigned char *q = p + utfStride(p);
+		while (isIdTail(q))
+		    q += utfStride(q);
 		if (*q == ':')	// identifier: ends it
 		{   idlen = q - p;
 		    idstart = p;
@@ -1141,12 +1160,13 @@
     while (p < pend)
     {
 	// Skip to start of macro
-	for (; 1; p++)
+	while (1)
 	{
 	    switch (*p)
 	    {
 		case ' ':
 		case '\t':
+		    p++;
 		    continue;
 
 		case '\n':
@@ -1154,20 +1174,18 @@
 		    goto Lcont;
 
 		default:
-		    if (!(isalpha(*p) || *p == '_'))
-		    {
-			if (namelen)
-			    goto Ltext;		// continuation of prev macro
-			goto Lskipline;
-		    }
-		    break;
+		    if (isIdStart(p))
+			break;
+		    if (namelen)
+			goto Ltext;		// continuation of prev macro
+		    goto Lskipline;
 	    }
 	    break;
 	}
 	tempstart = p;
 
-	while (isalnum(*p) || *p == '_')
-	    p++;
+	while (isIdTail(p))
+	    p += utfStride(p);
 	templen = p - tempstart;
 
 	while (*p == ' ' || *p == '\t')
@@ -1269,7 +1287,7 @@
     while (p < pend)
     {
 	// Skip to start of macro
-	for (; 1; p++)
+	while (1)
 	{
 	    if (p >= pend)
 		goto Ldone;
@@ -1277,6 +1295,7 @@
 	    {
 		case ' ':
 		case '\t':
+		    p++;
 		    continue;
 
 		case '\n':
@@ -1284,13 +1303,11 @@
 		    goto Lcont;
 
 		default:
-		    if (!(isalpha(*p) || *p == '_'))
-		    {
-			if (namelen)
-			    goto Ltext;		// continuation of prev macro
-			goto Lskipline;
-		    }
-		    break;
+		    if (isIdStart(p))
+			break;
+		    if (namelen)
+			goto Ltext;		// continuation of prev macro
+		    goto Lskipline;
 	    }
 	    break;
 	}
@@ -1300,9 +1317,9 @@
 	{
 	    if (p >= pend)
 		goto Ldone;
-	    if (!(isalnum(*p) || *p == '_'))
+	    if (!isIdTail(p))
 		break;
-	    p++;
+	    p += utfStride(p);
 	}
 	templen = p - tempstart;
 
@@ -1486,16 +1503,25 @@
  *	end of buf
  */
 
-unsigned skiptoident(OutBuffer *buf, unsigned i)
+unsigned skiptoident(OutBuffer *buf, size_t i)
 {
-    for (; i < buf->offset; i++)
-    {
-	// BUG: handle unicode alpha's
-	unsigned char c = buf->data[i];
-	if (isalpha(c) || c == '_')
+    while (i < buf->offset)
+    {	dchar_t c;
+
+	size_t oi = i;
+	if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c))
+	    /* Ignore UTF errors, but still consume input
+	     */
 	    break;
-	if (c == '\n')
-	    break;
+	if (c >= 0x80)
+	{
+	    if (!isUniAlpha(c))
+		continue;
+	}
+	else if (!(isalpha(c) || c == '_' || c == '\n'))
+	    continue;
+	i = oi;
+	break;
     }
     return i;
 }
@@ -1504,14 +1530,25 @@
  * Scan forward past end of identifier.
  */
 
-unsigned skippastident(OutBuffer *buf, unsigned i)
+unsigned skippastident(OutBuffer *buf, size_t i)
 {
-    for (; i < buf->offset; i++)
-    {
-	// BUG: handle unicode alpha's
-	unsigned char c = buf->data[i];
-	if (!(isalnum(c) || c == '_'))
+    while (i < buf->offset)
+    {	dchar_t c;
+
+	size_t oi = i;
+	if (utf_decodeChar((unsigned char *)buf->data, buf->offset, &i, &c))
+	    /* Ignore UTF errors, but still consume input
+	     */
 	    break;
+	if (c >= 0x80)
+	{
+	    if (isUniAlpha(c))
+		continue;
+	}
+	else if (isalnum(c) || c == '_')
+	    continue;
+	i = oi;
+	break;
     }
     return i;
 }
@@ -1525,7 +1562,7 @@
  *	index just past it if it is a URL
  */
 
-unsigned skippastURL(OutBuffer *buf, unsigned i)
+unsigned skippastURL(OutBuffer *buf, size_t i)
 {   unsigned length = buf->offset - i;
     unsigned char *p = &buf->data[i];
     unsigned j;
@@ -1810,7 +1847,7 @@
 
 	    default:
 		leadingBlank = 0;
-		if (sc && !inCode && (isalpha(c) || c == '_'))
+		if (sc && !inCode && isIdStart(&buf->data[i]))
 		{   unsigned j;
 
 		    j = skippastident(buf, i);
@@ -1881,7 +1918,7 @@
 	    i = buf->insert(i, se, len);
 	    i--;		// point to ';'
 	}
-	else if (isalpha(c) || c == '_')
+	else if (isIdStart(&buf->data[i]))
 	{   unsigned j;
 
 	    j = skippastident(buf, i);
@@ -2017,3 +2054,54 @@
     return s;
 }
 
+/****************************************
+ * Determine if p points to the start of an identifier.
+ */
+
+int isIdStart(unsigned char *p)
+{
+    unsigned c = *p;
+    if (isalpha(c) || c == '_')
+	return 1;
+    if (c >= 0x80)
+    {	size_t i = 0;
+	if (utf_decodeChar(p, 4, &i, &c))
+	    return 0;	// ignore errors
+	if (isUniAlpha(c))
+	    return 1;
+    }
+    return 0;
+}
+
+/****************************************
+ * Determine if p points to the rest of an identifier.
+ */
+
+int isIdTail(unsigned char *p)
+{
+    unsigned c = *p;
+    if (isalnum(c) || c == '_')
+	return 1;
+    if (c >= 0x80)
+    {	size_t i = 0;
+	if (utf_decodeChar(p, 4, &i, &c))
+	    return 0;	// ignore errors
+	if (isUniAlpha(c))
+	    return 1;
+    }
+    return 0;
+}
+
+/*****************************************
+ * Return number of bytes in UTF character.
+ */
+
+int utfStride(unsigned char *p)
+{
+    unsigned c = *p;
+    if (c < 0x80)
+	return 1;
+    size_t i = 0;
+    utf_decodeChar(p, 4, &i, &c);	// ignore errors, but still consume input
+    return i;
+}
--- a/dmd/dsymbol.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/dsymbol.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -28,7 +28,7 @@
 #include "init.h"
 #include "import.h"
 #include "template.h"
-
+#include "attrib.h"
 #include "../gen/enums.h"
 
 /****************************** Dsymbol ******************************/
@@ -45,7 +45,7 @@
 #endif
     this->loc = 0;
     this->comment = NULL;
-
+    this->scope = NULL;
 #if IN_LLVM
     this->llvmInternal = LLVMnone;
     this->irsym = NULL;
@@ -64,7 +64,7 @@
 #endif
     this->loc = 0;
     this->comment = NULL;
-
+    this->scope = NULL;
 #if IN_LLVM
     this->llvmInternal = LLVMnone;
     this->irsym = NULL;
@@ -164,7 +164,7 @@
     return ident ? ident->toChars() : (char *)"__anonymous";
 }
 
-char *Dsymbol::toPrettyChars()
+const char *Dsymbol::toPrettyChars()
 {   Dsymbol *p;
     char *s;
     char *q;
@@ -190,6 +190,16 @@
 	if (q == s)
 	    break;
 	q--;
+#if TARGET_NET
+    if (AggregateDeclaration* ad = p->isAggregateDeclaration())
+    {
+        if (ad->isNested() && p->parent && p->parent->isAggregateDeclaration())
+        {
+            *q = '/';
+            continue;
+        }
+    }
+#endif
 	*q = '.';
     }
     return s;
@@ -266,24 +276,57 @@
     return ident ? 0 : 1;
 }
 
+/*************************************
+ * Set scope for future semantic analysis so we can
+ * deal better with forward references.
+ */
+
+void Dsymbol::setScope(Scope *sc)
+{
+    //printf("Dsymbol::setScope() %p %s\n", this, toChars());
+    if (!sc->nofree)
+	sc->setNoFree();		// may need it even after semantic() finishes
+    scope = sc;
+}
+
+void Dsymbol::importAll(Scope *sc)
+{
+}
+
+/*************************************
+ * Does semantic analysis on the public face of declarations.
+ */
+
 void Dsymbol::semantic(Scope *sc)
 {
     error("%p has no semantic routine", this);
 }
 
+/*************************************
+ * Does semantic analysis on initializers and members of aggregates.
+ */
+
 void Dsymbol::semantic2(Scope *sc)
 {
     // Most Dsymbols have no further semantic analysis needed
 }
 
+/*************************************
+ * Does semantic analysis on function bodies.
+ */
+
 void Dsymbol::semantic3(Scope *sc)
 {
     // Most Dsymbols have no further semantic analysis needed
 }
 
+/*************************************
+ * Look for function inlining possibilities.
+ */
+
 void Dsymbol::inlineScan()
 {
-    // Most Dsymbols have no further semantic analysis needed
+    // Most Dsymbols aren't functions
 }
 
 /*********************************************
@@ -341,7 +384,7 @@
 		return NULL;
 	    }
 	    ti->tempdecl = td;
-	    if (!ti->semanticdone)
+	    if (!ti->semanticRun)
 		ti->semantic(sc);
 	    sm = ti->toAlias();
 	    break;
@@ -408,6 +451,13 @@
     return FALSE;
 }
 
+#if DMDV2
+int Dsymbol::isOverloadable()
+{
+    return 0;
+}
+#endif
+
 LabelDsymbol *Dsymbol::isLabel()		// is this a LabelDsymbol()?
 {
     return NULL;
@@ -439,7 +489,7 @@
     parent = sd;
     if (!isAnonymous())		// no name, so can't add it to symbol table
     {
-	if (!sd->symtab->insert(this))	// if name is already defined
+	if (!sd->symtabInsert(this))	// if name is already defined
 	{
 	    Dsymbol *s2;
 
@@ -631,8 +681,8 @@
 
 void Dsymbol::addComment(unsigned char *comment)
 {
-//    if (comment)
-//	printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
+    //if (comment)
+	//printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars());
 
     if (!this->comment)
 	this->comment = comment;
@@ -644,6 +694,25 @@
 #endif
 }
 
+/********************************* OverloadSet ****************************/
+
+#if DMDV2
+OverloadSet::OverloadSet()
+    : Dsymbol()
+{
+}
+
+void OverloadSet::push(Dsymbol *s)
+{
+    a.push(s);
+}
+
+const char *OverloadSet::kind()
+{
+    return "overloadset";
+}
+#endif
+
 
 /********************************* ScopeDsymbol ****************************/
 
@@ -681,6 +750,7 @@
 Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
 {
     //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
+    //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0;
 
     // Look in symbols declared in this module
     Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
@@ -771,7 +841,7 @@
 	    {   ScopeDsymbol *ss;
 
 		ss = (ScopeDsymbol *) imports->data[i];
-		if (ss == s)
+		if (ss == s)			// if already imported
 		{
 		    if (protection > prots[i])
 			prots[i] = protection;	// upgrade access
@@ -849,6 +919,73 @@
     return "ScopeDsymbol";
 }
 
+Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s)
+{
+    return symtab->insert(s);
+}
+
+/***************************************
+ * Determine number of Dsymbols, folding in AttribDeclaration members.
+ */
+
+#if DMDV2
+size_t ScopeDsymbol::dim(Array *members)
+{
+    size_t n = 0;
+    if (members)
+    {
+	for (size_t i = 0; i < members->dim; i++)
+	{   Dsymbol *s = (Dsymbol *)members->data[i];
+	    AttribDeclaration *a = s->isAttribDeclaration();
+
+	    if (a)
+	    {
+		n += dim(a->decl);
+	    }
+	    else
+		n++;
+	}
+    }
+    return n;
+}
+#endif
+
+/***************************************
+ * Get nth Dsymbol, folding in AttribDeclaration members.
+ * Returns:
+ *	Dsymbol*	nth Dsymbol
+ *	NULL		not found, *pn gets incremented by the number
+ *			of Dsymbols
+ */
+
+#if DMDV2
+Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn)
+{
+    if (!members)
+	return NULL;
+
+    size_t n = 0;
+    for (size_t i = 0; i < members->dim; i++)
+    {   Dsymbol *s = (Dsymbol *)members->data[i];
+	AttribDeclaration *a = s->isAttribDeclaration();
+
+	if (a)
+	{
+	    s = getNth(a->decl, nth - n, &n);
+	    if (s)
+		return s;
+	}
+	else if (n == nth)
+	    return s;
+	else
+	    n++;
+    }
+
+    if (pn)
+	*pn += n;
+    return NULL;
+}
+#endif
 
 /*******************************************
  * Look for member of the form:
@@ -938,7 +1075,8 @@
     L1:
 
 	if (td)
- 	{
+ 	{   /* $ gives the number of elements in the tuple
+	     */
 	    VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
 	    Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t);
 	    v->init = new ExpInitializer(0, e);
@@ -947,7 +1085,8 @@
 	}
 
 	if (type)
- 	{
+ 	{   /* $ gives the number of type entries in the type tuple
+	     */
 	    VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
 	    Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t);
 	    v->init = new ExpInitializer(0, e);
@@ -956,22 +1095,30 @@
 	}
 
 	if (exp->op == TOKindex)
-	{
+	{   /* array[index] where index is some function of $
+	     */
 	    IndexExp *ie = (IndexExp *)exp;
 
 	    pvar = &ie->lengthVar;
 	    ce = ie->e1;
 	}
 	else if (exp->op == TOKslice)
-	{
+	{   /* array[lwr .. upr] where lwr or upr is some function of $
+	     */
 	    SliceExp *se = (SliceExp *)exp;
 
 	    pvar = &se->lengthVar;
 	    ce = se->e1;
 	}
 	else
+	    /* Didn't find $, look in enclosing scope(s).
+	     */
 	    return NULL;
 
+	/* If we are indexing into an array that is really a type
+	 * tuple, rewrite this as an index into a type tuple and
+	 * try again.
+	 */
 	if (ce->op == TOKtype)
 	{
 	    Type *t = ((TypeExp *)ce)->type;
@@ -981,8 +1128,13 @@
 	    }
 	}
 
-	if (!*pvar)
-	{
+	/* *pvar is lazily initialized, so if we refer to $
+	 * multiple times, it gets set only once.
+	 */
+	if (!*pvar)		// if not already initialized
+	{   /* Create variable v and set it to the value of $,
+	     * which will be a constant.
+	     */
 	    VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL);
 
 	    if (ce->op == TOKstring)
@@ -1030,13 +1182,12 @@
 }
 
 Dsymbol *DsymbolTable::lookup(Identifier *ident)
-{   StringValue *sv;
-
+{
 #ifdef DEBUG
     assert(ident);
     assert(tab);
 #endif
-    sv = tab->lookup((char*)ident->string, ident->len);
+    StringValue *sv = tab->lookup((char*)ident->string, ident->len);
     return (Dsymbol *)(sv ? sv->ptrvalue : NULL);
 }
 
--- a/dmd/dsymbol.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/dsymbol.h	Fri Nov 06 23:58:01 2009 +0100
@@ -1,6 +1,6 @@
 
 // Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
+// Copyright (c) 1999-2009 by Digital Mars
 // All Rights Reserved
 // written by Walter Bright
 // http://www.digitalmars.com
@@ -28,6 +28,7 @@
 struct Scope;
 struct DsymbolTable;
 struct Declaration;
+struct ThisDeclaration;
 struct TupleDeclaration;
 struct TypedefDeclaration;
 struct AliasDeclaration;
@@ -41,6 +42,7 @@
 struct FuncAliasDeclaration;
 struct FuncLiteralDeclaration;
 struct CtorDeclaration;
+struct PostBlitDeclaration;
 struct DtorDeclaration;
 struct StaticCtorDeclaration;
 struct StaticDtorDeclaration;
@@ -70,11 +72,13 @@
 struct HdrGenState;
 struct TypeInfoDeclaration;
 struct ClassInfoDeclaration;
-
+struct OverloadSet;
+#if TARGET_NET
+struct PragmaScope;
+#endif
 #if IN_DMD
 struct Symbol;
 #endif
-
 #if IN_GCC
 union tree_node;
 typedef union tree_node TYPE;
@@ -82,6 +86,9 @@
 struct TYPE;
 #endif
 
+// Back end
+struct Classsym;
+
 #if IN_LLVM
 class Ir;
 class IrSymbol;
@@ -114,11 +121,11 @@
 #endif
     unsigned char *comment;	// documentation comment for this Dsymbol
     Loc loc;			// where defined
+    Scope *scope;		// !=NULL means context to use for semantic()
 
     Dsymbol();
     Dsymbol(Identifier *);
     char *toChars();
-    char *toPrettyChars();
     char *locToChars();
     int equals(Object *o);
     int isAnonymous();
@@ -136,9 +143,12 @@
 
     static Array *arraySyntaxCopy(Array *a);
 
+    virtual const char *toPrettyChars();
     virtual const char *kind();
     virtual Dsymbol *toAlias();			// resolve real symbol
     virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
+    virtual void setScope(Scope *sc);
+    virtual void importAll(Scope *sc);
     virtual void semantic(Scope *sc);
     virtual void semantic2(Scope *sc);
     virtual void semantic3(Scope *sc);
@@ -152,6 +162,7 @@
 #endif
     virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     virtual void toDocBuffer(OutBuffer *buf);
+    virtual void toJsonBuffer(OutBuffer *buf);
     virtual unsigned size(Loc loc);
     virtual int isforwardRef();
     virtual void defineRef(Dsymbol *s);
@@ -160,6 +171,9 @@
     virtual int isExport();			// is Dsymbol exported?
     virtual int isImportedSymbol();		// is Dsymbol imported?
     virtual int isDeprecated();			// is Dsymbol deprecated?
+#if DMDV2
+    virtual int isOverloadable();
+#endif
     virtual LabelDsymbol *isLabel();		// is this a LabelDsymbol?
     virtual AggregateDeclaration *isMember();	// is this symbol a member of an AggregateDeclaration?
     virtual Type *getType();			// is this a type?
@@ -198,6 +212,7 @@
     virtual TemplateInstance *isTemplateInstance() { return NULL; }
     virtual TemplateMixin *isTemplateMixin() { return NULL; }
     virtual Declaration *isDeclaration() { return NULL; }
+    virtual ThisDeclaration *isThisDeclaration() { return NULL; }
     virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
     virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
     virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
@@ -206,6 +221,7 @@
     virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
     virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
     virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
+    virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }
     virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
     virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
     virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
@@ -230,6 +246,11 @@
     virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
     virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
 
+    virtual OverloadSet *isOverloadSet() { return NULL; }
+#if TARGET_NET
+    virtual PragmaScope* isPragmaScope() { return NULL; }
+#endif
+
 #if IN_LLVM
     /// Codegen traversal
     virtual void codegen(Ir* ir);
@@ -250,7 +271,7 @@
     DsymbolTable *symtab;	// members[] sorted into table
 
     Array *imports;		// imported ScopeDsymbol's
-    unsigned char *prots;	// PROT for each import
+    unsigned char *prots;	// array of PROT, one for each import
 
     ScopeDsymbol();
     ScopeDsymbol(Identifier *id);
@@ -262,9 +283,14 @@
     static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
     Dsymbol *nameCollision(Dsymbol *s);
     const char *kind();
+    FuncDeclaration *findGetMembers();
+    virtual Dsymbol *symtabInsert(Dsymbol *s);
 
     void emitMemberComments(Scope *sc);
 
+    static size_t dim(Array *members);
+    static Dsymbol *getNth(Array *members, size_t nth, size_t *pn = NULL);
+
     ScopeDsymbol *isScopeDsymbol() { return this; }
 };
 
@@ -287,6 +313,7 @@
     Expression *exp;	// IndexExp or SliceExp
     TypeTuple *type;	// for tuple[length]
     TupleDeclaration *td;	// for tuples of objects
+    Scope *sc;
 
     ArrayScopeSymbol(Expression *e);
     ArrayScopeSymbol(TypeTuple *t);
@@ -296,6 +323,20 @@
     ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
 };
 
+// Overload Sets
+
+#if DMDV2
+struct OverloadSet : Dsymbol
+{
+    Dsymbols a;		// array of Dsymbols
+
+    OverloadSet();
+    void push(Dsymbol *s);
+    OverloadSet *isOverloadSet() { return this; }
+    const char *kind();
+};
+#endif
+
 // Table of Dsymbol's
 
 struct DsymbolTable : Object
--- a/dmd/enum.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/enum.h	Fri Nov 06 23:58:01 2009 +0100
@@ -1,94 +1,95 @@
-
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#ifndef DMD_ENUM_H
-#define DMD_ENUM_H
-
-#ifdef __DMC__
-#pragma once
-#endif /* __DMC__ */
-
-#include "root.h"
-#include "dsymbol.h"
-
-struct Identifier;
-struct Type;
-struct Expression;
-#ifdef _DH
-struct HdrGenState;
-#endif
-
-
-struct EnumDeclaration : ScopeDsymbol
-{
-    Type *type;			// the TypeEnum
-    Type *memtype;		// type of the members
-
-#if DMDV1
-    dinteger_t maxval;
-    dinteger_t minval;
-    dinteger_t defaultval;	// default initializer
-#else
-    Expression *maxval;
-    Expression *minval;
-    Expression *defaultval;	// default initializer
-
-    Scope *scope;		// !=NULL means context to use
-#endif
-    int isdeprecated;
-
-    EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void semantic(Scope *sc);
-    int oneMember(Dsymbol **ps);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    Type *getType();
-    const char *kind();
-#if DMDV2
-    Dsymbol *search(Loc, Identifier *ident, int flags);
-#endif
-    int isDeprecated();			// is Dsymbol deprecated?
-
-    void emitComment(Scope *sc);
-    void toDocBuffer(OutBuffer *buf);
-
-    EnumDeclaration *isEnumDeclaration() { return this; }
-
-#if IN_DMD
-    void toObjFile(int multiobj);			// compile to .obj file
-    void toDebug();
-    int cvMember(unsigned char *p);
-
-    Symbol *sinit;
-    Symbol *toInitializer();
-#endif
-
-#if IN_LLVM
-    void codegen(Ir*);
-#endif
-};
-
-
-struct EnumMember : Dsymbol
-{
-    Expression *value;
-
-    EnumMember(Loc loc, Identifier *id, Expression *value);
-    Dsymbol *syntaxCopy(Dsymbol *s);
-    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
-    const char *kind();
-
-    void emitComment(Scope *sc);
-    void toDocBuffer(OutBuffer *buf);
-
-    EnumMember *isEnumMember() { return this; }
-};
-
-#endif /* DMD_ENUM_H */
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-2008 by Digital Mars
+// All Rights Reserved
+// written by Walter Bright
+// http://www.digitalmars.com
+// License for redistribution is by either the Artistic License
+// in artistic.txt, or the GNU General Public License in gnu.txt.
+// See the included readme.txt for details.
+
+#ifndef DMD_ENUM_H
+#define DMD_ENUM_H
+
+#ifdef __DMC__
+#pragma once
+#endif /* __DMC__ */
+
+#include "root.h"
+#include "dsymbol.h"
+
+struct Identifier;
+struct Type;
+struct Expression;
+#ifdef _DH
+struct HdrGenState;
+#endif
+
+
+struct EnumDeclaration : ScopeDsymbol
+{   /* enum ident : memtype { ... }
+     */
+    Type *type;			// the TypeEnum
+    Type *memtype;		// type of the members
+
+#if DMDV1
+    dinteger_t maxval;
+    dinteger_t minval;
+    dinteger_t defaultval;	// default initializer
+#else
+    Expression *maxval;
+    Expression *minval;
+    Expression *defaultval;	// default initializer
+#endif
+    int isdeprecated;
+
+    EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void semantic(Scope *sc);
+    int oneMember(Dsymbol **ps);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    Type *getType();
+    const char *kind();
+#if DMDV2
+    Dsymbol *search(Loc, Identifier *ident, int flags);
+#endif
+    int isDeprecated();			// is Dsymbol deprecated?
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toDocBuffer(OutBuffer *buf);
+
+    EnumDeclaration *isEnumDeclaration() { return this; }
+
+#if IN_DMD
+    void toObjFile(int multiobj);			// compile to .obj file
+    void toDebug();
+    int cvMember(unsigned char *p);
+
+    Symbol *sinit;
+    Symbol *toInitializer();
+#endif
+
+#if IN_LLVM
+    void codegen(Ir*);
+#endif
+};
+
+
+struct EnumMember : Dsymbol
+{
+    Expression *value;
+
+    EnumMember(Loc loc, Identifier *id, Expression *value);
+    Dsymbol *syntaxCopy(Dsymbol *s);
+    void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    const char *kind();
+
+    void emitComment(Scope *sc);
+    void toJsonBuffer(OutBuffer *buf);
+    void toDocBuffer(OutBuffer *buf);
+
+    EnumMember *isEnumMember() { return this; }
+};
+
+#endif /* DMD_ENUM_H */
--- a/dmd/expression.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/expression.c	Fri Nov 06 23:58:01 2009 +0100
@@ -35,8 +35,8 @@
 #endif
 
 #include "rmem.h"
-
-//#include "port.h"
+#include "port.h"
+
 #include "mtype.h"
 #include "init.h"
 #include "expression.h"
@@ -373,6 +373,11 @@
 	}
 
     }
+    else if (e->op == TOKdottd)
+    {
+	e = new CallExp(e->loc, e);
+	e = e->semantic(sc);
+    }
     return e;
 }
 
@@ -543,7 +548,7 @@
     size_t nparams = Argument::dim(tf->parameters);
 
     if (nargs > nparams && tf->varargs == 0)
-	error(loc, "expected %zu arguments, not %zu", nparams, nargs);
+	error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars());
 
     n = (nargs > nparams) ? nargs : nparams;	// n = max(nargs, nparams)
 
@@ -568,7 +573,7 @@
 		{
 		    if (tf->varargs == 2 && i + 1 == nparams)
 			goto L2;
-		    error(loc, "expected %zu arguments, not %zu", nparams, nargs);
+		    error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
 		    break;
 		}
 		arg = p->defaultArg;
@@ -590,7 +595,7 @@
 		if (arg->implicitConvTo(p->type))
 		{
 		    if (nargs != nparams)
-		        error(loc, "expected %zu arguments, not %zu", nparams, nargs);
+		        error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
 		    goto L1;
 		}
 	     L2:
@@ -669,7 +674,16 @@
 
 	L1:
 	    if (!(p->storageClass & STClazy && p->type->ty == Tvoid))
-		arg = arg->implicitCastTo(sc, p->type);
+	    {
+		if (p->type != arg->type)
+		{
+		    //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars());
+		    if (arg->op == TOKtype)
+			arg->error("cannot pass type %s as function argument", arg->toChars());
+		    arg = arg->implicitCastTo(sc, p->type);
+		    arg = arg->optimize(WANTvalue);
+		}
+	    }
 	    if (p->storageClass & (STCout | STCref))
 	    {
 		// BUG: should check that argument to ref is type 'invariant'
@@ -773,11 +787,15 @@
 	    {
 		arg = callCpCtor(loc, sc, arg);
 	    }
+#endif
 
 	    // Give error for overloaded function addresses
+#if DMDV2
 	    if (arg->op == TOKsymoff)
 	    {	SymOffExp *se = (SymOffExp *)arg;
-		if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
+		if (
+		    se->hasOverloads &&
+		    !se->var->isFuncDeclaration()->isUnique())
 		    arg->error("function %s is overloaded", arg->toChars());
 	    }
 #endif
@@ -1214,10 +1232,10 @@
 Expression *Expression::deref()
 {
     //printf("Expression::deref()\n");
-    if (type->ty == Treference)
-    {	Expression *e;
-
-	e = new PtrExp(loc, this);
+    // type could be null if forward referencing an 'auto' variable
+    if (type && type->ty == Treference)
+    {
+	Expression *e = new PtrExp(loc, this);
 	e->type = ((TypeReference *)type)->next;
 	return e;
     }
@@ -2155,6 +2173,10 @@
     f = s->isFuncDeclaration();
     if (f)
     {	//printf("'%s' is a function\n", f->toChars());
+	if (!f->type->deco)
+	{
+	    error("forward reference to %s", toChars());
+	}
 	return new VarExp(loc, f);
     }
     cd = s->isClassDeclaration();
@@ -2209,7 +2231,7 @@
 
     TemplateInstance *ti = s->isTemplateInstance();
     if (ti && !global.errors)
-    {   if (!ti->semanticdone)
+    {   if (!ti->semanticRun)
 	    ti->semantic(sc);
 	s = ti->inst->toAlias();
 	if (!s->isTemplateInstance())
@@ -3166,7 +3188,16 @@
 	    if (v->init)
 	    {   e = v->init->toExpression();
 		if (!e)
-		    error("cannot make expression out of initializer for %s", v->toChars());
+		{   error("cannot make expression out of initializer for %s", v->toChars());
+		    e = new ErrorExp();
+		}
+		else if (v->scope)
+		{   // Do deferred semantic anaylsis
+		    Initializer *i2 = v->init->syntaxCopy();
+		    i2 = i2->semantic(v->scope, v->type);
+		    e = i2->toExpression();
+		    v->scope = NULL;
+		}
 	    }
 	    else
 	    {	e = v->type->defaultInit();
@@ -3200,8 +3231,26 @@
 	e = (Expression *)elements->data[i];
 	if (e)
 	{
-	    e = e->copy();
-	    e->type = type;
+	    //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());
+
+	    /* If type is a static array, and e is an initializer for that array,
+	     * then the field initializer should be an array literal of e.
+	     */
+	    if (e->type != type && type->ty == Tsarray)
+	    {   TypeSArray *tsa = (TypeSArray *)type;
+		uinteger_t length = tsa->dim->toInteger();
+		Expressions *z = new Expressions;
+		z->setDim(length);
+		for (int q = 0; q < length; ++q)
+		    z->data[q] = e->copy();
+		e = new ArrayLiteralExp(loc, z);
+		e->type = type;
+	    }
+	    else
+	    {
+		e = e->copy();
+		e->type = type;
+	    }
 	}
     }
     return e;
@@ -3216,20 +3265,23 @@
 {
     /* Find which field offset is by looking at the field offsets
      */
-    for (size_t i = 0; i < sd->fields.dim; i++)
-    {
-	Dsymbol *s = (Dsymbol *)sd->fields.data[i];
-	VarDeclaration *v = s->isVarDeclaration();
-	assert(v);
-
-	if (offset == v->offset &&
-	    type->size() == v->type->size())
-	{   Expression *e = (Expression *)elements->data[i];
-	    if (e)
-	    {
-		return i;
-	    }
-	    break;
+    if (elements->dim)
+    {
+	for (size_t i = 0; i < sd->fields.dim; i++)
+	{
+	    Dsymbol *s = (Dsymbol *)sd->fields.data[i];
+	    VarDeclaration *v = s->isVarDeclaration();
+	    assert(v);
+
+	    if (offset == v->offset &&
+		type->size() == v->type->size())
+	    {   Expression *e = (Expression *)elements->data[i];
+		if (e)
+		{
+		    return i;
+		}
+		break;
+	    }
 	}
     }
     return -1;
@@ -3365,7 +3417,7 @@
     ti = sds->isTemplateInstance();
     if (ti && !global.errors)
     {	Dsymbol *s;
-	if (!ti->semanticdone)
+	if (!ti->semanticRun)
 	    ti->semantic(sc);
 	s = ti->inst->toAlias();
 	sds2 = s->isScopeDsymbol();
@@ -3583,7 +3635,7 @@
 	    else if (thisexp)
 		error("e.new is only for allocating nested classes");
 	    else if (fdn)
-	    {
+ 	    {
 		// make sure the parent context fdn of cd is reachable from sc
 		for (Dsymbol *sp = sc->parent; 1; sp = sp->parent)
 		{
@@ -3606,7 +3658,7 @@
 	if (f)
 	{
 	    assert(f);
-	    f = f->overloadResolve(loc, arguments, sc->module);
+	    f = f->overloadResolve(loc, NULL, arguments, sc->module);
 	    checkDeprecated(sc, f);
 	    member = f->isCtorDeclaration();
 	    assert(member);
@@ -3634,7 +3686,7 @@
 		newargs = new Expressions();
 	    newargs->shift(e);
 
-	    f = cd->aggNew->overloadResolve(loc, newargs, sc->module);
+	    f = cd->aggNew->overloadResolve(loc, NULL, newargs, sc->module);
 	    allocator = f->isNewDeclaration();
 	    assert(allocator);
 
@@ -3667,7 +3719,7 @@
 		newargs = new Expressions();
 	    newargs->shift(e);
 
-	    f = f->overloadResolve(loc, newargs, sc->module);
+	    f = f->overloadResolve(loc, NULL, newargs, sc->module);
 	    allocator = f->isNewDeclaration();
 	    assert(allocator);
 
@@ -4200,6 +4252,7 @@
 	return (Expression *)exps->data[0];
     }
     type = new TypeTuple(exps);
+    type = type->semantic(loc, sc);
     //printf("-TupleExp::semantic(%s)\n", toChars());
     return this;
 }
@@ -4263,13 +4316,13 @@
 	fd->parent = sc->parent;
 	if (global.errors)
 	{
-	    if (!fd->type->next)
-		fd->type->next = Type::terror;
 	}
 	else
 	{
 	    fd->semantic2(sc);
-	    if (!global.errors)
+	    if (!global.errors ||
+		// need to infer return type
+		(fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()))
 	    {
 		fd->semantic3(sc);
 
@@ -4278,6 +4331,10 @@
 	    }
 	}
 
+	// need to infer return type
+	if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())
+	    ((TypeFunction *)fd->type)->next = Type::terror;
+
 	// Type is a "delegate to" or "pointer to" the function literal
 	if (fd->isNested())
 	{
@@ -4377,7 +4434,13 @@
     }
     if (!s->isVarDeclaration())
     {
-	declaration->semantic(sc);
+	Scope *sc2 = sc;
+	if (sc2->stc & (STCpure | STCnothrow))
+	    sc2 = sc->push();
+	sc2->stc &= ~(STCpure | STCnothrow);
+	declaration->semantic(sc2);
+	if (sc2 != sc)
+	    sc2->pop();
 	s->parent = sc->parent;
     }
     if (!global.errors)
@@ -4920,7 +4983,7 @@
 
 	if (op == TOKmodass && e2->type->iscomplex())
 	{   error("cannot perform modulo complex arithmetic");
-	    return new IntegerExp(0);
+	    return new ErrorExp();
 	}
     }
     return this;
@@ -4985,6 +5048,46 @@
     return Expression::checkSideEffect(flag);
 }
 
+// generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
+void BinExp::checkComplexMulAssign()
+{
+    // Any multiplication by an imaginary or complex number yields a complex result.
+    // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
+    const char *opstr = Token::toChars(op);
+    if ( e1->type->isreal() && e2->type->iscomplex())
+    {
+        error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
+            e1->type->toChars(), opstr, e2->type->toChars(), 
+            e1->type->toChars(), opstr, e2->type->toChars());
+    }
+    else if (e1->type->isimaginary() && e2->type->iscomplex())
+    {
+        error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
+            e1->type->toChars(), opstr, e2->type->toChars(),
+            e1->type->toChars(), opstr, e2->type->toChars());
+    }
+    else if ((e1->type->isreal() || e1->type->isimaginary()) &&
+	e2->type->isimaginary())
+    {
+        error("%s %s %s is an undefined operation", e1->type->toChars(),
+		opstr, e2->type->toChars());
+    }
+}
+
+// generate an error if this is a nonsensical += or -=, eg real += imaginary
+void BinExp::checkComplexAddAssign()
+{
+    // Addition or subtraction of a real and an imaginary is a complex result.
+    // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
+    if ( (e1->type->isreal() && (e2->type->isimaginary() || e2->type->iscomplex())) ||
+         (e1->type->isimaginary() && (e2->type->isreal() || e2->type->iscomplex()))        
+        )
+    {
+        error("%s %s %s is undefined (result is complex)",
+	    e1->type->toChars(), Token::toChars(op), e2->type->toChars());
+    }
+}
+
 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 {
     expToCBuffer(buf, hgs, e1, precedence[op]);
@@ -5094,7 +5197,7 @@
     }
 
     if (global.params.verbose)
-	printf("file      %s\t(%s)\n", (char*)se->string, name);
+	printf("file      %s\t(%s)\n", (char *)se->string, name);
 
     {	File f(name);
 	if (f.read())
@@ -5177,7 +5280,10 @@
 #if DMDV2
 int AssertExp::canThrow()
 {
-    return (global.params.useAssert != 0);
+    /* assert()s are non-recoverable errors, so functions that
+     * use them can be considered "nothrow"
+     */
+    return 0; //(global.params.useAssert != 0);
 }
 #endif
 
@@ -5479,7 +5585,11 @@
 	     ident != Id::init && ident != Id::__sizeof &&
 	     ident != Id::alignof && ident != Id::offsetof &&
 	     ident != Id::mangleof && ident != Id::stringof)
-    {
+    {	/* Rewrite:
+         *   p.ident
+         * as:
+         *   (*p).ident
+         */
 	e = new PtrExp(loc, e1);
 	e->type = ((TypePointer *)e1->type)->next;
 	return e->type->dotExp(sc, e, ident);
@@ -5598,7 +5708,7 @@
 	type = var->type;
 	if (!type && global.errors)
 	{   // var is goofed up, just return 0
-	    return new IntegerExp(0);
+	    return new ErrorExp();
 	}
 	assert(type);
 
@@ -5935,9 +6045,10 @@
 	: UnaExp(loc, TOKcall, sizeof(CallExp), e)
 {
     Expressions *arguments = new Expressions();
-    arguments->setDim(1);
-    arguments->data[0] = (void *)earg1;
-
+    if (earg1)
+    {	arguments->setDim(1);
+	arguments->data[0] = (void *)earg1;
+    }
     this->arguments = arguments;
 }
 
@@ -6040,7 +6151,7 @@
     if (e1->op == TOKimport && !e1->type)
     {	ScopeExp *se = (ScopeExp *)e1;
 	TemplateInstance *ti = se->sds->isTemplateInstance();
-	if (ti && !ti->semanticdone)
+	if (ti && !ti->semanticRun)
 	{
 	    /* Attempt to instantiate ti. If that works, go with it.
 	     * If not, go with partial explicit specialization.
@@ -6067,7 +6178,7 @@
     if (e1->op == TOKdotti && !e1->type)
     {	DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1;
 	TemplateInstance *ti = se->ti;
-	if (!ti->semanticdone)
+	if (!ti->semanticRun)
 	{
 	    /* Attempt to instantiate ti. If that works, go with it.
 	     * If not, go with partial explicit specialization.
@@ -6163,6 +6274,36 @@
 	if (t1->ty == Tstruct)
 	{
 	    ad = ((TypeStruct *)t1)->sym;
+#if DMDV2
+	    // First look for constructor
+	    if (ad->ctor && arguments && arguments->dim)
+	    {
+		// Create variable that will get constructed
+		Identifier *idtmp = Lexer::uniqueId("__ctmp");
+		VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, NULL);
+		Expression *av = new DeclarationExp(loc, tmp);
+		av = new CommaExp(loc, av, new VarExp(loc, tmp));
+
+		Expression *e;
+		CtorDeclaration *cf = ad->ctor->isCtorDeclaration();
+		if (cf)
+		    e = new DotVarExp(loc, av, cf, 1);
+		else
+		{   TemplateDeclaration *td = ad->ctor->isTemplateDeclaration();
+		    assert(td);
+		    e = new DotTemplateExp(loc, av, td);
+		}
+		e = new CallExp(loc, e, arguments);
+#if !STRUCTTHISREF
+		/* Constructors return a pointer to the instance
+		 */
+		e = new PtrExp(loc, e);
+#endif
+		e = e->semantic(sc);
+		return e;
+	    }
+#endif
+	    // No constructor, look for overload of opCall
 	    if (search_function(ad, Id::call))
 		goto L1;	// overload of opCall, therefore it's a call
 
@@ -6205,7 +6346,7 @@
 
 	    f = dve->var->isFuncDeclaration();
 	    assert(f);
-	    f = f->overloadResolve(loc, arguments, sc->module);
+	    f = f->overloadResolve(loc, NULL, arguments, sc->module);
 
 	    ad = f->toParent()->isAggregateDeclaration();
 	}
@@ -6306,7 +6447,7 @@
 		    sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
 		}
 
-		f = f->overloadResolve(loc, arguments, sc->module);
+		f = f->overloadResolve(loc, NULL, arguments, sc->module);
 		checkDeprecated(sc, f);
 #if DMDV2
 		checkPurity(sc, f);
@@ -6346,7 +6487,7 @@
 	    }
 
 	    f = cd->ctor;
-	    f = f->overloadResolve(loc, arguments, sc->module);
+	    f = f->overloadResolve(loc, NULL, arguments, sc->module);
 	    checkDeprecated(sc, f);
 #if DMDV2
 	    checkPurity(sc, f);
@@ -6440,7 +6581,7 @@
 	    }
 	}
 
-	f = f->overloadResolve(loc, arguments, sc->module);
+	f = f->overloadResolve(loc, NULL, arguments, sc->module);
 	checkDeprecated(sc, f);
 #if DMDV2
 	checkPurity(sc, f);
@@ -6523,6 +6664,7 @@
 #if DMDV2
 int CallExp::canThrow()
 {
+    //printf("CallExp::canThrow() %s\n", toChars());
     if (e1->canThrow())
 	return 1;
 
@@ -6531,10 +6673,13 @@
     for (size_t i = 0; i < arguments->dim; i++)
     {   Expression *e = (Expression *)arguments->data[i];
 
-	if (e->canThrow())
+	if (e && e->canThrow())
 	    return 1;
     }
 
+    if (global.errors && !e1->type)
+	return 0;			// error recovery
+
     /* If calling a function or delegate that is typed as nothrow,
      * then this expression cannot throw.
      * Note that pure functions can throw.
@@ -6552,8 +6697,8 @@
 #if DMDV2
 int CallExp::isLvalue()
 {
-    if (type->toBasetype()->ty == Tstruct)
-	return 1;
+//    if (type->toBasetype()->ty == Tstruct)
+//	return 1;
     Type *tb = e1->type->toBasetype();
     if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
 	return 1;		// function returns a reference
@@ -6563,12 +6708,28 @@
 
 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
 {
+#if 1
     if (type->toBasetype()->ty == Tstruct)
 	return this;
     else
+#endif
 	return Expression::toLvalue(sc, e);
 }
 
+Expression *CallExp::modifiableLvalue(Scope *sc, Expression *e)
+{
+#if 1
+    return Expression::modifiableLvalue(sc, e);
+#else
+    /* Although function return values being usable as "ref" parameters is
+     * unsound, disabling it breaks existing code.
+     * Bugzilla 3167
+     */
+    error("cannot assign to function call");
+    return toLvalue(sc, e);
+#endif
+}
+
 void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 {   int i;
 
@@ -6600,8 +6761,19 @@
 	if (!e1->type)
 	{
 	    error("cannot take address of %s", e1->toChars());
-	    type = Type::tint32;
-	    return this;
+	    return new ErrorExp();
+	}
+	if (!e1->type->deco)
+	{
+	    /* No deco means semantic() was not run on the type.
+	     * We have to run semantic() on the symbol to get the right type:
+	     *	auto x = &bar;
+	     *	pure: int bar() { return 1;}
+	     * otherwise the 'pure' is missing from the type assigned to x.
+	     */
+
+	    error("forward reference to %s", e1->toChars());
+	    return new ErrorExp();
 	}
 	type = e1->type->pointerTo();
 
@@ -6653,8 +6825,8 @@
 PtrExp::PtrExp(Loc loc, Expression *e)
 	: UnaExp(loc, TOKstar, sizeof(PtrExp), e)
 {
-    if (e->type)
-	type = ((TypePointer *)e->type)->next;
+//    if (e->type)
+//	type = ((TypePointer *)e->type)->next;
 }
 
 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
@@ -6664,43 +6836,35 @@
 }
 
 Expression *PtrExp::semantic(Scope *sc)
-{   Type *tb;
-
+{
 #if LOGSEMANTIC
     printf("PtrExp::semantic('%s')\n", toChars());
 #endif
-    UnaExp::semantic(sc);
-    e1 = resolveProperties(sc, e1);
-    if (type)
-	return this;
-    if (!e1->type)
-	printf("PtrExp::semantic('%s')\n", toChars());
-    tb = e1->type->toBasetype();
-    switch (tb->ty)
-    {
-	case Tpointer:
-	    type = tb->next;
-	    if (type->isbit())
-	    {	Expression *e;
-
-		// Rewrite *p as p[0]
-		e = new IndexExp(loc, e1, new IntegerExp(0));
-		return e->semantic(sc);
-	    }
-	    break;
-
-	case Tsarray:
-	case Tarray:
-	    type = tb->next;
-	    e1 = e1->castTo(sc, type->pointerTo());
-	    break;
-
-	default:
-	    error("can only * a pointer, not a '%s'", e1->type->toChars());
-	    type = Type::tint32;
-	    break;
-    }
-    rvalue();
+    if (!type)
+    {
+	UnaExp::semantic(sc);
+	e1 = resolveProperties(sc, e1);
+	if (!e1->type)
+	    printf("PtrExp::semantic('%s')\n", toChars());
+	Type *tb = e1->type->toBasetype();
+	switch (tb->ty)
+	{
+	    case Tpointer:
+		type = tb->next;
+		break;
+
+	    case Tsarray:
+	    case Tarray:
+		type = tb->next;
+		e1 = e1->castTo(sc, type->pointerTo());
+		break;
+
+	    default:
+		error("can only * a pointer, not a '%s'", e1->type->toChars());
+		return new ErrorExp();
+	}
+	rvalue();
+    }
     return this;
 }
 
@@ -6766,7 +6930,7 @@
 	    return e;
 
 	e1->checkNoBool();
-	if (e1->op != TOKslice)
+	if (!e1->isArrayOperand())
 	    e1->checkArithmetic();
 	type = e1->type;
     }
@@ -6816,7 +6980,7 @@
 	    return e;
 
 	e1->checkNoBool();
-	if (e1->op != TOKslice)
+	if (!e1->isArrayOperand())
 	    e1 = e1->checkIntegral();
 	type = e1->type;
     }
@@ -7012,9 +7176,16 @@
 	    return e->implicitCastTo(sc, to);
 	}
 
+	if (e1->op == TOKtemplate)
+	{
+	    error("cannot cast template %s to type %s", e1->toChars(), to->toChars());
+	    return new ErrorExp();
+	}
+
+	Type *t1b = e1->type->toBasetype();
 	Type *tob = to->toBasetype();
 	if (tob->ty == Tstruct &&
-	    !tob->equals(e1->type->toBasetype()) &&
+	    !tob->equals(t1b) &&
 	    ((TypeStruct *)to)->sym->search(0, Id::call, 0)
 	   )
 	{
@@ -7031,6 +7202,18 @@
 	    e = e->semantic(sc);
 	    return e;
 	}
+
+	// Struct casts are possible only when the sizes match
+	if (tob->ty == Tstruct || t1b->ty == Tstruct)
+	{
+	    size_t fromsize = t1b->size(loc);
+	    size_t tosize = tob->size(loc);
+	    if (fromsize != tosize)
+	    {
+		error("cannot cast from %s to %s", e1->type->toChars(), to->toChars());
+		return new ErrorExp();
+	    }
+	}
     }
     e = e1->castTo(sc, to);
     return e;
@@ -7737,7 +7920,7 @@
 
 /************************************************************/
 
-/* Can be TOKconstruct too */
+/* op can be TOKassign, TOKconstruct, or TOKblit */
 
 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
 	: BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
@@ -7746,26 +7929,39 @@
 }
 
 Expression *AssignExp::semantic(Scope *sc)
-{   Type *t1;
+{
     Expression *e1old = e1;
 
 #if LOGSEMANTIC
     printf("AssignExp::semantic('%s')\n", toChars());
 #endif
     //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op));
+    //printf("e2->op = %d, '%s'\n", e2->op, Token::toChars(e2->op));
+
+    if (type)
+	return this;
+
+    if (e2->op == TOKcomma)
+    {	/* Rewrite to get rid of the comma from rvalue
+	 */
+	AssignExp *ea = new AssignExp(loc, e1, ((CommaExp *)e2)->e2);
+	ea->op = op;
+	Expression *e = new CommaExp(loc, ((CommaExp *)e2)->e1, ea);
+	return e->semantic(sc);
+    }
 
     /* Look for operator overloading of a[i]=value.
      * Do it before semantic() otherwise the a[i] will have been
      * converted to a.opIndex() already.
      */
     if (e1->op == TOKarray)
-    {	Type *t1;
+    {
 	ArrayExp *ae = (ArrayExp *)e1;
 	AggregateDeclaration *ad;
 	Identifier *id = Id::index;
 
 	ae->e1 = ae->e1->semantic(sc);
-	t1 = ae->e1->type->toBasetype();
+	Type *t1 = ae->e1->type->toBasetype();
 	if (t1->ty == Tstruct)
 	{
 	    ad = ((TypeStruct *)t1)->sym;
@@ -7880,13 +8076,20 @@
 	}
     }
 
-    t1 = e1->type->toBasetype();
+    // Determine if this is an initialization of a reference
+    int refinit = 0;
+    if (op == TOKconstruct && e1->op == TOKvar)
+    {	VarExp *ve = (VarExp *)e1;
+	VarDeclaration *v = ve->var->isVarDeclaration();
+	if (v->storage_class & (STCout | STCref))
+	    refinit = 1;
+    }
+
+    Type *t1 = e1->type->toBasetype();
 
     if (t1->ty == Tfunction)
     {	// Rewrite f=value to f(value)
-	Expression *e;
-
-	e = new CallExp(loc, e1, e2);
+	Expression *e = new CallExp(loc, e1, e2);
 	e = e->semantic(sc);
 	return e;
     }
@@ -7918,7 +8121,8 @@
     else
     {	// Try to do a decent error message with the expression
 	// before it got constant folded
-	e1 = e1->modifiableLvalue(sc, e1old);
+	if (op != TOKconstruct)
+	    e1 = e1->modifiableLvalue(sc, e1old);
     }
 
     if (e1->op == TOKslice &&
@@ -7930,7 +8134,7 @@
 	ismemset = 1;	// make it easy for back end to tell what this is
 	e2 = e2->implicitCastTo(sc, t1->next);
     }
-    else if (t1->ty == Tsarray)
+    else if (t1->ty == Tsarray && !refinit)
     {
 	error("cannot assign to static array %s", e1->toChars());
     }
@@ -8061,6 +8265,7 @@
 	    typeCombine(sc);
 	    e1->checkArithmetic();
 	    e2->checkArithmetic();
+	    checkComplexAddAssign();
 	    if (type->isreal() || type->isimaginary())
 	    {
 		assert(global.errors || e2->type->isfloating());
@@ -8111,6 +8316,7 @@
     {
 	e1 = e1->checkArithmetic();
 	e2 = e2->checkArithmetic();
+	checkComplexAddAssign();
 	type = e1->type;
 	typeCombine(sc);
 	if (type->isreal() || type->isimaginary())
@@ -8215,6 +8421,7 @@
     typeCombine(sc);
     e1->checkArithmetic();
     e2->checkArithmetic();
+    checkComplexMulAssign();
     if (e2->type->isfloating())
     {	Type *t1;
 	Type *t2;
@@ -8281,6 +8488,7 @@
     typeCombine(sc);
     e1->checkArithmetic();
     e2->checkArithmetic();
+    checkComplexMulAssign();
     if (e2->type->isimaginary())
     {	Type *t1;
 	Type *t2;
@@ -8328,6 +8536,8 @@
 
 Expression *ModAssignExp::semantic(Scope *sc)
 {
+    BinExp::semantic(sc);
+    checkComplexMulAssign();
     return commonSemanticAssign(sc);
 }
 
@@ -8736,10 +8946,10 @@
 	return e;
 
     typeCombine(sc);
-    if (e1->op != TOKslice && e2->op != TOKslice)
-    {	e1->checkArithmetic();
+    if (!e1->isArrayOperand())
+	e1->checkArithmetic();
+    if (!e2->isArrayOperand())
 	e2->checkArithmetic();
-    }
     if (type->isfloating())
     {	Type *t1 = e1->type;
 	Type *t2 = e2->type;
@@ -8802,10 +9012,10 @@
 	return e;
 
     typeCombine(sc);
-    if (e1->op != TOKslice && e2->op != TOKslice)
-    {	e1->checkArithmetic();
+    if (!e1->isArrayOperand())
+	e1->checkArithmetic();
+    if (!e2->isArrayOperand())
 	e2->checkArithmetic();
-    }
     if (type->isfloating())
     {	Type *t1 = e1->type;
 	Type *t2 = e2->type;
@@ -8869,10 +9079,10 @@
 	return e;
 
     typeCombine(sc);
-    if (e1->op != TOKslice && e2->op != TOKslice)
-    {	e1->checkArithmetic();
+    if (!e1->isArrayOperand())
+	e1->checkArithmetic();
+    if (!e2->isArrayOperand())
 	e2->checkArithmetic();
-    }
     if (type->isfloating())
     {	type = e1->type;
 	if (e2->type->iscomplex())
@@ -8983,10 +9193,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    if (e1->op != TOKslice && e2->op != TOKslice)
-	    {   e1->checkIntegral();
+	    if (!e1->isArrayOperand())
+		e1->checkIntegral();
+	    if (!e2->isArrayOperand())
 		e2->checkIntegral();
-	    }
 	}
     }
     return this;
@@ -9016,10 +9226,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    if (e1->op != TOKslice && e2->op != TOKslice)
-	    {   e1->checkIntegral();
+	    if (!e1->isArrayOperand())
+		e1->checkIntegral();
+	    if (!e2->isArrayOperand())
 		e2->checkIntegral();
-	    }
 	}
     }
     return this;
@@ -9049,10 +9259,10 @@
 	else
 	{
 	    typeCombine(sc);
-	    if (e1->op != TOKslice && e2->op != TOKslice)
-	    {   e1->checkIntegral();
+	    if (!e1->isArrayOperand())
+		e1->checkIntegral();
+	    if (!e2->isArrayOperand())
 		e2->checkIntegral();
-	    }
 	}
     }
     return this;
@@ -9254,8 +9464,6 @@
 
 Expression *CmpExp::semantic(Scope *sc)
 {   Expression *e;
-    Type *t1;
-    Type *t2;
 
 #if LOGSEMANTIC
     printf("CmpExp::semantic('%s')\n", toChars());
@@ -9265,8 +9473,10 @@
 
     BinExp::semanticp(sc);
 
-    if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull ||
-	e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull)
+    Type *t1 = e1->type->toBasetype();
+    Type *t2 = e2->type->toBasetype();
+    if (t1->ty == Tclass && e2->op == TOKnull ||
+	t2->ty == Tclass && e1->op == TOKnull)
     {
 	error("do not use null when comparing class types");
     }
@@ -9286,6 +9496,15 @@
 	return e;
     }
 
+    /* Disallow comparing T[]==T and T==T[]
+     */
+    if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) ||
+	e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf()))
+    {
+	incompatibleTypes();
+	return new ErrorExp();
+    }
+
     typeCombine(sc);
     type = Type::tboolean;
 
@@ -9337,8 +9556,6 @@
 
 Expression *EqualExp::semantic(Scope *sc)
 {   Expression *e;
-    Type *t1;
-    Type *t2;
 
     //printf("EqualExp::semantic('%s')\n", toChars());
     if (type)
@@ -9367,8 +9584,10 @@
 	}
     }
 
-    if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull ||
-	e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull)
+    Type *t1 = e1->type->toBasetype();
+    Type *t2 = e2->type->toBasetype();
+    if (t1->ty == Tclass && e2->op == TOKnull ||
+	t2->ty == Tclass && e1->op == TOKnull)
     {
 	error("use '%s' instead of '%s' when comparing with null",
 		Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity),
@@ -9389,6 +9608,15 @@
 	}
     }
 
+    /* Disallow comparing T[]==T and T==T[]
+     */
+    if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) ||
+	e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf()))
+    {
+	incompatibleTypes();
+	return new ErrorExp();
+    }
+
     e = typeCombine(sc);
     type = Type::tboolean;
 
--- a/dmd/expression.h	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/expression.h	Fri Nov 06 23:58:01 2009 +0100
@@ -81,6 +81,11 @@
 Expression *fromConstInitializer(int result, Expression *e);
 int arrayExpressionCanThrow(Expressions *exps);
 
+struct IntRange
+{   uinteger_t imin;
+    uinteger_t imax;
+};
+
 struct Expression : Object
 {
     Loc loc;			// file location
@@ -157,6 +162,7 @@
     // For array ops
     virtual void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
     virtual Expression *buildArrayLoop(Arguments *fparams);
+    int isArrayOperand();
 
 #if IN_DMD
     // Back end
@@ -291,6 +297,7 @@
 struct DsymbolExp : Expression
 {
     Dsymbol *s;
+    int hasOverloads;
 
     DsymbolExp(Loc loc, Dsymbol *s);
     Expression *semantic(Scope *sc);
@@ -306,6 +313,7 @@
 
     ThisExp(Loc loc);
     Expression *semantic(Scope *sc);
+    Expression *interpret(InterState *istate);
     int isBool(int result);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     Expression *toLvalue(Scope *sc, Expression *e);
@@ -343,6 +351,7 @@
     NullExp(Loc loc);
     Expression *semantic(Scope *sc);
     int isBool(int result);
+    int isConst();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     void toMangleBuffer(OutBuffer *buf);
     MATCH implicitConvTo(Type *t);
@@ -591,6 +600,7 @@
 	Type *newtype, Expressions *arguments);
     Expression *syntaxCopy();
     Expression *semantic(Scope *sc);
+    Expression *optimize(int result);
 #if IN_DMD
     elem *toElem(IRState *irs);
 #endif
@@ -842,6 +852,8 @@
     Expression *commonSemanticAssign(Scope *sc);
     Expression *commonSemanticAssignIntegral(Scope *sc);
     int checkSideEffect(int flag);
+    void checkComplexMulAssign();
+    void checkComplexAddAssign();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     Expression *scaleFactor(Scope *sc);
     Expression *typeCombine(Scope *sc);
@@ -1022,6 +1034,7 @@
 #endif
     void scanForNestedRef(Scope *sc);
     Expression *toLvalue(Scope *sc, Expression *e);
+    Expression *modifiableLvalue(Scope *sc, Expression *e);
 
     int inlineCost(InlineCostState *ics);
     Expression *doInline(InlineDoState *ids);
@@ -1182,6 +1195,8 @@
     int checkSideEffect(int flag);
     void checkEscape();
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+    void buildArrayIdent(OutBuffer *buf, Expressions *arguments);
+    Expression *buildArrayLoop(Arguments *fparams);
 #if IN_DMD
     elem *toElem(IRState *irs);
 #endif
--- a/dmd/func.c	Fri Nov 06 21:51:41 2009 +0100
+++ b/dmd/func.c	Fri Nov 06 23:58:01 2009 +0100
@@ -1,3081 +1,3451 @@
-// Compiler implementation of the D programming language
-// Copyright (c) 1999-2008 by Digital Mars
-// All Rights Reserved
-// written by Walter Bright
-// http://www.digitalmars.com
-// License for redistribution is by either the Artistic License
-// in artistic.txt, or the GNU General Public License in gnu.txt.
-// See the included readme.txt for details.
-
-#include <stdio.h>
-#include <assert.h>
-
-#include "mars.h"
-#include "init.h"
-#include "declaration.h"
-#include "attrib.h"
-#include "expression.h"
-#include "scope.h"
-#include "mtype.h"
-#include "aggregate.h"
-#include "identifier.h"
-#include "id.h"
-#include "module.h"
-#include "statement.h"
-#include "template.h"
-#include "hdrgen.h"
-
-#ifdef IN_GCC
-#include "d-dmd-gcc.h"
-#endif
-
-/********************************* FuncDeclaration ****************************/
-
-FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
-    : Declaration(id)
-{
-    //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
-    this->storage_class = storage_class;
-    this->type = type;
-    this->loc = loc;
-    this->endloc = endloc;
-    fthrows = NULL;
-    frequire = NULL;
-    outId = NULL;
-    vresult = NULL;
-    returnLabel = NULL;
-    fensure = NULL;
-    fbody = NULL;
-    localsymtab = NULL;
-    vthis = NULL;
-    v_arguments = NULL;
-#if IN_GCC
-    v_argptr = NULL;
-#endif
-    parameters = NULL;
-    labtab = NULL;
-    overnext = NULL;
-    vtblIndex = -1;
-    hasReturnExp = 0;
-    naked = 0;
-    inlineStatus = ILSuninitialized;
-    inlineNest = 0;
-    inlineAsm = 0;
-    cantInterpret = 0;
-    semanticRun = 0;
-    nestedFrameRef = 0;
-    fes = NULL;
-    introducing = 0;
-    tintro = NULL;
-    /* The type given for "infer the return type" is a TypeFunction with
-     * NULL for the return type.
-     */
-    inferRetType = (type && type->nextOf() == NULL);
-    scope = NULL;
-    hasReturnExp = 0;
-    nrvo_can = 1;
-    nrvo_var = NULL;
-#if IN_DMD
-    shidden = NULL;
-#endif
-
-#if IN_LLVM
-    // LDC
-    isArrayOp = false;
-    allowInlining = false;
-
-    availableExternally = true; // assume this unless proven otherwise
-
-    // function types in ldc don't merge if the context parameter differs
-    // so we actually don't care about the function declaration, but only
-    // what kind of context parameter it has.
-    // however, this constructor is usually called from the parser, which
-    // unfortunately doesn't provide the information needed to get to the
-    // aggregate type. So we have to stick with the FuncDeclaration and
-    // just be sure we don't actually rely on the symbol it points to,
-    // but rather just the type of its context parameter.
-    // this means some function might have a function type pointing to
-    // another function declaration
-
-    if (type)
-    {
-        assert(type->ty == Tfunction && "invalid function type");
-        TypeFunction* tf = (TypeFunction*)type;
-        if (tf->funcdecl == NULL)
-            tf->funcdecl = this;
-    }
-#endif
-}
-
-Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
-{
-    FuncDeclaration *f;
-
-    //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
-    if (s)
-	f = (FuncDeclaration *)s;
-    else
-	f = new FuncDeclaration(loc, endloc, ident, (enum STC) storage_class, type->syntaxCopy());
-    f->outId = outId;
-    f->frequire = frequire ? frequire->syntaxCopy() : NULL;
-    f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
-    f->fbody    = fbody    ? fbody->syntaxCopy()    : NULL;
-    assert(!fthrows); // deprecated
-
-    // LDC
-    f->intrinsicName = intrinsicName;
-
-    return f;
-}
-
-
-// Do the semantic analysis on the external interface to the function.
-
-void FuncDeclaration::semantic(Scope *sc)
-{   TypeFunction *f;
-    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 (isFuncLiteralDeclaration())
-	printf("\tFuncLiteralDeclaration()\n");
-    printf("sc->parent = %s\n", sc->parent->toChars());
-    printf("type: %p, %s\n", type, type->toChars());
-#endif
-
-    if (semanticRun && isFuncLiteralDeclaration())
-    {
-	/* Member functions that have return types that are
-	 * forward references can have semantic() run more than
-	 * once on them.
-	 * See test\interface2.d, test20
-	 */
-	return;
-    }
-    assert(semanticRun <= 1);
-    semanticRun = 1;
-
-    if (type->nextOf())
-	type = type->semantic(loc, sc);
-    //type->print();
-    if (type->ty != Tfunction)
-    {
-	error("%s must be a function", toChars());
-	return;
-    }
-    f = (TypeFunction *)(type);
-    size_t nparams = Argument::dim(f->parameters);
-
-    linkage = sc->linkage;
-//    if (!parent)
-    {
-	//parent = sc->scopesym;
-	parent = sc->parent;
-    }
-    protection = sc->protection;
-    storage_class |= sc->stc;
-    //printf("function storage_class = x%x\n", storage_class);
-    Dsymbol *parent = toParent();
-
-    if (ident == Id::ctor && !isCtorDeclaration())
-	error("_ctor is reserved for constructors");
-
-    if (isConst() || isAuto() || isScope())
-	error("functions cannot be const, auto or scope");
-
-    if (isAbstract() && !isVirtual())
-	error("non-virtual functions cannot be abstract");
-
-    if (isAbstract() && isFinal())
-	error("cannot be both final and abstract");
-#if 0
-    if (isAbstract() && fbody)
-	error("abstract functions cannot have bodies");
-#endif
-
-#if 0
-    if (isStaticConstructor() || isStaticDestructor())
-    {
-	if (!isStatic() || type->nextOf()->ty != Tvoid)
-	    error("static constructors / destructors must be static void");
-	if (f->arguments && f->arguments->dim)
-	    error("static constructors / destructors must have empty parameter list");
-	// BUG: check for invalid storage classes
-    }
-#endif
-
-#ifdef IN_GCC
-    AggregateDeclaration *ad;
-
-    ad = parent->isAggregateDeclaration();
-    if (ad)
-	ad->methods.push(this);
-#endif
-    sd = parent->isStructDeclaration();
-    if (sd)
-    {
-	// Verify no constructors, destructors, etc.
-	if (isCtorDeclaration() ||
-	    isDtorDeclaration()
-	    //|| isInvariantDeclaration()
-	    //|| isUnitTestDeclaration()
-	   )
-	{
-	    error("special member functions not allowed for %ss", sd->kind());
-	}
-
-#if 0
-	if (!sd->inv)
-	    sd->inv = isInvariantDeclaration();
-
-	if (!sd->aggNew)
-	    sd->aggNew = isNewDeclaration();
-
-	if (isDelete())
-	{
-	    if (sd->aggDelete)
-		error("multiple delete's for struct %s", sd->toChars());
-	    sd->aggDelete = (DeleteDeclaration *)(this);
-	}
-#endif
-    }
-
-    id = parent->isInterfaceDeclaration();
-    if (id)
-    {
-	storage_class |= STCabstract;
-
-	if (isCtorDeclaration() ||
-	    isDtorDeclaration() ||
-	    isInvariantDeclaration() ||
-	    isUnitTestDeclaration() || isNewDeclaration() || isDelete())
-	    error("special function not allowed in interface %s", id->toChars());
-	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)
-    {	int vi;
-	CtorDeclaration *ctor;
-	DtorDeclaration *dtor;
-	InvariantDeclaration *inv;
-
-	if (isCtorDeclaration())
-	{
-//	    ctor = (CtorDeclaration *)this;
-//	    if (!cd->ctor)
-//		cd->ctor = ctor;
-	    return;
-	}
-
-#if 0
-	dtor = isDtorDeclaration();
-	if (dtor)
-	{
-	    if (cd->dtor)
-		error("multiple destructors for class %s", cd->toChars());
-	    cd->dtor = dtor;
-	}
-
-	inv = isInvariantDeclaration();
-	if (inv)
-	{
-	    cd->inv = inv;
-	}
-
-	if (isNewDeclaration())
-	{
-	    if (!cd->aggNew)
-		cd->aggNew = (NewDeclaration *)(this);
-	}
-
-	if (isDelete())
-	{
-	    if (cd->aggDelete)
-		error("multiple delete's for class %s", cd->toChars());
-	    cd->aggDelete = (DeleteDeclaration *)(this);
-	}
-#endif
-
-	if (storage_class & STCabstract)
-	    cd->isabstract = 1;
-
-	// if static function, do not put in vtbl[]
-	if (!isVirtual())
-	{
-	    //printf("\tnot virtual\n");
-	    goto Ldone;
-	}
-
-	// Find index of existing function in vtbl[] to override
-	vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0);
-	switch (vi)
-	{
-	    case -1:
-		/* Didn't find one, so
-		 * This is an 'introducing' function which gets a new
-		 * slot in the vtbl[].
-		 */
-
-		// Verify this doesn't override previous final function
-		if (cd->baseClass)
-		{   Dsymbol *s = cd->baseClass->search(loc, ident, 0);
-		    if (s)
-		    {
-			FuncDeclaration *f = s->isFuncDeclaration();
-			f = f->overloadExactMatch(type, getModule());
-			if (f && f->isFinal() && f->prot() != PROTprivate)
-			    error("cannot override final function %s", f->toPrettyChars());
-		    }
-		}
-
-		if (isFinal())
-		{
-		    if (isOverride())
-			error("does not override any function");
-		    cd->vtblFinal.push(this);
-		}
-		else
-		{
-		    // Append to end of vtbl[]
-		    //printf("\tintroducing function\n");
-		    introducing = 1;
-		    vi = cd->vtbl.dim;
-		    cd->vtbl.push(this);
-		    vtblIndex = vi;
-		}
-		break;
-
-	    case -2:	// can't determine because of fwd refs
-		cd->sizeok = 2;	// can't finish due to forward reference
-		return;
-
-	    default:
-	    {   FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi];
-		// This function is covariant with fdv
-		if (fdv->isFinal())
-		    error("cannot override final function %s", fdv->toPrettyChars());
-
-#if DMDV2
-		if (!isOverride())
-		    warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
-#endif
-
-		if (fdv->toParent() == parent)
-		{
-		    // If both are mixins, then error.
-		    // If either is not, the one that is not overrides
-		    // the other.
-		    if (fdv->parent->isClassDeclaration())
-			break;
-		    if (!this->parent->isClassDeclaration()
-#if !BREAKABI
-			&& !isDtorDeclaration()
-#endif
-#if DMDV2
-			&& !isPostBlitDeclaration()
-#endif
-			)
-			error("multiple overrides of same function");
-		}
-		cd->vtbl.data[vi] = (void *)this;
-		vtblIndex = vi;
-
-		/* This works by whenever this function is called,
-		 * it actually returns tintro, which gets dynamically
-		 * cast to type. But we know that tintro is a base
-		 * of type, so we could optimize it by not doing a
-		 * dynamic cast, but just subtracting the isBaseOf()
-		 * offset if the value is != null.
-		 */
-
-		if (fdv->tintro)
-		    tintro = fdv->tintro;
-		else if (!type->equals(fdv->type))
-		{
-		    /* Only need to have a tintro if the vptr
-		     * offsets differ
-		     */
-		    int offset;
-		    if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
-		    {
-			tintro = fdv->type;
-		    }
-		}
-		break;
-	    }
-	}
-
-	/* Go through all the interface bases.
-	 * If this function is covariant with any members of those interface
-	 * functions, set the tintro.
-	 */
-	for (int i = 0; i < cd->interfaces_dim; i++)
-	{
-#if 1
-	    BaseClass *b = cd->interfaces[i];
-	    vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim);
-	    switch (vi)
-	    {
-		case -1:
-		    break;
-
-		case -2:
-		    cd->sizeok = 2;	// can't finish due to forward reference
-		    return;
-
-		default:
-		{   FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi];
-		    Type *ti = NULL;
-
-		    if (fdv->tintro)
-			ti = fdv->tintro;
-		    else if (!type->equals(fdv->type))
-		    {
-			/* Only need to have a tintro if the vptr
-			 * offsets differ
-			 */
-			int offset;
-			if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
-			{
-			    ti = fdv->type;
-#if 0
-			    if (offset)
-				ti = fdv->type;
-			    else if (type->nextOf()->ty == Tclass)
-			    {   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
-				if (cdn && cdn->sizeok != 1)
-				    ti = fdv->type;
-			    }
-#endif
-			}
-		    }
-		    if (ti)
-		    {
-			if (tintro && !tintro->equals(ti))
-			{
-			    error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
-			}
-			tintro = ti;
-		    }
-		    goto L2;
-		}
-	    }
-#else
-	    BaseClass *b = cd->interfaces[i];
-	    for (vi = 0; vi < b->base->vtbl.dim; vi++)
-	    {
-		Dsymbol *s = (Dsymbol *)b->base->vtbl.data[vi];
-		//printf("interface %d vtbl[%d] %p %s\n", i, vi, s, s->toChars());
-		FuncDeclaration *fdv = s->isFuncDeclaration();
-		if (fdv && fdv->ident == ident)
-		{
-		    int cov = type->covariant(fdv->type);
-		    //printf("\tcov = %d\n", cov);
-		    if (cov == 2)
-		    {
-			//type->print();
-			//fdv->type->print();
-			//printf("%s %s\n", type->deco, fdv->type->deco);
-			error("of type %s overrides but is not covariant with %s of type %s",
-			    type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
-		    }
-		    if (cov == 1)
-		    {	Type *ti = NULL;
-
-			if (fdv->tintro)
-			    ti = fdv->tintro;
-			else if (!type->equals(fdv->type))
-			{
-			    /* Only need to have a tintro if the vptr
-			     * offsets differ
-			     */
-			    int offset;
-			    if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
-			    {
-				ti = fdv->type;
-#if 0
-				if (offset)
-				    ti = fdv->type;
-				else if (type->nextOf()->ty == Tclass)
-				{   ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
-				    if (cdn && cdn->sizeok != 1)
-					ti = fdv->type;
-				}
-#endif
-			    }
-			}
-			if (ti)
-			{
-			    if (tintro && !tintro->equals(ti))
-			    {
-				error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
-			    }
-			    tintro = ti;
-			}
-			goto L2;
-		    }
-		    if (cov == 3)
-		    {
-			cd->sizeok = 2;	// can't finish due to forward reference
-			return;
-		    }
-		}
-	    }
-#endif
-	}
-
-	if (introducing && isOverride())
-	{
-	    error("does not override any function");
-	}
-
-    L2: ;
-    }
-    else if (isOverride() && !parent->isTemplateInstance())
-	error("override only applies to class member functions");
-
-    /* Do not allow template instances to add virtual functions
-     * to a class.
-     */
-    if (isVirtual())
-    {
-	TemplateInstance *ti = parent->isTemplateInstance();
-	if (ti)
-	{
-	    // Take care of nested templates
-	    while (1)
-	    {
-		TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance();
-		if (!ti2)
-		    break;
-		ti = ti2;
-	    }
-
-	    // If it's a member template
-	    ClassDeclaration *cd = ti->tempdecl->isClassMember();
-	    if (cd)
-	    {
-		error("cannot use template to add virtual function to class '%s'", cd->toChars());
-	    }
-	}
-    }
-
-    if (isMain())
-    {
-	// Check parameters to see if they are either () or (char[][] args)
-	switch (nparams)
-	{
-	    case 0:
-		break;
-
-	    case 1:
-	    {
-		Argument *arg0 = Argument::getNth(f->parameters, 0);
-		if (arg0->type->ty != Tarray ||
-		    arg0->type->nextOf()->ty != Tarray ||
-		    arg0->type->nextOf()->nextOf()->ty != Tchar ||
-		    arg0->storageClass & (STCout | STCref | STClazy))
-		    goto Lmainerr;
-		break;
-	    }
-
-	    default:
-		goto Lmainerr;
-	}
-
-	if (f->nextOf()->ty != Tint32 && f->nextOf()->ty != Tvoid)
-	    error("must return int or void, not %s", f->nextOf()->toChars());
-	if (f->varargs)
-	{
-	Lmainerr:
-	    error("parameters must be main() or main(char[][] args)");
-	}
-    }
-
-    if (ident == Id::assign && (sd || cd))
-    {	// Disallow identity assignment operator.
-
-	// opAssign(...)
-	if (nparams == 0)
-	{   if (f->varargs == 1)
-		goto Lassignerr;
-	}
-	else
-	{
-	    Argument *arg0 = Argument::getNth(f->parameters, 0);
-	    Type *t0 = arg0->type->toBasetype();
-	    Type *tb = sd ? sd->type : cd->type;
-	    if (arg0->type->implicitConvTo(tb) ||
-		(sd && t0->ty == Tpointer && t0->nextOf()->implicitConvTo(tb))
-	       )
-	    {
-		if (nparams == 1)
-		    goto Lassignerr;
-		Argument *arg1 = Argument::getNth(f->parameters, 1);
-		if (arg1->defaultArg)
-		    goto Lassignerr;
-	    }
-	}
-    }
-
-Ldone:
-    /* Save scope for possible later use (if we need the
-     * function internals)
-     */
-    scope = new Scope(*sc);
-    scope->setNoFree();
-    return;
-
-Lassignerr:
-    error("identity assignment operator overload is illegal");
-}
-
-void FuncDeclaration::semantic2(Scope *sc)
-{
-}
-
-// Do the semantic analysis on the internals of the function.
-
-void FuncDeclaration::semantic3(Scope *sc)
-{   TypeFunction *f;
-    AggregateDeclaration *ad;
-    VarDeclaration *argptr = NULL;
-    VarDeclaration *_arguments = NULL;
-
-    if (!parent)
-    {
-	if (global.errors)
-	    return;
-	//printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
-	assert(0);
-    }
-    //printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
-    //fflush(stdout);
-    //{ static int x; if (++x == 2) *(char*)0=0; }
-    //printf("\tlinkage = %d\n", sc->linkage);
-
-    //printf(" sc->incontract = %d\n", sc->incontract);
-    if (semanticRun >= 3)
-	return;
-    semanticRun = 3;
-
-    // LDC
-    if (!global.params.useAvailableExternally)
-        availableExternally = false;
-
-    if (!type || type->ty != Tfunction)
-	return;
-    f = (TypeFunction *)(type);
-    size_t nparams = Argument::dim(f->parameters);
-
-    // Check the 'throws' clause
-    if (fthrows)
-    {
-	for (int i = 0; i < fthrows->dim; i++)
-	{
-	    Type *t = (Type *)fthrows->data[i];
-
-	    t = t->semantic(loc, sc);
-	    if (!t->isClassHandle())
-		error("can only throw classes, not %s", t->toChars());
-	}
-    }
-
-    if (fbody || frequire)
-    {
-	/* Symbol table into which we place parameters and nested functions,
-	 * solely to diagnose name collisions.
-	 */
-	localsymtab = new DsymbolTable();
-
-	// Establish function scope
-	ScopeDsymbol *ss = new ScopeDsymbol();
-	ss->parent = sc->scopesym;
-	Scope *sc2 = sc->push(ss);
-	sc2->func = this;
-	sc2->parent = this;
-	sc2->callSuper = 0;
-	sc2->sbreak = NULL;
-	sc2->scontinue = NULL;
-	sc2->sw = NULL;
-	sc2->fes = fes;
-	sc2->linkage = LINKd;
-	sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCfinal);
-	sc2->protection = PROTpublic;
-	sc2->explicitProtection = 0;
-	sc2->structalign = 8;
-	sc2->incontract = 0;
-	sc2->enclosingFinally = NULL;
-	sc2->enclosingScopeExit = NULL;
-	sc2->noctor = 0;
-
-	// Declare 'this'
-	ad = isThis();
-	if (ad)
-	{   VarDeclaration *v;
-
-	    if (isFuncLiteralDeclaration() && isNested())
-	    {
-		error("literals cannot be class members");
-		return;
-	    }
-	    else
-	    {
-		assert(!isNested());	// can't be both member and nested
-		assert(ad->handle);
-		v = new ThisDeclaration(loc, ad->handle);
-		v->storage_class |= STCparameter | STCin;
-		v->semantic(sc2);
-		if (!sc2->insert(v))
-		    assert(0);
-		v->parent = this;
-		vthis = v;
-	    }
-	}
-	else if (isNested())
-	{
-	    /* The 'this' for a nested function is the link to the
-	     * enclosing function's stack frame.
-	     * Note that nested functions and member functions are disjoint.
-	     */
-	    VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo());
-	    v->storage_class |= STCparameter | STCin;
-	    v->semantic(sc2);
-	    if (!sc2->insert(v))
-		assert(0);
-	    v->parent = this;
-	    vthis = v;
-	}
-
-	// Declare hidden variable _arguments[] and _argptr
-	if (f->varargs == 1)
-	{   Type *t;
-
-	    if (f->linkage == LINKd)
-	    {	// Declare _arguments[]
-#if BREAKABI
-		v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
-		v_arguments->storage_class = STCparameter | STCin;
-		v_arguments->semantic(sc2);
-		sc2->insert(v_arguments);
-		v_arguments->parent = this;
-
-		t = Type::typeinfo->type->arrayOf();
-		_arguments = new VarDeclaration(0, t, Id::_arguments, NULL);
-		_arguments->semantic(sc2);
-		sc2->insert(_arguments);
-		_arguments->parent = this;
-#else
-		t = Type::typeinfo->type->arrayOf();
-		v_arguments = new VarDeclaration(0, t, Id::_arguments, NULL);
-		v_arguments->storage_class = STCparameter | STCin;
-		v_arguments->semantic(sc2);
-		sc2->insert(v_arguments);
-		v_arguments->parent = this;
-#endif
-	    }
-	    if (f->linkage == LINKd || (parameters && parameters->dim))
-	    {	// Declare _argptr
-#if IN_GCC
-		t = d_gcc_builtin_va_list_d_type;
-#else
-		t = Type::tvoid->pointerTo();
-#endif
-		argptr = new VarDeclaration(0, t, Id::_argptr, NULL);
-		argptr->semantic(sc2);
-		sc2->insert(argptr);
-		argptr->parent = this;
-	    }
-	}
-
-#if IN_LLVM
-        // LDC make sure argument type is semanticed.
-        // Turns TypeTuple!(int, int) into two int parameters, for instance.
-        if (f->parameters)
-        {
-            for (size_t i = 0; i < Argument::dim(f->parameters); i++)
-	    {	Argument *arg = (Argument *)Argument::getNth(f->parameters, i);
-                Type* nw = arg->type->semantic(0, sc);
-                if (arg->type != nw) {
-                    arg->type = nw;
-                    // Examine this index again.
-                    // This is important if it turned into a tuple.
-                    // In particular, the empty tuple should be handled or the
-                    // next parameter will be skipped.
-                    // FIXME: Maybe we only need to do this for tuples,
-                    //        and can add tuple.length after decrement?
-                    i--;
-                }
-            }
-            // update nparams to include expanded tuples
-            nparams = Argument::dim(f->parameters);
-        }
-#endif
-
-	// Propagate storage class from tuple parameters to their element-parameters.
-	if (f->parameters)
-	{
-	    for (size_t i = 0; i < f->parameters->dim; i++)
-	    {	Argument *arg = (Argument *)f->parameters->data[i];
-
-		if (arg->type->ty == Ttuple)
-		{   TypeTuple *t = (TypeTuple *)arg->type;
-		    size_t dim = Argument::dim(t->arguments);
-		    for (size_t j = 0; j < dim; j++)
-		    {	Argument *narg = Argument::getNth(t->arguments, j);
-			narg->storageClass = arg->storageClass;
-		    }
-		}
-	    }
-	}
-
-	// Declare all the function parameters as variables
-	if (nparams)
-	{   /* parameters[] has all the tuples removed, as the back end
-	     * doesn't know about tuples
-	     */
-	    parameters = new Dsymbols();
-	    parameters->reserve(nparams);
-	    for (size_t i = 0; i < nparams; i++)
-	    {
-		Argument *arg = Argument::getNth(f->parameters, i);
-		Identifier *id = arg->ident;
-		if (!id)
-		{
-		    /* Generate identifier for un-named parameter,
-		     * because we need it later on.
-		     */
-		    arg->ident = id = Identifier::generateId("_param_", i);
-		}
-		VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL);
-		//printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
-		v->storage_class |= STCparameter;
-		if (f->varargs == 2 && i + 1 == nparams)
-		    v->storage_class |= STCvariadic;
-		v->storage_class |= arg->storageClass & (STCin | STCout | STCref | STClazy);
-		if (v->storage_class & STClazy)
-		    v->storage_class |= STCin;
-		v->semantic(sc2);
-		if (!sc2->insert(v))
-		    error("parameter %s.%s is already defined", toChars(), v->toChars());
-		else
-		    parameters->push(v);
-		localsymtab->insert(v);
-		v->parent = this;
-	    }
-	}
-
-	// Declare the tuple symbols and put them in the symbol table,
-	// but not in parameters[].
-	if (f->parameters)
-	{
-	    for (size_t i = 0; i < f->parameters->dim; i++)
-	    {	Argument *arg = (Argument *)f->parameters->data[i];
-
-		if (!arg->ident)
-		    continue;			// never used, so ignore
-		if (arg->type->ty == Ttuple)
-		{   TypeTuple *t = (TypeTuple *)arg->type;
-		    size_t dim = Argument::dim(t->arguments);
-		    Objects *exps = new Objects();
-		    exps->setDim(dim);
-		    for (size_t j = 0; j < dim; j++)
-		    {	Argument *narg = Argument::getNth(t->arguments, j);
-			assert(narg->ident);
-			VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration();
-			assert(v);
-			Expression *e = new VarExp(v->loc, v);
-			exps->data[j] = (void *)e;
-		    }
-		    assert(arg->ident);
-		    TupleDeclaration *v = new TupleDeclaration(loc, arg->ident, exps);
-		    //printf("declaring tuple %s\n", v->toChars());
-		    v->isexp = 1;
-		    if (!sc2->insert(v))
-			error("parameter %s.%s is already defined", toChars(), v->toChars());
-		    localsymtab->insert(v);
-		    v->parent = this;
-		}
-	    }
-	}
-
-	/* Do the semantic analysis on the [in] preconditions and
-	 * [out] postconditions.
-	 */
-	sc2->incontract++;
-
-	if (frequire)
-	{   /* frequire is composed of the [in] contracts
-	     */
-	    // BUG: need to error if accessing out parameters
-	    // BUG: need to treat parameters as const
-	    // BUG: need to disallow returns and throws
-	    // BUG: verify that all in and ref parameters are read
-	    frequire = frequire->semantic(sc2);
-	    labtab = NULL;		// so body can't refer to labels
-	}
-
-	if (fensure || addPostInvariant())
-	{   /* fensure is composed of the [out] contracts
-	     */
-	    ScopeDsymbol *sym = new ScopeDsymbol();
-	    sym->parent = sc2->scopesym;
-	    sc2 = sc2->push(sym);
-
-	    assert(type->nextOf());
-	    if (type->nextOf()->ty == Tvoid)
-	    {
-		if (outId)
-		    error("void functions have no result");
-	    }
-	    else
-	    {
-		if (!outId)
-		    outId = Id::result;		// provide a default
-	    }
-
-	    if (outId)
-	    {	// Declare result variable
-		VarDeclaration *v;
-		Loc loc = this->loc;
-
-		if (fensure)
-		    loc = fensure->loc;
-
-		v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
-		v->noscope = 1;
-		sc2->incontract--;
-		v->semantic(sc2);
-		sc2->incontract++;
-		if (!sc2->insert(v))
-		    error("out result %s is already defined", v->toChars());
-		v->parent = this;
-		vresult = v;
-
-		// vresult gets initialized with the function return value
-		// in ReturnStatement::semantic()
-	    }
-
-	    // BUG: need to treat parameters as const
-	    // BUG: need to disallow returns and throws
-	    if (fensure)
-	    {	fensure = fensure->semantic(sc2);
-		labtab = NULL;		// so body can't refer to labels
-	    }
-
-	    if (!global.params.useOut)
-	    {	fensure = NULL;		// discard
-		vresult = NULL;
-	    }
-
-	    // Postcondition invariant
-	    if (addPostInvariant())
-	    {
-		Expression *e = NULL;
-		if (isCtorDeclaration())
-		{
-		    // Call invariant directly only if it exists
-		    InvariantDeclaration *inv = ad->inv;
-		    ClassDeclaration *cd = ad->isClassDeclaration();
-
-		    while (!inv && cd)
-		    {
-			cd = cd->baseClass;
-			if (!cd)
-			    break;
-			inv = cd->inv;
-		    }
-		    if (inv)
-		    {
-			e = new DsymbolExp(0, inv);
-			e = new CallExp(0, e);
-			e = e->semantic(sc2);
-		    }
-		}
-		else
-		{   // Call invariant virtually
-		    ThisExp *v = new ThisExp(0);
-		    v->type = vthis->type;
-		    e = new AssertExp(0, v);
-		}
-		if (e)
-		{
-		    ExpStatement *s = new ExpStatement(0, e);
-		    if (fensure)
-			fensure = new CompoundStatement(0, s, fensure);
-		    else
-			fensure = s;
-		}
-	    }
-
-	    if (fensure)
-	    {	returnLabel = new LabelDsymbol(Id::returnLabel);
-		LabelStatement *ls = new LabelStatement(0, Id::returnLabel, fensure);
-		ls->isReturnLabel = 1;
-		returnLabel->statement = ls;
-	    }
-	    sc2 = sc2->pop();
-	}
-
-	sc2->incontract--;
-
-	if (fbody)
-	{   ClassDeclaration *cd = isClassMember();
-
-	    /* If this is a class constructor
-	     */
-	    if (isCtorDeclaration() && cd)
-	    {
-		for (int i = 0; i < cd->fields.dim; i++)
-		{   VarDeclaration *v = (VarDeclaration *)cd->fields.data[i];
-
-		    v->ctorinit = 0;
-		}
-	    }
-
-	    if (inferRetType || f->retStyle() != RETstack)
-		nrvo_can = 0;
-
-	    fbody = fbody->semantic(sc2);
-
-	    if (inferRetType)
-	    {	// If no return type inferred yet, then infer a void
-		if (!type->nextOf())
-		{
-		    ((TypeFunction *)type)->next = Type::tvoid;
-		    type = type->semantic(loc, sc);
-		}
-		f = (TypeFunction *)type;
-	    }
-
-	    int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE;
-
-	    if (isStaticCtorDeclaration())
-	    {	/* It's a static constructor. Ensure that all
-		 * ctor consts were initialized.
-		 */
-
-		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();
-		    }
-		}
-	    }
-
-	    if (isCtorDeclaration() && cd)
-	    {
-		//printf("callSuper = x%x\n", sc2->callSuper);
-
-		// Verify that all the ctorinit fields got initialized
-		if (!(sc2->callSuper & CSXthis_ctor))
-		{
-		    for (int i = 0; i < cd->fields.dim; i++)
-		    {   VarDeclaration *v = (VarDeclaration *)cd->fields.data[i];
-
-			if (v->ctorinit == 0 && v->isCtorinit())
-			    error("missing initializer for const field %s", v->toChars());
-		    }
-		}
-
-		if (!(sc2->callSuper & CSXany_ctor) &&
-		    cd->baseClass && cd->baseClass->ctor)
-		{
-		    sc2->callSuper = 0;
-
-		    // Insert implicit super() at start of fbody
-		    Expression *e1 = new SuperExp(0);
-		    Expression *e = new CallExp(0, e1);
-
-		    unsigned errors = global.errors;
-		    global.gag++;
-		    e = e->semantic(sc2);
-		    global.gag--;
-		    if (errors != global.errors)
-			error("no match for implicit super() call in constructor");
-
-		    Statement *s = new ExpStatement(0, e);
-		    fbody = new CompoundStatement(0, s, fbody);
-		}
-	    }
-	    else if (fes)
-	    {	// For foreach(){} body, append a return 0;
-		Expression *e = new IntegerExp(0);
-		Statement *s = new ReturnStatement(0, e);
-		fbody = new CompoundStatement(0, fbody, s);
-		assert(!returnLabel);
-	    }
-	    else if (!hasReturnExp && type->nextOf()->ty != Tvoid)
-		error("expected to return a value of type %s", type->nextOf()->toChars());
-	    else if (!inlineAsm)
-	    {
-		if (type->nextOf()->ty == Tvoid)
-		{
-		    if (offend && isMain())
-		    {	// Add a return 0; statement
-			Statement *s = new ReturnStatement(0, new IntegerExp(0));
-			fbody = new CompoundStatement(0, fbody, s);
-		    }
-		}
-		else
-		{
-		    if (offend)
-		    {   Expression *e;
-
-			warning(loc, "no return at end of function");
-
-			if (global.params.useAssert &&
-			    !global.params.useInline)
-			{   /* Add an assert(0, msg); where the missing return
-			     * should be.
-			     */
-			    e = new AssertExp(
-				  endloc,
-				  new IntegerExp(0),
-				  new StringExp(loc, (char *)"missing return expression")
-				);
-			}
-			else
-			    e = new HaltExp(endloc);
-			e = new CommaExp(0, e, type->nextOf()->defaultInit());
-			e = e->semantic(sc2);
-			Statement *s = new ExpStatement(0, e);
-			fbody = new CompoundStatement(0, fbody, s);
-		    }
-		}
-	    }
-	}
-
-	{
-	    Statements *a = new Statements();
-
-	    // Merge in initialization of 'out' parameters
-	    if (parameters)
-	    {	for (size_t i = 0; i < parameters->dim; i++)
-		{
-		    VarDeclaration *v = (VarDeclaration *)parameters->data[i];
-		    if (v->storage_class & STCout)
-		    {
-			assert(v->init);
-			ExpInitializer *ie = v->init->isExpInitializer();
-			assert(ie);
-			a->push(new ExpStatement(0, ie->exp));
-		    }
-		}
-	    }
-
-// we'll handle variadics ourselves
-#if !IN_LLVM
-	    if (argptr)
-	    {	// Initialize _argptr to point past non-variadic arg
-#if IN_GCC
-		// Handled in FuncDeclaration::toObjFile
-		v_argptr = argptr;
-		v_argptr->init = new VoidInitializer(loc);
-#else
-		Expression *e1;
-		Expression *e;
-		Type *t = argptr->type;
-		VarDeclaration *p;
-		unsigned offset;
-
-		e1 = new VarExp(0, argptr);
-		if (parameters && parameters->dim)
-		    p = (VarDeclaration *)parameters->data[parameters->dim - 1];
-		else
-		    p = v_arguments;		// last parameter is _arguments[]
-		offset = p->type->size();
-		offset = (offset + 3) & ~3;	// assume stack aligns on 4
-		e = new SymOffExp(0, p, offset);
-		e = new AssignExp(0, e1, e);
-		e->type = t;
-		a->push(new ExpStatement(0, e));
-#endif // IN_GCC
-	    }
-
-	    if (_arguments)
-	    {
-		/* Advance to elements[] member of TypeInfo_Tuple with:
-		 *  _arguments = v_arguments.elements;
-		 */
-		Expression *e = new VarExp(0, v_arguments);
-		e = new DotIdExp(0, e, Id::elements);
-		Expression *e1 = new VarExp(0, _arguments);
-		e = new AssignExp(0, e1, e);
-		e = e->semantic(sc);
-		a->push(new ExpStatement(0, e));
-	    }
-
-#endif // !IN_LLVM
-
-	    // Merge contracts together with body into one compound statement
-
-#ifdef _DH
-	    if (frequire && global.params.useIn)
-	    {	frequire->incontract = 1;
-		a->push(frequire);
-	    }
-#else
-	    if (frequire && global.params.useIn)
-		a->push(frequire);
-#endif
-
-	    // Precondition invariant
-	    if (addPreInvariant())
-	    {
-		Expression *e = NULL;
-                Expression *ee = NULL;
-		if (isDtorDeclaration())
-		{
-		    // Call invariant directly only if it exists
-		    InvariantDeclaration *inv = ad->inv;
-		    ClassDeclaration *cd = ad->isClassDeclaration();
-
-		    while (!inv && cd)
-		    {
-			cd = cd->baseClass;
-			if (!cd)
-			    break;
-			inv = cd->inv;
-		    }
-		    if (inv)
-		    {
-			e = new DsymbolExp(0, inv);
-			e = new CallExp(0, e);
-			e = e->semantic(sc2);
-		    }
-		}
-		else
-		{   // Call invariant virtually
-                    // LDC: unless this is a struct without invariant
-                    StructDeclaration* sd = ad->isStructDeclaration();
-                    if (!sd || sd->inv)
-                    {
-                        ThisExp *v = new ThisExp(0);
-                        v->type = vthis->type;
-                        e = new AssertExp(loc, v, NULL);
-                    }
-
-                    // LDC: check for null this
-                    ThisExp* v = new ThisExp(0);
-                    v->type = vthis->type;
-                    v->var = vthis;
-
-                    NullExp *nv = new NullExp(0);
-                    nv->type = v->type;
-
-                    IdentityExp *ie = new IdentityExp(TOKnotidentity, 0, v, nv);
-                    ie->type = Type::tbool;
-
-		    Expression *se = new StringExp(0, (char *)"null this");
-		    se = se->semantic(sc);
-		    se->type = Type::tchar->arrayOf();
-
-		    ee = new AssertExp(loc, ie, se);
-		}
-                if (ee)
-                {
-                    ExpStatement *s = new ExpStatement(0, ee);
-                    a->push(s);
-                }
-		if (e)
-		{
-		    ExpStatement *s = new ExpStatement(0, e);
-		    a->push(s);
-		}
-	    }
-
-	    if (fbody)
-		a->push(fbody);
-
-	    if (fensure)
-	    {
-		a->push(returnLabel->statement);
-
-		if (type->nextOf()->ty != Tvoid)
-		{
-		    // Create: return vresult;
-		    assert(vresult);
-		    Expression *e = new VarExp(0, vresult);
-		    if (tintro)
-		    {	e = e->implicitCastTo(sc, tintro->nextOf());
-			e = e->semantic(sc);
-		    }
-		    ReturnStatement *s = new ReturnStatement(0, e);
-		    a->push(s);
-		}
-	    }
-
-	    fbody = new CompoundStatement(0, a);
-
-	    // wrap body of synchronized functions in a synchronized statement
-	    if (isSynchronized())
-	    {
-		ClassDeclaration *cd = parent->isClassDeclaration();
-		if (!cd)
-		    error("synchronized function %s must be a member of a class", toChars());
-		    
-		Expression *sync;
-		if (isStatic())
-		{
-		    // static member functions synchronize on classinfo 
-		    sync = cd->type->dotExp(sc2, new TypeExp(loc, cd->type), Id::classinfo);
-		}
-		else
-		{
-		    // non-static member functions synchronize on this
-		    sync = new VarExp(loc, vthis);
-		}
-                
-		// we do not want to rerun semantics on the whole function, so we
-		// manually adjust all labels in the function that currently don't
-		// have an enclosingScopeExit to use the new SynchronizedStatement
-		SynchronizedStatement* s = new SynchronizedStatement(loc, sync, NULL);
-		s->semantic(sc2);
-		s->body = fbody;
-		
-		// LDC
-		LabelMap::iterator it, end = labmap.end();
-		for (it = labmap.begin(); it != end; ++it)
-		    if (it->second->enclosingScopeExit == NULL)
-			it->second->enclosingScopeExit = s;
-		
-		a = new Statements;
-		a->push(s);
-		fbody = new CompoundStatement(0, a);
-	    }
-	}
-
-	sc2->callSuper = 0;
-	sc2->pop();
-    }
-    semanticRun = 4;
-}
-
-void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars());
-
-    type->toCBuffer(buf, ident, hgs);
-    bodyToCBuffer(buf, hgs);
-}
-
-
-void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    if (fbody &&
-	(!hgs->hdrgen || hgs->tpltMember || canInline(1,1))
-       )
-    {	buf->writenl();
-
-	// in{}
-	if (frequire)
-	{   buf->writestring("in");
-	    buf->writenl();
-	    frequire->toCBuffer(buf, hgs);
-	}
-
-	// out{}
-	if (fensure)
-	{   buf->writestring("out");
-	    if (outId)
-	    {   buf->writebyte('(');
-		buf->writestring(outId->toChars());
-		buf->writebyte(')');
-	    }
-	    buf->writenl();
-	    fensure->toCBuffer(buf, hgs);
-	}
-
-        if (frequire || fensure)
-	{   buf->writestring("body");
-	    buf->writenl();
-	}
-
-	buf->writebyte('{');
-	buf->writenl();
-	fbody->toCBuffer(buf, hgs);
-	buf->writebyte('}');
-	buf->writenl();
-    }
-    else
-    {	buf->writeByte(';');
-	buf->writenl();
-    }
-}
-
-/****************************************************
- * Determine if 'this' overrides fd.
- * Return !=0 if it does.
- */
-
-int FuncDeclaration::overrides(FuncDeclaration *fd)
-{   int result = 0;
-
-    if (fd->ident == ident)
-    {
-	int cov = type->covariant(fd->type);
-	if (cov)
-	{   ClassDeclaration *cd1 = toParent()->isClassDeclaration();
-	    ClassDeclaration *cd2 = fd->toParent()->isClassDeclaration();
-
-	    if (cd1 && cd2 && cd2->isBaseOf(cd1, NULL))
-		result = 1;
-	}
-    }
-    return result;
-}
-
-/*************************************************
- * Find index of function in vtbl[0..dim] that
- * this function overrides.
- * Returns:
- *	-1	didn't find one
- *	-2	can't determine because of forward references
- */
-
-int FuncDeclaration::findVtblIndex(Array *vtbl, int dim)
-{
-    for (int vi = 0; vi < dim; vi++)
-    {
-	FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration();
-	if (fdv && fdv->ident == ident)
-	{
-	    int cov = type->covariant(fdv->type);
-	    //printf("\tbaseclass cov = %d\n", cov);
-	    switch (cov)
-	    {
-		case 0:		// types are distinct
-		    break;
-
-		case 1:
-		    return vi;
-
-		case 2:
-		    //type->print();
-		    //fdv->type->print();
-		    //printf("%s %s\n", type->deco, fdv->type->deco);
-		    error("of type %s overrides but is not covariant with %s of type %s",
-			type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
-		    break;
-
-		case 3:
-		    return -2;	// forward references
-
-		default:
-		    assert(0);
-	    }
-	}
-    }
-    return -1;
-}
-
-/****************************************************
- * Overload this FuncDeclaration with the new one f.
- * Return !=0 if successful; i.e. no conflict.
- */
-
-int FuncDeclaration::overloadInsert(Dsymbol *s)
-{
-    FuncDeclaration *f;
-    AliasDeclaration *a;
-
-    //printf("FuncDeclaration::overloadInsert(%s)\n", s->toChars());
-    a = s->isAliasDeclaration();
-    if (a)
-    {
-	if (overnext)
-	    return overnext->overloadInsert(a);
-	if (!a->aliassym && a->type->ty != Tident && a->type->ty != Tinstance)
-	{
-	    //printf("\ta = '%s'\n", a->type->toChars());
-	    return FALSE;
-	}
-	overnext = a;
-	//printf("\ttrue: no conflict\n");
-	return TRUE;
-    }
-    f = s->isFuncDeclaration();
-    if (!f)
-	return FALSE;
-
-    if (type && f->type &&	// can be NULL for overloaded constructors
-	f->type->covariant(type) &&
-	!isFuncAliasDeclaration())
-    {
-	//printf("\tfalse: conflict %s\n", kind());
-	return FALSE;
-    }
-
-    if (overnext)
-	return overnext->overloadInsert(f);
-    overnext = f;
-    //printf("\ttrue: no conflict\n");
-    return TRUE;
-}
-
-/********************************************
- * Find function in overload list that exactly matches t.
- */
-
-/***************************************************
- * Visit each overloaded function in turn, and call
- * (*fp)(param, f) on it.
- * Exit when no more, or (*fp)(param, f) returns 1.
- * Returns:
- *	0	continue
- *	1	done
- */
-
-int overloadApply(Module* from, FuncDeclaration *fstart,
-	int (*fp)(void *, FuncDeclaration *),
-	void *param)
-{
-    FuncDeclaration *f;
-    Declaration *d;
-    Declaration *next;
-
-    for (d = fstart; d; d = next)
-    {	FuncAliasDeclaration *fa = d->isFuncAliasDeclaration();
-
-	if (fa)
-	{
-	    if (fa->getModule() == from || fa->importprot != PROTprivate)
-		if (overloadApply(from, fa->funcalias, fp, param))
-		    return 1;
-	    next = fa->overnext;
-	}
-	else
-	{
-	    AliasDeclaration *a = d->isAliasDeclaration();
-
-	    if (a)
-	    {
-		Dsymbol *s = a->toAlias();
-		next = s->isDeclaration();
-		if (next == a)
-		    break;
-		if (next == fstart)
-		    break;
-		if (a->importprot == PROTprivate && a->getModule() != from)
-		    if (FuncDeclaration* fd = next->isFuncDeclaration())
-			next = fd->overnext;
-	    }
-	    else
-	    {
-		f = d->isFuncDeclaration();
-		if (!f)
-		{   d->error("is aliased to a function");
-		    break;		// BUG: should print error message?
-		}
-		if ((*fp)(param, f))
-		    return 1;
-
-		next = f->overnext;
-	    }
-	}
-    }
-    return 0;
-}
-
-/********************************************
- * Find function in overload list that exactly matches t.
- */
-
-struct Param1
-{
-    Type *t;		// type to match
-    FuncDeclaration *f;	// return value
-};
-
-int fp1(void *param, FuncDeclaration *f)
-{   Param1 *p = (Param1 *)param;
-    Type *t = p->t;
-
-    if (t->equals(f->type))
-    {	p->f = f;
-	return 1;
-    }
-
-#if DMDV2
-    /* Allow covariant matches, if it's just a const conversion
-     * of the return type
-     */
-    if (t->ty == Tfunction)
-    {   TypeFunction *tf = (TypeFunction *)f->type;
-	if (tf->covariant(t) == 1 &&
-	    tf->nextOf()->implicitConvTo(t->nextOf()) >= MATCHconst)
-	{
-	    p->f = f;
-	    return 1;
-	}
-    }
-#endif
-    return 0;
-}
-
-FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t, Module* from)
-{
-    Param1 p;
-    p.t = t;
-    p.f = NULL;
-    overloadApply(from, this, &fp1, &p);
-    return p.f;
-}
-
-#if 0
-FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
-{
-    FuncDeclaration *f;
-    Declaration *d;
-    Declaration *next;
-
-    for (d = this; d; d = next)
-    {	FuncAliasDeclaration *fa = d->isFuncAliasDeclaration();
-
-	if (fa)
-	{
-	    FuncDeclaration *f2 = fa->funcalias->overloadExactMatch(t);
-	    if (f2)
-		return f2;
-	    next = fa->overnext;
-	}
-	else
-	{
-	    AliasDeclaration *a = d->isAliasDeclaration();
-
-	    if (a)
-	    {
-		Dsymbol *s = a->toAlias();
-		next = s->isDeclaration();
-		if (next == a)
-		    break;
-	    }
-	    else
-	    {
-		f = d->isFuncDeclaration();
-		if (!f)
-		    break;		// BUG: should print error message?
-		if (t->equals(d->type))
-		    return f;
-		next = f->overnext;
-	    }
-	}
-    }
-    return NULL;
-}
-#endif
-
-/********************************************
- * Decide which function matches the arguments best.
- */
-
-struct Param2
-{
-    Match *m;
-    Expressions *arguments;
-};
-
-int fp2(void *param, FuncDeclaration *f)
-{   Param2 *p = (Param2 *)param;
-    Match *m = p->m;
-    Expressions *arguments = p->arguments;
-    MATCH match;
-
-    if (f != m->lastf)		// skip duplicates
-    {
-	m->anyf = f;
-	TypeFunction *tf = (TypeFunction *)f->type;
-	match = (MATCH) tf->callMatch(arguments);
-	//printf("1match = %d\n", match);
-	if (match != MATCHnomatch)
-	{
-	    if (match > m->last)
-		goto LfIsBetter;
-
-	    if (match < m->last)
-		goto LlastIsBetter;
-
-	    /* See if one of the matches overrides the other.
-	     */
-	    if (m->lastf->overrides(f))
-		goto LlastIsBetter;
-	    else if (f->overrides(m->lastf))
-		goto LfIsBetter;
-
-	Lambiguous:
-	    m->nextf = f;
-	    m->count++;
-	    return 0;
-
-	LfIsBetter:
-	    m->last = match;
-	    m->lastf = f;
-	    m->count = 1;
-	    return 0;
-
-	LlastIsBetter:
-	    return 0;
-	}
-    }
-    return 0;
-}
-
-
-void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments, Module* from)
-{
-    Param2 p;
-    p.m = m;
-    p.arguments = arguments;
-    overloadApply(from, fstart, &fp2, &p);
-}
-
-#if 0
-// Recursive helper function
-
-void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments)
-{
-    MATCH match;
-    Declaration *d;
-    Declaration *next;
-
-    for (d = fstart; d; d = next)
-    {
-	FuncDeclaration *f;
-	FuncAliasDeclaration *fa;
-	AliasDeclaration *a;
-
-	fa = d->isFuncAliasDeclaration();
-	if (fa)
-	{
-	    overloadResolveX(m, fa->funcalias, arguments);
-	    next = fa->overnext;
-	}
-	else if ((f = d->isFuncDeclaration()) != NULL)
-	{
-	    next = f->overnext;
-	    if (f == m->lastf)
-		continue;			// skip duplicates
-	    else
-	    {
-		TypeFunction *tf;
-
-		m->anyf = f;
-		tf = (TypeFunction *)f->type;
-		match = (MATCH) tf->callMatch(arguments);
-		//printf("2match = %d\n", match);
-		if (match != MATCHnomatch)
-		{
-		    if (match > m->last)
-			goto LfIsBetter;
-
-		    if (match < m->last)
-			goto LlastIsBetter;
-
-		    /* See if one of the matches overrides the other.
-		     */
-		    if (m->lastf->overrides(f))
-			goto LlastIsBetter;
-		    else if (f->overrides(m->lastf))
-			goto LfIsBetter;
-
-		Lambiguous:
-		    m->nextf = f;
-		    m->count++;
-		    continue;
-
-		LfIsBetter:
-		    m->last = match;
-		    m->lastf = f;
-		    m->count = 1;
-		    continue;
-
-		LlastIsBetter:
-		    continue;
-		}
-	    }
-	}
-	else if ((a = d->isAliasDeclaration()) != NULL)
-	{
-	    Dsymbol *s = a->toAlias();
-	    next = s->isDeclaration();
-	    if (next == a)
-		break;
-	    if (next == fstart)
-		break;
-	}
-	else
-	{   d->error("is aliased to a function");
-	    break;
-	}
-    }
-}
-#endif
-
-FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expressions *arguments, Module* from)
-{
-    TypeFunction *tf;
-    Match m;
-
-#if 0
-printf("FuncDeclaration::overloadResolve('%s')\n", toChars());
-if (arguments)
-{   int i;
-
-    for (i = 0; i < arguments->dim; i++)
-    {   Expression *arg;
-
-	arg = (Expression *)arguments->data[i];
-	assert(arg->type);
-	printf("\t%s: ", arg->toChars());
-	arg->type->print();
-    }
-}
-#endif
-
-    memset(&m, 0, sizeof(m));
-    m.last = MATCHnomatch;
-    overloadResolveX(&m, this, arguments, from);
-
-    if (m.count == 1)		// exactly one match
-    {
-	return m.lastf;
-    }
-    else
-    {
-	OutBuffer buf;
-
-	if (arguments)
-	{
-	    HdrGenState hgs;
-
-	    argExpTypesToCBuffer(&buf, arguments, &hgs);
-	}
-
-	if (m.last == MATCHnomatch)
-	{
-	    tf = (TypeFunction *)type;
-
-	    //printf("tf = %s, args = %s\n", tf->deco, ((Expression *)arguments->data[0])->type->deco);
-	    error(loc, "%s does not match parameter types (%s)",
-		Argument::argsTypesToChars(tf->parameters, tf->varargs),
-		buf.toChars());
-	    return m.anyf;		// as long as it's not a FuncAliasDeclaration
-	}
-	else
-	{
-#if 1
-	    TypeFunction *t1 = (TypeFunction *)m.lastf->type;
-	    TypeFunction *t2 = (TypeFunction *)m.nextf->type;
-
-	    error(loc, "called with argument types:\n\t(%s)\nmatches both:\n\t%s%s\nand:\n\t%s%s",
-		    buf.toChars(),
-		    m.lastf->toPrettyChars(), Argument::argsTypesToChars(t1->parameters, t1->varargs),
-		    m.nextf->toPrettyChars(), Argument::argsTypesToChars(t2->parameters, t2->varargs));
-#else
-	    error(loc, "overloads %s and %s both match argument list for %s",
-		    m.lastf->type->toChars(),
-		    m.nextf->type->toChars(),
-		    m.lastf->toChars());
-#endif
-	    return m.lastf;
-	}
-    }
-}
-
-/********************************
- * Labels are in a separate scope, one per function.
- */
-
-LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
-{   Dsymbol *s;
-
-    if (!labtab)
-	labtab = new DsymbolTable();	// guess we need one
-
-    s = labtab->lookup(ident);
-    if (!s)
-    {
-	s = new LabelDsymbol(ident);
-	labtab->insert(s);
-    }
-    return (LabelDsymbol *)s;
-}
-
-/****************************************
- * If non-static member function that has a 'this' pointer,
- * return the aggregate it is a member of.
- * Otherwise, return NULL.
- */
-
-AggregateDeclaration *FuncDeclaration::isThis()
-{   AggregateDeclaration *ad;
-
-    //printf("+FuncDeclaration::isThis() '%s'\n", toChars());
-    ad = NULL;
-    if ((storage_class & STCstatic) == 0)
-    {
-	ad = isMember2();
-    }
-    //printf("-FuncDeclaration::isThis() %p\n", ad);
-    return ad;
-}
-
-AggregateDeclaration *FuncDeclaration::isMember2()
-{   AggregateDeclaration *ad;
-
-    //printf("+FuncDeclaration::isMember2() '%s'\n", toChars());
-    ad = NULL;
-    for (Dsymbol *s = this; s; s = s->parent)
-    {
-//printf("\ts = '%s', parent = '%s', kind = %s\n", s->toChars(), s->parent->toChars(), s->parent->kind());
-	ad = s->isMember();
-	if (ad)
-{   //printf("test4\n");
-	    break;
-}
-	if (!s->parent ||
-	    (!s->parent->isTemplateInstance()))
-{   //printf("test5\n");
-	    break;
-}
-    }
-    //printf("-FuncDeclaration::isMember2() %p\n", ad);
-    return ad;
-}
-
-/*****************************************
- * Determine lexical level difference from 'this' to nested function 'fd'.
- * Error if this cannot call fd.
- * Returns:
- *	0	same level
- *	-1	increase nesting by 1 (fd is nested within 'this')
- *	>0	decrease nesting by number
- */
-
-int FuncDeclaration::getLevel(Loc loc, FuncDeclaration *fd)
-{   int level;
-    Dsymbol *s;
-    Dsymbol *fdparent;
-
-    //printf("FuncDeclaration::getLevel(fd = '%s')\n", fd->toChars());
-    fdparent = fd->toParent2();
-    if (fdparent == this)
-	return -1;
-    s = this;
-    level = 0;
-    while (fd != s && fdparent != s->toParent2())
-    {
-	//printf("\ts = '%s'\n", s->toChars());
-	FuncDeclaration *thisfd = s->isFuncDeclaration();
-	if (thisfd)
-	{   if (!thisfd->isNested() && !thisfd->vthis)
-		goto Lerr;
-	}
-	else
-	{
-	    ClassDeclaration *thiscd = s->isClassDeclaration();
-	    if (thiscd)
-	    {	if (!thiscd->isNested())
-		    goto Lerr;
-	    }
-	    else
-		goto Lerr;
-	}
-
-	s = s->toParent2();
-	assert(s);
-	level++;
-    }
-    return level;
-
-Lerr:
-    error(loc, "cannot access frame of function %s", fd->toChars());
-    return 1;
-}
-
-void FuncDeclaration::appendExp(Expression *e)
-{   Statement *s;
-
-    s = new ExpStatement(0, e);
-    appendState(s);
-}
-
-void FuncDeclaration::appendState(Statement *s)
-{   CompoundStatement *cs;
-
-    if (!fbody)
-    {	Statements *a;
-
-	a = new Statements();
-	fbody = new CompoundStatement(0, a);
-    }
-    cs = fbody->isCompoundStatement();
-    cs->statements->push(s);
-}
-
-
-int FuncDeclaration::isMain()
-{
-    return ident == Id::main &&
-	linkage != LINKc && !isMember() && !isNested();
-}
-
-int FuncDeclaration::isWinMain()
-{
-    //printf("FuncDeclaration::isWinMain() %s\n", toChars());
-#if 0
-    int x = ident == Id::WinMain &&
-	linkage != LINKc && !isMember();
-    printf("%s\n", x ? "yes" : "no");
-    return x;
-#else
-    return ident == Id::WinMain &&
-	linkage != LINKc && !isMember();
-#endif
-}
-
-int FuncDeclaration::isDllMain()
-{
-    return ident == Id::DllMain &&
-	linkage != LINKc && !isMember();
-}
-
-int FuncDeclaration::isExport()
-{
-    return protection == PROTexport;
-}
-
-int FuncDeclaration::isImportedSymbol()
-{
-    //printf("isImportedSymbol()\n");
-    //printf("protection = %d\n", protection);
-    return (protection == PROTexport) && !fbody;
-}
-
-// Determine if function goes into virtual function pointer table
-
-int FuncDeclaration::isVirtual()
-{
-#if 0
-    printf("FuncDeclaration::isVirtual(%s)\n", toChars());
-    printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
-    printf("result is %d\n",
-	isMember() &&
-	!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
-	toParent()->isClassDeclaration());
-#endif
-    return isMember() &&
-	!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
-	toParent()->isClassDeclaration();
-}
-
-int FuncDeclaration::isFinal()
-{
-    ClassDeclaration *cd;
-#if 0
-    printf("FuncDeclaration::isFinal(%s)\n", toChars());
-    printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
-    printf("result is %d\n",
-	isMember() &&
-	!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
-	(cd = toParent()->isClassDeclaration()) != NULL &&
-	cd->storage_class & STCfinal);
-#endif
-    return isMember() &&
-	(Declaration::isFinal() ||
-	 ((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal));
-}
-
-int FuncDeclaration::isAbstract()
-{
-    return storage_class & STCabstract;
-}
-
-int FuncDeclaration::isCodeseg()
-{
-    return TRUE;		// functions are always in the code segment
-}
-
-// Determine if function needs
-// a static frame pointer to its lexically enclosing function
-
-int FuncDeclaration::isNested()
-{
-    //if (!toParent())
-	//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
-    //printf("\ttoParent() = '%s'\n", toParent()->toChars());
-    return ((storage_class & STCstatic) == 0) && toParent2() &&
-	   (toParent2()->isFuncDeclaration() != NULL);
-}
-
-int FuncDeclaration::needThis()
-{
-    //printf("FuncDeclaration::needThis() '%s'\n", toChars());
-    int i = isThis() != NULL;
-    //printf("\t%d\n", i);
-    if (!i && isFuncAliasDeclaration())
-	i = ((FuncAliasDeclaration *)this)->funcalias->needThis();
-    return i;
-}
-
-int FuncDeclaration::addPreInvariant()
-{
-    AggregateDeclaration *ad = isThis();
-    return (ad &&
-	    //ad->isClassDeclaration() &&
-	    global.params.useInvariants &&
-	    (protection == PROTpublic || protection == PROTexport) &&
-	    !naked);
-}
-
-int FuncDeclaration::addPostInvariant()
-{
-    AggregateDeclaration *ad = isThis();
-    return (ad &&
-	    ad->inv &&
-	    //ad->isClassDeclaration() &&
-	    global.params.useInvariants &&
-	    (protection == PROTpublic || protection == PROTexport) &&
-	    !naked);
-}
-
-/**********************************
- * Generate a FuncDeclaration for a runtime library function.
- */
-
-//
-// LDC: Adjusted to give argument info to the runtime function decl.
-//
-
-FuncDeclaration *FuncDeclaration::genCfunc(Arguments *args, Type *treturn, const char *name)
-{
-    return genCfunc(args, treturn, Lexer::idPool(name));
-}
-
-FuncDeclaration *FuncDeclaration::genCfunc(Arguments *args, Type *treturn, Identifier *id)
-{
-    FuncDeclaration *fd;
-    TypeFunction *tf;
-    Dsymbol *s;
-    static DsymbolTable *st = NULL;
-
-    //printf("genCfunc(name = '%s')\n", id->toChars());
-    //printf("treturn\n\t"); treturn->print();
-
-    // See if already in table
-    if (!st)
-	st = new DsymbolTable();
-    s = st->lookup(id);
-    if (s)
-    {
-	fd = s->isFuncDeclaration();
-	assert(fd);
-	assert(fd->type->nextOf()->equals(treturn));
-    }
-    else
-    {
-	tf = new TypeFunction(args, treturn, 0, LINKc);
-	fd = new FuncDeclaration(0, 0, id, STCstatic, tf);
-	fd->protection = PROTpublic;
-	fd->linkage = LINKc;
-
-	st->insert(fd);
-    }
-    return fd;
-}
-
-const char *FuncDeclaration::kind()
-{
-    return "function";
-}
-
-/*******************************
- * Look at all the variables in this function that are referenced
- * by nested functions, and determine if a closure needs to be
- * created for them.
- */
-
-#if DMDV2
-int FuncDeclaration::needsClosure()
-{
-    /* Need a closure for all the closureVars[] if any of the
-     * closureVars[] are accessed by a
-     * function that escapes the scope of this function.
-     * We take the conservative approach and decide that any function that:
-     * 1) is a virtual function
-     * 2) has its address taken
-     * 3) has a parent that escapes
-     *
-     * Note that since a non-virtual function can be called by
-     * a virtual one, if that non-virtual function accesses a closure
-     * var, the closure still has to be taken. Hence, we check for isThis()
-     * instead of isVirtual(). (thanks to David Friedman)
-     */
-
-    //printf("FuncDeclaration::needsClosure() %s\n", toChars());
-    for (int i = 0; i < closureVars.dim; i++)
-    {	VarDeclaration *v = (VarDeclaration *)closureVars.data[i];
-	assert(v->isVarDeclaration());
-	//printf("\tv = %s\n", v->toChars());
-
-	for (int j = 0; j < v->nestedrefs.dim; j++)
-	{   FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j];
-	    assert(f != this);
-
-	    //printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf);
-	    if (f->isThis() || f->tookAddressOf)
-		goto Lyes;	// assume f escapes this function's scope
-
-	    // Look to see if any parents of f that are below this escape
-	    for (Dsymbol *s = f->parent; s && s != this; s = s->parent)
-	    {
-		f = s->isFuncDeclaration();
-		if (f && (f->isThis() || f->tookAddressOf))
-		    goto Lyes;
-	    }
-	}
-    }
-    return 0;
-
-Lyes:
-    //printf("\tneeds closure\n");
-    return 1;
-}
-#endif
-
-/****************************** FuncAliasDeclaration ************************/
-
-// Used as a way to import a set of functions from another scope into this one.
-
-FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias)
-    : FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident,
-	(enum STC)funcalias->storage_class, funcalias->type)
-{
-    assert(funcalias != this);
-    this->funcalias = funcalias;
-    importprot = PROTundefined;
-}
-
-const char *FuncAliasDeclaration::kind()
-{
-    return "function alias";
-}
-
-
-/****************************** FuncLiteralDeclaration ************************/
-
-FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
-	enum TOK tok, ForeachStatement *fes)
-    : FuncDeclaration(loc, endloc, NULL, STCundefined, type)
-{
-    const char *id;
-
-    if (fes)
-	id = "__foreachbody";
-    else if (tok == TOKdelegate)
-	id = "__dgliteral";
-    else
-	id = "__funcliteral";
-    this->ident = Identifier::generateId(id);
-    this->tok = tok;
-    this->fes = fes;
-    //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
-}
-
-Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s)
-{
-    FuncLiteralDeclaration *f;
-
-    //printf("FuncLiteralDeclaration::syntaxCopy('%s')\n", toChars());
-    if (s)
-	f = (FuncLiteralDeclaration *)s;
-    else
-	f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes);
-    FuncDeclaration::syntaxCopy(f);
-    return f;
-}
-
-int FuncLiteralDeclaration::isNested()
-{
-    //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars());
-    return (tok == TOKdelegate);
-}
-
-int FuncLiteralDeclaration::isVirtual()
-{
-    return FALSE;
-}
-
-const char *FuncLiteralDeclaration::kind()
-{
-    // GCC requires the (char*) casts
-    return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function";
-}
-
-void FuncLiteralDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    static Identifier *idfunc;
-    static Identifier *iddel;
-
-    if (!idfunc)
-	idfunc = new Identifier("function", 0);
-    if (!iddel)
-	iddel = new Identifier("delegate", 0);
-
-    type->toCBuffer(buf, ((tok == TOKdelegate) ? iddel : idfunc), hgs);
-    bodyToCBuffer(buf, hgs);
-}
-
-
-/********************************* CtorDeclaration ****************************/
-
-CtorDeclaration::CtorDeclaration(Loc loc, Loc endloc, Arguments *arguments, int varargs)
-    : FuncDeclaration(loc, endloc, Id::ctor, STCundefined, NULL)
-{
-    this->arguments = arguments;
-    this->varargs = varargs;
-    //printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars());
-}
-
-Dsymbol *CtorDeclaration::syntaxCopy(Dsymbol *s)
-{
-    CtorDeclaration *f;
-
-    f = new CtorDeclaration(loc, endloc, NULL, varargs);
-
-    f->outId = outId;
-    f->frequire = frequire ? frequire->syntaxCopy() : NULL;
-    f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
-    f->fbody    = fbody    ? fbody->syntaxCopy()    : NULL;
-    assert(!fthrows); // deprecated
-
-    f->arguments = Argument::arraySyntaxCopy(arguments);
-    return f;
-}
-
-
-void CtorDeclaration::semantic(Scope *sc)
-{
-    ClassDeclaration *cd;
-    Type *tret;
-
-    //printf("CtorDeclaration::semantic()\n");
-    if (type)
-	return;
-
-    sc = sc->push();
-    sc->stc &= ~STCstatic;		// not a static constructor
-
-    parent = sc->parent;
-    Dsymbol *parent = toParent();
-    cd = parent->isClassDeclaration();
-    if (!cd)
-    {
-	error("constructors are only for class definitions");
-	fatal();
-	tret = Type::tvoid;
-    }
-    else
-	tret = cd->type; //->referenceTo();
-    type = new TypeFunction(arguments, tret, varargs, LINKd);
-    if (!originalType)
-	originalType = type;
-
-    sc->flags |= SCOPEctor;
-    type = type->semantic(loc, sc);
-    sc->flags &= ~SCOPEctor;
-
-    // Append:
-    //	return this;
-    // to the function body
-    if (fbody)
-    {	Expression *e;
-	Statement *s;
-
-	e = new ThisExp(0);
-	s = new ReturnStatement(0, e);
-	fbody = new CompoundStatement(0, fbody, s);
-    }
-
-    FuncDeclaration::semantic(sc);
-
-    sc->pop();
-
-    // See if it's the default constructor
-    if (cd && varargs == 0 && Argument::dim(arguments) == 0)
-	cd->defaultCtor = this;
-}
-
-const char *CtorDeclaration::kind()
-{
-    return "constructor";
-}
-
-char *CtorDeclaration::toChars()
-{
-    return (char *)"this";
-}
-
-int CtorDeclaration::isVirtual()
-{
-    return FALSE;
-}
-
-int CtorDeclaration::addPreInvariant()
-{
-    return FALSE;
-}
-
-int CtorDeclaration::addPostInvariant()
-{
-    return (isThis() && vthis && global.params.useInvariants);
-}
-
-
-void CtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    buf->writestring("this");
-    Argument::argsToCBuffer(buf, hgs, arguments, varargs);
-    bodyToCBuffer(buf, hgs);
-}
-
-/********************************* DtorDeclaration ****************************/
-
-DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc)
-    : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL)
-{
-}
-
-DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, Identifier *id)
-    : FuncDeclaration(loc, endloc, id, STCundefined, NULL)
-{
-}
-
-Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s)
-{
-    assert(!s);
-    DtorDeclaration *dd = new DtorDeclaration(loc, endloc, ident);
-    return FuncDeclaration::syntaxCopy(dd);
-}
-
-
-void DtorDeclaration::semantic(Scope *sc)
-{
-    ClassDeclaration *cd;
-
-    parent = sc->parent;
-    Dsymbol *parent = toParent();
-    cd = parent->isClassDeclaration();
-    if (!cd)
-    {
-	error("destructors only are for class definitions");
-	fatal();
-    }
-    else
-	cd->dtors.push(this);
-    type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
-
-    sc = sc->push();
-    sc->stc &= ~STCstatic;		// not a static destructor
-    sc->linkage = LINKd;
-
-    FuncDeclaration::semantic(sc);
-
-    sc->pop();
-}
-
-int DtorDeclaration::overloadInsert(Dsymbol *s)
-{
-    return FALSE;	// cannot overload destructors
-}
-
-int DtorDeclaration::addPreInvariant()
-{
-    return (isThis() && vthis && global.params.useInvariants);
-}
-
-int DtorDeclaration::addPostInvariant()
-{
-    return FALSE;
-}
-
-int DtorDeclaration::isVirtual()
-{
-    /* This should be FALSE so that dtor's don't get put into the vtbl[],
-     * but doing so will require recompiling everything.
-     */
-#if BREAKABI
-    return FALSE;
-#else
-    return FuncDeclaration::isVirtual();
-#endif
-}
-
-void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
-{
-    if (hgs->hdrgen)
-	return;
-    buf->writestring("~this()");
-    bodyToCBuffer(buf, hgs);
-}
-
-/********************************* StaticCtorDeclaration ****************************/
-
-StaticCtorDeclaration::StaticCtorDeclaration(Loc loc, Loc endloc)
-    : FuncDeclaration(loc, endloc,
-      Identifier::generateId("_staticCtor"), STCstatic, NULL)
-{
-}
-
-Dsymbol *StaticCtorDeclaration::syntaxCopy(Dsymbol *s)
-{
-    StaticCtorDeclaration *scd;
-
-    assert(!s);
-    scd = new StaticCtorDeclaration(loc, endloc);
-    return FuncDeclaration::syntaxCopy(scd);
-}
-
-
-void StaticCtorDeclaration::semantic(Scope *sc)
-{
-    //printf("StaticCtorDeclaration::semantic()\n");
-
-    type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
-
-    /* If the static ctor appears within a template instantiation,
-     * it could get called multiple times by the module constructors
-     * for different modules. Thus, protect it with a gate.
-     */
-    if (inTemplateInstance())
-    {
-	/* Add this prefix to the function:
-	 *	static int gate;
-	 *	if (++gate != 1) return;
-	 * Note that this is not thread safe; should not have threads
-	 * during static construction.
-	 */
-	Identifier *id = Lexer::idPool("__gate");
-	VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
-	v->storage_class = STCstatic;
-	Statements *sa = new Statements();
-	Statement *s = new DeclarationStatement(0, v);
-	sa->push(s);
-