mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-18 01:39:03 +02:00
fixes #431 :: apply DMDFE 1.062; thanks SiegeLord
This commit is contained in:
151
dmd/statement.c
151
dmd/statement.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user