ecere/com; compiler/libec: (#1087) Fixed class:struct issues
[sdk] / compiler / libec / src / pass2.ec
index a588c4d..e955b2d 100644 (file)
@@ -8,7 +8,7 @@ static Statement curCompound;
 
 static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
 {
-   
+
    Expression memberExp = *memberExpPtr;
    if(memberExp && memberExp.type == ExpressionType::memberExp &&
       memberExp.member.exp && (memberExp.member.exp.type == bracketsExp || memberExp.member.exp.type == extensionExpressionExp))
@@ -26,10 +26,12 @@ 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;
-      
+
          exp.type = bracketsExp;
          exp.list = bracketExp.list;
          bracketExp.list = null;
@@ -38,7 +40,7 @@ static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
          exp.list->Add(newExp);
          FreeExpression(bracketExp);
 
-         *expPtr = newExp; //FixRefExp(newExp);
+         *expPtr = exp; //FixRefExp(newExp);      // TESTING THIS: exp was not used!
       }
    }
    else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
@@ -50,7 +52,7 @@ static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
       *memberExpPtr = null;
       newExp = CopyExpression(exp);
       *(Expression *)((byte *)newExp + (uint)((byte *)memberExpPtr - (byte *)exp)) = memberExp.list->last;
-   
+
       exp.type = bracketsExp;
       exp.list = memberExp.list;
       memberExp.list = null;
@@ -95,11 +97,13 @@ static Expression FixReference(Expression e, bool wantReference)
       {
          Class _class = type._class ? type._class.registered : null;
          // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
-         if(_class && (_class.type == structClass || _class.type == noHeadClass || 
-           (_class.type == systemClass && _class.base && 
-           strcmp(_class.fullName, "ecere::com::Instance") && 
-           strcmp(_class.fullName, "ecere::com::Class") && 
-           strcmp(_class.dataTypeString, "char *"))))
+         // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
+         if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass ||
+           (_class.type == systemClass && _class.base &&
+           strcmp(_class.fullName, "uintptr") &&
+           strcmp(_class.fullName, "intptr") &&
+           strcmp(_class.fullName, "uintsize") &&
+           strcmp(_class.fullName, "intsize"))))
          {
             // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
             if(wantReference != (e.byReference || isPointer))
@@ -135,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++;
@@ -146,7 +152,7 @@ static Expression FixReference(Expression e, bool wantReference)
                            exp.op.op = '&';
                         else
                            exp.op.op = '*';
-                       
+
                         e.byReference = wantReference;
                         exp.byReference = wantReference;
                      }
