[svn r357] Merged DMD 1.033

This commit is contained in:
Tomas Lindquist Olsen
2008-07-12 19:38:31 +02:00
parent fc6e0cfc65
commit 832504e5d7
59 changed files with 18354 additions and 16980 deletions

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -113,6 +113,16 @@ int Statement::usesEH()
return FALSE;
}
/* Only valid after semantic analysis
*/
int Statement::blockExit()
{
printf("Statement::blockExit(%p)\n", this);
printf("%s\n", toChars());
assert(0);
return BEany;
}
// TRUE if statement may fall off the end without a throw or return
int Statement::fallOffEnd()
@@ -197,6 +207,25 @@ Statement *ExpStatement::semantic(Scope *sc)
return this;
}
int ExpStatement::blockExit()
{ int result = BEfallthru;
if (exp)
{
if (exp->op == TOKhalt)
return BEhalt;
if (exp->op == TOKassert)
{ AssertExp *a = (AssertExp *)exp;
if (a->e1->isBool(FALSE)) // if it's an assert(0)
return BEhalt;
}
if (exp->canThrow())
result |= BEthrow;
}
return result;
}
int ExpStatement::fallOffEnd()
{
if (exp)
@@ -237,15 +266,15 @@ void CompileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}
Statement *CompileStatement::semantic(Scope *sc)
Statements *CompileStatement::flatten(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
//printf("CompileStatement::flatten() %s\n", exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ error("argument to mixin must be a string, not (%s)", exp->toChars());
return this;
return NULL;
}
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
@@ -253,14 +282,22 @@ Statement *CompileStatement::semantic(Scope *sc)
p.loc = loc;
p.nextToken();
Statements *statements = new Statements();
Statements *a = new Statements();
while (p.token.value != TOKeof)
{
Statement *s = p.parseStatement(PSsemi | PScurlyscope);
statements->push(s);
a->push(s);
}
return a;
}
Statement *s = new CompoundStatement(loc, statements);
Statement *CompileStatement::semantic(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
Statements *a = flatten(sc);
if (!a)
return NULL;
Statement *s = new CompoundStatement(loc, a);
return s->semantic(sc);
}
@@ -468,7 +505,9 @@ Statement *CompoundStatement::semantic(Scope *sc)
i++;
}
if (statements->dim == 1 && !isAsmBlockStatement())
return s;
{
return (Statement *)statements->data[0];
}
return this;
}
@@ -478,13 +517,11 @@ Statements *CompoundStatement::flatten(Scope *sc)
}
ReturnStatement *CompoundStatement::isReturnStatement()
{ int i;
{
ReturnStatement *rs = NULL;
for (i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
rs = s->isReturnStatement();
@@ -496,12 +533,9 @@ ReturnStatement *CompoundStatement::isReturnStatement()
}
void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
for (i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
s->toCBuffer(buf, hgs);
}
@@ -510,15 +544,38 @@ void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
int CompoundStatement::usesEH()
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{ Statement *s = (Statement *) statements->data[i];
if (s && s->usesEH())
return TRUE;
}
return FALSE;
}
int CompoundStatement::blockExit()
{
//printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim);
int result = BEfallthru;
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
//printf("result = x%x\n", result);
//printf("%s\n", s->toChars());
if (!(result & BEfallthru) && !s->comeFrom())
{
if (global.params.warnings)
{ fprintf(stdmsg, "warning - ");
s->error("statement is not reachable");
}
}
result &= ~BEfallthru;
result |= s->blockExit();
}
}
return result;
}
int CompoundStatement::fallOffEnd()
{ int falloff = TRUE;
@@ -634,15 +691,27 @@ int UnrolledLoopStatement::hasContinue()
int UnrolledLoopStatement::usesEH()
{
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{ Statement *s = (Statement *) statements->data[i];
if (s && s->usesEH())
return TRUE;
}
return FALSE;
}
int UnrolledLoopStatement::blockExit()
{
int result = BEfallthru;
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
int r = s->blockExit();
result |= r & ~(BEbreak | BEcontinue);
}
}
return result;
}
int UnrolledLoopStatement::fallOffEnd()
{
//printf("UnrolledLoopStatement::fallOffEnd()\n");
@@ -655,7 +724,6 @@ int UnrolledLoopStatement::fallOffEnd()
return TRUE;
}
int UnrolledLoopStatement::comeFrom()
{ int comefrom = FALSE;
@@ -743,6 +811,12 @@ int ScopeStatement::usesEH()
return statement ? statement->usesEH() : FALSE;
}
int ScopeStatement::blockExit()
{
//printf("ScopeStatement::blockExit(%p)\n", statement);
return statement ? statement->blockExit() : BEfallthru;
}
int ScopeStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
@@ -844,6 +918,35 @@ int WhileStatement::usesEH()
return body ? body->usesEH() : 0;
}
int WhileStatement::blockExit()
{
//printf("WhileStatement::blockExit(%p)\n", this);
int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (condition->isBool(TRUE))
{
if (body)
{ result |= body->blockExit();
if (result & BEbreak)
result |= BEfallthru;
}
}
else if (condition->isBool(FALSE))
{
result |= BEfallthru;
}
else
{
if (body)
result |= body->blockExit();
result |= BEfallthru;
}
result &= ~(BEbreak | BEcontinue);
return result;
}
int WhileStatement::fallOffEnd()
{
if (body)
@@ -917,6 +1020,28 @@ int DoStatement::usesEH()
return body ? body->usesEH() : 0;
}
int DoStatement::blockExit()
{ int result;
if (body)
{ result = body->blockExit();
if (result == BEbreak)
return BEfallthru;
if (result & BEcontinue)
result |= BEfallthru;
}
else
result = BEfallthru;
if (result & BEfallthru)
{ if (condition->canThrow())
result |= BEthrow;
if (!(result & BEbreak) && condition->isBool(TRUE))
result &= ~BEfallthru;
}
result &= ~(BEbreak | BEcontinue);
return result;
}
int DoStatement::fallOffEnd()
{
if (body)
@@ -1024,6 +1149,31 @@ int ForStatement::usesEH()
return (init && init->usesEH()) || body->usesEH();
}
int ForStatement::blockExit()
{ int result = BEfallthru;
if (init)
{ result = init->blockExit();
if (!(result & BEfallthru))
return result;
}
if (condition)
{ if (condition->canThrow())
result |= BEthrow;
}
else
result &= ~BEfallthru; // the body must do the exiting
if (body)
{ int r = body->blockExit();
if (r & BEbreak)
result |= BEfallthru;
result |= r & ~(BEbreak | BEcontinue);
}
if (increment && increment->canThrow())
result |= BEthrow;
return result;
}
int ForStatement::fallOffEnd()
{
if (body)
@@ -1216,10 +1366,6 @@ Statement *ForeachStatement::semantic(Scope *sc)
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
if (e->isConst())
v->storage_class |= STCconst;
#if V2
else
v->storage_class |= STCfinal;
#endif
var = v;
}
}
@@ -1589,6 +1735,19 @@ int ForeachStatement::usesEH()
return body->usesEH();
}
int ForeachStatement::blockExit()
{ int result = BEfallthru;
if (aggr->canThrow())
result |= BEthrow;
if (body)
{
result |= body->blockExit() & ~(BEbreak | BEcontinue);
}
return result;
}
int ForeachStatement::fallOffEnd()
{
if (body)
@@ -1607,7 +1766,6 @@ void ForeachStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(Token::toChars(op));
buf->writestring(" (");
int i;
for (int i = 0; i < arguments->dim; i++)
{
Argument *a = (Argument *)arguments->data[i];
@@ -1718,6 +1876,42 @@ int IfStatement::usesEH()
return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH());
}
int IfStatement::blockExit()
{
//printf("IfStatement::blockExit(%p)\n", this);
int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (condition->isBool(TRUE))
{
if (ifbody)
result |= ifbody->blockExit();
else
result |= BEfallthru;
}
else if (condition->isBool(FALSE))
{
if (elsebody)
result |= elsebody->blockExit();
else
result |= BEfallthru;
}
else
{
if (ifbody)
result |= ifbody->blockExit();
else
result |= BEfallthru;
if (elsebody)
result |= elsebody->blockExit();
else
result |= BEfallthru;
}
//printf("IfStatement::blockExit(%p) = x%x\n", this, result);
return result;
}
int IfStatement::fallOffEnd()
{
if (!ifbody || ifbody->fallOffEnd() ||
@@ -1812,13 +2006,21 @@ void ConditionalStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
condition->toCBuffer(buf, hgs);
buf->writenl();
buf->writeByte('{');
buf->writenl();
if (ifbody)
ifbody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
if (elsebody)
{
buf->writestring("else");
buf->writenl();
buf->writeByte('{');
buf->writenl();
elsebody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
}
buf->writenl();
}
@@ -1908,6 +2110,18 @@ int PragmaStatement::usesEH()
return body && body->usesEH();
}
int PragmaStatement::blockExit()
{
int result = BEfallthru;
#if 0 // currently, no code is generated for Pragma's, so it's just fallthru
if (arrayExpressionCanThrow(args))
result |= BEthrow;
if (body)
result |= body->blockExit();
#endif
return result;
}
int PragmaStatement::fallOffEnd()
{
if (body)
@@ -2097,6 +2311,24 @@ int SwitchStatement::usesEH()
return body ? body->usesEH() : 0;
}
int SwitchStatement::blockExit()
{ int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (body)
{ result |= body->blockExit();
if (result & BEbreak)
{ result |= BEfallthru;
result &= ~BEbreak;
}
}
else
result |= BEfallthru;
return result;
}
int SwitchStatement::fallOffEnd()
{
if (body)
@@ -2204,6 +2436,11 @@ int CaseStatement::usesEH()
return statement->usesEH();
}
int CaseStatement::blockExit()
{
return statement->blockExit();
}
int CaseStatement::fallOffEnd()
{
return statement->fallOffEnd();
@@ -2243,6 +2480,7 @@ Statement *DefaultStatement::syntaxCopy()
Statement *DefaultStatement::semantic(Scope *sc)
{
//printf("DefaultStatement::semantic()\n");
if (sc->sw)
{
if (sc->sw->sdefault)
@@ -2262,6 +2500,11 @@ int DefaultStatement::usesEH()
return statement->usesEH();
}
int DefaultStatement::blockExit()
{
return statement->blockExit();
}
int DefaultStatement::fallOffEnd()
{
return statement->fallOffEnd();
@@ -2302,6 +2545,11 @@ Statement *GotoDefaultStatement::semantic(Scope *sc)
return this;
}
int GotoDefaultStatement::blockExit()
{
return BEgoto;
}
int GotoDefaultStatement::fallOffEnd()
{
return FALSE;
@@ -2351,6 +2599,11 @@ Statement *GotoCaseStatement::semantic(Scope *sc)
return this;
}
int GotoCaseStatement::blockExit()
{
return BEgoto;
}
int GotoCaseStatement::fallOffEnd()
{
return FALSE;
@@ -2374,6 +2627,11 @@ SwitchErrorStatement::SwitchErrorStatement(Loc loc)
{
}
int SwitchErrorStatement::blockExit()
{
return BEthrow;
}
int SwitchErrorStatement::fallOffEnd()
{
return FALSE;
@@ -2427,6 +2685,8 @@ Statement *ReturnStatement::semantic(Scope *sc)
Type *tret = fd->type->nextOf();
if (fd->tintro)
/* We'll be implicitly casting the return expression to tintro
*/
tret = fd->tintro->nextOf();
Type *tbret = NULL;
@@ -2636,9 +2896,13 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
if (exp && tbret->ty == Tvoid && !fd->isMain())
{ Statement *s;
s = new ExpStatement(loc, exp);
{
/* Replace:
* return exp;
* with:
* exp; return;
*/
Statement *s = new ExpStatement(loc, exp);
loc = 0;
exp = NULL;
return new CompoundStatement(loc, s, this);
@@ -2647,6 +2911,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
return this;
}
int ReturnStatement::blockExit()
{ int result = BEreturn;
if (exp && exp->canThrow())
result |= BEthrow;
return result;
}
int ReturnStatement::fallOffEnd()
{
return FALSE;
@@ -2678,6 +2950,7 @@ Statement *BreakStatement::syntaxCopy()
Statement *BreakStatement::semantic(Scope *sc)
{
//printf("BreakStatement::semantic()\n");
enclosinghandler = sc->tfOfTry;
// If:
// break Identifier;
@@ -2739,6 +3012,12 @@ Statement *BreakStatement::semantic(Scope *sc)
return this;
}
int BreakStatement::blockExit()
{
//printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak);
return ident ? BEgoto : BEbreak;
}
int BreakStatement::fallOffEnd()
{
return FALSE;
@@ -2842,6 +3121,11 @@ Statement *ContinueStatement::semantic(Scope *sc)
return this;
}
int ContinueStatement::blockExit()
{
return ident ? BEgoto : BEcontinue;
}
int ContinueStatement::fallOffEnd()
{
return FALSE;
@@ -2932,6 +3216,11 @@ int SynchronizedStatement::usesEH()
return TRUE;
}
int SynchronizedStatement::blockExit()
{
return body ? body->blockExit() : BEfallthru;
}
int SynchronizedStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
@@ -3042,6 +3331,18 @@ int WithStatement::usesEH()
return body ? body->usesEH() : 0;
}
int WithStatement::blockExit()
{
int result = BEnone;
if (exp->canThrow())
result = BEthrow;
if (body)
result |= body->blockExit();
else
result |= BEfallthru;
return result;
}
int WithStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
@@ -3075,14 +3376,14 @@ Statement *TryCatchStatement::semantic(Scope *sc)
{
body = body->semanticScope(sc, NULL /*this*/, NULL);
for (int i = 0; i < catches->dim; i++)
{ Catch *c;
c = (Catch *)catches->data[i];
/* Even if body is NULL, still do semantic analysis on catches
*/
for (size_t i = 0; i < catches->dim; i++)
{ Catch *c = (Catch *)catches->data[i];
c->semantic(sc);
// Determine if current catch 'hides' any previous catches
for (int j = 0; j < i; j++)
for (size_t j = 0; j < i; j++)
{ Catch *cj = (Catch *)catches->data[j];
char *si = c->loc.toChars();
char *sj = cj->loc.toChars();
@@ -3104,6 +3405,20 @@ int TryCatchStatement::usesEH()
return TRUE;
}
int TryCatchStatement::blockExit()
{ int result;
assert(body);
result = body->blockExit();
for (size_t i = 0; i < catches->dim; i++)
{
Catch *c = (Catch *)catches->data[i];
result |= c->blockExit();
}
return result;
}
int TryCatchStatement::fallOffEnd()
{
int result = FALSE;
@@ -3126,8 +3441,7 @@ void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
if (body)
body->toCBuffer(buf, hgs);
int i;
for (i = 0; i < catches->dim; i++)
for (size_t i = 0; i < catches->dim; i++)
{
Catch *c = (Catch *)catches->data[i];
c->toCBuffer(buf, hgs);
@@ -3193,6 +3507,11 @@ void Catch::semantic(Scope *sc)
sc->pop();
}
int Catch::blockExit()
{
return handler ? handler->blockExit() : BEfallthru;
}
void Catch::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("catch");
@@ -3204,7 +3523,8 @@ void Catch::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
buf->writebyte('{');
buf->writenl();
handler->toCBuffer(buf, hgs);
if (handler)
handler->toCBuffer(buf, hgs);
buf->writebyte('}');
buf->writenl();
}
@@ -3269,6 +3589,12 @@ int TryFinallyStatement::usesEH()
return TRUE;
}
int TryFinallyStatement::blockExit()
{
int result = body->blockExit();
return result;
}
int TryFinallyStatement::fallOffEnd()
{ int result;
@@ -3300,6 +3626,11 @@ Statement *OnScopeStatement::semantic(Scope *sc)
return this;
}
int OnScopeStatement::blockExit()
{ // At this point, this statement is just an empty placeholder
return BEfallthru;
}
void OnScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(Token::toChars(tok));
@@ -3391,6 +3722,11 @@ Statement *ThrowStatement::semantic(Scope *sc)
return this;
}
int ThrowStatement::blockExit()
{
return BEthrow; // obviously
}
int ThrowStatement::fallOffEnd()
{
return FALSE;
@@ -3449,6 +3785,11 @@ Statements *VolatileStatement::flatten(Scope *sc)
return a;
}
int VolatileStatement::blockExit()
{
return statement ? statement->blockExit() : BEfallthru;
}
int VolatileStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
@@ -3512,6 +3853,12 @@ Statement *GotoStatement::semantic(Scope *sc)
return this;
}
int GotoStatement::blockExit()
{
//printf("GotoStatement::blockExit(%p)\n", this);
return BEgoto;
}
int GotoStatement::fallOffEnd()
{
return FALSE;
@@ -3601,6 +3948,12 @@ int LabelStatement::usesEH()
return statement ? statement->usesEH() : FALSE;
}
int LabelStatement::blockExit()
{
//printf("LabelStatement::blockExit(%p)\n", this);
return statement ? statement->blockExit() : BEfallthru;
}
int LabelStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;