mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-08-02 20:40:05 +02:00
Merge dmdfe 2.053beta
This commit is contained in:
135
dmd2/init.c
135
dmd2/init.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user