@@ -161,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;
@@ -218,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)));
@@ -248,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")),
@@ -269,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);
             }
          }
          /*
@@ -299,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;
@@ -318,7 +347,7 @@ static void ProcessExpression(Expression exp)
          switch(exp.op.op)
          {
             // Assignment Operators
-            case '=': 
+            case '=':
                if(exp.op.exp2)
                   exp.op.exp2.usage.usageGet = true;
                break;
@@ -379,7 +408,7 @@ static void ProcessExpression(Expression exp)
             case '|':
             case '^':
             case AND_OP:
-            case OR_OP:            
+            case OR_OP:
                if(exp.op.exp1)
                   exp.op.exp1.usage.usageGet = true;
                if(exp.op.exp2)
@@ -394,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)
@@ -403,7 +433,7 @@ static void ProcessExpression(Expression exp)
                Expression lastExp = exp.op.exp1, parentExp = null;
                Property lastProperty = null;
                Class propertyClass;
-               
+
                char setName[1024], getName[1024];
                testExp = exp.op.exp1.member.exp;
                while(true)
@@ -422,7 +452,7 @@ static void ProcessExpression(Expression exp)
                   }
                   if(!testExp) break;
 
-                  if(testExp.member.memberType == propertyMember || 
+                  if(testExp.member.memberType == propertyMember ||
                      testExp.member.memberType == reverseConversionMember)
                   {
                      Type type = testExp.member.exp.expType;
@@ -438,17 +468,17 @@ static void ProcessExpression(Expression exp)
                               _class = FindClass(testExp.member.member.string).registered;
                               // lastProperty = eClass_FindProperty(_class, convertTo.name, privateModule);
                               lastProperty = eClass_FindProperty(_class, convertTo.fullName, privateModule);
-                           }                              
+                           }
                            else
                            {
                               lastProperty = eClass_FindProperty(_class, testExp.member.member.string, privateModule);
                            }
                            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 && 
+                              propertyClass = convertTo ? _class :
+                                 ((((Symbol)lastProperty.symbol).type &&
                                     ((Symbol)lastProperty.symbol).type.kind == classType) ? ((Symbol)lastProperty.symbol).type._class.registered : ((Symbol)lastProperty.symbol)._class);
                               // TODO: Handle this kind of things with bit classes?
                               if(propertyClass && propertyClass.type == structClass)
@@ -462,7 +492,7 @@ static void ProcessExpression(Expression exp)
                                  parentExp = lastExp;
                               }
                            }
-                           
+
                         }
                      }
                   }
@@ -478,7 +508,7 @@ static void ProcessExpression(Expression exp)
                      Expression value;
                      char className[1024];
                      Expression tempExp;
-                  
+
                      sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
                      tempExp = QMkExpId(className);
                      tempExp.expType = MkClassType(propertyClass.fullName);
@@ -498,7 +528,7 @@ static void ProcessExpression(Expression exp)
                      tempExp.expType.refCount++;
 
                      // Go on as usual with these new values:
-                     exp.op.exp1 = topExp;                  
+                     exp.op.exp1 = topExp;
                      exp.op.exp2 = value;
                      exp.op.op = '=';
 
@@ -511,7 +541,7 @@ static void ProcessExpression(Expression exp)
                      Expression value;
                      char className[1024];
                      Expression tempExp;
-                  
+
                      sprintf(className, "__simpleStruct%d", curContext.simpleID); //++);
                      tempExp = QMkExpId(className);
                      tempExp.expType = MkClassType(propertyClass.fullName);
@@ -533,7 +563,7 @@ static void ProcessExpression(Expression exp)
                      //value = MkExpOp(exp.op.exp1, exp.op.op, exp.op.exp2);
 
                      // Go on as usual with these new values:
-                     exp.op.exp1 = topExp;                  
+                     exp.op.exp1 = topExp;
                      exp.op.exp2 = value;
                      exp.op.op = '=';
 
@@ -545,7 +575,7 @@ static void ProcessExpression(Expression exp)
 
             memberExp = exp.op.exp1;
 
-            while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) || 
+            while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
                memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
             {
                parentExp = memberExp;
@@ -555,13 +585,21 @@ static void ProcessExpression(Expression exp)
                   memberExp = memberExp.list->last;
             }
 
-            if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType && 
+            if(memberExp && memberExp.type == indexExp && memberExp.index.exp && memberExp.index.exp.expType &&
                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) || 
+               while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
                   memberExp.type == extensionExpressionExp || memberExp.type == extensionCompoundExp))
                {
                   parentExp = memberExp;
@@ -596,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)
@@ -619,20 +657,20 @@ static void ProcessExpression(Expression exp)
 
                      if(_class && _class.type == bitClass && memberExp.member.memberType == dataMember)
                      {
-                         BitMember bitMember = 
-                            (BitMember)eClass_FindDataMember(_class, 
+                         BitMember bitMember =
+                            (BitMember)eClass_FindDataMember(_class,
                               memberExp.member.member.string, privateModule, null, null);
                          char mask[32], shift[10];
                          OldList * specs = MkList();
                          //Declarator decl = SpecDeclFromString(bitMember.dataTypeString, specs, null);
-                         Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);                         
+                         Declarator decl = SpecDeclFromString(_class.dataTypeString, specs, null);
                          TypeName type = MkTypeName(specs, decl);
 
                          if(bitMember.mask > MAXDWORD)
                             sprintf(mask, FORMAT64HEXLL, bitMember.mask);
                          else
                             sprintf(mask, FORMAT64HEX, bitMember.mask);
-                         sprintf(shift, "%d", bitMember.pos);                         
+                         sprintf(shift, "%d", bitMember.pos);
 
                          // color = (color & ~0xFF0000) | (((unsigned char)200) << 16)
                          exp.op.exp1 = memberExp.member.exp;
@@ -649,10 +687,10 @@ static void ProcessExpression(Expression exp)
                          else
                          {
                             exp.op.exp2 = MkExpOp(
-                               MkExpBrackets(MkListOne(MkExpOp(CopyExpression(memberExp.member.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;
@@ -683,7 +721,7 @@ static void ProcessExpression(Expression exp)
 
                         if(memberExp.member.memberType == classPropertyMember)
                            classProperty = eClass_FindClassProperty(_class, memberExp.member.member.string);
-                        
+
                         exp.tempCount = memberExp.member.exp.tempCount;
 
                         if(classProperty)
@@ -706,8 +744,14 @@ 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)));
-                              ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT)), null), value));
+                              {
+                                 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);
 
@@ -742,14 +786,14 @@ static void ProcessExpression(Expression exp)
                               if(operator != '=')
                               {
                                  if(operator == INC_OP)
-                                    value = MkExpOp(CopyExpression(memberExp), 
+                                    value = MkExpOp(CopyExpression(memberExp),
                                        '+', MkExpConstant("1"));
                                  else if(operator == DEC_OP)
-                                    value = MkExpOp(CopyExpression(memberExp), 
+                                    value = MkExpOp(CopyExpression(memberExp),
                                        '-', MkExpConstant("1"));
                                  else
                                  {
-                                    value = MkExpOp(CopyExpression(memberExp), 
+                                    value = MkExpOp(CopyExpression(memberExp),
                                        operator, value);
                                     exp2 = null;
                                  }
@@ -760,19 +804,19 @@ static void ProcessExpression(Expression exp)
                               else if(value)
                               {
                                  // Dont free exp2, we're using it
-                                 exp2 = null;                              
+                                 exp2 = null;
                               }
-                        
+
                               if(value)
                                  value.usage.usageArg = true;
 
-                              DeclareProperty(prop, setName, getName);
+                              DeclareProperty(curExternal, prop, setName, getName);
 
                               if(memberExp.member.exp)
                                  ProcessExpression(memberExp.member.exp);
 
                               // If get flag present
-                              if(exp.usage.usageGet && 
+                              if(exp.usage.usageGet &&
                                  ((!convertTo && prop.Get) || (convertTo && prop.Set)))
                               {
                                  OldList * list = MkList();
@@ -780,7 +824,7 @@ static void ProcessExpression(Expression exp)
                                  char ecereTemp[100];
                                  Context context = PushContext();
                                  exp.tempCount++;
-                           
+
                                  curExternal.function.tempCount = Max(curExternal.function.tempCount, exp.tempCount);
                                  sprintf(ecereTemp, "__ecTemp%d", exp.tempCount);
 
@@ -789,7 +833,7 @@ static void ProcessExpression(Expression exp)
                                  exp.compound = MkCompoundStmt(
                                     MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(
                                        MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
-                                          MkInitializerAssignment(QBrackets(memberExp.member.exp)))))), 
+                                          MkInitializerAssignment(QBrackets(memberExp.member.exp)))))),
                                     list);
 
                                  // Add the set
@@ -806,7 +850,7 @@ static void ProcessExpression(Expression exp)
                                     ListAdd(args, value);
                                     ListAdd(list, MkExpressionStmt(MkListOne(MkExpCall(QMkExpId(setName), args))));
                                  }
-                              
+
                                  // Add the get
                                  args = MkList();
                                  if(convertTo)
@@ -861,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);
@@ -894,7 +938,7 @@ static void ProcessExpression(Expression exp)
                               {
                                  OldList * list = MkList();
                                  OldList * args;
-                           
+
                                  // Set the method
                                  args = MkList();
                                  ListAdd(args, memberExp.member.exp);
@@ -952,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;
@@ -961,7 +1007,7 @@ static void ProcessExpression(Expression exp)
          {
             Expression object = exp.op.exp2;
             OldList * args = MkList();
-            
+
             exp.type = bracketsExp;
             exp.list = MkList();
 
@@ -973,11 +1019,9 @@ static void ProcessExpression(Expression exp)
 
             // TOFIX: Same time as when we fix for = 0
 
-            if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && 
-               ((exp.expType._class.registered.type == normalClass && 
-                  // TODO: Improve on this, only fixed this issue here... Different String class defined in each module
-                  !eClass_IsDerived(exp.expType._class.registered, eSystem_FindClass(exp.expType._class.registered.module, "char *")) /*strcmp(exp.expType._class.string, "String")*/) ||
-                (exp.expType._class.registered.type == systemClass && !strcmp(exp.expType._class.string, "ecere::com::Instance"))))
+            if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
+               exp.expType._class.registered.type == normalClass &&
+               strcmp(exp.expType._class.registered.dataTypeString, "char *"))
             {
                Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
                ProcessExpressionType(decRefExp);
@@ -991,25 +1035,25 @@ static void ProcessExpression(Expression exp)
 
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, exp.expType._class.string, true);
-               MangleClassName(className);
 
                DeclareClass(exp.expType._class, className);
