ecere/com; compiler/libec: (#1087) Fixed class:struct issues
[sdk] / compiler / libec / src / pass2.ec
index 5caab59..e955b2d 100644 (file)
@@ -245,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)));
@@ -275,11 +275,10 @@ 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);
@@ -302,7 +301,7 @@ static void ProcessExpression(Expression exp)
 
                exp.identifier._class = null;
                exp.identifier.string = CopyString(name);
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
             }
          }
          /*
@@ -329,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;
@@ -476,7 +475,7 @@ static void ProcessExpression(Expression exp)
                            }
                            if(lastProperty && lastProperty.Get && lastProperty.Set)
                            {
-                              DeclareProperty(lastProperty, setName, getName);
+                              DeclareProperty(curExternal, lastProperty, setName, getName);
                               // propertyClass = convertTo ? _class : ((Symbol)lastProperty.symbol)._class;
                               propertyClass = convertTo ? _class :
                                  ((((Symbol)lastProperty.symbol).type &&
@@ -593,6 +592,7 @@ static void ProcessExpression(Expression exp)
                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;
                }
@@ -749,6 +749,8 @@ static void ProcessExpression(Expression exp)
                                  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);
@@ -808,7 +810,7 @@ static void ProcessExpression(Expression exp)
                               if(value)
                                  value.usage.usageArg = true;
 
-                              DeclareProperty(prop, setName, getName);
+                              DeclareProperty(curExternal, prop, setName, getName);
 
                               if(memberExp.member.exp)
                                  ProcessExpression(memberExp.member.exp);
@@ -1033,7 +1035,6 @@ static void ProcessExpression(Expression exp)
 
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, exp.expType._class.string, true);
-               //MangleClassName(className);
 
                DeclareClass(exp.expType._class, className);
 
@@ -1060,11 +1061,10 @@ static void ProcessExpression(Expression exp)
                   if(_class.templateClass) _class = _class.templateClass;
                   strcpy(className, "__ecereClass_");
                   FullClassNameCat(className, _class.fullName, false /*true*/);
-                  //MangleClassName(className);
 
                   if(!_class.symbol)
                      _class.symbol = FindClass(_class.fullName);
-                  DeclareClass(_class.symbol, className);
+                  DeclareClass(curExternal, _class.symbol, className);
 
                   // Call the non virtual destructor
                   ListAdd(list,
@@ -1087,6 +1087,7 @@ static void ProcessExpression(Expression exp)
                   );
                }
                ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
                o = CopyExpression(object);
                ProcessExpressionType(o);
                o.usage.usageGet = true;
@@ -1121,7 +1122,7 @@ static void ProcessExpression(Expression exp)
                   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")),
@@ -1130,7 +1131,10 @@ static void ProcessExpression(Expression exp)
                }
             }
             else
+            {
                ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
+            }
 
             //ProcessExpression(object);
 
@@ -1172,6 +1176,7 @@ static void ProcessExpression(Expression exp)
                      derefExp.index.exp = null;
                      FreeExpression(derefExp);
 
+                     // BOOSTRAP FIX
                      derefExp = MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), indexExp), '+',
                         MkExpBrackets(MkListOne(MkExpOp(MkExpBrackets(indexExpIndex), '*', MkExpBrackets(MkListOne(CopyExpression(sizeExp)))))));
                   }
@@ -1208,7 +1213,7 @@ static void ProcessExpression(Expression exp)
                      ProcessExpressionType(args->last);
                      ProcessExpression(args->last);
 
-                     DeclareFunctionUtil("memcpy");
+                     DeclareFunctionUtil(curExternal, "memcpy");
 
                      exp.list = MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("memcpy")), args));
                      exp.type = bracketsExp;
@@ -1244,7 +1249,7 @@ static void ProcessExpression(Expression exp)
                      MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                         // array
                         MkListOne(
-                           MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
+                           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")))),
@@ -1475,9 +1480,9 @@ static void ProcessExpression(Expression exp)
                   // ((class.type == structClass) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                      // ((byte *)array) + (i) * class.size
-                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
+                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(MkExpOp(
                         MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
-                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
+                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp)))))))),
 
                   // ((class.size == 1) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1649,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...
@@ -1690,7 +1695,10 @@ static void ProcessExpression(Expression exp)
                      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
                   {
@@ -1770,12 +1778,11 @@ static void ProcessExpression(Expression exp)
                      // Need the class itself here...
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, cl.fullName, true);
-                     //MangleClassName(className);
 
                      if(!cl.symbol)
                         cl.symbol = FindClass(cl.fullName);
 
