fixes #431 :: apply DMDFE 1.062; thanks SiegeLord

This commit is contained in:
Moritz Warning
2010-09-27 00:06:28 +02:00
parent b032e3d1f7
commit c4e255206a
35 changed files with 918 additions and 335 deletions

View File

@@ -75,18 +75,28 @@ Statement *Statement::semantic(Scope *sc)
return this;
}
// Same as semantic(), but do create a new scope
Statement *Statement::semanticNoScope(Scope *sc)
{
//printf("Statement::semanticNoScope() %s\n", toChars());
Statement *s = this;
if (!s->isCompoundStatement() && !s->isScopeStatement())
{
s = new CompoundStatement(loc, this); // so scopeCode() gets called
}
s = s->semantic(sc);
return s;
}
// Same as semanticNoScope(), but do create a new scope
Statement *Statement::semanticScope(Scope *sc, Statement *sbreak, Statement *scontinue)
{ Scope *scd;
Statement *s;
scd = sc->push();
{
Scope *scd = sc->push();
if (sbreak)
scd->sbreak = sbreak;
if (scontinue)
scd->scontinue = scontinue;
s = semantic(scd);
Statement *s = semanticNoScope(scd);
scd->pop();
return s;
}
@@ -394,6 +404,13 @@ CompoundStatement::CompoundStatement(Loc loc, Statement *s1, Statement *s2)
statements->push(s2);
}
CompoundStatement::CompoundStatement(Loc loc, Statement *s1)
: Statement(loc)
{
statements = new Statements();
statements->push(s1);
}
Statement *CompoundStatement::syntaxCopy()
{
Statements *a = new Statements();
@@ -859,6 +876,7 @@ Statement *ScopeStatement::semantic(Scope *sc)
if (sfinally)
{
//printf("adding sfinally\n");
sfinally = sfinally->semantic(sc);
statement = new CompoundStatement(loc, statement, sfinally);
}
}
@@ -1065,7 +1083,8 @@ int DoStatement::blockExit()
else
result = BEfallthru;
if (result & BEfallthru)
{ if (condition->canThrow())
{
if (condition->canThrow())
result |= BEthrow;
if (!(result & BEbreak) && condition->isBool(TRUE))
result &= ~BEfallthru;
@@ -1148,7 +1167,7 @@ Statement *ForStatement::semantic(Scope *sc)
sc->sbreak = this;
sc->scontinue = this;
if (body)
body = body->semantic(sc);
body = body->semanticNoScope(sc);
sc->noctor--;
sc->pop();
@@ -1266,10 +1285,14 @@ ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Parameters *arguments,
this->value = NULL;
this->func = NULL;
this->cases = NULL;
this->gotos = NULL;
}
Statement *ForeachStatement::syntaxCopy()
{
//printf("ForeachStatement::syntaxCopy()\n");
Parameters *args = Parameter::arraySyntaxCopy(arguments);
Expression *exp = aggr->syntaxCopy();
ForeachStatement *s = new ForeachStatement(loc, op, args, exp,
@@ -1661,28 +1684,21 @@ Statement *ForeachStatement::semantic(Scope *sc)
#endif
case Tdelegate:
Lapply:
{ FuncDeclaration *fdapply;
Parameters *args;
{
Expression *ec;
Expression *e;
FuncLiteralDeclaration *fld;
Parameter *a;
Type *t;
Expression *flde;
Identifier *id;
Type *tret;
TypeDelegate* dgty;
TypeDelegate* dgty2;
TypeDelegate* fldeTy;
tret = func->type->nextOf();
Type *tret = func->type->nextOf();
// Need a variable to hold value from any return statements in body.
if (!sc->func->vresult && tret && tret != Type::tvoid)
{ VarDeclaration *v;
v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noscope = 1;
{
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noauto = 1;
v->semantic(sc);
if (!sc->insert(v))
assert(0);
@@ -1693,9 +1709,10 @@ Statement *ForeachStatement::semantic(Scope *sc)
/* Turn body into the function literal:
* int delegate(ref T arg) { body }
*/
args = new Parameters();
Parameters *args = new Parameters();
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = (Parameter *)arguments->data[i];
Identifier *id;
arg->type = arg->type->semantic(loc, sc);
if (arg->storageClass & STCref)
@@ -1703,34 +1720,33 @@ Statement *ForeachStatement::semantic(Scope *sc)
else
{ // Make a copy of the ref argument so it isn't
// a reference.
VarDeclaration *v;
Initializer *ie;
id = Lexer::uniqueId("__applyArg", i);
ie = new ExpInitializer(0, new IdentifierExp(0, id));
v = new VarDeclaration(0, arg->type, arg->ident, ie);
Initializer *ie = new ExpInitializer(0, new IdentifierExp(0, id));
VarDeclaration *v = new VarDeclaration(0, arg->type, arg->ident, ie);
s = new DeclarationStatement(0, v);
body = new CompoundStatement(loc, s, body);
}
a = new Parameter(STCref, arg->type, id, NULL);
args->push(a);
}
t = new TypeFunction(args, Type::tint32, 0, LINKd);
fld = new FuncLiteralDeclaration(loc, 0, t, TOKdelegate, this);
Type *t = new TypeFunction(args, Type::tint32, 0, LINKd);
cases = new Array();
gotos = new Array();
FuncLiteralDeclaration *fld = new FuncLiteralDeclaration(loc, 0, t, TOKdelegate, this);
fld->fbody = body;
flde = new FuncExp(loc, fld);
Expression *flde = new FuncExp(loc, fld);
flde = flde->semantic(sc);
// Resolve any forward referenced goto's
for (int i = 0; i < gotos.dim; i++)
{ CompoundStatement *cs = (CompoundStatement *)gotos.data[i];
for (size_t i = 0; i < gotos->dim; i++)
{ CompoundStatement *cs = (CompoundStatement *)gotos->data[i];
GotoStatement *gs = (GotoStatement *)cs->statements->data[0];
if (!gs->label->statement)
{ // 'Promote' it to this scope, and replace with a return
cases.push(gs);
s = new ReturnStatement(0, new IntegerExp(cases.dim + 1));
cases->push(gs);
s = new ReturnStatement(0, new IntegerExp(cases->dim + 1));
cs->statements->data[0] = (void *)s;
}
}
@@ -1779,6 +1795,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
args->push(new Parameter(STCin, aaApply_dg, NULL, NULL));
aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply");
}
FuncDeclaration *fdapply;
if (dim == 2) {
fdapply = aaApply2_fd;
fldeTy = aaApply2_dg;
@@ -1838,6 +1855,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
#endif
assert(j < sizeof(fdname));
//LDC: Build arguments.
FuncDeclaration *fdapply;
Parameters* args = new Parameters;
args->push(new Parameter(STCin, tn->arrayOf(), NULL, NULL));
if (dim == 2) {
@@ -1899,7 +1917,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
error("opApply() function for %s must return an int", tab->toChars());
}
if (!cases.dim)
if (!cases->dim)
// Easy case, a clean exit from the loop
s = new ExpStatement(loc, e);
else
@@ -1913,9 +1931,9 @@ Statement *ForeachStatement::semantic(Scope *sc)
a->push(s);
// cases 2...
for (int i = 0; i < cases.dim; i++)
for (int i = 0; i < cases->dim; i++)
{
s = (Statement *)cases.data[i];
s = (Statement *)cases->data[i];
s = new CaseStatement(0, new IntegerExp(i + 2), s);
a->push(s);
}
@@ -2064,7 +2082,9 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
/* Must infer types from lwr and upr
*/
AddExp ea(loc, lwr, upr);
ea.typeCombine(sc);
Expression *e = ea.typeCombine(sc);
if (e->op == TOKerror)
return this;
arg->type = ea.type->mutableOf();
lwr = ea.e1;
upr = ea.e2;
@@ -2265,7 +2285,7 @@ Statement *IfStatement::semantic(Scope *sc)
Type *t = arg->type ? arg->type : condition->type;
match = new VarDeclaration(loc, t, arg->ident, NULL);
match->noscope = 1;
match->noauto = 1;
match->semantic(scd);
if (!scd->insert(match))
assert(0);
@@ -2280,7 +2300,7 @@ Statement *IfStatement::semantic(Scope *sc)
}
else
scd = sc->push();
ifbody = ifbody->semantic(scd);
ifbody = ifbody->semanticNoScope(scd);
scd->pop();
cs1 = sc->callSuper;
@@ -2482,21 +2502,14 @@ Statement *PragmaStatement::semantic(Scope *sc)
Expression *e = (Expression *)args->data[i];
e = e->semantic(sc);
#if 1
e = e->optimize(WANTvalue | WANTinterpret);
#else
e = e->interpret(NULL);
if (e == EXP_CANT_INTERPRET)
fprintf(stdmsg, ((Expression *)args->data[i])->toChars());
else
#endif
if (e->op == TOKstring)
{
StringExp *se = (StringExp *)e;
fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
}
else
fprintf(stdmsg, e->toChars());
fprintf(stdmsg, "%s", e->toChars());
}
fprintf(stdmsg, "\n");
}
@@ -3368,18 +3381,18 @@ Statement *ReturnStatement::semantic(Scope *sc)
exp->op == TOKthis || exp->op == TOKsuper || exp->op == TOKnull ||
exp->op == TOKstring)
{
sc->fes->cases.push(this);
// Construct: return cases.dim+1;
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
sc->fes->cases->push(this);
// Construct: return cases->dim+1;
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1));
}
else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
{
s = new ReturnStatement(0, NULL);
sc->fes->cases.push(s);
sc->fes->cases->push(s);
// Construct: { exp; return cases.dim + 1; }
// Construct: { exp; return cases->dim + 1; }
Statement *s1 = new ExpStatement(loc, exp);
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1));
s = new CompoundStatement(loc, s1, s2);
}
else
@@ -3388,7 +3401,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
if (!fd->vresult)
{ // Declare vresult
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noscope = 1;
v->noauto = 1;
v->semantic(scx);
if (!scx->insert(v))
assert(0);
@@ -3397,14 +3410,13 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
s = new ReturnStatement(0, new VarExp(0, fd->vresult));
sc->fes->cases.push(s);
sc->fes->cases->push(s);
// Construct: { vresult = exp; return cases.dim + 1; }
exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp);
exp->op = TOKconstruct;
// Construct: { vresult = exp; return cases->dim + 1; }
exp = new ConstructExp(loc, new VarExp(0, fd->vresult), exp);
exp = exp->semantic(sc);
Statement *s1 = new ExpStatement(loc, exp);
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1));
s = new CompoundStatement(loc, s1, s2);
}
return s;
@@ -3529,8 +3541,8 @@ Statement *BreakStatement::semantic(Scope *sc)
* and 1 is break.
*/
Statement *s;
sc->fes->cases.push(this);
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
sc->fes->cases->push(this);
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1));
return s;
}
break; // can't break to it
@@ -3632,8 +3644,8 @@ Statement *ContinueStatement::semantic(Scope *sc)
* and 1 is break.
*/
Statement *s;
sc->fes->cases.push(this);
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
sc->fes->cases->push(this);
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases->dim + 1));
return s;
}
break; // can't continue to it
@@ -4083,7 +4095,7 @@ void Catch::semantic(Scope *sc)
type = new TypeIdentifier(0, Id::Object);
type = type->semantic(loc, sc);
if (!type->toBasetype()->isClassHandle())
error("can only catch class objects, not '%s'", type->toChars());
error(loc, "can only catch class objects, not '%s'", type->toChars());
else if (ident)
{
var = new VarDeclaration(loc, type, ident, NULL);
@@ -4136,17 +4148,12 @@ Statement *TryFinallyStatement::syntaxCopy()
Statement *TryFinallyStatement::semantic(Scope *sc)
{
//printf("TryFinallyStatement::semantic()\n");
Statement* oldScopeExit = sc->enclosingScopeExit;
sc->enclosingScopeExit = this;
body = body->semantic(sc);
sc->enclosingScopeExit = oldScopeExit;
sc = sc->push();
sc->enclosingFinally = this;
sc->sbreak = NULL;
sc->scontinue = NULL; // no break or continue out of finally block
finalbody = finalbody->semantic(sc);
finalbody = finalbody->semanticNoScope(sc);
sc->pop();
return this;
}
@@ -4414,7 +4421,7 @@ Statement *GotoStatement::semantic(Scope *sc)
a->push(this);
s = new CompoundStatement(loc, a);
sc->fes->gotos.push(s); // 'look at this later' list
sc->fes->gotos->push(s); // 'look at this later' list
return s;
}
if (label->statement && label->statement->enclosingFinally != sc->enclosingFinally)
@@ -4476,7 +4483,7 @@ Statement *LabelStatement::semantic(Scope *sc)
sc->callSuper |= CSXlabel;
sc->slabel = this;
if (statement)
statement = statement->semantic(sc);
statement = statement->semanticNoScope(sc);
sc->pop();
// LDC put in labmap