-               
+
                // Call the non virtual destructor
                ListAdd(list, MkExpCall(MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")), CopyList(args, CopyExpression)));
                ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
 
                ListAdd(exp.list, MkExpBrackets(MkListOne(MkExpCondition(CopyExpression(object), MkListOne(
-                  
-                  MkExpBrackets(MkListOne(MkExpCondition(   
+
+                  MkExpBrackets(MkListOne(MkExpCondition(
                   MkExpPointer(QMkExpId(className), MkIdentifier("Destructor")),
                   MkListOne(MkExpBrackets(list)), MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), CopyList(args, CopyExpression)))))), MkExpConstant("0"))))
-                  
+
                   );
                */
 
                OldList * list = MkList();
                Class _class;
+               Expression o;
                for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
                {
                   char className[1024];
@@ -1017,26 +1061,25 @@ 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,
                      MkExpCondition(
                         MkExpPointer(
-                           QMkExpId(className), 
+                           QMkExpId(className),
                            MkIdentifier("Destructor")
                         ),
                         MkListOne(
                            MkExpCall(
                               MkExpPointer(
-                                 QMkExpId(className), 
+                                 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));
-               ListAdd(exp.list, 
+               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,21 +1120,25 @@ 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")),
                            MkListOne(MkExpIdentifier(MkIdentifier("__ecereVMethodID_class_OnFree"))))))), args));
-                  //ProcessExpression(exp.list->last);                  
+                  //ProcessExpression(exp.list->last);
                }
             }
             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;
 
@@ -1096,35 +1149,35 @@ static void ProcessExpression(Expression exp)
          if(exp.type == opExp)
          {
             // Handle assigment of template structures
-            if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType && 
+            if(exp.op.op == '=' && exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind == templateType &&
                (exp.op.exp1.type == indexExp || (exp.op.exp1.type == opExp && exp.op.exp1.op.op == '*' && !exp.op.exp1.op.exp1)))
             {
                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)
                   {
                      Expression indexExp = derefExp.index.exp;
                      OldList * indexExpIndex = derefExp.index.index;
-                     
+
                      derefExp.index.index = null;
                      derefExp.index.exp = null;
                      FreeExpression(derefExp);
 
-                     derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+', 
+                     // BOOSTRAP FIX
+                     derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
                         MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
                   }
                   else
@@ -1134,14 +1187,15 @@ static void ProcessExpression(Expression exp)
                      FreeExpression(derefExp);
                      derefExp = indexExp;
                   }
-                  
+
                   args->Add(derefExp);
                   ProcessExpressionType(args->last);
                   ProcessExpression(args->last);
 
-                  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)))));
+                  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(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;
                   {
@@ -1151,17 +1205,19 @@ static void ProcessExpression(Expression exp)
                         type = MkClassType(thisClass.fullName);
                      };
                      globalContext.symbols.Add((BTNode)thisSymbol);
-                     
+
                      ProcessExpressionType(args->last);
                      ProcessExpression(args->last);
 
                      args->Add(sizeExp);
                      ProcessExpressionType(args->last);
                      ProcessExpression(args->last);
-                     
+
+                     DeclareFunctionUtil(curExternal, "memcpy");
+
                      exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
                      exp.type = bracketsExp;
-                  
+
                      //globalContext.symbols.Delete((BTNode)thisSymbol);
                      globalContext.symbols.Remove((BTNode)thisSymbol);
                      FreeSymbol(thisSymbol);
@@ -1170,35 +1226,30 @@ static void ProcessExpression(Expression exp)
                   return;
                }
             }
-            else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType && 
+            else if(exp.op.op == '*' && !exp.op.exp1 && exp.op.exp2 && exp.op.exp2.expType && exp.op.exp2.expType.kind == pointerType &&
                exp.op.exp2.expType.type && exp.op.exp2.expType.type.kind == templateType)
             {
                Expression argExp = GetTemplateArgExp(exp.op.exp2.expType.type.templateParameter, thisClass, false);
                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(
                      // (uint64)
-                     MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), 
+                     MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
 
                      // ((class.type == structClass) ?
                      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")))),
@@ -1219,9 +1270,9 @@ static void ProcessExpression(Expression exp)
                            CopyExpression(exp.op.exp2)))))),
 
                      // *((uint64 *)array)
-                     MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)), 
-                        exp.op.exp2)))))))))))))))))))));
-                  
+                     MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
+                        exp.op.exp2))))))))))))))))))));
+
                   // Add this to the context
                   thisClass = curExternal.function ? curExternal.function._class : null;
                   {
@@ -1231,10 +1282,10 @@ static void ProcessExpression(Expression exp)
                         type = MkClassType(thisClass.fullName);
                      };
                      globalContext.symbols.Add((BTNode)thisSymbol);
-                     
+
                      ProcessExpressionType(exp.list->first);
                      ProcessExpression(exp.list->first);
-                     
+
                      //globalContext.symbols.Delete((BTNode)thisSymbol);
                      globalContext.symbols.Remove((BTNode)thisSymbol);
                      FreeSymbol(thisSymbol);
@@ -1253,9 +1304,9 @@ static void ProcessExpression(Expression exp)
                   ProcessExpression(exp.op.exp1);
 
                   // TESTING THIS...
-                  if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference || 
-                     (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class && 
-                      exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) && 
+                  if(exp.op.op == '=' && exp.op.exp2 && (!exp.op.exp2.byReference ||
+                     (exp.op.exp2.expType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class &&
+                      exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass)) &&
                      exp.op.exp2.expType && (exp.op.exp2.expType.kind != pointerType && exp.op.exp2.expType.kind != templateType /*|| !exp.op.exp2.expType.type || exp.op.exp2.expType.type.kind != voidType*/))
                      FixReference(exp.op.exp1, false);
                   // TEST: exp.tempCount = Max(exp.op.exp1.tempCount, exp.tempCount);
