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;