-                     DeclareClass(cl.symbol, className);
+                     DeclareClass(curExternal, cl.symbol, className);
                   }
 
                   if(type && type.kind == subClassType && !_class && !exp.call.exp.expType.methodClass && memberExp)
@@ -1832,7 +1839,7 @@ static void ProcessExpression(Expression exp)
                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;
@@ -1882,20 +1889,22 @@ static void ProcessExpression(Expression exp)
                   if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
                   {
                      bool changeReference = false;
+                     bool stillAddReferenceOp = false;
                      Expression memberExpMemberExp = CopyExpression(memberExp.member.exp);
+                     Type expType = memberExp.member.exp.expType;
+                     Class c = expType.kind == classType && expType._class ? expType._class.registered : null;
 
                      // Patched so that class isn't considered SYSTEM...
                      if(argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") &&
                         strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
                         changeReference = true;
-                     if(!memberExp.member.exp.expType.classObjectType &&
-                        (((
-                           (memberExp.member.exp.expType.kind != pointerType &&
-                              (memberExp.member.exp.expType.kind != classType || !memberExp.member.exp.expType._class ||
-                               !memberExp.member.exp.expType._class.registered || memberExp.member.exp.expType._class.registered.type == structClass)))) ||
-                           method.dataType.byReference)) // ADDED THIS FOR OnGetDataFromString
+                     if(!expType.classObjectType && ( ( (expType.kind != pointerType && (!c || c.type == structClass) ) ) || method.dataType.byReference) ) // ADDED THIS FOR OnGetDataFromString
+                     {
+                        if(c && (c.type == normalClass || c.type == noHeadClass))
+                           stillAddReferenceOp = true;
                         changeReference = true;
-                     if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
+                     }
+                     if(typedObject && expType.classObjectType && expType.byReference != method.dataType.byReference)
                         changeReference = true;
                      if(changeReference)
                      {
@@ -1910,7 +1919,7 @@ static void ProcessExpression(Expression exp)
                            exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
                            memberExp.member.exp.op.exp2 = null;
                         }
-                        else if(!memberExp.member.exp.byReference)
+                        else if(!memberExp.member.exp.byReference || stillAddReferenceOp)
                         {
                            // TESTING THIS... REUSE THIS CODE?
                            Expression checkedExp = memberExp.member.exp;
@@ -1945,7 +1954,13 @@ static void ProcessExpression(Expression exp)
                            if(!parentExp)
                               nullMemberExp = true;
 
-                           newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
+                           if(typedObject && !expType.classObjectType && !stillAddReferenceOp)
+                              newExp = checkedExp;
+                           else
+                           {
+                              newExp = MkExpOp(null, '&', checkedExp);
+                              newExp.byReference = true;
+                           }
                            if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
                            {
                               parentExp.list->Remove(checkedExp);
@@ -1958,7 +1973,7 @@ static void ProcessExpression(Expression exp)
                               if(newExp.expType && newExp.expType.classObjectType)
                                  parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
                            }
-                           if(typedObject && !memberExp.member.exp.expType.classObjectType)
+                           if(typedObject && !expType.classObjectType)
                            {
                               Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
                               FreeType((parentExp ? parentExp : newExp).expType);
@@ -1995,11 +2010,10 @@ static void ProcessExpression(Expression exp)
                            // Need the class itself here...
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, cl.fullName, true);
-                           //MangleClassName(className);
 
                            if(!cl.symbol)
                               cl.symbol = FindClass(cl.fullName);
-                           DeclareClass(cl.symbol, className);
+                           DeclareClass(curExternal, cl.symbol, className);
                         }
 
                         if(className[0])
@@ -2117,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)
@@ -2151,7 +2165,7 @@ static void ProcessExpression(Expression exp)
                               {
                                  char size[100];
                                  ComputeTypeSize(e.expType);
-                                 sprintf(size, "%d", e.expType.size);
+                                 sprintf(size, "%d", e.expType.size);   // BOOTSTRAP FIX
                                  newExp = MkExpBrackets(MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)),
                                     MkDeclaratorPointer(MkPointer(null, null), null)), newExp), '+',
                                        MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")), MkListOne(MkExpConstant(size))))));
@@ -2262,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)
@@ -2277,8 +2291,12 @@ static void ProcessExpression(Expression exp)
                                  else if(checkedExp.type == castExp)
                                     checkedExp = checkedExp.cast.exp;
                               }