@@ -1270,11 +1321,11 @@ static void ProcessExpression(Expression exp)
                   if(exp.op.exp1 || (exp.op.op != '*' && exp.op.op != '&'))
                   {
                      // TESTING THIS IF:
-                     if((!exp.op.exp1 && 
-                        (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered || 
-                        (exp.op.exp2.expType._class.registered.type != normalClass && 
-                         exp.op.exp2.expType._class.registered.type != structClass && 
-                         exp.op.exp2.expType._class.registered.type != noHeadClass))) 
+                     if((!exp.op.exp1 &&
+                        (!exp.op.exp2 || !exp.op.exp2.expType || exp.op.exp2.expType.kind != classType || !exp.op.exp2.expType._class || !exp.op.exp2.expType._class.registered ||
+                        (exp.op.exp2.expType._class.registered.type != normalClass &&
+                         exp.op.exp2.expType._class.registered.type != structClass &&
+                         exp.op.exp2.expType._class.registered.type != noHeadClass)))
 
                             // TESTING THIS TEMPLATE TYPE CHECK HERE
                         || (exp.op.exp1 && exp.op.exp1.expType && exp.op.exp1.expType.kind != pointerType && exp.op.exp1.expType.kind != templateType))
@@ -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"))))))));
+                  exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
+                                 MkExpOp(null, '&', exp2)), '+',
+                                    MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
+                                       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
@@ -1390,8 +1433,8 @@ static void ProcessExpression(Expression exp)
       case indexExp:
       {
          Expression e;
-         /*bool isBuiltin = exp && exp.index.exp && 
-            (exp.index.exp.type == ExpressionType::arrayExp || 
+         /*bool isBuiltin = exp && exp.index.exp &&
+            (exp.index.exp.type == ExpressionType::arrayExp ||
               (exp.index.exp.type == castExp && exp.index.exp.cast.exp.type == ExpressionType::arrayExp));
          */
          Expression checkedExp = exp.index.exp;
@@ -1415,36 +1458,31 @@ static void ProcessExpression(Expression exp)
          exp.index.exp.usage.usageGet = true;
          ProcessExpression(exp.index.exp);
 
-         if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType && 
+         if(exp.index.exp.expType && exp.index.exp.expType.kind == pointerType &&
             exp.index.exp.expType.type && exp.index.exp.expType.type.kind == templateType)
          {
             Expression argExp = GetTemplateArgExp(exp.index.exp.expType.type.templateParameter, thisClass, false);
             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(
                   // (uint64)
-                  MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), 
+                  MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null),
 
                   // ((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(
-                        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)))),
+                     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.size == 1) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1465,9 +1503,9 @@ static void ProcessExpression(Expression exp)
                         CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression))),
 
                   // ((uint64 *)array)[i]
-                  MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)), 
-                     exp.index.exp))), exp.index.index))))))))))))))))));
-               
+                  MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
+                     exp.index.exp))), exp.index.index)))))))))))))))));
+
                // Add this to the context
                thisClass = curExternal.function ? curExternal.function._class : null;
                {
@@ -1477,10 +1515,10 @@ static void ProcessExpression(Expression exp)
                      type = MkClassType(thisClass.fullName);
                   };
                   globalContext.symbols.Add((BTNode)thisSymbol);
-                     
+
                   ProcessExpressionType(exp.list->first);
                   ProcessExpression(exp.list->first);
-                     
+
                   //globalContext.symbols.Delete((BTNode)thisSymbol);
                   globalContext.symbols.Remove((BTNode)thisSymbol);
                   FreeSymbol(thisSymbol);
@@ -1511,11 +1549,11 @@ static void ProcessExpression(Expression exp)
                Class arrayClass = eSystem_FindClass(privateModule, "Array");
                if(source && eClass_IsDerived(source._class.registered, arrayClass))
                   isArray = true;
-               if(isArray)
+               if(isArray && _class.templateArgs)
                {
                   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,8 +1562,8 @@ 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);
-                  exp.index.exp = MkExpBrackets(MkListOne(MkExpCast(typeName, 
+                  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);
                   ProcessExpression(exp);
@@ -1543,16 +1581,16 @@ static void ProcessExpression(Expression exp)
                   Context context = PushContext();
 
                   sprintf(iteratorType, "Iterator<%s, %s >", _class.templateArgs[2].dataTypeString, _class.templateArgs[1].dataTypeString);
-         
+
                   ListAdd(instMembers, MkMemberInit(null, MkInitializerAssignment(exp.index.exp)));
-                  
+
                   ListAdd(declarations, MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
                      MkExpIdentifier(MkIdentifier("__internalIterator")), MkListOne(MkMembersInitList(instMembers)))));
 
                   ListAdd(args, MkExpBrackets(exp.index.index));
                   ListAdd(args, exp.usage.usageSet ? MkExpIdentifier(MkIdentifier("true")) : MkExpIdentifier(MkIdentifier("false")));
-                  
-                  ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")), 
+
+                  ListAdd(statements, MkExpressionStmt(MkListOne(MkExpCall(MkExpMember(MkExpIdentifier(MkIdentifier("__internalIterator")),
                      MkIdentifier("Index")), args))));
 
                   // ListAdd(statements, MkExpressionStmt(MkListOne(MkExpOp(null, '&', MkExpIdentifier(MkIdentifier("__internalIterator"))))));
@@ -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...
@@ -1622,9 +1662,9 @@ static void ProcessExpression(Expression exp)
                // Cast function to its type
                {
                   Context context = SetupTemplatesContext(method._class);
-                  
+
                   decl = SpecDeclFromString(method.dataTypeString, specs, MkDeclaratorBrackets(MkDeclaratorPointer(MkPointer(null, null), null)));
-                  
+
                   FinishTemplatesContext(context);
                }
                curContext = back;
