ecere/com; compiler/libec: (#1087) Fixed class:struct issues
[sdk] / compiler / libec / src / pass2.ec
index 71b7a2c..e955b2d 100644 (file)
@@ -26,6 +26,8 @@ static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
 
          *memberExpPtr = null;
          newExp = CopyExpression(exp);
+         FreeExpContents(exp);
+
          *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp;
 
          memberExp.member.exp = idExp;
@@ -137,6 +139,8 @@ static Expression FixReference(Expression e, bool wantReference)
                      {
                         Expression newExp { };
                         *newExp = *exp;
+                        newExp.prev = null;
+                        newExp.next = null;
 
                         if(exp.destType) exp.destType.refCount++;
                         if(exp.expType) exp.expType.refCount++;
@@ -163,6 +167,27 @@ static Expression FixReference(Expression e, bool wantReference)
    return e;
 }
 
+static Expression GetInnerExp(Expression exp)
+{
+   Expression e = exp;
+   while(e && (e.type == bracketsExp || e.type == castExp))
+   {
+      if(e.type == bracketsExp)
+         e = e.list ? e.list->last : null;
+      else if(e.type == castExp)
+         e = e.cast.exp;
+   }
+   return e;
+}
+
+Expression GetNonBracketsExp(Expression exp)
+{
+   Expression e = exp;
+   while(e && e.type == bracketsExp)
+      e = e.list ? e.list->last : null;
+   return e;
+}
+
 static bool FixMember(Expression exp)
 {
    bool byReference = false;
@@ -220,7 +245,7 @@ static void ProcessExpression(Expression exp)
                strcat(name, "_");
                strcat(name, method.name);
 
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
 
                // Cast function to its type
                decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
@@ -250,12 +275,13 @@ static void ProcessExpression(Expression exp)
                   // Need the class itself here...
                   strcpy(className, "__ecereClass_");
                   FullClassNameCat(className, _class.fullName, true);
-                  MangleClassName(className);
 
                   if(!_class.symbol)
                      _class.symbol = FindClass(_class.fullName);
-                  DeclareClass(_class.symbol, className);
+                  DeclareClass(curExternal, _class.symbol, className);
 
+                  if(exp.identifier)
+                     FreeIdentifier(exp.identifier);
                   exp.type = bracketsExp;
                   exp.list = MkListOne(MkExpCast(typeName,
                      MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
@@ -271,10 +297,11 @@ static void ProcessExpression(Expression exp)
                strcat(name, method.name);
 
                delete exp.identifier.string;
+               FreeSpecifier(exp.identifier._class);
 
                exp.identifier._class = null;
                exp.identifier.string = CopyString(name);
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
             }
          }
          /*
@@ -301,10 +328,10 @@ static void ProcessExpression(Expression exp)
 
          switch(exp.type)
          {
-            case newExp:   exp.call.exp = QMkExpId("ecere::com::eSystem_New"); break;
-            case new0Exp:  exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); break;
-            case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); break;
-            case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); break;
+            case newExp:   exp.call.exp = QMkExpId("ecere::com::eSystem_New"); DeclareFunctionUtil(curExternal, "eSystem_New"); break;
+            case new0Exp:  exp.call.exp = QMkExpId("ecere::com::eSystem_New0"); DeclareFunctionUtil(curExternal, "eSystem_New0"); break;
+            case renewExp: exp.call.exp = QMkExpId("ecere::com::eSystem_Renew"); DeclareFunctionUtil(curExternal, "eSystem_Renew"); break;
+            case renew0Exp:exp.call.exp = QMkExpId("ecere::com::eSystem_Renew0"); DeclareFunctionUtil(curExternal, "eSystem_Renew0"); break;
          }
          exp.call.arguments = args;
          exp.type = callExp;
@@ -396,6 +423,7 @@ static void ProcessExpression(Expression exp)
          {
             Expression memberExp;
             Expression parentExp = null; // Where to take memberExp out from
+            bool isIndexedContainerAssignment = false;
 
             // TOCHECK: See note below for this if
             if(exp.op.exp1 && exp.op.exp1.type == ExpressionType::memberExp)
@@ -447,7 +475,7 @@ static void ProcessExpression(Expression exp)
                            }
                            if(lastProperty && lastProperty.Get && lastProperty.Set)
                            {
-                              DeclareProperty(lastProperty, setName, getName);
+                              DeclareProperty(curExternal, lastProperty, setName, getName);
                               // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
                               propertyClass = convertTo ? _class :
                                  ((((Symbol)lastProperty.symbol).type &&
@@ -561,6 +589,14 @@ static void ProcessExpression(Expression exp)
                memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
                memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
             {
+               Class c = memberExp.index.exp.expType._class.registered;
+               if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
+               {
+                  exp.op.exp2 = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2)));
+                  exp.op.exp2 = MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(exp.op.exp2)))));
+                  isIndexedContainerAssignment = true;
+               }
+
                ProcessExpression(memberExp);
 
                while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
@@ -598,7 +634,7 @@ static void ProcessExpression(Expression exp)
 
             if(memberExp && memberExp.type != ExpressionType::memberExp) memberExp = null;
 
-            if(memberExp && memberExp.type == ExpressionType::memberExp)
+            if(memberExp && memberExp.type == ExpressionType::memberExp && memberExp.member.member)
             {
                Type type = memberExp.member.exp.expType;
                if(type)
@@ -654,7 +690,7 @@ static void ProcessExpression(Expression exp)
                                MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.exp), '&',
                                  MkExpOp(null, '~', MkExpConstant(mask))))), '|',
                                MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(
-                                 MkListOne(MkExpCast(type, exp.op.exp2))), LEFT_OP, MkExpConstant(shift)))));
+                                 MkListOne(MkExpCast(type, MkExpBrackets(MkListOne(exp.op.exp2))))), LEFT_OP, MkExpConstant(shift)))));
                          }
 
                          memberExp.member.exp = null;
@@ -708,7 +744,13 @@ static void ProcessExpression(Expression exp)
                               exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_SetProperty"));
                               exp.call.arguments = MkList();
                               ListAdd(exp.call.arguments, classExp);
-                              ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
+                              {
+                                 char * s = QMkString(id.string);
+                                 ListAdd(exp.call.arguments, MkExpString(s));
+                                 delete s;
+                              }
+                              if(value.expType.isPointerType)
+                                 value = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("intptr")), null), value);
                               ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
 
                               FreeIdentifier(id);
@@ -768,7 +810,7 @@ static void ProcessExpression(Expression exp)
                               if(value)
                                  value.usage.usageArg = true;
 
-                              DeclareProperty(prop, setName, getName);
+                              DeclareProperty(curExternal, prop, setName, getName);
 
                               if(memberExp.member.exp)
                                  ProcessExpression(memberExp.member.exp);
@@ -863,7 +905,7 @@ static void ProcessExpression(Expression exp)
                                  value.tempCount = exp.tempCount;
                                  ProcessExpression(value);
                                  if(needAddress)
-                                    FixReference(value, true);
+                                    FixReference(isIndexedContainerAssignment ? GetInnerExp(value) : value, true);
                               }
 
                               FreeExpression(memberExp);
@@ -954,6 +996,8 @@ static void ProcessExpression(Expression exp)
             Expression object = exp.op.exp2;
             exp.op.exp2 = null;
             FreeExpContents(exp);
+            FreeType(exp.expType);
+            FreeType(exp.destType);
             exp.expType = null;
             exp.destType = null;
             exp.op.op = INC_OP;
@@ -991,7 +1035,6 @@ static void ProcessExpression(Expression exp)
 
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, exp.expType._class.string, true);
-               MangleClassName(className);
 
                DeclareClass(exp.expType._class, className);
 
@@ -1010,6 +1053,7 @@ static void ProcessExpression(Expression exp)
 
                OldList * list = MkList();
                Class _class;
+               Expression o;
                for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
                {
                   char className[1024];
@@ -1017,11 +1061,10 @@ static void ProcessExpression(Expression exp)
                   if(_class.templateClass) _class = _class.templateClass;
                   strcpy(className, "__ecereClass_");
                   FullClassNameCat(className, _class.fullName, false /*true*/);
-                  MangleClassName(className);
 
                   if(!_class.symbol)
                      _class.symbol = FindClass(_class.fullName);
-                  DeclareClass(_class.symbol, className);
+                  DeclareClass(curExternal, _class.symbol, className);
 
                   // Call the non virtual destructor
                   ListAdd(list,
@@ -1036,7 +1079,7 @@ static void ProcessExpression(Expression exp)
                                  QMkExpId(className),
                                  MkIdentifier("Destructor")
                               ),
-                              CopyList(args, CopyExpression)
+                              MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
                            )
                         ),
                         MkExpConstant("0")
