compiler/libec; ecere; ide: (Emscripten WIP) Address virtual method issues
[sdk] / compiler / bootstrap / libec / bootstrap / pass15.c
index 430f564..8bd85f8 100644 (file)
@@ -51,7 +51,7 @@ typedef unsigned __int64 uint64;
 #include <sys/types.h>
 enum yytokentype
 {
-IDENTIFIER = 258, CONSTANT = 259, STRING_LITERAL = 260, SIZEOF = 261, PTR_OP = 262, INC_OP = 263, DEC_OP = 264, LEFT_OP = 265, RIGHT_OP = 266, LE_OP = 267, GE_OP = 268, EQ_OP = 269, NE_OP = 270, AND_OP = 271, OR_OP = 272, MUL_ASSIGN = 273, DIV_ASSIGN = 274, MOD_ASSIGN = 275, ADD_ASSIGN = 276, SUB_ASSIGN = 277, LEFT_ASSIGN = 278, RIGHT_ASSIGN = 279, AND_ASSIGN = 280, XOR_ASSIGN = 281, OR_ASSIGN = 282, TYPE_NAME = 283, TYPEDEF = 284, EXTERN = 285, STATIC = 286, AUTO = 287, REGISTER = 288, CHAR = 289, SHORT = 290, INT = 291, UINT = 292, INT64 = 293, LONG = 294, SIGNED = 295, UNSIGNED = 296, FLOAT = 297, DOUBLE = 298, CONST = 299, VOLATILE = 300, VOID = 301, VALIST = 302, STRUCT = 303, UNION = 304, ENUM = 305, ELLIPSIS = 306, CASE = 307, DEFAULT = 308, IF = 309, SWITCH = 310, WHILE = 311, DO = 312, FOR = 313, GOTO = 314, CONTINUE = 315, BREAK = 316, RETURN = 317, IFX = 318, ELSE = 319, CLASS = 320, THISCLASS = 321, CLASS_NAME = 322, PROPERTY = 323, SETPROP = 324, GETPROP = 325, NEWOP = 326, RENEW = 327, DELETE = 328, EXT_DECL = 329, EXT_STORAGE = 330, IMPORT = 331, DEFINE = 332, VIRTUAL = 333, ATTRIB = 334, PUBLIC = 335, PRIVATE = 336, TYPED_OBJECT = 337, ANY_OBJECT = 338, _INCREF = 339, EXTENSION = 340, ASM = 341, TYPEOF = 342, WATCH = 343, STOPWATCHING = 344, FIREWATCHERS = 345, WATCHABLE = 346, CLASS_DESIGNER = 347, CLASS_NO_EXPANSION = 348, CLASS_FIXED = 349, ISPROPSET = 350, CLASS_DEFAULT_PROPERTY = 351, PROPERTY_CATEGORY = 352, CLASS_DATA = 353, CLASS_PROPERTY = 354, SUBCLASS = 355, NAMESPACE = 356, NEW0OP = 357, RENEW0 = 358, VAARG = 359, DBTABLE = 360, DBFIELD = 361, DBINDEX = 362, DATABASE_OPEN = 363, ALIGNOF = 364, ATTRIB_DEP = 365, __ATTRIB = 366, BOOL = 367, _BOOL = 368, _COMPLEX = 369, _IMAGINARY = 370, RESTRICT = 371, THREAD = 372, WIDE_STRING_LITERAL = 373
+IDENTIFIER = 258, CONSTANT = 259, STRING_LITERAL = 260, SIZEOF = 261, PTR_OP = 262, INC_OP = 263, DEC_OP = 264, LEFT_OP = 265, RIGHT_OP = 266, LE_OP = 267, GE_OP = 268, EQ_OP = 269, NE_OP = 270, AND_OP = 271, OR_OP = 272, MUL_ASSIGN = 273, DIV_ASSIGN = 274, MOD_ASSIGN = 275, ADD_ASSIGN = 276, SUB_ASSIGN = 277, LEFT_ASSIGN = 278, RIGHT_ASSIGN = 279, AND_ASSIGN = 280, XOR_ASSIGN = 281, OR_ASSIGN = 282, TYPE_NAME = 283, TYPEDEF = 284, EXTERN = 285, STATIC = 286, AUTO = 287, REGISTER = 288, CHAR = 289, SHORT = 290, INT = 291, UINT = 292, INT64 = 293, LONG = 294, SIGNED = 295, UNSIGNED = 296, FLOAT = 297, DOUBLE = 298, CONST = 299, VOLATILE = 300, VOID = 301, VALIST = 302, STRUCT = 303, UNION = 304, ENUM = 305, ELLIPSIS = 306, CASE = 307, DEFAULT = 308, IF = 309, SWITCH = 310, WHILE = 311, DO = 312, FOR = 313, GOTO = 314, CONTINUE = 315, BREAK = 316, RETURN = 317, IFX = 318, ELSE = 319, CLASS = 320, THISCLASS = 321, CLASS_NAME = 322, PROPERTY = 323, SETPROP = 324, GETPROP = 325, NEWOP = 326, RENEW = 327, DELETE = 328, EXT_DECL = 329, EXT_STORAGE = 330, IMPORT = 331, DEFINE = 332, VIRTUAL = 333, ATTRIB = 334, PUBLIC = 335, PRIVATE = 336, TYPED_OBJECT = 337, ANY_OBJECT = 338, _INCREF = 339, EXTENSION = 340, ASM = 341, TYPEOF = 342, WATCH = 343, STOPWATCHING = 344, FIREWATCHERS = 345, WATCHABLE = 346, CLASS_DESIGNER = 347, CLASS_NO_EXPANSION = 348, CLASS_FIXED = 349, ISPROPSET = 350, CLASS_DEFAULT_PROPERTY = 351, PROPERTY_CATEGORY = 352, CLASS_DATA = 353, CLASS_PROPERTY = 354, SUBCLASS = 355, NAMESPACE = 356, NEW0OP = 357, RENEW0 = 358, VAARG = 359, DBTABLE = 360, DBFIELD = 361, DBINDEX = 362, DATABASE_OPEN = 363, ALIGNOF = 364, ATTRIB_DEP = 365, __ATTRIB = 366, BOOL = 367, _BOOL = 368, _COMPLEX = 369, _IMAGINARY = 370, RESTRICT = 371, THREAD = 372, WIDE_STRING_LITERAL = 373, BUILTIN_OFFSETOF = 374
 };
 
 extern int returnCode;
@@ -182,6 +182,8 @@ extern const char *  sourceFile;
 
 extern struct __ecereNameSpace__ecere__com__Property * __ecereProp_Type_specConst;
 
+unsigned int reachedPass15;
+
 extern unsigned int memoryGuard;
 
 struct __ecereNameSpace__ecere__sys__OldList
@@ -643,12 +645,12 @@ extern void FreeExpression(struct Expression * exp);
 
 extern void FreeExpContents(struct Expression * exp);
 
+extern struct Expression * GetNonBracketsExp(struct Expression * exp);
+
 extern struct Expression * CopyExpression(struct Expression * exp);
 
 extern struct Expression * MkExpBrackets(struct __ecereNameSpace__ecere__sys__OldList * expressions);
 
-extern struct Expression * GetNonBracketsExp(struct Expression * exp);
-
 extern struct Expression * MkExpCall(struct Expression * expression, struct __ecereNameSpace__ecere__sys__OldList * arguments);
 
 extern struct Expression * MkExpCondition(struct Expression * cond, struct __ecereNameSpace__ecere__sys__OldList * expressions, struct Expression * elseExp);
@@ -1378,6 +1380,11 @@ struct
 struct Expression * exp;
 struct TypeName * typeName;
 } ecere_gcc_struct vaArg;
+struct
+{
+struct TypeName * typeName;
+struct Identifier * id;
+} ecere_gcc_struct offset;
 } ecere_gcc_struct __anon1;
 unsigned int debugValue;
 struct __ecereNameSpace__ecere__com__DataValue val;
@@ -1393,6 +1400,9 @@ unsigned int addedThis;
 unsigned int needCast;
 unsigned int thisPtr;
 unsigned int opDestType;
+unsigned int usedInComparison;
+unsigned int ambiguousUnits;
+unsigned int parentOpDestType;
 unsigned int needTemplateCast;
 } ecere_gcc_struct;
 