@@ -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
                   {
@@ -1663,83 +1712,120 @@ static void ProcessExpression(Expression exp)
                // Added !exp.call.exp.expType.methodClass
                if(memberExp && memberExp.member.exp.expType)
                {
-                  if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class && memberExp.member.exp.expType._class.registered)
+                  Type type = memberExp.member.exp.expType;
+
+                  if(type.kind == classType && type._class && type._class.registered)
+                  {
+                     Class regClass = type._class.registered;
+                     ClassType classType = regClass.type;
+                     if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
+                        argClass = regClass;
+                  }
+                  else if(type.kind == subClassType)
                   {
-                     ClassType type = memberExp.member.exp.expType._class.registered.type;
-                     if(type != normalClass || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
-                        argClass = memberExp.member.exp.expType._class.registered;
+                     argClass = FindClass("ecere::com::Class").registered;
+                  }
+                  else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
+                  {
+                     argClass = FindClass("char *").registered;
+                  }
+                  else if(type.kind == pointerType)
+                  {
+                     argClass = eSystem_FindClass(privateModule, "uintptr");
+                     FreeType(memberExp.member.exp.expType);
+                     memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
+                     memberExp.member.exp.byReference = true;
                   }
                   else
                   {
-                     switch(memberExp.member.exp.expType.kind)
-                     {
-                        case intType:
-                        {
-                           argClass = eSystem_FindClass(privateModule, "int");
-                           break;
-                        }
-                     }
+                     char string[1024] = "";
+                     Symbol classSym;
+                     PrintTypeNoConst(type, string, false, true);
+                     classSym = FindClass(string);
+                     if(classSym) argClass = classSym.registered;
                   }
+
                   /*
                   if(!_class && argClass && strcmp(argClass.fullName, "class"))
                      _class = argClass;
                   */
                }
 
-               // *** Added !_class here
-               if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType)
                {
-                  if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
-                     memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)
+                  Type type = memberExp ? memberExp.member.exp.expType : null;
+                  Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
+                  char className[1024];
+
+                  if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
+                     strcpy(className, "class");
+                  else
+                  {
+                     Class cl = _class;
+                     // TESTING: Moved this here...
+                     if(!cl && argClass && strcmp(argClass.fullName, "class"))
+                        cl = argClass;
+                     if(!cl)
+                        cl = regClass;
+                     if(!cl)
+                        // TODO: Unhandled case here, what should happen?
+                        cl = class(int);
+
+                     // To avoid declaring classes templatized after this class template (e.g. public struct Iterator<class T, class IT = int> { Container<T, IT> container; } )
+                     if(cl.templateClass && !_class && exp.call.exp.expType._class && !exp.call.exp.expType.methodClass &&
+                        (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
+                        cl = cl.templateClass;
+
+                     // Need the class itself here...
+                     strcpy(className, "__ecereClass_");
+                     FullClassNameCat(className, cl.fullName, true);
+
+                     if(!cl.symbol)
+                        cl.symbol = FindClass(cl.fullName);
+
+                     DeclareClass(curExternal, cl.symbol, className);
+                  }
+
+                  if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
                   {
-                     // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
-                     // as opposed to the File class vTbl one
                      exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                        MkExpIndex(MkExpPointer(MkExpBrackets(MkListOne(CopyExpression(memberExp.member.exp))), MkIdentifier("_vTbl")),
+                        MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
                   }
-                  else
+                  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("class")), MkIdentifier("_vTbl")),
+                        MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
                   }
-               }
-               else if(memberExp && !_class && exp.call.exp.expType._class &&
-                     (memberExp.member.exp.expType.kind == subClassType || (memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
-                     memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)))
-               {
-                  exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                     MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
-                     MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
-               }
-               else 
-               {
-                  char className[1024];
-
-                  // TESTING: Moved this here...
-                  if(!_class && argClass && strcmp(argClass.fullName, "class"))
-                     _class = argClass;
-
-                  if(!_class)
+                  else
                   {
-                     // TODO: Unhandled case here, what should happen?
-                     _class = class(int);
-                  }
-
-                  // 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);
+                     // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
+                     // as opposed to the File class vTbl one
 
-                  exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                     MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
-                     MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                     // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
+                     Expression c;
+                     Context context = PushContext();
+                     OldList * specs;
+                     c = MkExpExtensionCompound(MkCompoundStmt(
+                           MkListOne(MkDeclaration(
+                              (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);
+                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                        MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                  }
                }
             }
             else
@@ -1750,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;
@@ -1767,7 +1855,7 @@ static void ProcessExpression(Expression exp)
 
                   // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
                   /*
-                  if(memberExp.member.exp.expType.kind != classType || 
+                  if(memberExp.member.exp.expType.kind != classType ||
                      memberExp.member.exp.expType._class.registered.type == enumClass ||
                      memberExp.member.exp.expType._class.registered.type == unitClass)
                   {
@@ -1780,7 +1868,7 @@ static void ProcessExpression(Expression exp)
                      // THIS WAS NASTY:
                      // memberExp.member.exp.expType.kind = classType;
                      // memberExp.member.exp.expType._class = FindClass(typeString);
-                     
+
                      FreeType(memberExp.member.exp.expType);
                      memberExp.member.exp.expType = Type
                      {
@@ -1797,88 +1885,191 @@ static void ProcessExpression(Expression exp)
                      }
                   }
                   */
-                  
+
                   if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
                   {
-                     if(
-                        (argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") && strcmp(argClass.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-                        (!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
+                     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(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
                      {
-                        if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
+                        if(c && (c.type == normalClass || c.type == noHeadClass))
+                           stillAddReferenceOp = true;
+                        changeReference = true;
+                     }
+                     if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
+                        changeReference = true;
+                     if(changeReference)
+                     {
+                        if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 &&
+                           ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
+                        {
+                           exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
+                           ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
+                        }
+                        else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
                         {
                            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 = MkExpOp(null, '&', checkedExp);
                            if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
                            {
                               parentExp.list->Remove(checkedExp);
                               parentExp.list->Add(newExp);
                            }
                            else if(parentExp && parentExp.type == castExp)
+                           {
                               parentExp.cast.exp = newExp;
-
+                              // Add a dereference level here
+                              if(newExp.expType && newExp.expType.classObjectType)
+                                 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
+                           }
+                           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++;
+                           }
                            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);
-
-                     //if(memberExp.member.exp && memberExp.member.exp.type == identifierExp && !strcmp(memberExp.member.exp.identifier.string, "this") && FindSymbol("class", curContext, topContext, false))
-                     if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
                      {
-                        exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier("class")));
+                        exp.call.arguments->Insert(null, memberExp.member.exp);
+                        nullMemberExp = true;
                      }
-                     else
+
                      {
-                        if(memberExp && !argClass)
-                           exp.call.arguments->Insert(null, MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_class")));
-                        else
+                        char className[1024];
+                        Type type = memberExp.member.exp ? memberExp.member.exp.expType : null;
+                        Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
+                        Class cl = argClass ? argClass : regClass;
+                        className[0] = 0;
+
+                        if(memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType == ClassObjectType::typedObject)
+                           strcpy(className, "class");
+                        else if(cl)
                         {
-                           char className[1024];
                            // Need the class itself here...
                            strcpy(className, "__ecereClass_");
-                           FullClassNameCat(className, argClass.fullName, true);
-                           MangleClassName(className);
+                           FullClassNameCat(className, cl.fullName, true);
+
+                           if(!cl.symbol)
+                              cl.symbol = FindClass(cl.fullName);
+                           DeclareClass(curExternal, cl.symbol, className);
+                        }
 
-                           if(!argClass.symbol)
-                              argClass.symbol = FindClass(argClass.fullName);
-                           DeclareClass(argClass.symbol, className);
-                           exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
+                        if(className[0])
+                        {
+                           if(memberExp && cl && cl.type == normalClass && (!type || type.byReference == false) && strcmp(cl.dataTypeString, "char *"))
+                           {
+                              // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
+                              Expression c;
+                              Context context = PushContext();
+                              OldList * specs;
+
+                              c = MkExpExtensionCompound(MkCompoundStmt(
+                                    MkListOne(MkDeclaration(
+                                       (specs = MkListOne(MkSpecifierName("Instance"))),
+                                       MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
+                                          MkInitializerAssignment(memberExpMemberExp))))),
+                                    MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
+                                       MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
+                                       MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
+                                       MkExpIdentifier(MkIdentifier(className))))))));
+                              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
+                           }
+                           else
+                              exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
                         }
                      }
