Reorganize EnclosingHandlers to require less changes to the frontend and allow us to

implement the synchronized storage class for functions.
This commit is contained in:
Christian Kamm
2009-03-24 21:18:18 +01:00
parent a0d93e699a
commit 671c7791e3
12 changed files with 217 additions and 228 deletions

View File

@@ -682,8 +682,8 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->explicitProtection = 0;
sc2->structalign = 8;
sc2->incontract = 0;
sc2->tf = NULL;
sc2->tfOfTry = NULL;
sc2->enclosingFinally = NULL;
sc2->enclosingScopeExit = NULL;
sc2->noctor = 0;
// Declare 'this'
@@ -1243,6 +1243,38 @@ void FuncDeclaration::semantic3(Scope *sc)
}
fbody = new CompoundStatement(0, a);
// wrap body of synchronized functions in a synchronized statement
if (isSynchronized())
{
ClassDeclaration *cd = parent->isClassDeclaration();
if (!cd)
error("synchronized function %s must be a member of a class", toChars());
Expression *sync;
if (isStatic())
{
// static member functions synchronize on classinfo
// (the expression passed doesn't matter)
sync = cd->type->dotExp(sc2, new DollarExp(loc), Id::classinfo);
}
else
{
// non-static member functions synchronize on this
sync = new VarExp(loc, vthis);
}
// is is ok to not rerun semantic on the whole fbody here; only the enclosingScopeExit
// value will differ and as it is impossible to goto out of this synchronized statement,
// that should not lead to errors
SynchronizedStatement* s = new SynchronizedStatement(loc, sync, NULL);
s->semantic(sc2);
s->body = fbody;
a = new Statements;
a->push(s);
fbody = new CompoundStatement(0, a);
}
}
sc2->callSuper = 0;

View File

@@ -52,8 +52,8 @@ Scope::Scope()
this->enclosing = NULL;
this->parent = NULL;
this->sw = NULL;
this->tf = NULL;
this->tfOfTry = NULL;
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
this->tinst = NULL;
this->sbreak = NULL;
this->scontinue = NULL;
@@ -91,8 +91,8 @@ Scope::Scope(Scope *enclosing)
this->scopesym = NULL;
this->sd = NULL;
this->sw = enclosing->sw;
this->tf = enclosing->tf;
this->tfOfTry = enclosing->tfOfTry;
this->enclosingFinally = enclosing->enclosingFinally;
this->enclosingScopeExit = enclosing->enclosingScopeExit;
this->tinst = enclosing->tinst;
this->sbreak = enclosing->sbreak;
this->scontinue = enclosing->scontinue;

View File

@@ -46,8 +46,8 @@ struct Scope
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
EnclosingHandler *tfOfTry; // enclosing try-finally, volatile or synchronized statement; set inside its try or body block
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
TemplateInstance *tinst; // enclosing template instance
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"

View File

