diff dmd2/func.c @ 1577:e4f7b5d9c68a

DMD 2.032 Merge.
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 08 Sep 2009 10:07:56 +0100
parents 54b3c1394d62
children
line wrap: on
line diff
--- a/dmd2/func.c	Tue Aug 25 21:35:43 2009 +0200
+++ b/dmd2/func.c	Tue Sep 08 10:07:56 2009 +0100
@@ -180,7 +180,7 @@
 	    stc |= STCimmutable;
 	if (type->isConst())
 	    stc |= STCconst;
-	if (type->isShared())
+	if (type->isShared() || storage_class & STCsynchronized)
 	    stc |= STCshared;
 	switch (stc & STC_TYPECTOR)
 	{
@@ -1199,12 +1199,13 @@
 		error("expected to return a value of type %s", type->nextOf()->toChars());
 	    else if (!inlineAsm)
 	    {
+#if DMDV2
 		int blockexit = fbody ? fbody->blockExit() : BEfallthru;
 		if (f->isnothrow && blockexit & BEthrow)
 		    error("'%s' is nothrow yet may throw", toChars());
 
 		int offend = blockexit & BEfallthru;
-
+#endif
 		if (type->nextOf()->ty == Tvoid)
 		{
 		    if (offend && isMain())
@@ -1217,10 +1218,11 @@
 		{
 		    if (offend)
 		    {   Expression *e;
-
-			//warning(loc, "no return exp; or assert(0); at end of function");
+#if DMDV1
+			warning(loc, "no return exp; or assert(0); at end of function");
+#else
 			error("no return exp; or assert(0); at end of function");
-
+#endif
 			if (global.params.useAssert &&
 			    !global.params.useInline)
 			{   /* Add an assert(0, msg); where the missing return
@@ -1412,7 +1414,7 @@
 
 	    fbody = new CompoundStatement(0, a);
 
-#if IN_LLVM
+#if 0 // This seems to have been added in with dmd 2.032, see below
 	    // wrap body of synchronized functions in a synchronized statement
 	    if (isSynchronized())
 	    {
@@ -1450,7 +1452,7 @@
 		fbody = new CompoundStatement(0, a);
 	    }
 #endif
-
+#if DMDV2
 	    /* Append destructor calls for parameters as finally blocks.
 	     */
 	    if (parameters)
@@ -1479,6 +1481,46 @@
 		    }
 		}
 	    }
+#endif
+
+#if 1
+	    if (isSynchronized())
+	    {	/* Wrap the entire function body in a synchronized statement
+		 */
+		ClassDeclaration *cd = parent->isClassDeclaration();
+		if (cd)
+		{
+#if TARGET_WINDOS
+		    if (/*config.flags2 & CFG2seh &&*/	// always on for WINDOS
+			!isStatic() && !fbody->usesEH())
+		    {
+			/* The back end uses the "jmonitor" hack for syncing;
+			 * no need to do the sync at this level.
+			 */
+		    }
+		    else
+#endif
+		    {
+			Expression *vsync;
+			if (isStatic())
+			{   // The monitor is in the ClassInfo
+			    vsync = new DotIdExp(loc, new DsymbolExp(loc, cd), Id::classinfo);
+			}
+			else
+			{   // 'this' is the monitor
+			    vsync = new VarExp(loc, vthis);
+			}
+			fbody = new PeelStatement(fbody);	// don't redo semantic()
+			fbody = new SynchronizedStatement(loc, vsync, fbody);
+			fbody = fbody->semantic(sc2);
+		    }
+		}
+		else
+		{
+		    error("synchronized function %s must be a member of a class", toChars());
+		}
+	    }
+#endif
 	}
 
 	sc2->callSuper = 0;
@@ -1914,12 +1956,18 @@
     {
 	OutBuffer buf;
 
+	buf.writeByte('(');
 	if (arguments)
 	{
 	    HdrGenState hgs;
 
 	    argExpTypesToCBuffer(&buf, arguments, &hgs);
+	    buf.writeByte(')');
+	    if (ethis)
+		ethis->type->modToBuffer(&buf);
 	}
+	else
+	    buf.writeByte(')');
 
 	if (m.last == MATCHnomatch)
 	{
@@ -1928,9 +1976,13 @@
 
 	    tf = (TypeFunction *)type;
 
+	    OutBuffer buf2;
+	    tf->modToBuffer(&buf2);
+
 	    //printf("tf = %s, args = %s\n", tf->deco, ((Expression *)arguments->data[0])->type->deco);
-	    error(loc, "%s does not match parameter types (%s)",
+	    error(loc, "%s%s is not callable using argument types %s",
 		Argument::argsTypesToChars(tf->parameters, tf->varargs),
+		buf2.toChars(),
 		buf.toChars());
 	    return m.anyf;		// as long as it's not a FuncAliasDeclaration
 	}
@@ -2202,6 +2254,13 @@
     }
 }
 
+const char *FuncDeclaration::toPrettyChars()
+{
+    if (isMain())
+	return "D main";
+    else
+	return Dsymbol::toPrettyChars();
+}
 
 int FuncDeclaration::isMain()
 {