+
+                     if(memberExpMemberExp)
+                        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)
@@ -1908,19 +2099,26 @@ static void ProcessExpression(Expression exp)
                      {
                         _class = FindClass("char *").registered;
                      }
+                     else if(type.kind == pointerType)
+                     {
+                        _class = eSystem_FindClass(privateModule, "uintptr");
+                        FreeType(e.expType);
+                        e.expType = ProcessTypeString("uintptr", false);
+                        // Assume null pointers means 'no object' rather than an object holding a null pointer
+                        e.byReference = true;
+                     }
                      else
                      {
                         char string[1024] = "";
                         Symbol classSym;
-
-                        PrintType(type, string, false, true);
+                        PrintTypeNoConst(type, string, false, true);
                         classSym = FindClass(string);
                         if(classSym) _class = classSym.registered;
                         // if(!class) _class = eSystem_FindClass(privateModule, "int");
                      }
 
-                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
+                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
+                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
                         destType.byReference)))
                      {
                         //if(!_class || strcmp(_class.fullName, "String"))     // TESTING THIS WITH NEW String class...
@@ -1933,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)
@@ -1962,19 +2160,19 @@ static void ProcessExpression(Expression exp)
                               newExp = checkedExp.op.exp2;
                               checkedExp.op.exp2 = null;
                               FreeExpContents(checkedExp);
-                              
+
                               if(e.expType && e.expType.passAsTemplate)
                               {
                                  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))))));
                               }
 
                               if(parentExp.type == callExp)
-                              {                              
+                              {
                                  exp.call.arguments->Insert(e.prev, newExp);
                                  exp.call.arguments->Remove(e);
                                  e = newExp;
@@ -2039,18 +2237,36 @@ static void ProcessExpression(Expression exp)
                                     newExp.next = null;
                                     newExp.expType = null;
 
-                                    PrintType(e.expType, typeString, false, true);
+                                    PrintTypeNoConst(e.expType, typeString, false, true);
                                     decl = SpecDeclFromString(typeString, specs, null);
                                     newExp.destType = ProcessType(specs, decl);
 
                                     curContext = context;
                                     e.type = extensionCompoundExp;
-                                    e.compound = MkCompoundStmt(
-                                       MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(/*PlugDeclarator(decl, */
-                                          MkDeclaratorIdentifier(MkIdentifier("__internalValue"))/*)*/, MkInitializerAssignment(newExp))))), 
 
+                                    // We need a current compound for this
+                                    if(curCompound)
+                                    {
+                                       char name[100];
+                                       OldList * stmts = MkList();
+                                       sprintf(name, "__internalValue%03X", internalValueCounter++);
+                                       if(!curCompound.compound.declarations)
+                                          curCompound.compound.declarations = MkList();
+                                       curCompound.compound.declarations->Insert(null, MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier(name)), null))));
+                                       ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier(name)), '=', newExp))));
+                                       ListAdd(stmts, MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier(name)))));
+                                       e.compound = MkCompoundStmt(null, stmts);
+                                    }
+                                    else
+                                       printf("libec: compiler error, curCompound is null in ApplyAnyObjectLogic\n");
+
+                                    /*
+
+                                    e.compound = MkCompoundStmt(
+                                       MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
                                        MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
-                                    
+                                    */
+
                                     e.compound.compound.context = context;
                                     PopContext(context);
                                     curContext = context.parent;
@@ -2060,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)
@@ -2075,10 +2291,14 @@ 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);
                                  exp.call.arguments->Remove(e);
                                  e = newExp;
@@ -2098,7 +2318,7 @@ static void ProcessExpression(Expression exp)
                            }
                         }
                      }
-                     
+
                      if(destType.classObjectType == ClassObjectType::typedObject)
                      {
                         char className[1024];
@@ -2116,14 +2336,55 @@ 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);
                         }
