mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-18 01:39:03 +02:00
Merged DMD 1.037 frontend
This commit is contained in:
158
dmd/statement.c
158
dmd/statement.c
@@ -26,6 +26,7 @@
|
||||
#include "id.h"
|
||||
#include "hdrgen.h"
|
||||
#include "parse.h"
|
||||
#include "template.h"
|
||||
|
||||
/******************************** Statement ***************************/
|
||||
|
||||
@@ -451,10 +452,7 @@ Statement *CompoundStatement::semantic(Scope *sc)
|
||||
body = new CompoundStatement(0, a);
|
||||
body = new ScopeStatement(0, body);
|
||||
|
||||
static int num;
|
||||
char name[3 + sizeof(num) * 3 + 1];
|
||||
sprintf(name, "__o%d", ++num);
|
||||
Identifier *id = Lexer::idPool(name);
|
||||
Identifier *id = Lexer::uniqueId("__o");
|
||||
|
||||
Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id));
|
||||
handler = new CompoundStatement(0, sexception, handler);
|
||||
@@ -1107,12 +1105,17 @@ Statement *ForStatement::semantic(Scope *sc)
|
||||
// Use a default value
|
||||
condition = new IntegerExp(loc, 1, Type::tboolean);
|
||||
sc->noctor++;
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
condition = condition->optimize(WANTvalue);
|
||||
condition = condition->checkToBoolean();
|
||||
if (condition)
|
||||
{
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
condition = condition->optimize(WANTvalue);
|
||||
condition = condition->checkToBoolean();
|
||||
}
|
||||
if (increment)
|
||||
increment = increment->semantic(sc);
|
||||
{ increment = increment->semantic(sc);
|
||||
increment = resolveProperties(sc, increment);
|
||||
}
|
||||
|
||||
sc->sbreak = this;
|
||||
sc->scontinue = this;
|
||||
@@ -1257,8 +1260,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
//printf("ForeachStatement::semantic() %p\n", this);
|
||||
ScopeDsymbol *sym;
|
||||
Statement *s = this;
|
||||
int dim = arguments->dim;
|
||||
int i;
|
||||
size_t dim = arguments->dim;
|
||||
TypeAArray *taa = NULL;
|
||||
|
||||
Type *tn = NULL;
|
||||
@@ -1272,6 +1274,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
|
||||
aggr = aggr->semantic(sc);
|
||||
aggr = resolveProperties(sc, aggr);
|
||||
aggr = aggr->optimize(WANTvalue);
|
||||
if (!aggr->type)
|
||||
{
|
||||
error("invalid foreach aggregate %s", aggr->toChars());
|
||||
@@ -1387,7 +1390,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
return s;
|
||||
}
|
||||
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)arguments->data[i];
|
||||
if (!arg->type)
|
||||
{
|
||||
@@ -1419,7 +1422,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
|
||||
{ Argument *arg;
|
||||
|
||||
i = (dim == 1) ? 0 : 1; // index of value
|
||||
int i = (dim == 1) ? 0 : 1; // index of value
|
||||
arg = (Argument *)arguments->data[i];
|
||||
arg->type = arg->type->semantic(loc, sc);
|
||||
tnv = arg->type->toBasetype();
|
||||
@@ -1437,7 +1440,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ // Declare args
|
||||
Argument *arg = (Argument *)arguments->data[i];
|
||||
VarDeclaration *var;
|
||||
@@ -1468,7 +1471,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
if (aggr->op == TOKstring)
|
||||
aggr = aggr->implicitCastTo(sc, value->type->arrayOf());
|
||||
else
|
||||
error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars());
|
||||
error("foreach: %s is not an array of %s",
|
||||
tab->toChars(), value->type->toChars());
|
||||
}
|
||||
|
||||
if (key)
|
||||
@@ -1505,6 +1509,72 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
|
||||
case Tclass:
|
||||
case Tstruct:
|
||||
#if DMDV2
|
||||
{ /* Look for range iteration, i.e. the properties
|
||||
* .empty, .next, .retreat, .head and .rear
|
||||
* foreach (e; range) { ... }
|
||||
* translates to:
|
||||
* for (auto __r = range; !__r.empty; __r.next)
|
||||
* { auto e = __r.head;
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
if (dim != 1) // only one argument allowed with ranges
|
||||
goto Lapply;
|
||||
AggregateDeclaration *ad = (tab->ty == Tclass)
|
||||
? (AggregateDeclaration *)((TypeClass *)tab)->sym
|
||||
: (AggregateDeclaration *)((TypeStruct *)tab)->sym;
|
||||
Identifier *idhead;
|
||||
Identifier *idnext;
|
||||
if (op == TOKforeach)
|
||||
{ idhead = Id::Fhead;
|
||||
idnext = Id::Fnext;
|
||||
}
|
||||
else
|
||||
{ idhead = Id::Frear;
|
||||
idnext = Id::Fretreat;
|
||||
}
|
||||
Dsymbol *shead = search_function(ad, idhead);
|
||||
if (!shead)
|
||||
goto Lapply;
|
||||
|
||||
/* Generate a temporary __r and initialize it with the aggregate.
|
||||
*/
|
||||
Identifier *id = Identifier::generateId("__r");
|
||||
VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr));
|
||||
r->semantic(sc);
|
||||
Statement *init = new DeclarationStatement(loc, r);
|
||||
|
||||
// !__r.empty
|
||||
Expression *e = new VarExp(loc, r);
|
||||
e = new DotIdExp(loc, e, Id::Fempty);
|
||||
Expression *condition = new NotExp(loc, e);
|
||||
|
||||
// __r.next
|
||||
e = new VarExp(loc, r);
|
||||
Expression *increment = new DotIdExp(loc, e, idnext);
|
||||
|
||||
/* Declaration statement for e:
|
||||
* auto e = __r.idhead;
|
||||
*/
|
||||
e = new VarExp(loc, r);
|
||||
Expression *einit = new DotIdExp(loc, e, idhead);
|
||||
einit = einit->semantic(sc);
|
||||
Argument *arg = (Argument *)arguments->data[0];
|
||||
VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit));
|
||||
ve->storage_class |= STCforeach;
|
||||
ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant);
|
||||
|
||||
DeclarationExp *de = new DeclarationExp(loc, ve);
|
||||
|
||||
Statement *body = new CompoundStatement(loc,
|
||||
new DeclarationStatement(loc, de), this->body);
|
||||
|
||||
s = new ForStatement(loc, init, condition, increment, body);
|
||||
s = s->semantic(sc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case Tdelegate:
|
||||
Lapply:
|
||||
{ FuncDeclaration *fdapply;
|
||||
@@ -1540,7 +1610,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
* int delegate(ref T arg) { body }
|
||||
*/
|
||||
args = new Arguments();
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)arguments->data[i];
|
||||
|
||||
arg->type = arg->type->semantic(loc, sc);
|
||||
@@ -1551,10 +1621,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
// a reference.
|
||||
VarDeclaration *v;
|
||||
Initializer *ie;
|
||||
char applyArg[10 + sizeof(i)*3 + 1];
|
||||
|
||||
sprintf(applyArg, "__applyArg%d", i);
|
||||
id = Lexer::idPool(applyArg);
|
||||
id = Lexer::uniqueId("__applyArg", i);
|
||||
|
||||
ie = new ExpInitializer(0, new IdentifierExp(0, id));
|
||||
v = new VarDeclaration(0, arg->type, arg->ident, ie);
|
||||
@@ -2145,6 +2213,11 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
||||
}
|
||||
else if (ident == Id::lib)
|
||||
{
|
||||
#if 1
|
||||
/* Should this be allowed?
|
||||
*/
|
||||
error("pragma(lib) not allowed as statement");
|
||||
#else
|
||||
if (!args || args->dim != 1)
|
||||
error("string expected for library name");
|
||||
else
|
||||
@@ -2166,6 +2239,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
||||
mem.free(name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
error("unrecognized pragma(%s)", ident->toChars());
|
||||
@@ -2454,8 +2528,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
//printf("CaseStatement::semantic() %s\n", toChars());
|
||||
exp = exp->semantic(sc);
|
||||
if (sw)
|
||||
{ int i;
|
||||
|
||||
{
|
||||
exp = exp->implicitCastTo(sc, sw->condition->type);
|
||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
||||
if (exp->op != TOKstring && exp->op != TOKint64)
|
||||
@@ -2464,7 +2537,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
exp = new IntegerExp(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw->cases->dim; i++)
|
||||
for (int i = 0; i < sw->cases->dim; i++)
|
||||
{
|
||||
CaseStatement *cs = (CaseStatement *)sw->cases->data[i];
|
||||
|
||||
@@ -2478,7 +2551,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
sw->cases->push(this);
|
||||
|
||||
// Resolve any goto case's with no exp to this case statement
|
||||
for (i = 0; i < sw->gotoCases.dim; i++)
|
||||
for (size_t i = 0; i < sw->gotoCases.dim; i++)
|
||||
{
|
||||
GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i];
|
||||
|
||||
@@ -2875,32 +2948,25 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
exp->op == TOKstring)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Statement *s1;
|
||||
Statement *s2;
|
||||
|
||||
s = new ReturnStatement(0, NULL);
|
||||
sc->fes->cases.push(s);
|
||||
|
||||
// Construct: { exp; return cases.dim + 1; }
|
||||
s1 = new ExpStatement(loc, exp);
|
||||
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
Statement *s1 = new ExpStatement(loc, exp);
|
||||
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
s = new CompoundStatement(loc, s1, s2);
|
||||
}
|
||||
else
|
||||
{
|
||||
VarExp *v;
|
||||
Statement *s1;
|
||||
Statement *s2;
|
||||
|
||||
// Construct: return vresult;
|
||||
if (!fd->vresult)
|
||||
{ VarDeclaration *v;
|
||||
|
||||
v = new VarDeclaration(loc, tret, Id::result, NULL);
|
||||
{ // Declare vresult
|
||||
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
|
||||
v->noauto = 1;
|
||||
v->semantic(scx);
|
||||
if (!scx->insert(v))
|
||||
@@ -2909,16 +2975,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
fd->vresult = v;
|
||||
}
|
||||
|
||||
v = new VarExp(0, fd->vresult);
|
||||
s = new ReturnStatement(0, v);
|
||||
s = new ReturnStatement(0, new VarExp(0, fd->vresult));
|
||||
sc->fes->cases.push(s);
|
||||
|
||||
// Construct: { vresult = exp; return cases.dim + 1; }
|
||||
v = new VarExp(0, fd->vresult);
|
||||
exp = new AssignExp(loc, v, exp);
|
||||
exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp);
|
||||
exp = exp->semantic(sc);
|
||||
s1 = new ExpStatement(loc, exp);
|
||||
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
Statement *s1 = new ExpStatement(loc, exp);
|
||||
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
s = new CompoundStatement(loc, s1, s2);
|
||||
}
|
||||
return s;
|
||||
@@ -2959,9 +3023,10 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
|
||||
gs->label = fd->returnLabel;
|
||||
if (exp)
|
||||
{ Statement *s;
|
||||
|
||||
s = new ExpStatement(0, exp);
|
||||
{ /* Replace: return exp;
|
||||
* with: exp; goto returnLabel;
|
||||
*/
|
||||
Statement *s = new ExpStatement(0, exp);
|
||||
return new CompoundStatement(loc, s, gs);
|
||||
}
|
||||
return gs;
|
||||
@@ -3739,10 +3804,7 @@ void OnScopeStatement::scopeCode(Statement **sentry, Statement **sexception, Sta
|
||||
* sexception: x = 1;
|
||||
* sfinally: if (!x) statement;
|
||||
*/
|
||||
static int num;
|
||||
char name[5 + sizeof(num) * 3 + 1];
|
||||
sprintf(name, "__osf%d", ++num);
|
||||
Identifier *id = Lexer::idPool(name);
|
||||
Identifier *id = Lexer::uniqueId("__os");
|
||||
|
||||
ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0));
|
||||
VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie);
|
||||
|
||||
Reference in New Issue
Block a user