Merge dmdfe 2.053beta

This commit is contained in:
Alexey Prokhin
2011-07-19 10:14:04 +04:00
parent 928fa9c4de
commit 462cdda4ae
39 changed files with 2441 additions and 891 deletions

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -34,7 +34,7 @@ Initializer *Initializer::syntaxCopy()
return this;
}
Initializer *Initializer::semantic(Scope *sc, Type *t)
Initializer *Initializer::semantic(Scope *sc, Type *t, int needInterpret)
{
return this;
}
@@ -87,7 +87,7 @@ Initializer *VoidInitializer::syntaxCopy()
}
Initializer *VoidInitializer::semantic(Scope *sc, Type *t)
Initializer *VoidInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
//printf("VoidInitializer::semantic(t = %p)\n", t);
type = t;
@@ -141,7 +141,7 @@ void StructInitializer::addInit(Identifier *field, Initializer *value)
this->value.push(value);
}
Initializer *StructInitializer::semantic(Scope *sc, Type *t)
Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
int errors = 0;
@@ -168,6 +168,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
{
if (fieldi >= ad->fields.dim)
{ error(loc, "too many initializers for %s", ad->toChars());
errors = 1;
field.remove(i);
i--;
continue;
@@ -184,6 +185,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
if (!s)
{
error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
errors = 1;
continue;
}
@@ -192,7 +194,9 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
{
if (fieldi >= ad->fields.dim)
{
s->error("is not a per-instance initializable field");
error(loc, "%s.%s is not a per-instance initializable field",
t->toChars(), s->toChars());
errors = 1;
break;
}
if (s == (Dsymbol *)ad->fields.data[fieldi])
@@ -201,7 +205,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
}
if (s && (v = s->isVarDeclaration()) != NULL)
{
val = val->semantic(sc, v->type);
val = val->semantic(sc, v->type, needInterpret);
value.data[i] = (void *)val;
vars.data[i] = (void *)v;
}
@@ -222,7 +226,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
fd->endloc = loc;
Expression *e = new FuncExp(loc, fd);
ExpInitializer *ie = new ExpInitializer(loc, e);
return ie->semantic(sc, t);
return ie->semantic(sc, t, needInterpret);
}
else
{
@@ -238,7 +242,6 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
return this;
}
/***************************************
* This works by transforming a struct initializer into
* a struct literal. In the future, the two should be the
@@ -246,6 +249,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t)
*/
Expression *StructInitializer::toExpression()
{ Expression *e;
size_t offset;
//printf("StructInitializer::toExpression() %s\n", toChars());
if (!ad) // if fwd referenced
@@ -256,17 +260,110 @@ Expression *StructInitializer::toExpression()
if (!sd)
return NULL;
Expressions *elements = new Expressions();
for (size_t i = 0; i < value.dim; i++)
elements->setDim(ad->fields.dim);
for (int i = 0; i < elements->dim; i++)
{
if (field.data[i])
elements->data[i] = NULL;
}
unsigned fieldi = 0;
for (int i = 0; i < value.dim; i++)
{
Identifier *id = (Identifier *)field.data[i];
if (id)
{
Dsymbol * s = ad->search(loc, id, 0);
if (!s)
{
error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
goto Lno;
}
// Find out which field index it is
for (fieldi = 0; 1; fieldi++)
{
if (fieldi >= ad->fields.dim)
{
s->error("is not a per-instance initializable field");
goto Lno;
}
if (s == (Dsymbol *)ad->fields.data[fieldi])
break;
}
}
else if (fieldi >= ad->fields.dim)
{ error(loc, "too many initializers for '%s'", ad->toChars());
goto Lno;
}
Initializer *iz = (Initializer *)value.data[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
if (!ex)
goto Lno;
elements->push(ex);
if (elements->data[fieldi])
{ error(loc, "duplicate initializer for field '%s'",
((Dsymbol *)ad->fields.data[fieldi])->toChars());
goto Lno;
}
elements->data[fieldi] = ex;
++fieldi;
}
// Now, fill in any missing elements with default initializers.
// We also need to validate any anonymous unions
offset = 0;
for (int i = 0; i < elements->dim; )
{
VarDeclaration * vd = ((Dsymbol *)ad->fields.data[i])->isVarDeclaration();
//printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
if (vd->offset < offset)
{
// Only the first field of a union can have an initializer
if (elements->data[i])
goto Lno;
}
else
{
if (!elements->data[i])
// Default initialize
elements->data[i] = vd->type->defaultInit();
}
offset = vd->offset + vd->type->size();
i++;
#if 0
int unionSize = ad->numFieldsInUnion(i);
if (unionSize == 1)
{ // Not a union -- default initialize if missing
if (!elements->data[i])
elements->data[i] = vd->type->defaultInit();
}
else
{ // anonymous union -- check for errors
int found = -1; // index of the first field with an initializer
for (int j = i; j < i + unionSize; ++j)
{
if (!elements->data[j])
continue;
if (found >= 0)
{
VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration();
VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration();
error(loc, "%s cannot have initializers for fields %s and %s in same union",
ad->toChars(),
v1->toChars(), v->toChars());
goto Lno;
}
found = j;
}
if (found == -1)
{
error(loc, "no initializer for union that contains field %s",
vd->toChars());
goto Lno;
}
}
i += unionSize;
#endif
}
e = new StructLiteralExp(loc, sd, elements);
e->type = sd->type;
@@ -274,7 +371,6 @@ Expression *StructInitializer::toExpression()
Lno:
delete elements;
//error(loc, "struct initializers as expressions are not allowed");
return NULL;
}
@@ -340,7 +436,7 @@ void ArrayInitializer::addInit(Expression *index, Initializer *value)
type = NULL;
}
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{ unsigned i;
unsigned length;
const unsigned amax = 0x80000000;
@@ -375,7 +471,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
}
Initializer *val = (Initializer *)value.data[i];
val = val->semantic(sc, t->nextOf());
val = val->semantic(sc, t->nextOf(), needInterpret);
value.data[i] = (void *)val;
length++;
if (length == 0)
@@ -630,12 +726,17 @@ Initializer *ExpInitializer::syntaxCopy()
return new ExpInitializer(loc, exp->syntaxCopy());
}
Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue;
int olderrors = global.errors;
exp = exp->optimize(wantOptimize);
if (!global.gag && olderrors != global.errors)
return this; // Failed, suppress duplicate error messages
Type *tb = t->toBasetype();
/* Look for case of initializing a static array with a too-short
@@ -668,7 +769,7 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
exp = exp->implicitCastTo(sc, t);
L1:
exp = exp->optimize(WANTvalue | WANTinterpret);
exp = exp->optimize(wantOptimize);
//printf("-ExpInitializer::semantic(): "); exp->print();
return this;
}