-                        exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
+
+                        if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
+                        {
+                           // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._class : __ecereClass_...; })
+                           Expression c;
+                           Context context = PushContext();
+
+                           // Work around to avoid repeating the BuiltInContainer just to get the type
+                           // (a bit messy since we already transformed our expression to an extensionInitializerExp in earlier pass)
+                           if(_class.templateClass && !strcmp(_class.templateClass.name, "Container") &&
+                              e.list && e.list->first &&
+                              ((Expression)e.list->first).type == castExp &&
+                              ((Expression)e.list->first).cast.exp &&
+                              ((Expression)e.list->first).cast.exp.type == opExp &&
+                              ((Expression)e.list->first).cast.exp.op.op == '&' &&
+                              ((Expression)e.list->first).cast.exp.op.exp2 &&
+                              ((Expression)e.list->first).cast.exp.op.exp2.type == extensionInitializerExp)
+                           {
+                              exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
+                           }
+                           else
+                           {
+                              OldList * specs;
+                              c = MkExpExtensionCompound(MkCompoundStmt(
+                                    MkListOne(MkDeclaration(
+                                       (specs = MkListOne(MkSpecifierName("Instance"))),
+                                       MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
+                                          MkInitializerAssignment(CopyExpression(e)))))),
+                                    MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
+                                       MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
+                                       MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_class"))),
+                                       MkExpIdentifier(MkIdentifier(className))))))));
+                              c.compound.compound.context = context;
+                              PopContext(context);
+
+                              if(type.specConst)
+                                 specs->Insert(null, MkSpecifier(CONST));
+
+                              exp.call.arguments->Insert(e.prev, c);
+                           }
+                        }
+                        else
+                           exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
                      }
                   }
                }
@@ -2133,16 +2394,16 @@ static void ProcessExpression(Expression exp)
                   //PrintExpression(e, debugString);
 #endif
                   // If expression type is a simple class, make it an address
-                  FixReference(e, true);
+                  FixReference(e, !destType || !destType.declaredWithStruct);
                }
             }
             if(ellipsisDestType)
             {
-               if(usedEllipsis || 
-                  (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last && 
+               if(usedEllipsis ||
+                  (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last &&
                    ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
                {
-                  exp.call.arguments->Insert(exp.call.arguments->last, MkExpConstant("0"));
+                  exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
                }
             }
          }
@@ -2152,7 +2413,7 @@ static void ProcessExpression(Expression exp)
       {
          bool changeToPtr = false;
          bool noHead = false;
-         Type type = exp.member.exp.expType;
+         Type type = exp.member.exp ? exp.member.exp.expType : null;
          Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
          if(exp.member.member) exp.member.member._class = null;
 
@@ -2169,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");
@@ -2180,7 +2443,7 @@ static void ProcessExpression(Expression exp)
                // DANGER: Buffer overflow
                char string[2048] = "";
                Symbol classSym;
-               PrintType(type, string, false, true);
+               PrintTypeNoConst(type, string, false, true);
                classSym = FindClass(string);
                _class = classSym ? classSym.registered : null;
             }
@@ -2188,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)
             {
@@ -2198,17 +2461,17 @@ static void ProcessExpression(Expression exp)
                   prop = eClass_FindProperty(_class, exp.member.member.string, null);
                if(!prop)
                   prop = eClass_FindProperty(_class, exp.member.member.string, privateModule);
-               if(prop && (exp.usage.usageRef || 
+               if(prop && (exp.usage.usageRef ||
                   (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;
                      prop = null;
                   }
-                  else 
+                  else
                   {
                      if(exp.usage.usageRef)
                         Compiler_Error($"cannot obtain address of property\n");
@@ -2256,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 : 
+                     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...
@@ -2277,8 +2539,8 @@ static void ProcessExpression(Expression exp)
                            // Make a declaration in the closest compound statement
                            // (Do not reuse (since using address for function calls)...)
                            sprintf(className, "__simpleStruct%d", curContext.simpleID++);
-                           declarator = 
-                              SpecDeclFromString(propertyClass.dataTypeString, specs, 
+                           declarator =
+                              SpecDeclFromString(propertyClass.dataTypeString, specs,
                                  MkDeclaratorIdentifier(MkIdentifier(className)));
 
                            ListAdd(decls, MkInitDeclarator(declarator, null));
@@ -2325,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));
@@ -2404,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);
@@ -2445,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
                      {
@@ -2465,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
                   {
@@ -2476,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)
                {
@@ -2490,8 +2807,8 @@ static void ProcessExpression(Expression exp)
                ProcessExpression(exp.member.exp);
                // TEST: exp.tempCount = exp.member.exp.tempCount;
 
-               if(type.kind == classType)
-                  DeclareStruct(type._class.registered.fullName, false);
+               if(type.kind == classType && type._class && type._class.registered)
+                  DeclareStruct(curExternal, type._class.registered.fullName, false, true);
 
                // TESTING THIS NOHEAD STUFF...
                if(_class.type == noHeadClass)
@@ -2515,12 +2832,12 @@ static void ProcessExpression(Expression exp)
                   else
                      sprintf(mask, FORMAT64HEX, bitMember.mask);
                   sprintf(shift, "%d", bitMember.pos);
-                  
+
                   FreeIdentifier(exp.member.member);
-                 
+
                   // ((type) ((color & mask) >> bitPos))
                   ListAdd(list, MkExpCast(type, MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(MkListOne(
-                     MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP, 
+                     MkExpOp(exp.member.exp, '&', MkExpConstant(mask)))), RIGHT_OP,
                         MkExpConstant(shift))))));
 
                   exp.type = bracketsExp;
@@ -2532,34 +2849,33 @@ static void ProcessExpression(Expression exp)
                else
                {
                   // If it's a this pointer, replace by precomputed shortcut
-                  if(thisPtr)
+                  if(exp.member.exp.type == identifierExp && thisPtr && type.kind == classType && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
                   {
                      char pointerName[1024];
 
                      strcpy(pointerName, "__ecerePointer_");
                      FullClassNameCat(pointerName, type._class.registered.fullName, false);
-                     FreeIdentifier(exp.member.exp.identifier);
+                     if(exp.member.exp.identifier)
+                        FreeIdentifier(exp.member.exp.identifier);
                      exp.member.exp.identifier = MkIdentifier(pointerName);
                   }
                   // Otherwise, access the data the hard way
                   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);
@@ -2580,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;
@@ -2592,27 +2907,40 @@ 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);
                         }
                         else
                         {
-                           e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', 
+                           e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+',
                               MkExpPointer(QMkExpId(className), MkIdentifier("offset"))));
                         }
 
                         compound.compound.context = context;
                         compound.compound.statements = MkListOne(MkExpressionStmt(MkListOne(
-                           QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), 
+                           QBrackets(MkExpCast(MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)),
                               MkDeclaratorPointer(MkPointer(null, null), null)), e)))));
 
                         exp.member.exp =  MkExpExtensionCompound(compound);