@@ -1044,11 +1087,17 @@ static void ProcessExpression(Expression exp)
                   );
                }
                ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
+               o = CopyExpression(object);
+               ProcessExpressionType(o);
+               o.usage.usageGet = true;
+               ProcessExpression(o);
+
                ListAdd(exp.list,
                   MkExpBrackets(
                      MkListOne(
                         MkExpCondition(
-                           CopyExpression(object),
+                           o,
                            MkListOne(
                               MkExpBrackets(list)
                            ),
@@ -1071,8 +1120,9 @@ static void ProcessExpression(Expression exp)
                   typeName = MkTypeName(qualifiers, declarator);
 
                   ProcessExpressionType(classExp);
+                  ProcessExpression(classExp);
                   args->Insert(null, CopyExpression(classExp));
-                  DeclareMethod(eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
+                  DeclareMethod(curExternal, eClass_FindMethod(eSystem_FindClass(privateModule, "class"), "OnFree", privateModule), "__ecereVMethodID_class_OnFree");
                   ListAdd(exp.list, MkExpCall(
                      MkExpBrackets(MkListOne(MkExpCast(typeName,
                         MkExpIndex(MkExpPointer(classExp, MkIdentifier("_vTbl")),
@@ -1081,11 +1131,14 @@ static void ProcessExpression(Expression exp)
                }
             }
             else
+            {
                ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
+            }
 
             //ProcessExpression(object);
 
-            ListAdd(exp.list, MkExpOp(CopyExpression(object), '=', MkExpConstant("0")));
+            ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
 
             exp2 = null;
 
@@ -1102,18 +1155,17 @@ static void ProcessExpression(Expression exp)
                Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
                if(argExp)
                {
-                  // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
+                  // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
 
                   Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
                   OldList * args = MkList();
                   Expression derefExp = exp.op.exp1;
-                  Expression sizeExp = MkExpCondition(MkExpBrackets(MkListOne(
-                        MkExpOp(
-                           MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
-                           OR_OP,
-                           MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
-                           MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
-                           MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize")));
+                  Expression sizeExp;
+
+                  ProcessExpressionType(classExp);
+                  ProcessExpression(classExp);
+
+                  sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
 
                   if(exp.op.exp1.type == indexExp)
                   {
@@ -1124,6 +1176,7 @@ static void ProcessExpression(Expression exp)
                      derefExp.index.exp = null;
                      FreeExpression(derefExp);
 
+                     // BOOSTRAP FIX
                      derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
                         MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
                   }
@@ -1141,7 +1194,8 @@ static void ProcessExpression(Expression exp)
 
                   args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
                      MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
-                        MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
+                           MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
+                           MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
 
                   thisClass = curExternal.function ? curExternal.function._class : null;
                   {
@@ -1159,6 +1213,8 @@ static void ProcessExpression(Expression exp)
                      ProcessExpressionType(args->last);
                      ProcessExpression(args->last);
 
+                     DeclareFunctionUtil(curExternal, "memcpy");
+
                      exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
                      exp.type = bracketsExp;
 
@@ -1177,7 +1233,12 @@ static void ProcessExpression(Expression exp)
                if(argExp)
                {
                   Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
-                  Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
+                  Expression sizeExp;
+
+                  ProcessExpressionType(classExp);
+                  ProcessExpression(classExp);
+
+                  sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
 
                   exp.type = bracketsExp;
                   exp.list = MkListOne(
@@ -1188,17 +1249,7 @@ static void ProcessExpression(Expression exp)
                      MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                         // array
                         MkListOne(
-                           MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
-
-                     // ((class.type == normalClass || class.type == noHeadClass) ?
-                     MkExpCondition(MkExpBrackets(MkListOne(
-                        MkExpOp(
-                           MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
-                           OR_OP,
-                           MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
-                        // *((void **)array)
-                        MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
-                           CopyExpression(exp.op.exp2))))))),
+                           MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), CopyExpression(exp.op.exp2)))))),
 
                      // ((class.size == 1) ?
                      MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1220,7 +1271,7 @@ static void ProcessExpression(Expression exp)
 
                      // *((uint64 *)array)
                      MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
-                        exp.op.exp2)))))))))))))))))))));
+                        exp.op.exp2))))))))))))))))))));
 
                   // Add this to the context
                   thisClass = curExternal.function ? curExternal.function._class : null;
