changeset 1602:a413ae7329bf

Merge DMD r243: some harmonization with D2 dmd --- dmd/aggregate.h | 24 ++++- dmd/attrib.c | 63 ++++++---- dmd/attrib.h | 10 +- dmd/declaration.h | 5 +- dmd/func.c | 337 ++++++++++++++++++++++------------------------------- dmd/mars.c | 2 +- dmd/mars.h | 7 + dmd/mtype.h | 13 ++- dmd/parse.c | 32 ++++- dmd/parse.h | 14 ++- dmd/scope.h | 2 +- 11 files changed, 263 insertions(+), 246 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:19 -0300
parents 49722e6e6e05
children eae495e6ae8d
files dmd/aggregate.h dmd/attrib.c dmd/attrib.h dmd/declaration.h dmd/func.c dmd/mars.c dmd/mars.h dmd/mtype.h dmd/parse.c dmd/parse.h dmd/scope.h
diffstat 11 files changed, 263 insertions(+), 246 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/aggregate.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/aggregate.h	Wed Jan 06 15:18:19 2010 -0300
@@ -16,6 +16,7 @@
 #endif /* __DMC__ */
 
 #include "root.h"
+
 #include "dsymbol.h"
 
 #include <vector>
@@ -49,7 +50,7 @@
 struct AggregateDeclaration : ScopeDsymbol
 {
     Type *type;
-    unsigned storage_class;
+    StorageClass storage_class;
     enum PROT protection;
     Type *handle;		// 'this' type
     unsigned structsize;	// size of struct
@@ -63,6 +64,10 @@
 				// 2: cannot determine size; fwd referenced
     int isdeprecated;		// !=0 if deprecated
 
+#if DMDV2
+    int isnested;		// !=0 if is nested
+    VarDeclaration *vthis;	// 'this' parameter if this aggregate is nested
+#endif
     // Special member functions
     InvariantDeclaration *inv;		// invariant
     NewDeclaration *aggNew;		// allocator
@@ -92,6 +97,7 @@
     void addField(Scope *sc, VarDeclaration *v);
     int isDeprecated();		// is aggregate deprecated?
     FuncDeclaration *buildDtor(Scope *sc);
+    int isNested();
 
     void emitComment(Scope *sc);
     void toJsonBuffer(OutBuffer *buf);
@@ -147,7 +153,15 @@
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     char *mangle();
     const char *kind();
+#if DMDV1
     Expression *cloneMembers();
+#endif
+#if DMDV2
+    int needOpAssign();
+    FuncDeclaration *buildOpAssign(Scope *sc);
+    FuncDeclaration *buildPostBlit(Scope *sc);
+    FuncDeclaration *buildCpCtor(Scope *sc);
+#endif
     void toDocBuffer(OutBuffer *buf);
 
     PROT getAccess(Dsymbol *smember);	// determine access to smember
@@ -209,8 +223,10 @@
     static ClassDeclaration *classinfo;
 
     ClassDeclaration *baseClass;	// NULL only if this is Object
+#if DMDV1
     CtorDeclaration *ctor;
     CtorDeclaration *defaultCtor;	// default constructor
+#endif
     FuncDeclaration *staticCtor;
     FuncDeclaration *staticDtor;
     Array vtbl;				// Array of FuncDeclaration's making up the vtbl[]
@@ -231,10 +247,10 @@
 					// it derives from IUnknown)
     int isscope;			// !=0 if this is a scope class
     int isabstract;			// !=0 if abstract class
-
+#if DMDV1
     int isnested;			// !=0 if is nested
     VarDeclaration *vthis;		// 'this' parameter if this class is nested
-
+#endif
     int inuse;				// to prevent recursive attempts
 
     ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
@@ -252,7 +268,9 @@
 #endif
     FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
     void interfaceSemantic(Scope *sc);
+#if DMDV1
     int isNested();
+#endif
     int isCOMclass();
     virtual int isCOMinterface();
 #if DMDV2
--- a/dmd/attrib.c	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/attrib.c	Wed Jan 06 15:18:19 2010 -0300
@@ -78,7 +78,7 @@
 }
 
 void AttribDeclaration::setScopeNewSc(Scope *sc,
-	unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
+	StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
 	unsigned structalign)
 {
     if (decl)
@@ -113,7 +113,7 @@
 }
 
 void AttribDeclaration::semanticNewSc(Scope *sc,
-	unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
+	StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
 	unsigned structalign)
 {
     if (decl)
@@ -360,7 +360,7 @@
 
 /************************* StorageClassDeclaration ****************************/
 
-StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl)
+StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Array *decl)
 	: AttribDeclaration(decl)
 {
     this->stc = stc;
@@ -379,7 +379,7 @@
 {
     if (decl)
     {
-	unsigned scstc = sc->stc;
+	StorageClass scstc = sc->stc;
 
 	/* These sets of storage classes are mutually exclusive,
 	 * so choose the innermost or most recent one.
@@ -402,7 +402,7 @@
 {
     if (decl)
     {
-	unsigned scstc = sc->stc;
+	StorageClass scstc = sc->stc;
 
 	/* These sets of storage classes are mutually exclusive,
 	 * so choose the innermost or most recent one.
@@ -421,11 +421,11 @@
     }
 }
 
-void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
+void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
 {
     struct SCstring
     {
-	int stc;
+	StorageClass stc;
 	enum TOK tok;
     };
 
@@ -441,6 +441,19 @@
 	{ STCsynchronized, TOKsynchronized },
 	{ STCdeprecated,   TOKdeprecated },
 	{ STCoverride,     TOKoverride },
+	{ STClazy,         TOKlazy },
+	{ STCalias,        TOKalias },
+	{ STCout,          TOKout },
+	{ STCin,           TOKin },
+#if DMDV2
+	{ STCimmutable,    TOKimmutable },
+	{ STCshared,       TOKshared },
+	{ STCnothrow,      TOKnothrow },
+	{ STCpure,         TOKpure },
+	{ STCref,          TOKref },
+	{ STCtls,          TOKtls },
+	{ STCgshared,      TOKgshared },
+#endif
     };
 
     for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
@@ -1006,25 +1019,27 @@
 	goto Lnodecl;
     }
 #endif
+#if DMDV2
+    else if (ident == Id::startaddress)
+    {
+	if (!args || args->dim != 1)
+	    error("function name expected for start address");
+	else
+	{
+	    Expression *e = (Expression *)args->data[0];
+	    e = e->semantic(sc);
+	    e = e->optimize(WANTvalue | WANTinterpret);
+	    args->data[0] = (void *)e;
+	    Dsymbol *sa = getDsymbol(e);
+	    if (!sa || !sa->isFuncDeclaration())
+		error("function name expected for start address, not '%s'", e->toChars());
+	}
+	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
 
@@ -1385,7 +1400,7 @@
 	    e->toCBuffer(buf, hgs);
 	}
     }
-    buf->writestring(")");
+    buf->writeByte(')');
     AttribDeclaration::toCBuffer(buf, hgs);
 }
 
--- a/dmd/attrib.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/attrib.h	Wed Jan 06 15:18:19 2010 -0300
@@ -37,10 +37,10 @@
     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,
+	StorageClass 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,
+	StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
 	unsigned structalign);
     void semantic(Scope *sc);
     void semantic2(Scope *sc);
@@ -69,15 +69,15 @@
 
 struct StorageClassDeclaration: AttribDeclaration
 {
-    unsigned stc;
+    StorageClass stc;
 
-    StorageClassDeclaration(unsigned stc, Array *decl);
+    StorageClassDeclaration(StorageClass 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);
+    static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
 };
 
 struct LinkDeclaration : AttribDeclaration
--- a/dmd/declaration.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/declaration.h	Wed Jan 06 15:18:19 2010 -0300
@@ -104,7 +104,7 @@
 {
     Type *type;
     Type *originalType;		// before semantic analysis
-    unsigned storage_class;
+    StorageClass storage_class;
     enum PROT protection;
     enum LINK linkage;
     int inuse;			// used to detect cycles
@@ -260,6 +260,7 @@
     int noscope;		// no scope semantics
 #if DMDV2
     FuncDeclarations nestedrefs; // referenced by these lexically nested functions
+    bool isargptr;		// if parameter that _argptr points to
 #else
     int nestedref;		// referenced by a lexically nested function
 #endif
@@ -712,7 +713,7 @@
     int nestedFrameRef;			// !=0 if nested variables referenced
 #endif
 
-    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
+    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void semantic2(Scope *sc);
--- a/dmd/func.c	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/func.c	Wed Jan 06 15:18:19 2010 -0300
@@ -31,7 +31,7 @@
 
 /********************************* FuncDeclaration ****************************/
 
-FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
+FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
     : Declaration(id)
 {
     //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
@@ -124,7 +124,7 @@
     if (s)
 	f = (FuncDeclaration *)s;
     else
-	f = new FuncDeclaration(loc, endloc, ident, (enum STC) storage_class, type->syntaxCopy());
+	f = new FuncDeclaration(loc, endloc, ident, storage_class, type->syntaxCopy());
     f->outId = outId;
     f->frequire = frequire ? frequire->syntaxCopy() : NULL;
     f->fensure  = fensure  ? fensure->syntaxCopy()  : NULL;
@@ -446,7 +446,6 @@
 	 */
 	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)
@@ -499,68 +498,6 @@
 		    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())
@@ -1312,13 +1249,11 @@
 		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);
+		Expression *e1 = new VarExp(0, argptr);
 		if (parameters && parameters->dim)
 		    p = (VarDeclaration *)parameters->data[parameters->dim - 1];
 		else
@@ -1329,7 +1264,7 @@
 		else
 		    offset = p->type->size();
 		offset = (offset + 3) & ~3;	// assume stack aligns on 4
-		e = new SymOffExp(0, p, offset);
+		Expression *e = new SymOffExp(0, p, offset);
 		e = new AssignExp(0, e1, e);
 		e->type = t;
 		a->push(new ExpStatement(0, e));
@@ -1918,48 +1853,6 @@
     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.
@@ -1968,6 +1861,9 @@
 struct Param2
 {
     Match *m;
+#if DMDV2
+    Expression *ethis;
+#endif
     Expressions *arguments;
 };
 
@@ -1998,6 +1894,22 @@
 	    else if (f->overrides(m->lastf))
 		goto LfIsBetter;
 
+#if DMDV2
+	    /* Try to disambiguate using template-style partial ordering rules.
+	     * In essence, if f() and g() are ambiguous, if f() can call g(),
+	     * but g() cannot call f(), then pick f().
+	     * This is because f() is "more specialized."
+	     */
+	    {
+	    MATCH c1 = f->leastAsSpecialized(m->lastf);
+	    MATCH c2 = m->lastf->leastAsSpecialized(f);
+	    //printf("c1 = %d, c2 = %d\n", c1, c2);
+	    if (c1 > c2)
+		goto LfIsBetter;
+	    if (c1 < c2)
+		goto LlastIsBetter;
+	    }
+#endif
 	Lambiguous:
 	    m->nextf = f;
 	    m->count++;
@@ -2026,87 +1938,6 @@
     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, NULL, 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, Expression *ethis, Expressions *arguments, Module *from, int flags)
 {
@@ -2179,6 +2010,118 @@
     }
 }
 
