mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-08-03 04:50:05 +02:00
[svn r357] Merged DMD 1.033
This commit is contained in:
437
dmd/statement.c
437
dmd/statement.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user