@@ -2625,19 +2953,33 @@ static void ProcessExpression(Expression exp)
                         bytePtr = MkExpCast(QMkType("char", QMkPtrDecl(null)), /*CopyExpression(*/exp.member.exp/*)*/);
                         // DISABLED BECAUSE PREVENTS GETTING ADDRESS OF MEMBERS WITH ADDRESS 0
                         /*
-                        e = QBrackets(QMkExpCond(exp.member.exp, 
+                        e = QBrackets(QMkExpCond(exp.member.exp,
                            QBrackets(MkExpOp(bytePtr, '+', MkExpPointer(classExp, MkIdentifier("offset")))),
                            MkExpConstant("0")));
                         */
-                        
+
                         // 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;
@@ -2658,7 +3000,7 @@ static void ProcessExpression(Expression exp)
          FreeSpecifier(memberClassSpecifier);
 
          // Just moved this at the end... How is it?
-         if(exp.type == memberExp || exp.type == pointerExp)
+         if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
          {
             exp.member.exp.usage.usageGet = true;
             exp.member.exp.usage.usageMember = true;
@@ -2672,8 +3014,9 @@ static void ProcessExpression(Expression exp)
       }
       case extensionCompoundExp:
       {
-         ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage |= exp.usage & 
-            ExpUsage { usageGet = true, usageArg = true, usageMember = true };
+         Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
+         if(e)
+            e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
 
          ProcessStatement(exp.compound);
 
@@ -2696,26 +3039,16 @@ static void ProcessExpression(Expression exp)
             if(argExp)
             {
                Expression classExp;
-               
+
                FreeTypeName(exp.typeName);
 
                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);
@@ -2734,7 +3067,7 @@ static void ProcessExpression(Expression exp)
                exp.byReference = exp.cast.exp.byReference;
             if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass &&
                exp.cast.exp.expType && (exp.cast.exp.expType.kind == pointerType || exp.cast.exp.expType.kind == arrayType || (
-                  exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered && 
+                  exp.cast.exp.expType.kind == classType && exp.cast.exp.expType._class && exp.cast.exp.expType._class.registered &&
                      !strcmp(exp.cast.exp.expType._class.registered.dataTypeString, "char *")) ) )
                exp.byReference = true;
          }
@@ -2774,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);
             }
          }
@@ -2783,11 +3118,12 @@ static void ProcessExpression(Expression exp)
          {
             char className[1024];
             char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
-            
+            Symbol classSym = FindClass(string);
+
             strcpy(className, "__ecereClass_");
             FullClassNameCat(className, string, true);      // TODO: Verify this
-            MangleClassName(className);
-            DeclareClass(FindClass(string), className);
+
+            DeclareClass(curExternal, classSym, className);
             delete string;
 
             FreeList(exp._classExp.specifiers, FreeSpecifier);
@@ -2804,8 +3140,99 @@ static void ProcessExpression(Expression exp)
          ProcessExpression(exp.vaArg.exp);
          break;
       }
+      case extensionInitializerExp:
+      {
+         ProcessInitializer(exp.initializer.initializer);
+         break;
+      }
    }
    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;
 }
 
@@ -2814,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;
       }
    }
@@ -2843,7 +3276,7 @@ static void ProcessDeclaration(Declaration decl)
          if(decl.declarators)
          {
             InitDeclarator d;
-         
+
             for(d = decl.declarators->first; d; d = d.next)
             {
                if(d.initializer)
@@ -2936,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;
@@ -2947,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;
@@ -2985,7 +3424,7 @@ static void ProcessStatement(Statement stmt)
             ProcessStatement(stmt.forStmt.check);
          }
          if(stmt.forStmt.increment)
-         {        
+         {
             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
             {
                ProcessExpression(exp);
@@ -3010,6 +3449,9 @@ static void ProcessStatement(Statement stmt)
             for(exp = stmt.expressions->first; exp; exp = exp.next)
             {
                ProcessExpression(exp);
+               // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
+               if(!exp.next && exp.destType && exp.destType.byReference)
+                  FixReference(exp, true);
             }
          }
          break;
@@ -3048,26 +3490,7 @@ static void ProcessStatement(Statement stmt)
 static void ProcessFunction(FunctionDefinition function)
 {
    if(function.body)
-   {
       ProcessStatement(function.body);
-      if(function.tempCount)
-      {
-         Statement stmt = function.body;
-         int c;
-         // Declare ecereTemp here, we need it!
-         if(!stmt.compound.declarations)
-            stmt.compound.declarations = MkList();
-         curContext = stmt.compound.context;
-         for(c = 1; c<=function.tempCount; c++)
-         {
-            char ecereTemp[100];
-            sprintf(ecereTemp, "__ecereTemp%d", c);
-            stmt.compound.declarations->Insert(null,
-               QMkDeclarationBase(VOID, MkInitDeclarator(QMkPtrDecl(ecereTemp), null)));
-         }
-         curContext = stmt.compound.context.parent;
-      }
-   }
 }
 
 static void ProcessMemberInitData(MemberInit member)
@@ -3114,7 +3537,7 @@ public void ProcessMemberAccess()
             ProcessDeclaration(external.declaration);
       }
    }
-   
+
    for(external = ast->first; external; external = external.next)
    {
       curExternal = external;
@@ -3124,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;
@@ -3160,7 +3581,7 @@ public void ProcessMemberAccess()
                      type = MkClassType(regClass.fullName);
                   };
                   globalContext.symbols.Add((BTNode)thisSymbol);
-                  
+
                   for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
                   {
                      //thisClass = regClass;
@@ -3183,7 +3604,7 @@ public void ProcessMemberAccess()
                      type = MkClassType(regClass.fullName);
                   };
                   globalContext.symbols.Add((BTNode)thisSymbol);
-                  
+
                   //thisClass = regClass;
                   if(prop.setStmt)
                   {
@@ -3227,7 +3648,7 @@ public void ProcessMemberAccess()
                else if(def.type == propertyWatchClassDef && def.propertyWatch)
                {
                   PropertyWatch propertyWatch = def.propertyWatch;
-        
+
                   // Add this to the context
                   Symbol thisSymbol
                   {
@@ -3235,7 +3656,7 @@ public void ProcessMemberAccess()
                      type = MkClassType(regClass.fullName);
                   };
                   globalContext.symbols.Add((BTNode)thisSymbol);
-                  
+
                   //thisClass = regClass;
                   if(propertyWatch.compound)
                   {