@@ -1292,7 +1343,6 @@ static void ProcessExpression(Expression exp)
                Expression next = exp.next, prev = exp.prev;
                Expression derefExp = exp.op.exp2;
                Expression refExp = exp.op.exp2.op.exp2;
-               Type expType = exp.expType, destType = exp.destType;
 
                derefExp.op.exp2 = null;
                FreeExpression(derefExp);
@@ -1315,24 +1365,17 @@ static void ProcessExpression(Expression exp)
                {
                   Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
                   Expression e;
+
+                  ProcessExpressionType(classExp);
+                  ProcessExpression(classExp);
+
                   exp.type = bracketsExp;
                   exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
                                  MkExpOp(null, '&', exp2)), '+',
                                     MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
-                                       MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
-
-                              MkExpOp(
-                                 MkExpOp(
-                                    MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
-                                       OR_OP,
-                                       MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
-                                       OR_OP,
-                                       MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
-                             )),
-                           MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
-                           MkExpMember(classExp, MkIdentifier("typeSize"))))))));
+                                       MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
 
-                  // Add this to the context
+                                             // Add this to the context
                   thisClass = curExternal.function ? curExternal.function._class : null;
                   {
                      /*Symbol thisSymbol
@@ -1422,7 +1465,12 @@ static void ProcessExpression(Expression exp)
             if(argExp)
             {
                Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
-               Expression sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
+               Expression sizeExp;
+
+               ProcessExpressionType(classExp);
+               ProcessExpression(classExp);
+
+               sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
 
                exp.type = bracketsExp;
                exp.list = MkListOne(
@@ -1432,19 +1480,9 @@ static void ProcessExpression(Expression exp)
                   // ((class.type == structClass) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                      // ((byte *)array) + (i) * class.size
-                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
+                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(MkExpOp(
                         MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
-                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
-
-                  // ((class.type == normalClass || class.type == noHeadClass) ?
-                  MkExpCondition(MkExpBrackets(MkListOne(
-                     MkExpOp(
-                        MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
-                        OR_OP,
-                        MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
-                     // ((void **)array)[i]
-                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
-                        CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
+                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp)))))))),
 
                   // ((class.size == 1) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1466,7 +1504,7 @@ static void ProcessExpression(Expression exp)
 
                   // ((uint64 *)array)[i]
                   MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
-                     exp.index.exp))), exp.index.index))))))))))))))))));
+                     exp.index.exp))), exp.index.index)))))))))))))))));
 
                // Add this to the context
                thisClass = curExternal.function ? curExternal.function._class : null;
@@ -1515,7 +1553,7 @@ static void ProcessExpression(Expression exp)
                {
                   OldList * specs = MkList();
                   Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
-                  TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
+                  TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
                   exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, MkExpMember(exp.index.exp, MkIdentifier("array")))));
                   ProcessExpressionType(exp.index.exp);
                   ProcessExpression(exp);
@@ -1524,7 +1562,7 @@ static void ProcessExpression(Expression exp)
                {
                   OldList * specs = MkList();
                   Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, null);
-                  TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl);
+                  TypeName typeName = MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl));
                   exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
                      MkExpPointer(MkExpCast(QMkType("BuiltInContainer", QMkPtrDecl(null)), exp.index.exp), MkIdentifier("data")))));
                   ProcessExpressionType(exp.index.exp);
@@ -1575,7 +1613,6 @@ static void ProcessExpression(Expression exp)
       case callExp:
       {
          Expression e;
-         Expression memberExp;
          bool typedObject = false;
          Type ellipsisDestType = null;
          bool usedEllipsis = false;
@@ -1594,11 +1631,14 @@ static void ProcessExpression(Expression exp)
          exp.call.exp.usage.usageGet = true;
          exp.call.exp.usage.usageCall = true;
          exp.call.exp.tempCount = exp.tempCount;
+
          ProcessExpression(exp.call.exp);
-         memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
 
          if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
          {
+            bool nullMemberExp = false;
+            Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
+
             Class _class = exp.call.exp.expType.methodClass;     // For Virtual Method
             Class argClass = exp.call.exp.expType.methodClass;  // Class actually passed
             Method method = exp.call.exp.expType.method;
@@ -1614,7 +1654,7 @@ static void ProcessExpression(Expression exp)
                strcat(name, "_");
                strcat(name, method.name);
 
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
 
                back = curContext;
                // THIS SpecDeclFromString HERE SHOULD WORK WITH THE METHOD TEMPLATE PARAMETERS...
@@ -1639,17 +1679,26 @@ static void ProcessExpression(Expression exp)
                      Specifier firstSpec = firstParam ? firstParam.qualifiers->first : null;
 
                      if(firstParam && firstSpec && firstSpec.type == baseSpecifier && firstSpec.specifier == VOID && !firstParam.declarator)
+                     {
                         funcDecl.function.parameters->Remove(funcDecl.function.parameters->first);
+                        FreeTypeName(firstParam);
+                     }
                   }
 
                   if(method.dataType.thisClass && !strcmp(method.dataType.thisClass.string, "class"))
                   {
+                     TypeName param;
                      typedObject = true;
 
-                     funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null)));
+                     param = MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null,null), null));
+                     param.qualifiers->Insert(null, MkSpecifier(CONST));
+                     funcDecl.function.parameters->Insert(null, param);
                      // Testing this for any_object::
                      if(!method.dataType.extraParam)
+                     {
                         funcDecl.function.parameters->Insert(null, MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null)), MkDeclaratorPointer(MkPointer(null,null), null)));
+                        DeclareStruct(curExternal, "ecere::com::Class", false, true);
+                     }
                   }
                   else
                   {
@@ -1706,7 +1755,6 @@ static void ProcessExpression(Expression exp)
                   Type type = memberExp ? memberExp.member.exp.expType : null;
                   Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
                   char className[1024];
-                  bool useInstance = false;
 
                   if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
                      strcpy(className, "class");
@@ -1730,12 +1778,11 @@ static void ProcessExpression(Expression exp)
                      // Need the class itself here...
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, cl.fullName, true);
-                     MangleClassName(className);
 
                      if(!cl.symbol)
                         cl.symbol = FindClass(cl.fullName);
 
-                     DeclareClass(cl.symbol, className);
+                     DeclareClass(curExternal, cl.symbol, className);
                   }
 
                   if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
@@ -1747,6 +1794,8 @@ static void ProcessExpression(Expression exp)
                   else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
                          !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
                   {
+                     if(!memberExp)
+                        FreeExpression(exp.call.exp);
                      exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
                         MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
@@ -1759,15 +1808,18 @@ static void ProcessExpression(Expression exp)
                      // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
                      Expression c;
                      Context context = PushContext();
+                     OldList * specs;
                      c = MkExpExtensionCompound(MkCompoundStmt(
                            MkListOne(MkDeclaration(
-                              MkListOne(MkSpecifierName("Instance")),
+                              (specs = MkListOne(MkSpecifierName("Instance"))),
                               MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
                                  MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
                            MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
                               MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
                               MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
                               MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
+                     if(type.specConst)
+                        specs->Insert(null, MkSpecifier(CONST));
                      c.loc = exp.loc;
                      c.compound.compound.context = context;
                      PopContext(context);
@@ -1784,8 +1836,10 @@ static void ProcessExpression(Expression exp)
                strcat(name, "_");
                strcat(name, method.name);
 
+               if(!memberExp)
+                  FreeExpression(exp.call.exp);
                exp.call.exp = MkExpIdentifier(MkIdentifier(name));
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
                if(memberExp && memberExp.expType && method.dataType)
                {
                   exp.call.exp.expType = method.dataType;
@@ -1835,20 +1889,22 @@ static void ProcessExpression(Expression exp)
                   if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
                   {
                      bool changeReference = false;
+                     bool stillAddReferenceOp = false;
                      Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
+                     Type expType = memberExp.member.exp.expType;
+                     Class c = expType.kind == classType && expType._class ? expType._class.registered : null;
 
                      // Patched so that class isn't considered SYSTEM...
                      if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
                         strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
                         changeReference = true;
-                     if(!memberExp.member.exp.expType.classObjectType &&
-                        (((
-                           (memberExp.member.exp.expType.kind != pointerType &&
-                              (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
-                               !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
-                           method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
+                     if(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
+                     {
+                        if(c && (c.type == normalClass || c.type == noHeadClass))
+                           stillAddReferenceOp = true;
                         changeReference = true;
-                     if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
+                     }
+                     if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
                         changeReference = true;
                      if(changeReference)
                      {
@@ -1863,21 +1919,48 @@ static void ProcessExpression(Expression exp)
                            exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
                            memberExp.member.exp.op.exp2 = null;
                         }
-                        else if(!memberExp.member.exp.byReference)
+                        else if(!memberExp.member.exp.byReference || stillAddReferenceOp)
                         {
                            // TESTING THIS... REUSE THIS CODE?
                            Expression checkedExp = memberExp.member.exp;
                            Expression parentExp = null;
                            Expression newExp;
+                           bool disconnected = false;
                            while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp) && checkedExp.list) || checkedExp.type == castExp)
                            {
                               parentExp = checkedExp;
+
                               if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp)
+                              {
                                  checkedExp = checkedExp.list->last;
+                                 // Dissociate from memberExp which will get freed
+                                 if(checkedExp && !disconnected)
+                                 {
+                                    parentExp.list->Remove(checkedExp);
+                                    disconnected = true;
+                                 }
+                              }
                               else if(checkedExp.type == castExp)
+                              {
                                  checkedExp = checkedExp.cast.exp;
+                                 // Dissociate from memberExp which will get freed
+                                 if(checkedExp && !disconnected)
+                                 {
+                                    checkedExp.cast.exp = null;
+                                    disconnected = true;
+                                 }
+                              }
+                           }
+                           if(!parentExp)
+                              nullMemberExp = true;
+
+                           if(typedObject && !expType.classObjectType && !stillAddReferenceOp)
+                              newExp = checkedExp;
+                           else
+                           {
+                              newExp = MkExpOp(null, '&', checkedExp);
+                              newExp.byReference = true;
                            }
-                           newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
                            if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
                            {
                               parentExp.list->Remove(checkedExp);
@@ -1887,11 +1970,14 @@ static void ProcessExpression(Expression exp)
                            {
                               parentExp.cast.exp = newExp;
                               // Add a dereference level here
-                              parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
+                              if(newExp.expType && newExp.expType.classObjectType)
+                                 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
                            }
-                           if(typedObject && !memberExp.member.exp.expType.classObjectType)
+                           if(typedObject && !expType.classObjectType)
                            {
                               Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
+                              FreeType((parentExp ? parentExp : newExp).expType);
+                              FreeType((parentExp ? parentExp : newExp).destType);
                               (parentExp ? parentExp : newExp).expType = checkedExp.expType;
                               (parentExp ? parentExp : newExp).destType = destType;
                               if(checkedExp.expType) checkedExp.expType.refCount++;
@@ -1899,10 +1985,16 @@ static void ProcessExpression(Expression exp)
                            exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
                         }
                         else
+                        {
                            exp.call.arguments->Insert(null, memberExp.member.exp);
+                           nullMemberExp = true;
+                        }
                      }
                      else
+                     {
                         exp.call.arguments->Insert(null, memberExp.member.exp);
+                        nullMemberExp = true;
+                     }
 
                      {
                         char className[1024];
@@ -1918,11 +2010,10 @@ static void ProcessExpression(Expression exp)
                            // Need the class itself here...
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, cl.fullName, true);
-                           MangleClassName(className);
 
                            if(!cl.symbol)
                               cl.symbol = FindClass(cl.fullName);
-                           DeclareClass(cl.symbol, className);
+                           DeclareClass(curExternal, cl.symbol, className);
                         }
 
                         if(className[0])
@@ -1932,9 +2023,11 @@ static void ProcessExpression(Expression exp)
                               // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
                               Expression c;
                               Context context = PushContext();
+                              OldList * specs;
+
                               c = MkExpExtensionCompound(MkCompoundStmt(
                                     MkListOne(MkDeclaration(
-                                       MkListOne(MkSpecifierName("Instance")),
+                                       (specs = MkListOne(MkSpecifierName("Instance"))),
                                        MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
                                           MkInitializerAssignment(memberExpMemberExp))))),
                                     MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
@@ -1944,6 +2037,9 @@ static void ProcessExpression(Expression exp)
                               c.compound.compound.context = context;
                               PopContext(context);
 
+                              if(type.specConst)
+                                 specs->Insert(null, MkSpecifier(CONST));
+
                               exp.call.arguments->Insert(null, c);
 
                               memberExpMemberExp = null; // We used this
@@ -1957,15 +2053,23 @@ static void ProcessExpression(Expression exp)
                         FreeExpression(memberExpMemberExp);
                   }
                   else
+                  {
                      exp.call.arguments->Insert(null, memberExp.member.exp);
-                  memberExp.member.exp = null;
+                     nullMemberExp = true;
+                  }
                }
-               FreeExpression(memberExp);
             }
             /*else if(method->dataType)
             {
             }*/
+            if(memberExp)
+            {
+               if(nullMemberExp)
+                  memberExp.member.exp = null;
+               FreeExpression(memberExp);
+            }
          }
