Mercurial > projects > ldc
diff dmd/func.c @ 1141:f99a3b393c03
Reorganize EnclosingHandlers to require less changes to the frontend and allow us to
implement the synchronized storage class for functions.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Tue, 24 Mar 2009 21:18:18 +0100 |
parents | eeb8b95ea92e |
children | b28a57f4b530 |
line wrap: on
line diff
--- a/dmd/func.c Tue Mar 24 14:34:16 2009 +0100 +++ b/dmd/func.c Tue Mar 24 21:18:18 2009 +0100 @@ -682,8 +682,8 @@ 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 @@ } 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;