@@ -582,7 +582,6 @@ UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
: Statement(loc)
{
statements = s;
enclosinghandler = NULL;
}
Statement *UnrolledLoopStatement::syntaxCopy()
@@ -604,8 +603,6 @@ Statement *UnrolledLoopStatement::semantic(Scope *sc)
{
//printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
enclosinghandler = sc->tfOfTry;
sc->noctor++;
Scope *scd = sc->push();
scd->sbreak = this;
@@ -795,7 +792,6 @@ WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
{
condition = c;
body = b;
enclosinghandler = NULL;
}
Statement *WhileStatement::syntaxCopy()
@@ -830,8 +826,6 @@ Statement *WhileStatement::semantic(Scope *sc)
}
#endif
enclosinghandler = sc->tfOfTry;
condition = condition->semantic(sc);
condition = resolveProperties(sc, condition);
condition = condition->optimize(WANTvalue);
@@ -919,7 +913,6 @@ DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
{
body = b;
condition = c;
enclosinghandler = NULL;
}
Statement *DoStatement::syntaxCopy()
@@ -931,8 +924,6 @@ Statement *DoStatement::syntaxCopy()
Statement *DoStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
sc->noctor++;
if (body)
body = body->semanticScope(sc, this, this);
@@ -1010,7 +1001,6 @@ ForStatement::ForStatement(Loc loc, Statement *init, Expression *condition, Expr
this->condition = condition;
this->increment = increment;
this->body = body;
this->enclosinghandler = NULL;
}
Statement *ForStatement::syntaxCopy()
@@ -1030,8 +1020,6 @@ Statement *ForStatement::syntaxCopy()
Statement *ForStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
ScopeDsymbol *sym = new ScopeDsymbol();
sym->parent = sc->scopesym;
sc = sc->push(sym);
@@ -1169,7 +1157,6 @@ ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Arguments *arguments,
this->arguments = arguments;
this->aggr = aggr;
this->body = body;
this->enclosinghandler = NULL;
this->key = NULL;
this->value = NULL;
@@ -1197,8 +1184,6 @@ Statement *ForeachStatement::semantic(Scope *sc)
Type *tn = NULL;
Type *tnv = NULL;
enclosinghandler = sc->tfOfTry;
func = sc->func;
if (func->fes)
func = func->fes->func;
@@ -2253,8 +2238,6 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
sdefault = NULL;
cases = NULL;
hasNoDefault = 0;
// LDC
enclosinghandler = NULL;
}
Statement *SwitchStatement::syntaxCopy()
@@ -2269,8 +2252,6 @@ Statement *SwitchStatement::semantic(Scope *sc)
//printf("SwitchStatement::semantic(%p)\n", this);
assert(!cases); // ensure semantic() is only run once
enclosinghandler = sc->tfOfTry;
condition = condition->semantic(sc);
condition = resolveProperties(sc, condition);
if (condition->type->isString())
@@ -2571,7 +2552,6 @@ GotoDefaultStatement::GotoDefaultStatement(Loc loc)
: Statement(loc)
{
sw = NULL;
enclosinghandler = NULL;
}
Statement *GotoDefaultStatement::syntaxCopy()
@@ -2582,7 +2562,6 @@ Statement *GotoDefaultStatement::syntaxCopy()
Statement *GotoDefaultStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
sw = sc->sw;
if (!sw)
error("goto default not in switch statement");
@@ -2606,7 +2585,6 @@ GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
{
cs = NULL;
this->exp = exp;
enclosinghandler = NULL;
sw = NULL;
}
@@ -2619,7 +2597,6 @@ Statement *GotoCaseStatement::syntaxCopy()
Statement *GotoCaseStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
if (exp)
exp = exp->semantic(sc);
@@ -2678,7 +2655,6 @@ ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
: Statement(loc)
{
this->exp = exp;
this->enclosinghandler = NULL;
}
Statement *ReturnStatement::syntaxCopy()
@@ -2693,7 +2669,6 @@ Statement *ReturnStatement::syntaxCopy()
Statement *ReturnStatement::semantic(Scope *sc)
{
//printf("ReturnStatement::semantic() %s\n", toChars());
this->enclosinghandler = sc->tfOfTry;
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
Scope *scx = sc;
@@ -2730,7 +2705,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
if (sc->incontract || scx->incontract)
error("return statements cannot be in contracts");
if (sc->tf || scx->tf)
if (sc->enclosingFinally || scx->enclosingFinally)
error("return statements cannot be in finally, scope(exit) or scope(success) bodies");
if (fd->isCtorDeclaration())
@@ -2955,7 +2930,6 @@ BreakStatement::BreakStatement(Loc loc, Identifier *ident)
: Statement(loc)
{
this->ident = ident;
this->enclosinghandler = NULL;
}
Statement *BreakStatement::syntaxCopy()
@@ -2967,7 +2941,6 @@ Statement *BreakStatement::syntaxCopy()
Statement *BreakStatement::semantic(Scope *sc)
{
//printf("BreakStatement::semantic()\n");
enclosinghandler = sc->tfOfTry;
// If:
// break Identifier;
if (ident)
@@ -3005,7 +2978,7 @@ Statement *BreakStatement::semantic(Scope *sc)
if (!s->hasBreak())
error("label '%s' has no break", ident->toChars());
if (ls->tf != sc->tf)
if (ls->enclosingFinally != sc->enclosingFinally)
error("cannot break out of finally block");
this->target = ls;
@@ -3051,7 +3024,6 @@ ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
: Statement(loc)
{
this->ident = ident;
this->enclosinghandler = NULL;
}
Statement *ContinueStatement::syntaxCopy()
@@ -3062,7 +3034,6 @@ Statement *ContinueStatement::syntaxCopy()
Statement *ContinueStatement::semantic(Scope *sc)
{
enclosinghandler = sc->tfOfTry;
//printf("ContinueStatement::semantic() %p\n", this);
if (ident)
{
@@ -3109,7 +3080,7 @@ Statement *ContinueStatement::semantic(Scope *sc)
if (!s->hasContinue())
error("label '%s' has no continue", ident->toChars());
if (ls->tf != sc->tf)
if (ls->enclosingFinally != sc->enclosingFinally)
error("cannot continue out of finally block");
this->target = ls;
@@ -3156,7 +3127,6 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement
this->exp = exp;
this->body = body;
this->esync = NULL;
this->enclosinghandler = NULL;
// LDC
this->llsync = NULL;
}
@@ -3167,7 +3137,6 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *bo
this->exp = NULL;
this->body = body;
this->esync = esync;
this->enclosinghandler = NULL;
// LDC
this->llsync = NULL;
}
@@ -3199,10 +3168,10 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
}
if (body)
{
enclosinghandler = sc->tfOfTry;
sc->tfOfTry = new EnclosingSynchro(this);
body = body->semantic(sc);
sc->tfOfTry = enclosinghandler;
Statement* oldScopeExit = sc->enclosingScopeExit;
sc->enclosingScopeExit = this;
body = body->semantic(sc);
sc->enclosingScopeExit = oldScopeExit;
}
return this;
}
@@ -3455,7 +3424,7 @@ void Catch::semantic(Scope *sc)
//printf("Catch::semantic(%s)\n", ident->toChars());
#ifndef IN_GCC
if (sc->tf)
if (sc->enclosingFinally)
{
/* This is because the _d_local_unwind() gets the stack munged
* up on this. The workaround is to place any try-catches into
@@ -3516,7 +3485,6 @@ TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *fi
{
this->body = body;
this->finalbody = finalbody;
this->enclosinghandler = NULL;
}
Statement *TryFinallyStatement::syntaxCopy()
@@ -3530,13 +3498,13 @@ Statement *TryFinallyStatement::semantic(Scope *sc)
{
//printf("TryFinallyStatement::semantic()\n");
enclosinghandler = sc->tfOfTry;
sc->tfOfTry = new EnclosingTryFinally(this);
Statement* oldScopeExit = sc->enclosingScopeExit;
sc->enclosingScopeExit = this;
body = body->semantic(sc);
sc->tfOfTry = enclosinghandler;
sc->enclosingScopeExit = oldScopeExit;
sc = sc->push();
sc->tf = this;
sc->enclosingFinally = this;
sc->sbreak = NULL;
sc->scontinue = NULL; // no break or continue out of finally block
finalbody = finalbody->semantic(sc);
@@ -3711,7 +3679,6 @@ VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
: Statement(loc)
{
this->statement = statement;
this->enclosinghandler = NULL;
}
Statement *VolatileStatement::syntaxCopy()
@@ -3725,10 +3692,10 @@ Statement *VolatileStatement::semantic(Scope *sc)
{
if (statement)
{
enclosinghandler = sc->tfOfTry;
sc->tfOfTry = new EnclosingVolatile(this);
statement = statement->semantic(sc);
sc->tfOfTry = enclosinghandler;
Statement* oldScopeExit = sc->enclosingScopeExit;
sc->enclosingScopeExit = this;
statement = statement->semantic(sc);
sc->enclosingScopeExit = oldScopeExit;
}
return this;
}
@@ -3775,8 +3742,8 @@ GotoStatement::GotoStatement(Loc loc, Identifier *ident)
{
this->ident = ident;
this->label = NULL;
this->tf = NULL;
this->enclosinghandler = NULL;
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
}
Statement *GotoStatement::syntaxCopy()
@@ -3789,8 +3756,9 @@ Statement *GotoStatement::semantic(Scope *sc)
{ FuncDeclaration *fd = sc->parent->isFuncDeclaration();
//printf("GotoStatement::semantic()\n");
tf = sc->tf;
enclosinghandler = sc->tfOfTry;
enclosingFinally = sc->enclosingFinally;
enclosingScopeExit = sc->enclosingScopeExit;
label = fd->searchLabel(ident);
if (!label->statement && sc->fes)
{
@@ -3808,7 +3776,7 @@ Statement *GotoStatement::semantic(Scope *sc)
sc->fes->gotos.push(s); // 'look at this later' list
return s;
}
if (label->statement && label->statement->tf != sc->tf)
if (label->statement && label->statement->enclosingFinally != sc->enclosingFinally)
error("cannot goto in or out of finally block");
return this;
}
@@ -3834,8 +3802,8 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
{
this->ident = ident;
this->statement = statement;
this->tf = NULL;
this->enclosinghandler = NULL;
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
this->lblock = NULL;
this->isReturnLabel = 0;
this->asmLabel = false;
@@ -3857,8 +3825,10 @@ Statement *LabelStatement::semantic(Scope *sc)
error("Label '%s' already defined", ls->toChars());
else
ls->statement = this;
tf = sc->tf;
enclosinghandler = sc->tfOfTry;
enclosingFinally = sc->enclosingFinally;
enclosingScopeExit = sc->enclosingScopeExit;
sc = sc->push();
sc->scopesym = sc->enclosing->scopesym;
sc->callSuper |= CSXlabel;

View File

@@ -94,35 +94,6 @@ enum BE
BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt),
};
// LDC this is used for tracking try-finally, synchronized and volatile scopes
// definitions in gen/llvmhelpers.cpp
struct EnclosingHandler : Object
{
virtual void emitCode(IRState* p) = 0;
virtual EnclosingHandler* getEnclosing() = 0;
};
struct EnclosingTryFinally : EnclosingHandler
{
TryFinallyStatement* tf;
void emitCode(IRState* p);
EnclosingHandler* getEnclosing();
EnclosingTryFinally(TryFinallyStatement* _tf) : tf(_tf) {}
};
struct EnclosingVolatile : EnclosingHandler
{
VolatileStatement* v;
void emitCode(IRState* p);
EnclosingHandler* getEnclosing();
EnclosingVolatile(VolatileStatement* _tf) : v(_tf) {}
};
struct EnclosingSynchro : EnclosingHandler
{
SynchronizedStatement* s;
void emitCode(IRState* p);
EnclosingHandler* getEnclosing();
EnclosingSynchro(SynchronizedStatement* _tf) : s(_tf) {}
};
struct Statement : Object
{
Loc loc;
@@ -255,7 +226,6 @@ struct CompoundStatement : Statement
struct UnrolledLoopStatement : Statement
{
Statements *statements;
EnclosingHandler* enclosinghandler;
UnrolledLoopStatement(Loc loc, Statements *statements);
Statement *syntaxCopy();
@@ -300,7 +270,6 @@ struct WhileStatement : Statement
{
Expression *condition;
Statement *body;
EnclosingHandler* enclosinghandler;
WhileStatement(Loc loc, Expression *c, Statement *b);
Statement *syntaxCopy();
@@ -322,7 +291,6 @@ struct DoStatement : Statement
{
Statement *body;
Expression *condition;
EnclosingHandler* enclosinghandler;
DoStatement(Loc loc, Statement *b, Expression *c);
Statement *syntaxCopy();
@@ -346,7 +314,6 @@ struct ForStatement : Statement
Expression *condition;
Expression *increment;
Statement *body;
EnclosingHandler* enclosinghandler;
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body);
Statement *syntaxCopy();
@@ -371,7 +338,6 @@ struct ForeachStatement : Statement
Arguments *arguments; // array of Argument*'s
Expression *aggr;
Statement *body;
EnclosingHandler* enclosinghandler;
VarDeclaration *key;
VarDeclaration *value;
@@ -499,7 +465,6 @@ struct SwitchStatement : Statement
Statement *body;
DefaultStatement *sdefault;
EnclosingHandler* enclosinghandler;
Array gotoCases; // array of unresolved GotoCaseStatement's
Array *cases; // array of CaseStatement's
@@ -574,7 +539,6 @@ struct DefaultStatement : Statement
struct GotoDefaultStatement : Statement
{
SwitchStatement *sw;
EnclosingHandler* enclosinghandler;
GotoDefaultStatement(Loc loc);
Statement *syntaxCopy();
@@ -590,7 +554,6 @@ struct GotoCaseStatement : Statement
{
Expression *exp; // NULL, or which case to goto
CaseStatement *cs; // case statement it resolves to
EnclosingHandler* enclosinghandler;
SwitchStatement *sw;
GotoCaseStatement(Loc loc, Expression *exp);
@@ -615,7 +578,6 @@ struct SwitchErrorStatement : Statement
struct ReturnStatement : Statement
{
Expression *exp;
EnclosingHandler* enclosinghandler;
ReturnStatement(Loc loc, Expression *exp);
Statement *syntaxCopy();
@@ -636,7 +598,6 @@ struct ReturnStatement : Statement
struct BreakStatement : Statement
{
Identifier *ident;
EnclosingHandler* enclosinghandler;
BreakStatement(Loc loc, Identifier *ident);
Statement *syntaxCopy();
@@ -654,7 +615,6 @@ struct BreakStatement : Statement
struct ContinueStatement : Statement
{
Identifier *ident;
EnclosingHandler* enclosinghandler;
ContinueStatement(Loc loc, Identifier *ident);
Statement *syntaxCopy();
@@ -673,7 +633,6 @@ struct SynchronizedStatement : Statement
{
Expression *exp;
Statement *body;
EnclosingHandler* enclosinghandler;
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
Statement *syntaxCopy();
@@ -749,7 +708,6 @@ struct TryFinallyStatement : Statement
{
Statement *body;
Statement *finalbody;
EnclosingHandler* enclosinghandler;
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
Statement *syntaxCopy();
@@ -799,7 +757,6 @@ struct ThrowStatement : Statement
struct VolatileStatement : Statement
{
Statement *statement;
EnclosingHandler* enclosinghandler;
VolatileStatement(Loc loc, Statement *statement);
Statement *syntaxCopy();
@@ -817,8 +774,8 @@ struct GotoStatement : Statement
{
Identifier *ident;
LabelDsymbol *label;
TryFinallyStatement *tf;
EnclosingHandler* enclosinghandler;
TryFinallyStatement *enclosingFinally;
Statement* enclosingScopeExit;
GotoStatement(Loc loc, Identifier *ident);
Statement *syntaxCopy();
@@ -835,8 +792,8 @@ struct LabelStatement : Statement
{
Identifier *ident;
Statement *statement;
TryFinallyStatement *tf;
EnclosingHandler* enclosinghandler;
TryFinallyStatement *enclosingFinally;
Statement* enclosingScopeExit;
block *lblock; // back end
int isReturnLabel;
@@ -895,8 +852,8 @@ struct AsmStatement : Statement
struct AsmBlockStatement : CompoundStatement
{
EnclosingHandler* enclosinghandler;
TryFinallyStatement* tf;
TryFinallyStatement* enclosingFinally;
Statement* enclosingScopeExit;
AsmBlockStatement(Loc loc, Statements *s);
Statements *flatten(Scope *sc);