+
          if(exp.call.arguments)
          {
             for(e = exp.call.arguments->first; e; e = e.next)
@@ -2027,7 +2131,7 @@ static void ProcessExpression(Expression exp)
 
                            checkedExp = e;
                            parentExp = exp;
-                           while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
+                           while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
                            {
                               parentExp = checkedExp;
                               if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
@@ -2061,7 +2165,7 @@ static void ProcessExpression(Expression exp)
                               {
                                  char size[100];
                                  ComputeTypeSize(e.expType);
-                                 sprintf(size, "%d", e.expType.size);
+                                 sprintf(size, "%d", e.expType.size);   // BOOTSTRAP FIX
                                  newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
                                     MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
                                        MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
@@ -2172,7 +2276,7 @@ static void ProcessExpression(Expression exp)
                               // TODO: INTEGRATE THIS WITH VERSION ABOVE WHICH WAS ADDED TO ENCOMPASS OTHER CASE (*pointer)
                               checkedExp = e;
                               parentExp = exp;
-                              while(((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp)
+                              while(checkedExp && (((checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp) && checkedExp.list) || checkedExp.type == castExp))
                               {
                                  parentExp = checkedExp;
                                  if(checkedExp.type == bracketsExp || checkedExp.type == extensionExpressionExp || checkedExp.type == extensionCompoundExp)
@@ -2187,8 +2291,12 @@ static void ProcessExpression(Expression exp)
                                  else if(checkedExp.type == castExp)
                                     checkedExp = checkedExp.cast.exp;
                               }
-                              newExp = MkExpOp(null, '&', checkedExp);
-                              newExp.byReference = true;
+                              {
+                                 Expression i;
+                                 newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), (i = MkExpOp(null, '&', checkedExp)));
+                                 i.byReference = true;
+                                 newExp.byReference = true;
+                              }
                               if(parentExp.type == callExp)
                               {
                                  exp.call.arguments->Insert(e.prev, newExp);
@@ -2228,12 +2336,11 @@ static void ProcessExpression(Expression exp)
                         {
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, _class.fullName, true);
-                           MangleClassName(className);
 
                            if(!_class.symbol)
                               _class.symbol = FindClass(_class.fullName);
 
-                           DeclareClass(_class.symbol, className);
+                           DeclareClass(curExternal, _class.symbol, className);
                         }
 
                         if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
@@ -2257,9 +2364,10 @@ static void ProcessExpression(Expression exp)
                            }
                            else
                            {
+                              OldList * specs;
                               c = MkExpExtensionCompound(MkCompoundStmt(
                                     MkListOne(MkDeclaration(
-                                       MkListOne(MkSpecifierName("Instance")),
+                                       (specs = MkListOne(MkSpecifierName("Instance"))),
                                        MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
                                           MkInitializerAssignment(CopyExpression(e)))))),
                                     MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
@@ -2269,6 +2377,9 @@ static void ProcessExpression(Expression exp)
                               c.compound.compound.context = context;
                               PopContext(context);
 
+                              if(type.specConst)
+                                 specs->Insert(null, MkSpecifier(CONST));
+
                               exp.call.arguments->Insert(e.prev, c);
                            }
                         }
@@ -2319,6 +2430,8 @@ static void ProcessExpression(Expression exp)
             Method method = null;
             Class convertTo = null;
             DataMember member = null;
+            DataMember subMemberStack[256];
+            int subMemberStackPos = 0;
             bool thisPtr = exp.member.thisPtr;
             if(type.kind == subClassType && exp.member.exp.type == classExp)
                _class = eSystem_FindClass(privateModule, "ecere::com::Class");
@@ -2338,9 +2451,9 @@ static void ProcessExpression(Expression exp)
             if(_class && exp.member.memberType == dataMember)
             {
                if(!thisPtr && !exp.member.member.classSym)
-                  member = eClass_FindDataMember(_class, exp.member.member.string, null, null, null);
+                  member = eClass_FindDataMember(_class, exp.member.member.string, null, subMemberStack, &subMemberStackPos);
                if(!member)
-                  member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
+                  member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
             }
             else if(_class && exp.member.memberType == propertyMember)
             {
@@ -2352,7 +2465,7 @@ static void ProcessExpression(Expression exp)
                   (exp.usage.usageGet && !prop.Get && !prop.conversion) ||
                   (exp.usage.usageDelete && !prop.Set && !prop.conversion)))
                {
-                  member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, null, null);
+                  member = eClass_FindDataMember(_class, exp.member.member.string, privateModule, subMemberStack, &subMemberStackPos);
                   if(member)
                   {
                      exp.member.memberType = dataMember;
@@ -2406,12 +2519,11 @@ static void ProcessExpression(Expression exp)
                      ProcessExpression(exp.member.exp);
                      // TEST: exp.tempCount = exp.member.exp.tempCount;
 
-                     DeclareProperty(prop, setName, getName);
+                     DeclareProperty(curExternal, prop, setName, getName);
                      //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
                      propertyClass = convertTo ? _class :
                         ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
 
-
                      if(propertyClass && propertyClass.type == bitClass)
                      {
                         // Bit classes shouldn't have properties except for conversions...
@@ -2475,6 +2587,7 @@ static void ProcessExpression(Expression exp)
 
                         className[0] = 0;
                         FullClassNameCat(className, propertyClass.fullName, false); //true);
+                        DeclareStruct(curExternal, propertyClass.fullName, false, true);
 
                         //ListAdd(specs, MkSpecifierName(className));
                         ListAdd(specs, MkStructOrUnion(structSpecifier, MkIdentifier(className), null));
@@ -2554,13 +2667,32 @@ static void ProcessExpression(Expression exp)
                   {
                      Identifier id = exp.member.member;
                      Expression classExp = exp.member.exp;
+                     OldList * args = MkList();
 
+                     exp.type = castExp;
                      // Class Property
-                     exp.type = callExp;
-                     exp.call.exp = MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty"));
-                     exp.call.arguments = MkList();
-                     ListAdd(exp.call.arguments, classExp);
-                     ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
+                     if(exp.expType)
+                     {
+                        char typeString[2048];
+                        OldList * specs = MkList();
+                        Declarator decl;
+                        typeString[0] = 0;
+                        PrintType(exp.expType, typeString, false, false);
+                        decl = SpecDeclFromString(typeString, specs, null);
+                        exp.cast.typeName = MkTypeName(specs, decl);
+                     }
+                     else
+                        exp.cast.typeName = QMkType("uint64", null);
+                     exp.cast.exp = MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eClass_GetProperty")), args);
+                     if(exp.expType.isPointerType)
+                        exp.cast.exp = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), exp.cast.exp);
+
+                     ListAdd(args, classExp);
+                     {
+                        char * s = QMkString(id.string);
+                        ListAdd(args, MkExpString(s));
+                        delete s;
+                     }
                      FreeIdentifier(id);
 
                      ProcessExpression(exp);
@@ -2595,14 +2727,13 @@ static void ProcessExpression(Expression exp)
                         // Need the class itself here...
                         strcpy(className, "__ecereClass_");
                         FullClassNameCat(className, _class.fullName, true);
-                        MangleClassName(className);
 
                         if(!_class.symbol)
                            _class.symbol = FindClass(_class.fullName);
-                        DeclareClass(_class.symbol, className);
-                        exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
+                        DeclareClass(curExternal, _class.symbol, className);
 
-                        // WHAT HAPPENS TO exp.member.exp ?
+                        FreeExpression(exp.member.exp);
+                        exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
                      }
                      else
                      {
@@ -2615,7 +2746,7 @@ static void ProcessExpression(Expression exp)
                            exp.index.exp = MkExpPointer(exp.member.exp, MkIdentifier("_vTbl"));
                      }
                      exp.index.index = MkListOne(QMkExpId(name));