@@ -2978,7 +2988,7 @@ static unsigned int ShortDiv(struct Expression * exp, struct Operand * op1, stru
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s / value2)) : (short)0);
+exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s / value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -2993,7 +3003,7 @@ static unsigned int UShortDiv(struct Expression * exp, struct Operand * op1, str
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us / value2)) : (unsigned short)0);
+exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us / value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3008,7 +3018,7 @@ static unsigned int CharDiv(struct Expression * exp, struct Operand * op1, struc
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c / value2)) : (char)0);
+exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c / value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3023,7 +3033,7 @@ static unsigned int UCharDiv(struct Expression * exp, struct Operand * op1, stru
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc / value2)) : (unsigned char)0);
+exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc / value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3128,7 +3138,7 @@ static unsigned int ShortMod(struct Expression * exp, struct Operand * op1, stru
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s % value2)) : (short)0);
+exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s % value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3143,7 +3153,7 @@ static unsigned int UShortMod(struct Expression * exp, struct Operand * op1, str
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us % value2)) : (unsigned short)0);
+exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us % value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3158,7 +3168,7 @@ static unsigned int CharMod(struct Expression * exp, struct Operand * op1, struc
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c % value2)) : (char)0);
+exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c % value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3173,7 +3183,7 @@ static unsigned int UCharMod(struct Expression * exp, struct Operand * op1, stru
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc % value2)) : (unsigned char)0);
+exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc % value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3638,7 +3648,7 @@ static unsigned int ShortAsign(struct Expression * exp, struct Operand * op1, st
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s = value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s = value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3653,7 +3663,7 @@ static unsigned int UShortAsign(struct Expression * exp, struct Operand * op1, s
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us = value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us = value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3668,7 +3678,7 @@ static unsigned int CharAsign(struct Expression * exp, struct Operand * op1, str
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c = value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c = value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3683,7 +3693,7 @@ static unsigned int UCharAsign(struct Expression * exp, struct Operand * op1, st
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc = value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc = value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3788,7 +3798,7 @@ static unsigned int ShortAddAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s += value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s += value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3803,7 +3813,7 @@ static unsigned int UShortAddAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us += value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us += value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3818,7 +3828,7 @@ static unsigned int CharAddAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c += value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c += value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3833,7 +3843,7 @@ static unsigned int UCharAddAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc += value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc += value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3938,7 +3948,7 @@ static unsigned int ShortSubAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s -= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s -= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3953,7 +3963,7 @@ static unsigned int UShortSubAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us -= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us -= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3968,7 +3978,7 @@ static unsigned int CharSubAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c -= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c -= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -3983,7 +3993,7 @@ static unsigned int UCharSubAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc -= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc -= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4088,7 +4098,7 @@ static unsigned int ShortMulAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s *= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s *= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4103,7 +4113,7 @@ static unsigned int UShortMulAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us *= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us *= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4118,7 +4128,7 @@ static unsigned int CharMulAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c *= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c *= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4133,7 +4143,7 @@ static unsigned int UCharMulAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc *= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc *= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4238,7 +4248,7 @@ static unsigned int ShortDivAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s /= value2)) : (short)0);
+exp->__anon1.__anon2.string = PrintShort(value2 ? ((op1->__anon1.s /= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4253,7 +4263,7 @@ static unsigned int UShortDivAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us /= value2)) : (unsigned short)0);
+exp->__anon1.__anon2.string = PrintUShort(value2 ? ((op1->__anon1.us /= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4268,7 +4278,7 @@ static unsigned int CharDivAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c /= value2)) : (char)0);
+exp->__anon1.__anon2.string = PrintChar(value2 ? ((op1->__anon1.c /= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4283,7 +4293,7 @@ static unsigned int UCharDivAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc /= value2)) : (unsigned char)0);
+exp->__anon1.__anon2.string = PrintUChar(value2 ? ((op1->__anon1.uc /= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4388,7 +4398,7 @@ static unsigned int ShortModAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort(value2 ? ((short)(op1->__anon1.s %= value2)) : (short)0);
+exp->__anon1.__anon2.string = PrintShort(value2 ? ((op1->__anon1.s %= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4403,7 +4413,7 @@ static unsigned int UShortModAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort(value2 ? ((unsigned short)(op1->__anon1.us %= value2)) : (unsigned short)0);
+exp->__anon1.__anon2.string = PrintUShort(value2 ? ((op1->__anon1.us %= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4418,7 +4428,7 @@ static unsigned int CharModAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar(value2 ? ((char)(op1->__anon1.c %= value2)) : (char)0);
+exp->__anon1.__anon2.string = PrintChar(value2 ? ((op1->__anon1.c %= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -4433,7 +4443,7 @@ static unsigned int UCharModAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar(value2 ? ((unsigned char)(op1->__anon1.uc %= value2)) : (unsigned char)0);
+exp->__anon1.__anon2.string = PrintUChar(value2 ? ((op1->__anon1.uc %= value2)) : 0);
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5212,7 +5222,7 @@ static unsigned int ShortAndAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s &= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s &= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5227,7 +5237,7 @@ static unsigned int UShortAndAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us &= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us &= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5242,7 +5252,7 @@ static unsigned int CharAndAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c &= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c &= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5257,7 +5267,7 @@ static unsigned int UCharAndAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc &= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc &= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5332,7 +5342,7 @@ static unsigned int ShortOrAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s |= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s |= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5347,7 +5357,7 @@ static unsigned int UShortOrAsign(struct Expression * exp, struct Operand * op1,
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us |= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us |= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5362,7 +5372,7 @@ static unsigned int CharOrAsign(struct Expression * exp, struct Operand * op1, s
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c |= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c |= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5377,7 +5387,7 @@ static unsigned int UCharOrAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc |= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc |= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5452,7 +5462,7 @@ static unsigned int ShortXorAsign(struct Expression * exp, struct Operand * op1,
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s ^= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s ^= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5467,7 +5477,7 @@ static unsigned int UShortXorAsign(struct Expression * exp, struct Operand * op1
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us ^= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us ^= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5482,7 +5492,7 @@ static unsigned int CharXorAsign(struct Expression * exp, struct Operand * op1,
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c ^= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c ^= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5497,7 +5507,7 @@ static unsigned int UCharXorAsign(struct Expression * exp, struct Operand * op1,
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc ^= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc ^= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5572,7 +5582,7 @@ static unsigned int ShortLShiftAsign(struct Expression * exp, struct Operand * o
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s <<= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s <<= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5587,7 +5597,7 @@ static unsigned int UShortLShiftAsign(struct Expression * exp, struct Operand *
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us <<= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us <<= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5602,7 +5612,7 @@ static unsigned int CharLShiftAsign(struct Expression * exp, struct Operand * op
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c <<= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c <<= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5617,7 +5627,7 @@ static unsigned int UCharLShiftAsign(struct Expression * exp, struct Operand * o
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc <<= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc <<= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5692,7 +5702,7 @@ static unsigned int ShortRShiftAsign(struct Expression * exp, struct Operand * o
 short value2 = op2->__anon1.s;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintShort((short)(op1->__anon1.s >>= value2));
+exp->__anon1.__anon2.string = PrintShort((op1->__anon1.s >>= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5707,7 +5717,7 @@ static unsigned int UShortRShiftAsign(struct Expression * exp, struct Operand *
 unsigned short value2 = op2->__anon1.us;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUShort((unsigned short)(op1->__anon1.us >>= value2));
+exp->__anon1.__anon2.string = PrintUShort((op1->__anon1.us >>= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5722,7 +5732,7 @@ static unsigned int CharRShiftAsign(struct Expression * exp, struct Operand * op
 char value2 = op2->__anon1.c;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintChar((char)(op1->__anon1.c >>= value2));
+exp->__anon1.__anon2.string = PrintChar((op1->__anon1.c >>= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -5737,7 +5747,7 @@ static unsigned int UCharRShiftAsign(struct Expression * exp, struct Operand * o
 unsigned char value2 = op2->__anon1.uc;
 
 exp->type = 2;
-exp->__anon1.__anon2.string = PrintUChar((unsigned char)(op1->__anon1.uc >>= value2));
+exp->__anon1.__anon2.string = PrintUChar((op1->__anon1.uc >>= value2));
 if(!exp->expType)
 {
 exp->expType = op1->type;
@@ -7572,7 +7582,7 @@ struct Type * type = exp->expType;
 
 if(type)
 {
-while(type->kind == 8 && type->__anon1._class->__anon1.registered && (type->__anon1._class->__anon1.registered->type == 2 || type->__anon1._class->__anon1.registered->type == 3 || type->__anon1._class->__anon1.registered->type == 4))
+while(type->kind == 8 && type->__anon1._class && type->__anon1._class->__anon1.registered && (type->__anon1._class->__anon1.registered->type == 2 || type->__anon1._class->__anon1.registered->type == 3 || type->__anon1._class->__anon1.registered->type == 4))
 {
 if(!type->__anon1._class->__anon1.registered->dataType)
 type->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type->__anon1._class->__anon1.registered->dataTypeString, 0);
@@ -7928,6 +7938,15 @@ break;
 }
 }
 
+unsigned int RelatedUnits(struct __ecereNameSpace__ecere__com__Class * c1, struct __ecereNameSpace__ecere__com__Class * c2)
+{
+if(c1->base->type == 3)
+c1 = c1->base;
+if(c2->base->type == 3)
+c2 = c2->base;
+return c1 == c2;
+}
+
 extern char *  __ecereNameSpace__ecere__com__PrintString(struct __ecereNameSpace__ecere__com__Class * class, const void * object, ...);
 
 extern struct __ecereNameSpace__ecere__com__Class * __ecereClass___ecereNameSpace__ecere__sys__TempFile;
@@ -8226,17 +8245,27 @@ unsigned int backOutputLineNumbers = outputLineNumbers;
 outputLineNumbers = 0;
 if(exp)
 OutputExpression(exp, f);
-((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
+(__extension__ ({
+unsigned int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode);
+
+__internal_VirtualMethod = ((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = f;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__TempFile->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek])(f, 0, 0);
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek]);
+__internal_VirtualMethod ? __internal_VirtualMethod(f, 0, 0) : (unsigned int)1;
+}));
 count = strlen(string);
-count += ((int (*)(struct __ecereNameSpace__ecere__com__Instance *, void *  buffer, unsigned int size, unsigned int count))__extension__ ({
+count += (__extension__ ({
+int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, void *  buffer, unsigned int size, unsigned int count);
+
+__internal_VirtualMethod = ((int (*)(struct __ecereNameSpace__ecere__com__Instance *, void *  buffer, unsigned int size, unsigned int count))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = f;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__TempFile->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Read])(f, string + count, 1, 1023);
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Read]);
+__internal_VirtualMethod ? __internal_VirtualMethod(f, string + count, 1, 1023) : (int)1;
+}));
 string[count] = '\0';
 (__ecereNameSpace__ecere__com__eInstance_DecRef(f), f = 0);
 outputLineNumbers = backOutputLineNumbers;
@@ -8297,7 +8326,11 @@ FreeExpContents(checkedExp);
 FreeType(checkedExp->expType);
 FreeType(checkedExp->destType);
 *checkedExp = *newExp;
-((newExp ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)newExp) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(newExp)) : 0), newExp = 0);
+((newExp ? __extension__ ({
+void * __ecerePtrToDelete = (newExp);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), newExp = 0);
 checkedExp->prev = prev;
 checkedExp->next = next;
 }
@@ -8306,30 +8339,49 @@ void FinishTemplatesContext(struct Context * context)
 {
 PopContext(context);
 FreeContext(context);
-((context ? (__ecereClass_Context->Destructor ? __ecereClass_Context->Destructor((void *)context) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(context)) : 0), context = 0);
+((context ? __extension__ ({
+void * __ecerePtrToDelete = (context);
+
+__ecereClass_Context->Destructor ? __ecereClass_Context->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), context = 0);
 }
 
 static __attribute__((unused)) void UnusedFunction()
 {
 int a;
 
-((const char *  (*)(struct __ecereNameSpace__ecere__com__Class *, const void *, char *  tempString, void *  fieldData, unsigned int *  needClass))__ecereClass_int->_vTbl[__ecereVMethodID_class_OnGetString])(__ecereClass_int, (void *)&a, 0, 0, 0);
+(__extension__ ({
+const char *  (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Class * , const void * , char *  tempString, void *  fieldData, unsigned int *  needClass);
+
+__internal_VirtualMethod = ((const char *  (*)(struct __ecereNameSpace__ecere__com__Class *, const void *, char *  tempString, void *  fieldData, unsigned int *  needClass))__ecereClass_int->_vTbl[__ecereVMethodID_class_OnGetString]);
+__internal_VirtualMethod ? __internal_VirtualMethod(__ecereClass_int, (void *)&a, 0, 0, 0) : (const char * )1;
+}));
 }
 
 struct Expression * ParseExpressionString(char * expression)
 {
 parseError = 0;
 fileInput = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass___ecereNameSpace__ecere__sys__TempFile);
-((int (*)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count))__extension__ ({
+(__extension__ ({
+int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count);
+
+__internal_VirtualMethod = ((int (*)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = fileInput;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__File->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Write])(fileInput, expression, 1, strlen(expression));
-((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Write]);
+__internal_VirtualMethod ? __internal_VirtualMethod(fileInput, expression, 1, strlen(expression)) : (int)1;
+}));
+(__extension__ ({
+unsigned int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode);
+
+__internal_VirtualMethod = ((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = fileInput;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__File->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek])(fileInput, 0, 0);
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek]);
+__internal_VirtualMethod ? __internal_VirtualMethod(fileInput, 0, 0) : (unsigned int)1;
+}));
 echoOn = 0;
 parsedExpression = (((void *)0));
 resetScanner();
@@ -9871,6 +9923,8 @@ if(!id->_class || !id->_class->__anon1.__anon1.name || strcmp(id->_class->__anon
 {
 for(ctx = curContext; ctx != topContext->parent && !symbol; ctx = ctx->parent)
 {
+if(!ctx)
+break;
 symbol = (struct Symbol *)__ecereMethod___ecereNameSpace__ecere__sys__BinaryTree_FindString(&ctx->symbols, id->string);
 if(symbol)
 break;
@@ -10090,7 +10144,11 @@ if(exp->destType)
 exp->destType->refCount--;
 if(exp->expType)
 exp->expType->refCount--;
-((newExp ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)newExp) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(newExp)) : 0), newExp = 0);
+((newExp ? __extension__ ({
+void * __ecerePtrToDelete = (newExp);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), newExp = 0);
 }
 else
 {
@@ -10154,7 +10212,11 @@ if(exp->destType)
 exp->destType->refCount--;
 if(exp->expType)
 exp->expType->refCount--;
-((newExp ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)newExp) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(newExp)) : 0), newExp = 0);
+((newExp ? __extension__ ({
+void * __ecerePtrToDelete = (newExp);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), newExp = 0);
 }
 else
 {
@@ -10212,7 +10274,11 @@ if(type)
 {
 FreeType(exp->destType);
 FreeType(exp->expType);
-((newExp ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)newExp) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(newExp)) : 0), newExp = 0);
+((newExp ? __extension__ ({
+void * __ecerePtrToDelete = (newExp);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), newExp = 0);
 break;
 }
 }
@@ -10686,7 +10752,7 @@ if(_class->structAlignment)
 if(_class->memberOffset % _class->structAlignment)
 extra += _class->structAlignment - (_class->memberOffset % _class->structAlignment);
 }
-_class->structSize = (_class->base ? (_class->base->templateClass ? _class->base->templateClass->structSize : _class->base->structSize) : 0) + _class->memberOffset + extra;
+_class->structSize = (_class->base ? (_class->base->templateClass ? (_class->base->type == 5 ? _class->base->templateClass->memberOffset : _class->base->templateClass->structSize) : (_class->base->type == 5 ? _class->base->memberOffset : _class->base->structSize)) : 0) + _class->memberOffset + extra;
 if(!member)
 {
 struct __ecereNameSpace__ecere__com__Property * prop;
@@ -10709,7 +10775,7 @@ struct __ecereNameSpace__ecere__com__Class * deriv = derivative->data;
 
 if(deriv->computeSize)
 {
-deriv->offset = _class->structSize;
+deriv->offset = (_class->type == 5 ? _class->memberOffset : _class->structSize);
 deriv->memberOffset = 0;
 deriv->structSize = deriv->offset;
 ComputeClassMembers(deriv, 0);
@@ -10918,7 +10984,7 @@ else if(source->__anon1._class && dest->__anon1._class && (dest->classObjectType
 return 1;
 else
 {
-if(enumBaseType && dest->__anon1._class && dest->__anon1._class->__anon1.registered && dest->__anon1._class->__anon1.registered->type == 4 && ((source->__anon1._class && source->__anon1._class->__anon1.registered && source->__anon1._class->__anon1.registered->type != 4) || source->kind == 8))
+if(dest->__anon1._class && dest->__anon1._class->__anon1.registered && source->__anon1._class && source->__anon1._class->__anon1.registered && (dest->casted || (enumBaseType && dest->__anon1._class->__anon1.registered->type == 4 && (source->kind == 8 || source->__anon1._class->__anon1.registered->type != 4))))
 {
 if(__ecereNameSpace__ecere__com__eClass_IsDerived(dest->__anon1._class->__anon1.registered, source->__anon1._class->__anon1.registered))
 {
@@ -11750,7 +11816,11 @@ FreeExpContents(exp);
 FreeType(exp->expType);
 FreeType(exp->destType);
 *exp = *exp2;
-((exp2 ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)exp2) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(exp2)) : 0), exp2 = 0);
+((exp2 ? __extension__ ({
+void * __ecerePtrToDelete = (exp2);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), exp2 = 0);
 break;
 }
 case '-':
@@ -12426,7 +12496,6 @@ struct External * _DeclareStruct(struct External * neededBy, const char * name,
 struct External * external = (((void *)0));
 struct Symbol * classSym = FindClass(name);
 struct __ecereNameSpace__ecere__sys__OldList * curDeclarations = (((void *)0));
-struct Specifier * curSpec = (((void *)0));
 
 if(!inCompiler || !classSym)
 return (((void *)0));
@@ -12442,7 +12511,6 @@ struct Specifier * spec;
 for(spec = external->__anon1.declaration->__anon1.__anon1.specifiers ? (*external->__anon1.declaration->__anon1.__anon1.specifiers).first : (((void *)0)); spec; spec = spec->next)
 if(spec->type == 3 || spec->type == 4)
 {
-curSpec = spec;
 curDeclarations = spec->__anon1.__anon2.definitions;
 break;
 }
@@ -12453,15 +12521,14 @@ struct __ecereNameSpace__ecere__sys__OldList * specifiers, * declarators;
 struct __ecereNameSpace__ecere__sys__OldList * declarations = (((void *)0));
 char structName[1024];
 unsigned int addedPadding = 0;
+struct Specifier * curSpec = (((void *)0));
 
 classSym->declaring++;
 if(strchr(classSym->string, '<'))
 {
 if(classSym->__anon1.registered->templateClass)
-{
 external = _DeclareStruct(neededBy, classSym->__anon1.registered->templateClass->fullName, skipNoHead, needDereference, fwdDecl);
 classSym->declaring--;
-}
 return external;
 }
 structName[0] = 0;
@@ -12483,6 +12550,18 @@ if(!skipNoHead)
 declarations = MkList();
 AddMembers(external, declarations, classSym->__anon1.registered, 0, (((void *)0)), classSym->__anon1.registered, &addedPadding);
 }
+if(external->__anon1.declaration)
+{
+struct Specifier * spec;
+
+for(spec = external->__anon1.declaration->__anon1.__anon1.specifiers ? (*external->__anon1.declaration->__anon1.__anon1.specifiers).first : (((void *)0)); spec; spec = spec->next)
+if(spec->type == 3 || spec->type == 4)
+{
+curSpec = spec;
+curDeclarations = spec->__anon1.__anon2.definitions;
+break;
+}
+}
 if(declarations && (!(*declarations).count || ((*declarations).count == 1 && addedPadding)))
 {
 FreeList(declarations, (void *)(FreeClassDef));
@@ -12500,10 +12579,6 @@ if(curSpec)
 curSpec->__anon1.__anon2.definitions = declarations;
 else
 {
-char className[1024];
-
-strcpy(className, "__ecereClass_");
-FullClassNameCat(className, classSym->string, 1);
 specifiers = MkList();
 declarators = MkList();
 ListAdd(specifiers, MkStructOrUnion(3, MkIdentifier(structName), declarations));
@@ -12539,6 +12614,18 @@ classSym->__anon2.__anon1.structExternal = external = MkExternalDeclaration((((v
 external->symbol = classSym;
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Add((&*ast), external);
 }
+if(reachedPass15 && !external->__anon1.declaration && classSym->__anon1.registered && classSym->__anon1.registered->type == 5)
+{
+char structName[1024];
+struct __ecereNameSpace__ecere__sys__OldList * specifiers, * declarators;
+
+structName[0] = 0;
+FullClassNameCat(structName, name, 0);
+specifiers = MkList();
+declarators = MkList();
+ListAdd(specifiers, MkStructOrUnion(3, MkIdentifier(structName), (((void *)0))));
+external->__anon1.declaration = MkDeclaration(specifiers, declarators);
+}
 if(fwdDecl)
 {
 struct External * e = external->fwdDecl ? external->fwdDecl : external;
@@ -12965,7 +13052,11 @@ struct Conversion * convert = converts.first;
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Remove(&converts, convert);
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Add(conversions, convert);
 }
-((type ? (__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)type) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(type)) : 0), type = 0);
+((type ? __extension__ ({
+void * __ecerePtrToDelete = (type);
+
+__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), type = 0);
 return 1;
 }
 }
@@ -12973,7 +13064,11 @@ return 1;
 }
 if(converts.first)
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Free(&converts, (void *)(FreeConvert));
-((type ? (__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)type) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(type)) : 0), type = 0);
+((type ? __extension__ ({
+void * __ecerePtrToDelete = (type);
+
+__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), type = 0);
 }
 }
 for(nameSpace = (struct __ecereNameSpace__ecere__com__NameSpace *)__ecereProp___ecereNameSpace__ecere__sys__BinaryTree_Get_first(&nameSpace->nameSpaces); nameSpace != (((void *)0)); nameSpace = (struct __ecereNameSpace__ecere__com__NameSpace *)__ecereProp___ecereNameSpace__ecere__sys__BTNode_Get_next(((struct __ecereNameSpace__ecere__sys__BTNode *)nameSpace)))
@@ -13136,13 +13231,23 @@ struct __ecereNameSpace__ecere__sys__OldList * list = exp->__anon1.list;
 struct Expression * prev = exp->prev;
 struct Expression * next = exp->next;
 
+if(exp->expType && exp->expType->kind == 8 && (!e->expType || e->expType->kind != 8))
+{
+FreeType(e->expType);
+e->expType = exp->expType;
+e->expType->refCount++;
+}
 ComputeExpression(e);
 FreeType(exp->expType);
 FreeType(exp->destType);
 *exp = *e;
 exp->prev = prev;
 exp->next = next;
-((e ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)e) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(e)) : 0), e = 0);
+((e ? __extension__ ({
+void * __ecerePtrToDelete = (e);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), e = 0);
 (__ecereNameSpace__ecere__com__eSystem_Delete(list), list = 0);
 }
 else
@@ -13549,7 +13654,7 @@ case 24:
 case 1:
 if(type->isSigned)
 {
-char value = (char)0;
+char value = 0;
 
 if(GetChar(e, &value))
 {
@@ -13560,7 +13665,7 @@ exp->type = 2;
 }
 else
 {
-unsigned char value = (unsigned char)0;
+unsigned char value = 0;
 
 if(GetUChar(e, &value))
 {
@@ -13573,7 +13678,7 @@ break;
 case 2:
 if(type->isSigned)
 {
-short value = (short)0;
+short value = 0;
 
 if(GetShort(e, &value))
 {
@@ -13584,7 +13689,7 @@ exp->type = 2;
 }
 else
 {
-unsigned short value = (unsigned short)0;
+unsigned short value = 0;
 
 if(GetUShort(e, &value))
 {
@@ -13805,21 +13910,22 @@ unsigned int MatchTypeExpression(struct Expression * sourceExp, struct Type * de
 struct Type * source;
 struct Type * realDest = dest;
 struct Type * backupSourceExpType = (((void *)0));
-struct Expression * computedExp = sourceExp;
+struct Expression * nbExp = GetNonBracketsExp(sourceExp);
+struct Expression * computedExp = nbExp;
 
 dest->refCount++;
 if(sourceExp->isConstant && sourceExp->type != 2 && sourceExp->type != 0 && sourceExp->type != 11 && dest->kind == 8 && dest->__anon1._class && dest->__anon1._class->__anon1.registered && dest->__anon1._class->__anon1.registered->type == 4)
 {
-computedExp = CopyExpression(sourceExp);
+computedExp = CopyExpression(nbExp);
 ComputeExpression(computedExp);
 }
 source = sourceExp->expType;
 if(dest->kind == 13 && sourceExp->type == 2 && !strtoul(sourceExp->__anon1.__anon1.constant, (((void *)0)), 0))
 {
-if(computedExp != sourceExp)
+if(computedExp != nbExp)
 {
 FreeExpression(computedExp);
-computedExp = sourceExp;
+computedExp = nbExp;
 }
 FreeType(dest);
 return 1;
@@ -13836,10 +13942,10 @@ for(destBase = dest->__anon1._class->__anon1.registered; destBase && destBase->b
 ;
 if(sourceBase == destBase)
 {
-if(computedExp != sourceExp)
+if(computedExp != nbExp)
 {
 FreeExpression(computedExp);
-computedExp = sourceExp;
+computedExp = nbExp;
 }
 FreeType(dest);
 return 1;
@@ -13860,17 +13966,17 @@ value = strtoll(computedExp->__anon1.__anon1.constant, (((void *)0)), 0);
 else
 value = strtoull(computedExp->__anon1.__anon1.constant, (((void *)0)), 0);
 }
-else if(computedExp->type == 4 && sourceExp->__anon1.op.op == '-' && !computedExp->__anon1.op.exp1 && computedExp->__anon1.op.exp2 && computedExp->__anon1.op.exp2->type == 2)
+else if(computedExp->type == 4 && computedExp->__anon1.op.op == '-' && !computedExp->__anon1.op.exp1 && computedExp->__anon1.op.exp2 && computedExp->__anon1.op.exp2->type == 2)
 {
 if(source->isSigned)
 value = -strtoll(computedExp->__anon1.op.exp2->__anon1.__anon1.constant, (((void *)0)), 0);
 else
 value = -strtoull(computedExp->__anon1.op.exp2->__anon1.__anon1.constant, (((void *)0)), 0);
 }
-if(computedExp != sourceExp)
+if(computedExp != nbExp)
 {
 FreeExpression(computedExp);
-computedExp = sourceExp;
+computedExp = nbExp;
 }
 if(dest->kind != 8 && source->kind == 8 && source->__anon1._class && source->__anon1._class->__anon1.registered && !strcmp(source->__anon1._class->__anon1.registered->fullName, "unichar"))
 {
@@ -13916,7 +14022,11 @@ sourceExp->expType = dest;
 dest->refCount++;
 }
 flag = 1;
-((tempType ? (__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)tempType) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(tempType)) : 0), tempType = 0);
+((tempType ? __extension__ ({
+void * __ecerePtrToDelete = (tempType);
+
+__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), tempType = 0);
 }
 }
 if(_class && _class->type == 2 && source->kind != 8)
@@ -14001,7 +14111,11 @@ dest->classObjectType = source->classObjectType;
 FreeType(source);
 source = _class->dataType;
 source->refCount++;
-((tempType ? (__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)tempType) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(tempType)) : 0), tempType = 0);
+((tempType ? __extension__ ({
+void * __ecerePtrToDelete = (tempType);
+
+__ecereClass_Type->Destructor ? __ecereClass_Type->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), tempType = 0);
 }
 }
 }
@@ -14126,18 +14240,40 @@ ListAdd(specs, MkSpecifier(BOOL));
 }
 else if(dest->kind == 1 && (source->kind == 24 || source->kind == 1 || source->kind == 15 || source->kind == 2 || source->kind == 3) && (dest->isSigned ? (value >= -128 && value <= 127) : (value >= 0 && value <= 255)))
 {
+if(source->kind == 3)
+{
+FreeType(dest);
+FreeType(source);
+if(backupSourceExpType)
+FreeType(backupSourceExpType);
+return 1;
+}
+else
+{
 specs = MkList();
 if(!dest->isSigned)
 ListAdd(specs, MkSpecifier(UNSIGNED));
 ListAdd(specs, MkSpecifier(CHAR));
 }
+}
 else if(dest->kind == 2 && (source->kind == 15 || source->kind == 24 || source->kind == 1 || source->kind == 2 || (source->kind == 3 && (dest->isSigned ? (value >= -32768 && value <= 32767) : (value >= 0 && value <= 65535)))))
 {
+if(source->kind == 3)
+{
+FreeType(dest);
+FreeType(source);
+if(backupSourceExpType)
+FreeType(backupSourceExpType);
+return 1;
+}
+else
+{
 specs = MkList();
 if(!dest->isSigned)
 ListAdd(specs, MkSpecifier(UNSIGNED));
 ListAdd(specs, MkSpecifier(SHORT));
 }
+}
 else if(dest->kind == 3 && (source->kind == 15 || source->kind == 2 || source->kind == 24 || source->kind == 1 || source->kind == 3))
 {
 specs = MkList();
@@ -14207,10 +14343,10 @@ return 1;
 }
 else
 {
-if(computedExp != sourceExp)
+if(computedExp != nbExp)
 {
 FreeExpression(computedExp);
-computedExp = sourceExp;
+computedExp = nbExp;
 }
 while((sourceExp->type == 5 || sourceExp->type == 32) && sourceExp->__anon1.list)
 sourceExp = (*sourceExp->__anon1.list).last;
@@ -14650,7 +14786,7 @@ if(spec->__anon1.specifier == TYPED_OBJECT)
 struct Declarator * d = param->declarator;
 struct TypeName * newParam = (newParam = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass_TypeName), newParam->qualifiers = MkListOne(MkSpecifier(VOID)), newParam->declarator = MkDeclaratorPointer(MkPointer((((void *)0)), (((void *)0))), d), newParam);
 
-if(d->type != 5)
+if(!d || d->type != 5)
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Insert((&*newParam->qualifiers), (((void *)0)), MkSpecifier(CONST));
 FreeList(param->qualifiers, (void *)(FreeSpecifier));
 param->qualifiers = MkListOne(MkStructOrUnion(3, MkIdentifier("__ecereNameSpace__ecere__com__Class"), (((void *)0))));
@@ -14666,7 +14802,7 @@ struct Declarator * d = param->declarator;
 
 FreeList(param->qualifiers, (void *)(FreeSpecifier));
 param->qualifiers = MkListOne(MkSpecifier(VOID));
-if(d->type != 5)
+if(!d || d->type != 5)
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Insert((&*param->qualifiers), (((void *)0)), MkSpecifier(CONST));
 param->declarator = MkDeclaratorPointer(MkPointer((((void *)0)), (((void *)0))), d);
 break;
@@ -14687,6 +14823,13 @@ else if(spec->type == 1)
 {
 ProcessSpecifier(spec, isFunction, 1);
 }
+else if((spec->type == 3 || spec->type == 4) && !spec->__anon1.__anon2.definitions && spec->__anon1.__anon2.id && spec->__anon1.__anon2.id->string)
+{
+struct Declarator * d = param->declarator;
+
+if(!d || d->type != 5)
+DeclareStruct(curExternal, spec->__anon1.__anon2.id->string, 0, 1);
+}
 }
 }
 if(param->declarator)
@@ -15619,6 +15762,7 @@ DeclareFunctionUtil((((void *)0)), "eInstance_IncRef");
 DeclareFunctionUtil((((void *)0)), "eInstance_StopWatching");
 DeclareFunctionUtil((((void *)0)), "eInstance_Watch");
 DeclareFunctionUtil((((void *)0)), "eInstance_FireWatchers");
+reachedPass15 = 1;
 for(external = (*ast).first; external; external = external->next)
 {
 afterExternal = curExternal = external;
@@ -15660,7 +15804,11 @@ ProcessClass(_class->definitions, _class->symbol);
 if(inCompiler)
 {
 __ecereMethod___ecereNameSpace__ecere__sys__OldList_Remove((&*ast), external);
-((external ? (__ecereClass_External->Destructor ? __ecereClass_External->Destructor((void *)external) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(external)) : 0), external = 0);
+((external ? __extension__ ({
+void * __ecerePtrToDelete = (external);
+
+__ecereClass_External->Destructor ? __ecereClass_External->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), external = 0);
 }
 }
 else if(external->type == 4)
@@ -15717,8 +15865,13 @@ break;
 }
 else
 {
-struct Symbol * symbol = FindSymbol(id->string, curContext, topContext, 0, id->_class && id->_class->__anon1.__anon1.name == (((void *)0)));
+struct Symbol * symbol = (((void *)0));
+unsigned int findInGlobal = 0;
 
+if(!topContext->parent && exp->destType && exp->destType->kind == 8 && exp->destType->__anon1._class && exp->destType->__anon1._class->__anon1.registered && exp->destType->__anon1._class->__anon1.registered->type == 4)
+findInGlobal = 1;
+else
+symbol = FindSymbol(id->string, curContext, topContext, 0, id->_class && id->_class->__anon1.__anon1.name == (((void *)0)));
 if(!symbol)
 {
 if(exp->destType && CheckExpressionType(exp, exp->destType, 0, 0))
@@ -15742,6 +15895,8 @@ break;
 symbol = FindSymbol(id->string, topContext->parent, globalContext, 0, id->_class && id->_class->__anon1.__anon1.name == (((void *)0)));
 }
 }
+if(findInGlobal)
+symbol = FindSymbol(id->string, curContext, topContext, 0, id->_class && id->_class->__anon1.__anon1.name == (((void *)0)));
 if(symbol)
 {
 struct Type * type = symbol->type;
@@ -15822,16 +15977,26 @@ struct __ecereNameSpace__ecere__com__Instance * backInput = fileInput;
 
 definedExpStack[definedExpStackPos++] = definedExp;
 fileInput = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass___ecereNameSpace__ecere__sys__TempFile);
-((int (*)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count))__extension__ ({
+(__extension__ ({
+int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count);
+
+__internal_VirtualMethod = ((int (*)(struct __ecereNameSpace__ecere__com__Instance *, const void *  buffer, unsigned int size, unsigned int count))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = fileInput;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__File->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Write])(fileInput, definedExp->value, 1, strlen(definedExp->value));
-((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Write]);
+__internal_VirtualMethod ? __internal_VirtualMethod(fileInput, definedExp->value, 1, strlen(definedExp->value)) : (int)1;
+}));
+(__extension__ ({
+unsigned int (*  __internal_VirtualMethod)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode);
+
+__internal_VirtualMethod = ((unsigned int (*)(struct __ecereNameSpace__ecere__com__Instance *, int pos, int mode))__extension__ ({
 struct __ecereNameSpace__ecere__com__Instance * __internal_ClassInst = fileInput;
 
 __internal_ClassInst ? __internal_ClassInst->_vTbl : __ecereClass___ecereNameSpace__ecere__sys__File->_vTbl;
-})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek])(fileInput, 0, 0);
+})[__ecereVMethodID___ecereNameSpace__ecere__sys__File_Seek]);
+__internal_VirtualMethod ? __internal_VirtualMethod(fileInput, 0, 0) : (unsigned int)1;
+}));
 echoOn = 0;
 parsedExpression = (((void *)0));
 resetScanner();
@@ -16090,6 +16255,8 @@ unsigned int useDestType = 0, useSideType = 0;
 struct Location oldyylloc = yylloc;
 unsigned int useSideUnit = 0;
 struct __ecereNameSpace__ecere__com__Class * destClass = (exp->destType && exp->destType->kind == 8 && exp->destType->__anon1._class) ? exp->destType->__anon1._class->__anon1.registered : (((void *)0));
+unsigned int powerOp = 0, relationOp = 0;
+struct __ecereNameSpace__ecere__com__Class * c1 = (((void *)0)), * c2 = (((void *)0));
 struct Type * dummy = (dummy = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass_Type), dummy->count = 1, dummy->refCount = 1, dummy);
 
 switch(exp->__anon1.op.op)
@@ -16122,6 +16289,7 @@ case GE_OP:
 case NE_OP:
 boolResult = 1;
 useSideType = 1;
+relationOp = 1;
 break;
 case '+':
 case '-':
@@ -16141,6 +16309,8 @@ case '/':
 case '%':
 useSideType = 1;
 useDestType = 1;
+if(exp->__anon1.op.op == '/')
+powerOp = 1;
 break;
 case '&':
 case '*':
@@ -16148,6 +16318,8 @@ if(exp->__anon1.op.exp1)
 {
 useSideType = 1;
 useDestType = 1;
+if(exp->__anon1.op.op == '*')
+powerOp = 1;
 }
 break;
 }
@@ -16191,6 +16363,17 @@ if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
 exp->__anon1.op.exp1->destType = dummy;
 dummy->refCount++;
+if(powerOp)
+exp->__anon1.op.exp1->opDestType = 1;
+if(relationOp)
+exp->__anon1.op.exp1->usedInComparison = 1;
+}
+if(exp->__anon1.op.op == '+' || exp->__anon1.op.op == '-')
+{
+if(exp->opDestType)
+exp->__anon1.op.exp1->parentOpDestType = 1;
+if(exp->usedInComparison)
+exp->__anon1.op.exp1->usedInComparison = 1;
 }
 if(exp->__anon1.op.exp1->destType && exp->__anon1.op.op != '=')
 exp->__anon1.op.exp1->destType->count++;
@@ -16198,6 +16381,7 @@ ProcessExpressionType(exp->__anon1.op.exp1);
 if(exp->__anon1.op.exp1->destType && exp->__anon1.op.op != '=')
 exp->__anon1.op.exp1->destType->count--;
 exp->__anon1.op.exp1->opDestType = 0;
+exp->__anon1.op.exp1->usedInComparison = 0;
 if(!exp->__anon1.op.exp2 && (exp->__anon1.op.op == INC_OP || exp->__anon1.op.op == DEC_OP) && exp->__anon1.op.exp1->expType && exp->__anon1.op.exp1->expType->kind == 8 && exp->__anon1.op.exp1->expType->__anon1._class && exp->__anon1.op.exp1->expType->__anon1._class->__anon1.registered && exp->__anon1.op.exp1->expType->__anon1._class->__anon1.registered->type == 3)
 {
 exp->__anon1.op.exp2 = MkExpConstant("1");
@@ -16211,7 +16395,7 @@ exp->__anon1.op.exp1->destType = (((void *)0));
 }
 if(exp->__anon1.op.exp2)
 {
-if(exp->__anon1.op.exp1->expType && (exp->__anon1.op.exp1->expType->kind == 1 || exp->__anon1.op.exp1->expType->kind == 2))
+if(!assign && exp->__anon1.op.exp1->expType && (exp->__anon1.op.exp1->expType->kind == 1 || exp->__anon1.op.exp1->expType->kind == 2))
 {
 struct Type * type = (type = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass_Type), type->kind = 3, type->isSigned = 1, type->refCount = 1, type->signedBeforePromotion = exp->__anon1.op.exp1->expType->isSigned, type->bitMemberSize = exp->__anon1.op.exp1->expType->bitMemberSize, type->promotedFrom = exp->__anon1.op.exp1->expType->kind, type);
 
@@ -16296,6 +16480,10 @@ if(exp->__anon1.op.exp2->destType)
 FreeType(exp->__anon1.op.exp2->destType);
 exp->__anon1.op.exp2->destType = dummy;
 dummy->refCount++;
+if(powerOp)
+exp->__anon1.op.exp2->opDestType = 1;
+if(relationOp)
+exp->__anon1.op.exp2->usedInComparison = 1;
 }
 if(type1 && boolResult && useSideType && type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && (type1->__anon1._class->__anon1.registered->type == 2 || type1->__anon1._class->__anon1.registered->type == 4))
 {
@@ -16322,11 +16510,19 @@ e = (*e->__anon1.list).last;
 if(e->type == 11 && e->__anon1.cast.exp)
 e->__anon1.cast.exp->needCast = 1;
 }
+if(exp->__anon1.op.op == '+' || exp->__anon1.op.op == '-')
+{
+if(exp->opDestType)
+exp->__anon1.op.exp2->parentOpDestType = 1;
+if(exp->usedInComparison)
+exp->__anon1.op.exp2->usedInComparison = 1;
+}
 ProcessExpressionType(exp->__anon1.op.exp2);
 exp->__anon1.op.exp2->opDestType = 0;
+exp->__anon1.op.exp2->usedInComparison = 0;
 if(exp->__anon1.op.exp2->destType && exp->__anon1.op.op != '=')
 exp->__anon1.op.exp2->destType->count--;
-if(exp->__anon1.op.exp1 || exp->__anon1.op.op == '~')
+if(!assign && (exp->__anon1.op.exp1 || exp->__anon1.op.op == '~'))
 {
 if(exp->__anon1.op.exp2->expType && (exp->__anon1.op.exp2->expType->kind == 1 || exp->__anon1.op.exp2->expType->kind == 2))
 {
@@ -16395,6 +16591,17 @@ if(type2)
 type2->refCount++;
 }
 }
+c1 = type1 && type1->kind == 8 && type1->__anon1._class ? type1->__anon1._class->__anon1.registered : (((void *)0));
+c2 = type2 && type2->kind == 8 && type2->__anon1._class ? type2->__anon1._class->__anon1.registered : (((void *)0));
+if(relationOp && ((exp->__anon1.op.exp1 && exp->__anon1.op.exp1->ambiguousUnits && (!c2 || c2->type != 3)) || (exp->__anon1.op.exp2 && exp->__anon1.op.exp2->ambiguousUnits && (!c1 || c1->type != 3))))
+Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "ambiguous units in relational operation\n", (((void *)0))));
+if(!relationOp && ((exp->__anon1.op.exp1 && exp->__anon1.op.exp1->ambiguousUnits) || (exp->__anon1.op.exp2 && exp->__anon1.op.exp2->ambiguousUnits)) && (!powerOp || !c1 || c1->type != 3 || !c2 || c2->type != 3 || !RelatedUnits(c1, c2)))
+{
+if(exp->opDestType || exp->usedInComparison)
+exp->ambiguousUnits = 1;
+else
+Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "ambiguous units\n", (((void *)0))));
+}
 dummy->kind = 0;
 if(exp->__anon1.op.op == SIZEOF)
 {
@@ -16423,6 +16630,10 @@ exp->expType->refCount++;
 }
 else if(!assign)
 {
+if(c1 && !c1->dataType)
+c1->dataType = ProcessTypeString(c1->dataTypeString, 0);
+if(c2 && !c2->dataType)
+c2->dataType = ProcessTypeString(c2->dataTypeString, 0);
 if(boolOps)
 {
 if(exp->__anon1.op.exp1)
@@ -16454,19 +16665,36 @@ exp->__anon1.op.exp2->expType = MkClassType("bool");
 exp->__anon1.op.exp2->expType->truth = 1;
 }
 }
+else if(powerOp && exp->__anon1.op.exp1 && exp->__anon1.op.exp2 && ((c1 && c1->type == 3) || (c2 && c2->type == 3)))
+{
+if(c1 && c1->type == 3 && c2 && c2->type == 3)
+{
+if(c1->dataType->kind == 7)
+exp->expType = c1->dataType;
+else if(c2->dataType->kind == 7)
+exp->expType = c2->dataType;
+else if(c1->dataType->kind == 6)
+exp->expType = c1->dataType;
+else if(c2->dataType->kind == 6)
+exp->expType = c2->dataType;
+else
+exp->expType = c1->dataType;
+}
+else if((c1 && c1->type == 3) || exp->__anon1.op.op == '/')
+exp->expType = type1;
+else
+exp->expType = type2;
+if(exp->expType)
+exp->expType->refCount++;
+}
 else if(exp->__anon1.op.exp1 && exp->__anon1.op.exp2 && ((useSideType) || ((!type1 || type1->kind != 8 || !strcmp(type1->__anon1._class->string, "String")) && (!type2 || type2->kind != 8 || !strcmp(type2->__anon1._class->string, "String")))))
 {
 if(type1 && type2 && ((type1->kind == 8 && type1->__anon1._class && strcmp(type1->__anon1._class->string, "String")) == (type2->kind == 8 && type2->__anon1._class && strcmp(type2->__anon1._class->string, "String"))))
 {
-if(exp->__anon1.op.op == '-' && ((type1->kind == 8 && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4) || (type2->kind == 8 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4)))
+if(exp->__anon1.op.op == '-' && ((c1 && c1->type == 4) || (c2 && c2->type == 4)))
 {
-struct Type * intType;
+struct Type * intType = ProcessTypeString((c1 && c1->dataType->kind == 4) || (c2 && c2->dataType->kind == 4) ? "int64" : "int", 0);
 
-if(!type1->__anon1._class->__anon1.registered->dataType)
-type1->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type1->__anon1._class->__anon1.registered->dataTypeString, 0);
-if(!type2->__anon1._class->__anon1.registered->dataType)
-type2->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type2->__anon1._class->__anon1.registered->dataTypeString, 0);
-intType = ProcessTypeString((type1->__anon1._class->__anon1.registered->dataType->kind == 4 || type2->__anon1._class->__anon1.registered->dataType->kind == 4) ? "int64" : "int", 0);
 if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
 if(exp->__anon1.op.exp2->destType)
@@ -16486,8 +16714,13 @@ FreeType(exp->__anon1.op.exp1->destType);
 exp->__anon1.op.exp1->destType = type2;
 type2->refCount++;
 }
-if(!boolResult && type1->kind == 8 && (!exp->destType || exp->destType->kind != 8) && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && type1->__anon1._class->__anon1.registered != type2->__anon1._class->__anon1.registered)
+if(!boolResult && !exp->opDestType && (!exp->destType || exp->destType->kind != 8) && c1 && c1->type == 3 && c2 && c2->type == 3 && c1 != c2)
+{
+if(exp->usedInComparison || exp->parentOpDestType)
+exp->ambiguousUnits = 1;
+else
 Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "operating on %s and %s with an untyped result, assuming %s\n", (((void *)0))), type1->__anon1._class->string, type2->__anon1._class->string, type1->__anon1._class->string);
+}
 if(type1->kind == 13 && type1->__anon1.type->kind == 20 && type2->kind != 13)
 {
 struct Expression * argExp = GetTemplateArgExp(type1->__anon1.type->__anon1.templateParameter, thisClass, 1);
@@ -16507,6 +16740,7 @@ if(!exp->__anon1.op.exp2->expType)
 if(type2)
 FreeType(type2);
 type2 = exp->__anon1.op.exp2->expType = ProcessTypeString("int", 0);
+c2 = (((void *)0));
 type2->refCount++;
 }
 ProcessExpressionType(exp->__anon1.op.exp2);
@@ -16636,7 +16870,7 @@ Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "incompatibl
 }
 }
 }
-else if(!boolResult && (!useSideUnit) && type2 && type1 && type2->kind == 8 && type1->kind != 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3)
+else if(!boolResult && !useSideUnit && c2 && c2->type == 3 && type1 && type1->kind != 8)
 {
 if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
@@ -16648,7 +16882,7 @@ exp->expType = type2;
 if(type2)
 type2->refCount++;
 }
-else if(!boolResult && (!useSideUnit) && type1 && type2 && type1->kind == 8 && type2->kind != 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3)
+else if(!boolResult && !useSideUnit && c1 && c1->type == 3 && type2 && type2->kind != 8)
 {
 if(exp->__anon1.op.exp2->destType)
 FreeType(exp->__anon1.op.exp2->destType);
@@ -16664,40 +16898,38 @@ else if(type1)
 {
 unsigned int valid = 0;
 
-if(!boolResult && useSideUnit && type1 && type1->kind == 8 && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3 && type2 && type2->kind != 8)
+if(!boolResult && useSideUnit && c1 && c1->type == 3 && type2 && type2->kind != 8)
 {
 if(exp->__anon1.op.exp2->destType)
 FreeType(exp->__anon1.op.exp2->destType);
-if(!type1->__anon1._class->__anon1.registered->dataType)
-type1->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type1->__anon1._class->__anon1.registered->dataTypeString, 0);
-exp->__anon1.op.exp2->destType = type1->__anon1._class->__anon1.registered->dataType;
+exp->__anon1.op.exp2->destType = c1->dataType;
 exp->__anon1.op.exp2->destType->refCount++;
 CheckExpressionType(exp->__anon1.op.exp2, exp->__anon1.op.exp2->destType, 0, 0);
 if(type2)
 FreeType(type2);
 type2 = exp->__anon1.op.exp2->destType;
+c2 = type2 && type2->kind == 8 && type2->__anon1._class ? type2->__anon1._class->__anon1.registered : (((void *)0));
 if(type2)
 type2->refCount++;
 exp->expType = type2;
 type2->refCount++;
 }
-if(!boolResult && useSideUnit && type2 && type2->kind == 8 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && type1 && type1->kind != 8)
+if(!boolResult && useSideUnit && c2 && c2->type == 3 && type1 && type1->kind != 8)
 {
 if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
-if(!type2->__anon1._class->__anon1.registered->dataType)
-type2->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type2->__anon1._class->__anon1.registered->dataTypeString, 0);
-exp->__anon1.op.exp1->destType = type2->__anon1._class->__anon1.registered->dataType;
+exp->__anon1.op.exp1->destType = c2->dataType;
 exp->__anon1.op.exp1->destType->refCount++;
 CheckExpressionType(exp->__anon1.op.exp1, exp->__anon1.op.exp1->destType, 0, 0);
 type1 = exp->__anon1.op.exp1->destType;
+c1 = type1 && type1->kind == 8 && type1->__anon1._class ? type1->__anon1._class->__anon1.registered : (((void *)0));
 exp->expType = type1;
 type1->refCount++;
 }
 if(!boolResult || exp->__anon1.op.op == '>' || exp->__anon1.op.op == '<' || exp->__anon1.op.op == GE_OP || exp->__anon1.op.op == LE_OP)
 {
-unsigned int op1IsEnum = type1 && type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4;
-unsigned int op2IsEnum = type2 && type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4;
+unsigned int op1IsEnum = c1 && c1->type == 4;
+unsigned int op2IsEnum = c2 && c2->type == 4;
 
 if(exp->__anon1.op.op == '*' || exp->__anon1.op.op == '/' || exp->__anon1.op.op == '-' || exp->__anon1.op.op == '|' || exp->__anon1.op.op == '^')
 {
@@ -16756,7 +16988,7 @@ valid = 1;
 }
 if(!valid)
 {
-if(type2 && type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && (type1->kind != 8 || !type1->__anon1._class || !type1->__anon1._class->__anon1.registered || type1->__anon1._class->__anon1.registered->type != 3))
+if(c2 && c2->type == 3 && (!c1 || c1->type != 3))
 {
 if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
@@ -16806,13 +17038,13 @@ PrintType(exp->__anon1.op.exp1->expType, type1String, 0, 1);
 PrintType(exp->__anon1.op.exp2->expType, type2String, 0, 1);
 }
 Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "incompatible expressions %s (%s) and %s (%s)\n", (((void *)0))), expString1, type1String, expString2, type2String);
-if(type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4)
+if(c1 && c1->type == 4)
 {
 exp->expType = exp->__anon1.op.exp1->expType;
 if(exp->__anon1.op.exp1->expType)
 exp->__anon1.op.exp1->expType->refCount++;
 }
-else if(type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4)
+else if(c2 && c2->type == 4)
 {
 exp->expType = exp->__anon1.op.exp2->expType;
 if(exp->__anon1.op.exp2->expType)
@@ -16824,7 +17056,7 @@ exp->__anon1.op.exp2->expType->refCount++;
 }
 else if(type2)
 {
-if(type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4)
+if(c2 && c2->type == 4)
 {
 struct Type * oldType = exp->__anon1.op.exp1->expType;
 
@@ -16850,7 +17082,7 @@ exp->__anon1.op.exp1->destType->refCount++;
 }
 else if(type2 && (!type1 || (type2->kind == 8 && type1->kind != 8)))
 {
-if(type1 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3)
+if(type1 && c2 && c2->type == 3)
 {
 if(exp->__anon1.op.exp1->destType)
 FreeType(exp->__anon1.op.exp1->destType);
@@ -16873,7 +17105,7 @@ type2->refCount++;
 }
 else if(type1 && (!type2 || (type1->kind == 8 && type2->kind != 8)))
 {
-if(type2 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3)
+if(c2 && c2->type == 3)
 {
 if(exp->__anon1.op.exp2->destType)
 FreeType(exp->__anon1.op.exp2->destType);
@@ -16946,6 +17178,8 @@ if(!e->next)
 {
 FreeType(e->destType);
 e->opDestType = exp->opDestType;
+e->usedInComparison = exp->usedInComparison;
+e->parentOpDestType = exp->parentOpDestType;
 e->destType = exp->destType;
 if(e->destType)
 {
@@ -16953,11 +17187,14 @@ exp->destType->refCount++;
 }
 }
 ProcessExpressionType(e);
+if(e->ambiguousUnits)
+exp->ambiguousUnits = 1;
 if(!exp->expType && !e->next)
 {
 exp->expType = e->expType;
 if(e->expType)
 e->expType->refCount++;
+exp->needCast = e->needCast;
 }
 if(!e->isConstant)
 exp->isConstant = 0;
@@ -16973,7 +17210,11 @@ FreeType(exp->destType);
 *exp = *e;
 exp->prev = prev;
 exp->next = next;
-((e ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)e) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(e)) : 0), e = 0);
+((e ? __extension__ ({
+void * __ecerePtrToDelete = (e);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), e = 0);
 ProcessExpressionType(exp);
 }
 break;
@@ -18401,7 +18642,11 @@ FreeType(exp->expType);
 FreeType(exp->destType);
 exp->expType = expType;
 exp->destType = destType;
-((castExp ? (__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)castExp) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(castExp)) : 0), castExp = 0);
+((castExp ? __extension__ ({
+void * __ecerePtrToDelete = (castExp);
+
+__ecereClass_Expression->Destructor ? __ecereClass_Expression->Destructor((void *)__ecerePtrToDelete) : 0, __ecereNameSpace__ecere__com__eSystem_Delete(__ecerePtrToDelete);
+}) : 0), castExp = 0);
 exp->prev = prev;
 exp->next = next;
 }
@@ -18693,6 +18938,10 @@ __ecereMethod___ecereNameSpace__ecere__sys__OldList_Add(&exp->expType->__anon1._
 }
 }
 }
+if(!notByReference && exp->expType && exp->expType->kind == 8 && exp->expType->__anon1._class && exp->expType->__anon1._class->__anon1.registered && exp->expType->__anon1._class->__anon1.registered->type == 5 && (!exp->destType || (exp->destType->kind != 3 && exp->destType->kind != 4 && exp->destType->kind != 22 && exp->destType->kind != 23 && exp->destType->kind != 5 && exp->destType->kind != 2 && exp->destType->kind != 1 && exp->destType->kind != 24)))
+{
+exp->byReference = 1;
+}
 yylloc = exp->loc;
 if(exp->destType && (exp->destType->kind == 18))
 ;
@@ -18781,6 +19030,8 @@ struct Expression * nbExp = GetNonBracketsExp(exp);
 unsigned int skipWarning = 0;
 int kind = exp->destType->kind;
 
+if(nbExp->type == 12 && nbExp->destType && !nbExp->destType->casted && nbExp->destType->kind == exp->destType->kind)
+skipWarning = 1;
 if((kind == 1 || kind == 2) && exp->destType->isSigned == exp->expType->signedBeforePromotion && nbExp->type == 4 && nbExp->__anon1.op.exp1 && nbExp->__anon1.op.exp2)
 {
 int op = nbExp->__anon1.op.op;
@@ -18821,10 +19072,9 @@ break;
 case '-':
 if(!exp->destType->isSigned)
 {
-struct Expression * nbExp1 = GetNonBracketsExp(nbExp->__anon1.op.exp1);
-struct Expression * nbExp2 = GetNonBracketsExp(nbExp->__anon1.op.exp2);
-int from = nbExp2->expType->promotedFrom;
-
+nbExp1 = GetNonBracketsExp(nbExp->__anon1.op.exp1);
+nbExp2 = GetNonBracketsExp(nbExp->__anon1.op.exp2);
+from = nbExp2->expType->promotedFrom;
 if((from == 1 || from == 2) && nbExp1->isConstant && nbExp1->type == 2)
 {
 int n = strtol(nbExp1->__anon1.__anon1.constant, (((void *)0)), 0);
@@ -18834,6 +19084,30 @@ skipWarning = 1;
 }
 }
 break;
+case '|':
+{
+int kind1, kind2;
+
+nbExp1 = GetNonBracketsExp(nbExp->__anon1.op.exp1);
+nbExp2 = GetNonBracketsExp(nbExp->__anon1.op.exp2);
+kind1 = nbExp1->expType->promotedFrom ? nbExp1->expType->promotedFrom : nbExp1->expType->kind;
+kind2 = nbExp2->expType->promotedFrom ? nbExp2->expType->promotedFrom : nbExp2->expType->kind;
+if(((kind1 == 1 || (kind1 == 2 && kind == 2)) || MatchTypeExpression(nbExp1, exp->destType, (((void *)0)), 0, 0)) && ((kind2 == 1 || (kind2 == 2 && kind == 2)) || MatchTypeExpression(nbExp2, exp->destType, (((void *)0)), 0, 0)))
+skipWarning = 1;
+break;
+}
+case '&':
+{
+int kind1, kind2;
+
+nbExp1 = GetNonBracketsExp(nbExp->__anon1.op.exp1);
+nbExp2 = GetNonBracketsExp(nbExp->__anon1.op.exp2);
+kind1 = nbExp1->expType->promotedFrom ? nbExp1->expType->promotedFrom : nbExp1->expType->kind;
+kind2 = nbExp2->expType->promotedFrom ? nbExp2->expType->promotedFrom : nbExp2->expType->kind;
+if(((kind1 == 1 || (kind1 == 2 && kind == 2)) || MatchTypeExpression(nbExp1, exp->destType, (((void *)0)), 0, 0)) || ((kind2 == 1 || (kind2 == 2 && kind == 2)) || MatchTypeExpression(nbExp2, exp->destType, (((void *)0)), 0, 0)))
+skipWarning = 1;
+break;
+}
 }
 }
 if(!skipWarning)
@@ -19090,7 +19364,7 @@ if(_class->fixed)
 {
 struct Expression * e;
 
-if(_class->offset && _class->offset == _class->base->structSize)
+if(_class->offset && _class->offset == (_class->base->type == 5 ? _class->base->memberOffset : _class->base->structSize))
 {
 e = MkExpClassSize(MkSpecifierName(_class->base->fullName));
 ProcessExpressionType(e);
@@ -19393,6 +19667,7 @@ __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ParseExpressionString",
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ReplaceExpContents", "void ReplaceExpContents(Expression checkedExp, Expression newExp)", ReplaceExpContents, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ApplyAnyObjectLogic", "void ApplyAnyObjectLogic(Expression e)", ApplyAnyObjectLogic, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ApplyLocation", "void ApplyLocation(Expression exp, Location loc)", ApplyLocation, module, 1);
+__ecereNameSpace__ecere__com__eSystem_RegisterFunction("RelatedUnits", "bool RelatedUnits(ecere::com::Class c1, ecere::com::Class c2)", RelatedUnits, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ProcessExpressionType", "void ProcessExpressionType(Expression exp)", ProcessExpressionType, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("DeclareFunctionUtil", "void DeclareFunctionUtil(External neededBy, const String s)", DeclareFunctionUtil, module, 1);
 __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ComputeDataTypes", "void ComputeDataTypes(void)", ComputeDataTypes, module, 1);