-                              newExp = MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)), 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);
@@ -2318,12 +2336,11 @@ static void ProcessExpression(Expression exp)
                         {
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, _class.fullName, true);
-                           //MangleClassName(className);
 
                            if(!_class.symbol)
                               _class.symbol = FindClass(_class.fullName);
 
-                           DeclareClass(_class.symbol, className);
+                           DeclareClass(curExternal, _class.symbol, className);
                         }
 
                         if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
@@ -2502,12 +2519,11 @@ static void ProcessExpression(Expression exp)
                      ProcessExpression(exp.member.exp);
                      // TEST: exp.tempCount = exp.member.exp.tempCount;
 
-                     DeclareProperty(prop, setName, getName);
+                     DeclareProperty(curExternal, prop, setName, getName);
                      //propertyClass = convertTo ? _class : ((Symbol)prop.symbol)._class;
                      propertyClass = convertTo ? _class :
                         ((((Symbol)prop.symbol).type && ((Symbol)prop.symbol).type.kind == classType) ? ((Symbol)prop.symbol).type._class.registered : ((Symbol)prop.symbol)._class);
 
-
                      if(propertyClass && propertyClass.type == bitClass)
                      {
                         // Bit classes shouldn't have properties except for conversions...
@@ -2571,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));
@@ -2667,6 +2684,8 @@ static void ProcessExpression(Expression exp)
                      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);
                      {
@@ -2708,11 +2727,10 @@ 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);
 
                         FreeExpression(exp.member.exp);
                         exp.index.exp = MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"));
@@ -2728,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
                   {
@@ -2739,7 +2757,7 @@ static void ProcessExpression(Expression exp)
                      strcat(name, "_");
                      strcat(name, method.name);
                      exp.identifier = MkIdentifier(name);
-                     DeclareMethod(method, name);
+                     DeclareMethod(curExternal, method, name);
                   }
                }
             }
@@ -2790,7 +2808,7 @@ static void ProcessExpression(Expression exp)
                // TEST: exp.tempCount = exp.member.exp.tempCount;
 
                if(type.kind == classType && type._class && type._class.registered)
-                  DeclareStruct(type._class.registered.fullName, false);
+                  DeclareStruct(curExternal, type._class.registered.fullName, false, true);
 
                // TESTING THIS NOHEAD STUFF...
                if(_class.type == noHeadClass)
@@ -2850,15 +2868,14 @@ static void ProcessExpression(Expression exp)
                      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);
@@ -2893,11 +2910,24 @@ static void ProcessExpression(Expression exp)
                                  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);
@@ -2931,11 +2961,25 @@ static void ProcessExpression(Expression exp)
                         // if(class.fixed)
                         if(member._class.fixed)
                         {
-                           if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
+                           Class c = member._class.templateClass ? member._class.templateClass : member._class;
+                           if(c.offset)
                            {
-                              char string[256];
-                              sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
-                              e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', MkExpConstant(string))));
+                              Expression se;
+
+                              if(c.offset == c.base.structSize)
+                              {
+                                 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
+                                 ProcessExpressionType(se);
+                                 se.isConstant = false;
+                              }
+                              else
+                              {
+                                 char string[256];
+                                 sprintf(string, "%d", c.offset);
+                                 se = MkExpConstant(string);
+                              }
+
+                              e = QBrackets(QBrackets(MkExpOp(bytePtr, '+', se)));
                            }
                            else
                               e = bytePtr;
@@ -3078,8 +3122,8 @@ static void ProcessExpression(Expression exp)
 
             strcpy(className, "__ecereClass_");
             FullClassNameCat(className, string, true);      // TODO: Verify this
-            //MangleClassName(className);
-            DeclareClass(classSym, className);
+
+            DeclareClass(curExternal, classSym, className);
             delete string;
 
             FreeList(exp._classExp.specifiers, FreeSpecifier);
@@ -3112,13 +3156,15 @@ static void ProcessExpression(Expression exp)
       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 != pointerType || exp.expType.kind == pointerType))) &&
+         (!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';
 
@@ -3128,7 +3174,12 @@ static void ProcessExpression(Expression exp)
          if(exp.usage.usageDelete)
             strcpy(typeString, "void *");
          else
-            PrintType(exp.expType, typeString, false, false);
+         {
+            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);
 
@@ -3148,6 +3199,8 @@ static void ProcessExpression(Expression exp)
                specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
                decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
             }
+
+            castingToDest = true;
          }
 
          e.destType = exp.destType;
@@ -3155,7 +3208,28 @@ static void ProcessExpression(Expression exp)
             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;
       }
    }