-                     DeclareMethod(method, name);
+                     DeclareMethod(curExternal, method, name);
                   }
                   else
                   {
@@ -2626,12 +2757,48 @@ static void ProcessExpression(Expression exp)
                      strcat(name, "_");
                      strcat(name, method.name);
                      exp.identifier = MkIdentifier(name);
-                     DeclareMethod(method, name);
+                     DeclareMethod(curExternal, method, name);
                   }
                }
             }
             else if(member)
             {
+               if(subMemberStackPos)
+               {
+                  int i;
+                  DataMember parentMember = null;
+                  String s, prefix = null;
+                  for(i = 0; i < subMemberStackPos; i++)
+                  {
+                     DataMember curMember = subMemberStack[i];
+                     DataMember m;
+                     int anonID = 1;
+                     for(m = parentMember ? parentMember.members.first : _class.membersAndProperties.first; m; m = m.next)
+                     {
+                        if(m && !m.isProperty && (m.type == unionMember || m.type == structMember) && !m.name)
+                        {
+                           if(m == curMember)
+                              break;
+                           anonID++;
+                        }
+                     }
+
+                     if(prefix)
+                     {
+                        s = prefix;
+                        prefix = PrintString(prefix, ".__anon", anonID);
+                        delete s;
+                     }
+                     else
+                        prefix = PrintString("__anon", anonID);
+                     parentMember = curMember;
+                  }
+
+                  s = exp.member.member.string;
+                  exp.member.member.string = PrintString(prefix, ".", s);
+                  delete prefix;
+                  delete s;
+               }
                // Process this here since it won't be processed at the end...
                if(exp.usage.usageGet)
                {
@@ -2641,7 +2808,7 @@ static void ProcessExpression(Expression exp)
                // TEST: exp.tempCount = exp.member.exp.tempCount;
 
                if(type.kind == classType && type._class && type._class.registered)
-                  DeclareStruct(type._class.registered.fullName, false);
+                  DeclareStruct(curExternal, type._class.registered.fullName, false, true);
 
                // TESTING THIS NOHEAD STUFF...
                if(_class.type == noHeadClass)
@@ -2682,7 +2849,7 @@ static void ProcessExpression(Expression exp)
                else
                {
                   // If it's a this pointer, replace by precomputed shortcut
-                  if(exp.member.exp.type == identifierExp && thisPtr && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
+                  if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
                   {
                      char pointerName[1024];
 
@@ -2696,21 +2863,19 @@ static void ProcessExpression(Expression exp)
                   else
                   {
                      Expression bytePtr, e;
-                     Expression classExp;
                      Expression checkedExp;
                      char structName[1024];
                      char className[1024];
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, member._class.fullName, true);
-                     MangleClassName(className);
 
                      // classExp = QMkExpId(className);
 
                      if(!member._class.symbol)
                         member._class.symbol = FindClass(member._class.fullName);
 
-                     DeclareClass(member._class.symbol, className);
-                     DeclareStruct(member._class.fullName, false);
+                     DeclareClass(curExternal, member._class.symbol, className);
+                     DeclareStruct(curExternal, member._class.fullName, false, true);
 
                      structName[0] = 0;
                      FullClassNameCat(structName, member._class.fullName, false);
@@ -2731,7 +2896,6 @@ static void ProcessExpression(Expression exp)
                      {
                         char ecereTemp[100];
                         Statement compound;
-                        OldList * list = MkList();
                         Context context = PushContext();
                         if(exp.member.exp.tempCount > exp.tempCount)
                            exp.tempCount = exp.member.exp.tempCount;
@@ -2743,14 +2907,27 @@ static void ProcessExpression(Expression exp)
                         compound = MkCompoundStmt(
                            MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
                               MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
-                                 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
+                                 MkInitializerAssignment(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), QBrackets(exp.member.exp))))))), null);
                         if(member._class.fixed)
                         {
-                           if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
+                           Class c = member._class.templateClass ? member._class.templateClass : member._class;
+                           if(c.offset)
                            {
-                              char string[256];
-                              sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
-                              e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
+                              Expression se;
+
+                              if(c.offset == c.base.structSize)
+                              {
+                                 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
+                                 ProcessExpressionType(se);
+                                 se.isConstant = false;
+                              }
+                              else
+                              {
+                                 char string[256];
+                                 sprintf(string, "%d", c.offset);
+                                 se = MkExpConstant(string);
+                              }
+                              e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', se));
                            }
                            else
                               e = QMkExpId(ecereTemp);
@@ -2784,11 +2961,25 @@ static void ProcessExpression(Expression exp)
                         // if(class.fixed)
                         if(member._class.fixed)
                         {
-                           if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
+                           Class c = member._class.templateClass ? member._class.templateClass : member._class;
+                           if(c.offset)
                            {
-                              char string[256];
-                              sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
-                              e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
+                              Expression se;
+
+                              if(c.offset == c.base.structSize)
+                              {
+                                 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
+                                 ProcessExpressionType(se);
+                                 se.isConstant = false;
+                              }
+                              else
+                              {
+                                 char string[256];
+                                 sprintf(string, "%d", c.offset);
+                                 se = MkExpConstant(string);
+                              }
+
+                              e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', se)));
                            }
                            else
                               e = bytePtr;
@@ -2853,21 +3044,11 @@ static void ProcessExpression(Expression exp)
 
                classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
 
+               ProcessExpressionType(classExp);
+               ProcessExpression(classExp);
+
                exp.type = bracketsExp;
-               exp.list = MkListOne(
-                  MkExpCondition(MkExpBrackets(MkListOne(
-                     MkExpOp(
-                        MkExpOp(
-                           MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
-                              MkExpIdentifier(MkIdentifier("normalClass"))),
-                        OR_OP,
-                        MkExpOp(
-                           MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP,
-                              MkExpIdentifier(MkIdentifier("noHeadClass"))
-                            )))),
-                     MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
-                     MkExpMember(classExp, MkIdentifier("typeSize")))
-                  );
+               exp.list = MkListOne(MkExpMember(classExp, MkIdentifier("typeSize")));
 
                ProcessExpressionType(exp);
                ProcessExpression(exp);
@@ -2926,8 +3107,10 @@ static void ProcessExpression(Expression exp)
                exp.type = memberExp; //pointerExp;
                exp.member.exp = argExp;
                exp.member.member = MkIdentifier("dataTypeClass");
+               exp.member.memberType = dataMember;
 
                ProcessExpressionType(argExp);
+               ProcessExpressionType(exp);
                ProcessExpression(exp);
             }
          }