+/*************************************
+ * Determine partial specialization order of 'this' vs g.
+ * This is very similar to TemplateDeclaration::leastAsSpecialized().
+ * Returns:
+ *	match	'this' is at least as specialized as g
+ *	0	g is more specialized than 'this'
+ */
+
+#if DMDV2
+MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
+{
+#define LOG_LEASTAS     0
+
+#if LOG_LEASTAS
+    printf("%s.leastAsSpecialized(%s)\n", toChars(), g->toChars());
+#endif
+
+    /* This works by calling g() with f()'s parameters, and
+     * if that is possible, then f() is at least as specialized
+     * as g() is.
+     */
+
+    TypeFunction *tf = (TypeFunction *)type;
+    TypeFunction *tg = (TypeFunction *)g->type;
+    size_t nfparams = Argument::dim(tf->parameters);
+    size_t ngparams = Argument::dim(tg->parameters);
+    MATCH match = MATCHexact;
+
+    /* If both functions have a 'this' pointer, and the mods are not
+     * the same and g's is not const, then this is less specialized.
+     */
+    if (needThis() && g->needThis())
+    {
+	if (tf->mod != tg->mod)
+	{
+	    if (tg->mod == MODconst)
+		match = MATCHconst;
+	    else
+		return MATCHnomatch;
+	}
+    }
+
+    /* Create a dummy array of arguments out of the parameters to f()
+     */
+    Expressions args;
+    args.setDim(nfparams);
+    for (int u = 0; u < nfparams; u++)
+    {
+	Argument *p = Argument::getNth(tf->parameters, u);
+	Expression *e;
+	if (p->storageClass & (STCref | STCout))
+	{
+	    e = new IdentifierExp(0, p->ident);
+	    e->type = p->type;
+	}
+	else
+	    e = p->type->defaultInit();
+	args.data[u] = e;
+    }
+
+    MATCH m = (MATCH) tg->callMatch(NULL, &args);
+    if (m)
+    {
+        /* A variadic parameter list is less specialized than a
+         * non-variadic one.
+         */
+        if (tf->varargs && !tg->varargs)
+            goto L1;	// less specialized
+
+#if LOG_LEASTAS
+        printf("  matches %d, so is least as specialized\n", m);
+#endif
+        return m;
+    }
+  L1:
+#if LOG_LEASTAS
+    printf("  doesn't match, so is not as specialized\n");
+#endif
+    return MATCHnomatch;
+}
+
+/*******************************************
+ * Given a symbol that could be either a FuncDeclaration or
+ * a function template, resolve it to a function symbol.
+ *	sc		instantiation scope
+ *	loc		instantiation location
+ *	targsi		initial list of template arguments
+ *	ethis		if !NULL, the 'this' pointer argument
+ *	fargs		arguments to function
+ *	flags		1: do not issue error message on no match, just return NULL
+ */
+
+FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
+	Objects *tiargs,
+	Expression *ethis,
+	Expressions *arguments,
+	int flags)
+{
+    if (!s)
+	return NULL;			// no match
+    FuncDeclaration *f = s->isFuncDeclaration();
+    if (f)
+	f = f->overloadResolve(loc, ethis, arguments);
+    else
+    {	TemplateDeclaration *td = s->isTemplateDeclaration();
+	assert(td);
+	f = td->deduceFunctionTemplate(sc, loc, tiargs, NULL, arguments, flags);
+    }
+    return f;
+}
+#endif
+
 /********************************
  * Labels are in a separate scope, one per function.
  */
