From ff70cf1ee766d6c4c36090708bb0edcb563de3cc Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Tue, 9 Feb 2016 19:02:44 +0100
Subject: [PATCH] - fixed: Resolving non-constant DECORATE expressions must be
 delayed until everything has been parsed.

If done as before, forward-declared classes cannot be found, and the immediate resolving is only needed for constant expressions, so explicitly enabling it in the 4 places where it is needed ensures that those unresolvable expressions remain intact until the final processing pass righr before the code generator is started.
---
 src/thingdef/thingdef_exp.cpp        | 9 ++++++---
 src/thingdef/thingdef_exp.h          | 2 +-
 src/thingdef/thingdef_expression.cpp | 2 +-
 src/thingdef/thingdef_parse.cpp      | 8 ++++----
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp
index e198ec20b..e8a043d31 100644
--- a/src/thingdef/thingdef_exp.cpp
+++ b/src/thingdef/thingdef_exp.cpp
@@ -72,12 +72,15 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls);
 static FxExpression *ParseExpressionA (FScanner &sc, PClassActor *cls);
 static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls);
 
-FxExpression *ParseExpression (FScanner &sc, PClassActor *cls)
+FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
 {
 	FxExpression *data = ParseExpressionM (sc, cls);
 
-	FCompileContext ctx(cls);
-	data = data->Resolve(ctx);
+	if (mustresolve)
+	{
+		FCompileContext ctx(cls);
+		data = data->Resolve(ctx);
+	}
 
 	return data;
 }
diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h
index 6dd11a681..f81dd2b54 100644
--- a/src/thingdef/thingdef_exp.h
+++ b/src/thingdef/thingdef_exp.h
@@ -984,7 +984,7 @@ public:
 };
 
 
-FxExpression *ParseExpression (FScanner &sc, PClassActor *cls);
+FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve = false);
 
 
 #endif
diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp
index 0038bc337..8b2c52405 100644
--- a/src/thingdef/thingdef_expression.cpp
+++ b/src/thingdef/thingdef_expression.cpp
@@ -3564,8 +3564,8 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
 					delete this;
 					return NULL;
 				}
+				ScriptPosition.Message(MSG_DEBUG, "resolving '%s' as class name", clsname.GetChars());
 			}
-			ScriptPosition.Message(MSG_DEBUG, "resolving '%s' as class name", clsname.GetChars());
 		}
 		FxExpression *x = new FxConstant(cls, ScriptPosition);
 		delete this;
diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp
index 1db878bfa..cf76fb10b 100644
--- a/src/thingdef/thingdef_parse.cpp
+++ b/src/thingdef/thingdef_parse.cpp
@@ -79,7 +79,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
 	}
 	else if (type == TypeSInt32 || type == TypeFloat64)
 	{
-		x = ParseExpression (sc, cls);
+		x = ParseExpression (sc, cls, constant);
 		if (constant && !x->isConstant())
 		{
 			sc.ScriptMessage("Default parameter must be constant.");
@@ -190,7 +190,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
 		sc.MustGetToken(TK_Identifier);
 		FName symname = sc.String;
 		sc.MustGetToken('=');
-		FxExpression *expr = ParseExpression (sc, cls);
+		FxExpression *expr = ParseExpression (sc, cls, true);
 		sc.MustGetToken(';');
 
 		if (!expr->isConstant())
@@ -248,7 +248,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
 		FName symname = sc.String;
 		if (sc.CheckToken('='))
 		{
-			FxExpression *expr = ParseExpression (sc, cls);
+			FxExpression *expr = ParseExpression (sc, cls, true);
 			if (!expr->isConstant())
 			{
 				sc.ScriptMessage("'%s' must be constant", symname.GetChars());
@@ -536,7 +536,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
 
 	if (sc.CheckToken('['))
 	{
-		FxExpression *expr = ParseExpression(sc, cls);
+		FxExpression *expr = ParseExpression(sc, cls, true);
 		if (!expr->isConstant())
 		{
 			sc.ScriptMessage("Array size must be a constant");