@@ -2939,8 +3122,8 @@ static void ProcessExpression(Expression exp)
 
             strcpy(className, "__ecereClass_");
             FullClassNameCat(className, string, true);      // TODO: Verify this
-            MangleClassName(className);
-            DeclareClass(classSym, className);
+
+            DeclareClass(curExternal, classSym, className);
             delete string;
 
             FreeList(exp._classExp.specifiers, FreeSpecifier);
@@ -2964,6 +3147,92 @@ static void ProcessExpression(Expression exp)
       }
    }
    FixRefExp(exp);
+
+   if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
+   {
+      Expression nbExp = GetNonBracketsExp(exp);
+      Expression inner = GetInnerExp(nbExp);
+
+      if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
+         (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
+         (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
+         (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || (exp.destType.kind == pointerType || exp.destType.kind == intPtrType)) && ((exp.destType.kind != pointerType && exp.destType.kind != intPtrType) || exp.expType.kind == pointerType))) &&
+         !inner.needCast && inner.type != opExp)
+      {
+         Expression e = MoveExpContents(exp);
+         Declarator decl;
+         OldList * specs = MkList();
+         char typeString[1024];
+         bool castingToDest = false;
+         bool pointerCastExp = false;
+
+         typeString[0] = '\0';
+
+         e.needTemplateCast = 2;
+         inner.needTemplateCast = 2;
+         nbExp.needTemplateCast = 2;
+         if(exp.usage.usageDelete)
+            strcpy(typeString, "void *");
+         else
+         {
+            if(exp.expType.kind == templateType && exp.expType.templateParameter && exp.expType.templateParameter.dataTypeString)
+               strcpy(typeString, exp.expType.templateParameter.dataTypeString);
+            else
+               PrintType(exp.expType, typeString, false, false);
+         }
+
+         decl = SpecDeclFromString(typeString, specs, null);
+
+         if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
+            exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
+         {
+            if(decl) FreeDeclarator(decl);
+            FreeList(specs, FreeSpecifier);
+            if(exp.destType.templateParameter.dataTypeString)
+            {
+               specs = MkList();
+               strcpy(typeString, exp.destType.templateParameter.dataTypeString);
+               decl = SpecDeclFromString(typeString, specs, null);
+            }
+            else
+            {
+               specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
+               decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
+            }
+
+            castingToDest = true;
+         }
+
+         e.destType = exp.destType;
+         if(exp.destType)
+            exp.destType.refCount++;
+
+         exp.type = bracketsExp;
+
+         {
+            Specifier spec = specs ? specs->first : null;
+            TemplateParameter tp = (spec && spec.type == templateTypeSpecifier) ? spec.templateParameter : null;
+            Type type = castingToDest ? exp.destType : exp.expType;
+            bool specsDeclPointer = (spec.type == nameSpecifier && strcmp(spec.name, "uint64")) ||
+               (decl && decl.type == pointerDeclarator) ||
+               (tp && tp.dataType &&
+                  ( (tp.dataType.decl && tp.dataType.decl.type == pointerDeclarator) ||
+                    (tp.dataType.specifiers && ((Specifier)tp.dataType.specifiers->first).type == nameSpecifier && strcmp(((Specifier)tp.dataType.specifiers->first).name, "uint64")) ) );
+            pointerCastExp = type ? ((type.kind == templateType && specsDeclPointer) || type.isPointerType) : specsDeclPointer;
+         }
+
+         if(pointerCastExp)
+         {
+            e = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(e)));
+            e.needTemplateCast = 2;
+         }
+         exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
+         if(exp.destType && pointerCastExp == (exp.destType.passAsTemplate ||
+            (!exp.destType.isPointerType || (exp.destType.kind == templateType && (!exp.destType.templateParameter || (!exp.destType.templateParameter.dataType && !exp.destType.templateParameter.dataTypeString))))))
+            exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), decl), MkExpBrackets(exp.list)));
+         exp.needTemplateCast = 2;
+      }
+   }
    yylloc = oldyylloc;
 }
 