@@ -2298,15 +2241,14 @@
 }
 
 void FuncDeclaration::appendState(Statement *s)
-{   CompoundStatement *cs;
-
+{
     if (!fbody)
     {	Statements *a;
 
 	a = new Statements();
 	fbody = new CompoundStatement(0, a);
     }
-    cs = fbody->isCompoundStatement();
+    CompoundStatement *cs = fbody->isCompoundStatement();
     cs->statements->push(s);
 }
 
@@ -2362,7 +2304,7 @@
 {
 #if 0
     printf("FuncDeclaration::isVirtual(%s)\n", toChars());
-    printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
+    printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
     printf("result is %d\n",
 	isMember() &&
 	!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
@@ -2407,7 +2349,7 @@
 {
     //if (!toParent())
 	//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
-    //printf("\ttoParent() = '%s'\n", toParent()->toChars());
+    //printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
     return ((storage_class & STCstatic) == 0) && toParent2() &&
 	   (toParent2()->isFuncDeclaration() != NULL);
 }
@@ -3078,6 +3020,7 @@
 	m = sc->module;
     if (m)
     {	m->needmoduleinfo = 1;
+	//printf("module2 %s needs moduleinfo\n", m->toChars());
 #ifdef IN_GCC
 	m->strictlyneedmoduleinfo = 1;
 #endif
--- a/dmd/mars.c	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/mars.c	Wed Jan 06 15:18:19 2010 -0300
@@ -58,7 +58,7 @@
 
     copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen";
     written = "written by Walter Bright and Tomas Lindquist Olsen";
-    version = "v1.051";
+    version = "v1.052";
     ldc_version = LDC_REV;
     llvm_version = LLVM_REV_STR;
     global.structalign = 8;
--- a/dmd/mars.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/mars.h	Wed Jan 06 15:18:19 2010 -0300
@@ -93,6 +93,10 @@
 #define BREAKABI 1	// 0 if not ready to break the ABI just yet
 #define STRUCTTHISREF DMDV2	// if 'this' for struct is a reference, not a pointer
 #define SNAN_DEFAULT_INIT DMDV2	// if floats are default initialized to signalling NaN
+#define SARRAYVALUE DMDV2	// static arrays are value types
+
+// Set if C++ mangling is done by the front end
+#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
 
 /* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
  * TARGET_SOLARIS, which are
@@ -413,6 +417,9 @@
     MATCHexact		// exact match
 };
 
+typedef unsigned StorageClass;
+
+
 void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
 void vwarning(Loc loc, const char *format, va_list);
 void error(Loc loc, const char *format, ...) IS_PRINTF(2);
--- a/dmd/mtype.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/mtype.h	Wed Jan 06 15:18:19 2010 -0300
@@ -590,6 +590,9 @@
     MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
     TypeInfoDeclaration *getTypeInfoDeclaration();
     int hasPointers();
+#if CPP_MANGLE
+    void toCppMangle(OutBuffer *buf, CppMangleState *cms);
+#endif
 
 #if IN_DMD
     type *toCtype();
@@ -701,7 +704,7 @@
 #if DMDV2
     Type *toHeadMutable();
     MATCH constConv(Type *to);
-#if TARGET_LINUX || TARGET_OSX
+#if CPP_MANGLE
     void toCppMangle(OutBuffer *buf, CppMangleState *cms);
 #endif
 #endif
@@ -748,19 +751,21 @@
 struct Argument : Object
 {
     //enum InOut inout;
-    unsigned storageClass;
+    StorageClass storageClass;
     Type *type;
     Identifier *ident;
     Expression *defaultArg;
 
-    Argument(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg);
+    Argument(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
     Argument *syntaxCopy();
     Type *isLazyArray();
     void toDecoBuffer(OutBuffer *buf, bool mangle);
     static Arguments *arraySyntaxCopy(Arguments *args);
     static char *argsTypesToChars(Arguments *args, int varargs);
+    static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs);
     static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs);
     static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments, bool mangle);
+    static int isTPL(Arguments *arguments);
     static size_t dim(Arguments *arguments);
     static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
 };
@@ -771,4 +776,6 @@
 extern int Tsize_t;
 extern int Tptrdiff_t;
 
+int arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
+
 #endif /* DMD_MTYPE_H */
--- a/dmd/parse.c	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/parse.c	Wed Jan 06 15:18:19 2010 -0300
@@ -149,7 +149,7 @@
     Array *a;
     Array *aelse;
     enum PROT prot;
-    unsigned stc;
+    StorageClass stc;
     Condition *condition;
     unsigned char *comment;
 
@@ -286,6 +286,7 @@
 	    case TOKpure:         stc = STCpure;	 goto Lstc;
 	    case TOKref:          stc = STCref;          goto Lstc;
 	    case TOKtls:          stc = STCtls;		 goto Lstc;
+	    case TOKgshared:      stc = STCgshared;	 goto Lstc;
 	    //case TOKmanifest:	  stc = STCmanifest;	 goto Lstc;
 #endif
 
@@ -514,6 +515,23 @@
     return decldefs;
 }
 
+/*********************************************
+ * Give error on conflicting storage classes.
+ */
+
+#if DMDV2
+void Parser::composeStorageClass(StorageClass stc)
+{
+    StorageClass u = stc;
+    u &= STCconst | STCimmutable | STCmanifest;
+    if (u & (u - 1))
+	error("conflicting storage class %s", Token::toChars(token.value));
+    u = stc;
+    u &= STCgshared | STCshared | STCtls;
+    if (u & (u - 1))
+	error("conflicting storage class %s", Token::toChars(token.value));
+}
+#endif
 
 /********************************************
  * Parse declarations after an align, protection, or extern decl.
@@ -767,7 +785,7 @@
  * Current token is 'this'.
  */
 
-CtorDeclaration *Parser::parseCtor()
+Dsymbol *Parser::parseCtor()
 {
     CtorDeclaration *f;
     Arguments *arguments;
@@ -945,7 +963,7 @@
 	Identifier *ai = NULL;
 	Type *at;
 	Argument *a;
-	unsigned storageClass;
+	StorageClass storageClass = 0;
 	Expression *ae;
 
 	storageClass = STCin;		// parameter is "in" by default
@@ -1323,7 +1341,7 @@
  * Parse template parameter list.
  */
 
-TemplateParameters *Parser::parseTemplateParameterList()
+TemplateParameters *Parser::parseTemplateParameterList(int flag)
 {
     TemplateParameters *tpl = new TemplateParameters();
 
@@ -2082,8 +2100,8 @@
 
 Array *Parser::parseDeclarations()
 {
-    enum STC storage_class;
-    enum STC stc;
+    StorageClass storage_class;
+    StorageClass stc;
     Type *ts;
     Type *t;
     Type *tfirst;
@@ -2338,7 +2356,7 @@
  */
 
 #if DMDV2
-Array *Parser::parseAutoDeclarations(unsigned storageClass, unsigned char *comment)
+Array *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment)
 {
     Array *a = new Array;
 
--- a/dmd/parse.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/parse.h	Wed Jan 06 15:18:19 2010 -0300
@@ -68,18 +68,24 @@
 
     Array *parseModule();
     Array *parseDeclDefs(int once);
+    Array *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
     Array *parseBlock();
-    void composeStorageClass(unsigned stc);
+    void composeStorageClass(StorageClass stc);
+    Expression *parseConstraint();
     TemplateDeclaration *parseTemplateDeclaration();
-    TemplateParameters *parseTemplateParameterList();
+    TemplateParameters *parseTemplateParameterList(int flag = 0);
     Dsymbol *parseMixin();
     Objects *parseTemplateArgumentList();
+    Objects *parseTemplateArgumentList2();
+    Objects *parseTemplateArgument();
     StaticAssert *parseStaticAssert();
+    TypeQualified *parseTypeof();
     enum LINK parseLinkage();
     Condition *parseDebugCondition();
     Condition *parseVersionCondition();
     Condition *parseStaticIfCondition();
-    CtorDeclaration *parseCtor();
+    Dsymbol *parseCtor();
+    PostBlitDeclaration *parsePostBlit();
     DtorDeclaration *parseDtor();
     StaticCtorDeclaration *parseStaticCtor();
     StaticDtorDeclaration *parseStaticDtor();
@@ -92,6 +98,7 @@
     Dsymbol *parseAggregate();
     BaseClasses *parseBaseClasses();
     Import *parseImport(Array *decldefs, int isstatic);
+    Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
     Type *parseBasicType();
     Type *parseBasicType2(Type *t);
     Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
@@ -99,6 +106,7 @@
     void parseContracts(FuncDeclaration *f);
     Statement *parseStatement(int flags);
     Initializer *parseInitializer();
+    Expression *parseDefaultInitExp();
     void check(Loc loc, enum TOK value);
     void check(enum TOK value);
     void check(enum TOK value, const char *string);
--- a/dmd/scope.h	Mon Dec 28 02:23:54 2009 +0000
+++ b/dmd/scope.h	Wed Jan 06 15:18:19 2010 -0300
@@ -88,7 +88,7 @@
     enum PROT protection;	// protection for class members
     int explicitProtection;	// set if in an explicit protection attribute
 
-    unsigned stc;		// storage class
+    StorageClass stc;		// storage class
 
     unsigned flags;
 #define SCOPEctor	1	// constructor type