@@ -2972,21 +3241,27 @@ static void ProcessInitializer(Initializer init)
    switch(init.type)
    {
       case expInitializer:
-         init.exp.usage.usageGet = true;
-         ProcessExpression(init.exp);
-         if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
-            init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
+         if(init.exp)
          {
-            FixReference(init.exp, true);
+            init.exp.usage.usageGet = true;
+            ProcessExpression(init.exp);
+            if(init.exp.destType && init.exp.destType.kind == classType && init.exp.destType._class &&
+               init.exp.destType._class.registered && init.exp.destType._class.registered.type == noHeadClass)
+            {
+               FixReference(init.exp, true);
+            }
+            else if(init.exp.destType && init.exp.destType.kind == classType)
+               FixReference(init.exp, false);
          }
-         else if(init.exp.destType && init.exp.destType.kind == classType)
-            FixReference(init.exp, false);
          break;
       case listInitializer:
       {
-         Initializer i;
-         for(i = init.list->first; i; i = i.next)
-            ProcessInitializer(i);
+         if(init.list)
+         {
+            Initializer i;
+            for(i = init.list->first; i; i = i.next)
+               ProcessInitializer(i);
+         }
          break;
       }
    }
@@ -3094,10 +3369,13 @@ static void ProcessStatement(Statement stmt)
       case switchStmt:
       {
          Expression exp;
-         ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
-         for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
+         if(stmt.switchStmt.exp && stmt.switchStmt.exp->last)
          {
-            ProcessExpression(exp);
+            ((Expression)stmt.switchStmt.exp->last).usage.usageGet = true;
+            for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
+            {
+               ProcessExpression(exp);
+            }
          }
          ProcessStatement(stmt.switchStmt.stmt);
          break;
@@ -3105,10 +3383,13 @@ static void ProcessStatement(Statement stmt)
       case whileStmt:
       {
          Expression exp;
-         ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
-         for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
+         if(stmt.whileStmt.exp && stmt.whileStmt.exp->last)
          {
-            ProcessExpression(exp);
+            ((Expression)stmt.whileStmt.exp->last).usage.usageGet = true;
+            for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
+            {
+               ProcessExpression(exp);
+            }
          }
          ProcessStatement(stmt.whileStmt.stmt);
          break;
@@ -3266,14 +3547,12 @@ public void ProcessMemberAccess()
       }
       else if(external.type == declarationExternal)
       {
-         //currentClass = external.function._class;
          if(external.declaration)
             ProcessDeclaration(external.declaration);
       }
       else if(external.type == classExternal)
       {
          ClassDefinition _class = external._class;
-         //currentClass = external.symbol.registered;
          if(_class.definitions)
          {
             ClassDef def;