compiler/libec: Null checks
[sdk] / compiler / libec / src / pass2.ec
index d13ab15..b8b1ad9 100644 (file)
@@ -139,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++;
@@ -165,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;
@@ -222,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)));
@@ -252,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);
@@ -279,7 +301,7 @@ static void ProcessExpression(Expression exp)
 
                exp.identifier._class = null;
                exp.identifier.string = CopyString(name);
-               DeclareMethod(method, name);
+               DeclareMethod(curExternal, method, name);
             }
          }
          /*
@@ -306,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;
@@ -401,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)
@@ -452,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 &&
@@ -566,6 +589,17 @@ static void ProcessExpression(Expression exp)
                memberExp.index.exp.expType.kind == classType && memberExp.index.exp.expType._class && memberExp.index.exp.expType._class.registered &&
                memberExp.index.exp.expType._class.registered != containerClass && eClass_IsDerived(memberExp.index.exp.expType._class.registered, containerClass))
             {
+               Class c = memberExp.index.exp.expType._class.registered;
+               if(strcmp((c.templateClass ? c.templateClass : c).name, "Array"))
+               {
+                  if(exp.op.exp2 && exp.op.op == '=')
+                  {
+                     modifyPassAsTemplate(&exp.op.exp2.destType, true);
+                     CheckTemplateTypes(exp.op.exp2);
+                  }
+                  isIndexedContainerAssignment = true;
+               }
+
                ProcessExpression(memberExp);
 
                while(memberExp && ((memberExp.type == bracketsExp && memberExp.list->count == 1) ||
@@ -718,6 +752,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);
@@ -767,6 +803,22 @@ static void ProcessExpression(Expression exp)
                                  value.expType = memberExp.expType;
                                  memberExp.expType.refCount++;
                                  value.usage.usageArg = true;
+
+                                 if(isIndexedContainerAssignment)
+                                 {
+                                    value.op.exp1.usage.usageGet = true;
+                                    value.op.exp2.usage.usageGet = true;
+                                    modifyPassAsTemplate(&value.op.exp1.destType, false);
+                                    modifyPassAsTemplate(&value.op.exp2.destType, false);
+                                    CheckTemplateTypes(value.op.exp1);
+                                    CheckTemplateTypes(value.op.exp2);
+
+                                    modifyPassAsTemplate(&value.expType, false);
+                                    value.destType = value.expType;
+                                    value.expType.refCount++;
+                                    modifyPassAsTemplate(&value.destType, true);
+                                    CheckTemplateTypes(value);
+                                 }
                               }
                               else if(value)
                               {
@@ -777,10 +829,13 @@ 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);
+                                 CheckTemplateTypes(memberExp.member.exp);
+                              }
 
                               // If get flag present
                               if(exp.usage.usageGet &&
@@ -872,7 +927,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);
@@ -1002,7 +1057,6 @@ static void ProcessExpression(Expression exp)
 
                strcpy(className, "__ecereClass_");
                FullClassNameCat(className, exp.expType._class.string, true);
-               MangleClassName(className);
 
                DeclareClass(exp.expType._class, className);
 
@@ -1021,6 +1075,11 @@ static void ProcessExpression(Expression exp)
 
                OldList * list = MkList();
                Class _class;
+               Statement stmt;
+               Expression o;
+               Statement compound = MkCompoundStmt(MkListOne(MkDeclaration(MkListOne(MkSpecifier(VOID)), MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("__ecerePtrToDelete"))),
+                  MkInitializerAssignment(MkExpBrackets(args)))))), MkListOne(stmt = MkExpressionStmt(list)));
+               Expression stmtExp = MkExpExtensionCompound(compound);
                for(_class = exp.expType._class.registered; _class && _class.type == noHeadClass; _class = _class.base)
                {
                   char className[1024];
@@ -1028,11 +1087,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,
@@ -1047,21 +1105,28 @@ static void ProcessExpression(Expression exp)
                                  QMkExpId(className),
                                  MkIdentifier("Destructor")
                               ),
-                              MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), CopyExpression(args->first)))
+                              MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), QMkPtrDecl(null)), MkExpIdentifier(MkIdentifier("__ecerePtrToDelete")) /*CopyExpression(args->first)*/))
                            )
                         ),
                         MkExpConstant("0")
                      )
                   );
                }
-               ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               ListAdd(list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), MkListOne(MkExpIdentifier(MkIdentifier("__ecerePtrToDelete"))) /*args*/));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
+               o = CopyExpression(object);
+               ProcessExpressionType(o);
+               o.usage.usageGet = true;
+               ProcessExpression(o);
+
                ListAdd(exp.list,
                   MkExpBrackets(
                      MkListOne(
                         MkExpCondition(
-                           CopyExpression(object),
+                           o,
                            MkListOne(
-                              MkExpBrackets(list)
+                              //MkExpBrackets(list)
+                              stmtExp
                            ),
                            MkExpConstant("0")
                         )
@@ -1084,7 +1149,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")),
@@ -1093,11 +1158,14 @@ static void ProcessExpression(Expression exp)
                }
             }
             else
+            {
                ListAdd(exp.list, MkExpCall(QMkExpId("ecere::com::eSystem_Delete"), args));
+               DeclareFunctionUtil(curExternal, "eSystem_Delete");
+            }
 
             //ProcessExpression(object);
 
-            ListAdd(exp.list, MkExpOp(CopyExpression(object.type == castExp ? object.cast.exp : object), '=', MkExpConstant("0")));
+            ListAdd(exp.list, MkExpOp(CopyExpression(GetInnerExp(object)), '=', MkExpConstant("0")));
 
             exp2 = null;
 
@@ -1114,7 +1182,7 @@ static void ProcessExpression(Expression exp)
                Expression argExp = GetTemplateArgExp(exp.op.exp1.expType.templateParameter, thisClass, false);
                if(argExp)
                {
-                  // memcpy((byte *)array + (count * dataTypeClass.size), dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
+                  // memcpy((byte *)array + (count * dataTypeClass.size), (dataTypeClass.type == structClass) ? value : &value, dataTypeClass.size);
 
                   Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
                   OldList * args = MkList();
@@ -1124,13 +1192,7 @@ static void ProcessExpression(Expression exp)
                   ProcessExpressionType(classExp);
                   ProcessExpression(classExp);
 
-                  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")));
+                  sizeExp = MkExpMember(CopyExpression(classExp), MkIdentifier("typeSize"));
 
                   if(exp.op.exp1.type == indexExp)
                   {
@@ -1141,6 +1203,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)))))));
                   }
@@ -1158,7 +1221,8 @@ static void ProcessExpression(Expression exp)
 
                   args->Add(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
                      MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
-                        MkListOne(exp.op.exp2), MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
+                           MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(exp.op.exp2))))),
+                           MkExpOp(null, '&', CopyExpression(exp.op.exp2)))));
 
                   thisClass = curExternal.function ? curExternal.function._class : null;
                   {
@@ -1176,7 +1240,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;
@@ -1212,17 +1276,7 @@ static void ProcessExpression(Expression exp)
                      MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                         // array
                         MkListOne(
-                           MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), CopyExpression(exp.op.exp2))))),
-
-                     // ((class.type == normalClass || class.type == noHeadClass) ?
-                     MkExpCondition(MkExpBrackets(MkListOne(
-                        MkExpOp(
-                           MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
-                           OR_OP,
-                           MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
-                        // *((void **)array)
-                        MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
-                           CopyExpression(exp.op.exp2))))))),
+                           MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), CopyExpression(exp.op.exp2)))))),
 
                      // ((class.size == 1) ?
                      MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1244,7 +1298,7 @@ static void ProcessExpression(Expression exp)
 
                      // *((uint64 *)array)
                      MkExpOp(null, '*', MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
-                        exp.op.exp2)))))))))))))))))))));
+                        exp.op.exp2))))))))))))))))))));
 
                   // Add this to the context
                   thisClass = curExternal.function ? curExternal.function._class : null;
@@ -1316,7 +1370,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);
@@ -1347,20 +1400,9 @@ static void ProcessExpression(Expression exp)
                   exp.list = MkListOne(MkExpOp(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)),
                                  MkExpOp(null, '&', exp2)), '+',
                                     MkExpCall(MkExpIdentifier(MkIdentifier("__ENDIAN_PAD")),
-                                       MkListOne((e = MkExpCondition(MkExpBrackets(MkListOne(
-
-                              MkExpOp(
-                                 MkExpOp(
-                                    MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))),
-                                       OR_OP,
-                                       MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))),
-                                       OR_OP,
-                                       MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))))
-                             )),
-                           MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null), null)))),
-                           MkExpMember(classExp, MkIdentifier("typeSize"))))))));
+                                       MkListOne((e = MkExpMember(classExp, MkIdentifier("typeSize")))))));
 
-                  // Add this to the context
+                                             // Add this to the context
                   thisClass = curExternal.function ? curExternal.function._class : null;
                   {
                      /*Symbol thisSymbol
@@ -1465,19 +1507,9 @@ static void ProcessExpression(Expression exp)
                   // ((class.type == structClass) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("structClass"))))),
                      // ((byte *)array) + (i) * class.size
-                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpBrackets(MkListOne(MkExpOp(
+                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(MkExpOp(
                         MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), CopyExpression(exp.index.exp)))), '+',
-                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp))))))),
-
-                  // ((class.type == normalClass || class.type == noHeadClass) ?
-                  MkExpCondition(MkExpBrackets(MkListOne(
-                     MkExpOp(
-                        MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass"))),
-                        OR_OP,
-                        MkExpOp(MkExpMember(classExp, MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass")))))),
-                     // ((void **)array)[i]
-                     MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), null), MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, MkPointer(null, null)), null)),
-                        CopyExpression(exp.index.exp)))), CopyList(exp.index.index, CopyExpression)))),
+                        MkExpOp(MkExpBrackets(CopyList(exp.index.index, CopyExpression)), '*', CopyExpression(sizeExp)))))))),
 
                   // ((class.size == 1) ?
                   MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(CopyExpression(sizeExp), EQ_OP, MkExpConstant("1")))),
@@ -1499,7 +1531,7 @@ static void ProcessExpression(Expression exp)
 
                   // ((uint64 *)array)[i]
                   MkExpIndex(MkExpBrackets(MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uint64")), MkDeclaratorPointer(MkPointer(null, null), null)),
-                     exp.index.exp))), exp.index.index))))))))))))))))));
+                     exp.index.exp))), exp.index.index)))))))))))))))));
 
                // Add this to the context
                thisClass = curExternal.function ? curExternal.function._class : null;
@@ -1611,10 +1643,14 @@ static void ProcessExpression(Expression exp)
          bool typedObject = false;
          Type ellipsisDestType = null;
          bool usedEllipsis = false;
+         Expression expCallExp = exp.call.exp;
+         OldList * arguments = exp.call.arguments;
+         bool handleNullVMethod = false;
+         TypeName typeName = null;
 
-         if(exp.call.arguments)
+         if(arguments)
          {
-            for(e = exp.call.arguments->first; e; e = e.next)
+            for(e = arguments->first; e; e = e.next)
             {
                e.usage.usageGet = true;
                e.usage.usageArg = true;
@@ -1623,24 +1659,23 @@ static void ProcessExpression(Expression exp)
                exp.tempCount = Max(exp.tempCount, e.tempCount);
             }
          }
-         exp.call.exp.usage.usageGet = true;
-         exp.call.exp.usage.usageCall = true;
-         exp.call.exp.tempCount = exp.tempCount;
+         expCallExp.usage.usageGet = true;
+         expCallExp.usage.usageCall = true;
+         expCallExp.tempCount = exp.tempCount;
 
-         ProcessExpression(exp.call.exp);
+         ProcessExpression(expCallExp);
 
-         if(exp.call.exp.expType && exp.call.exp.expType.kind == methodType)
+         if(expCallExp.expType && expCallExp.expType.kind == methodType)
          {
             bool nullMemberExp = false;
-            Expression memberExp = (exp.call.exp.type == ExpressionType::memberExp) ? exp.call.exp : null;
+            Expression memberExp = (expCallExp.type == ExpressionType::memberExp) ? expCallExp : 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;
+            Class _class = expCallExp.expType.methodClass;     // For Virtual Method
+            Class argClass = expCallExp.expType.methodClass;  // Class actually passed
+            Method method = expCallExp.expType.method;
             if(method.type == virtualMethod)
             {
                char name[1024];
-               TypeName typeName;
                Declarator decl;
                Context back;
                OldList * specs = MkList();
@@ -1649,7 +1684,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 +1725,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
                   {
@@ -1701,7 +1739,6 @@ static void ProcessExpression(Expression exp)
 
                typeName = MkTypeName(specs, decl);
 
-               // Added !exp.call.exp.expType.methodClass
                if(memberExp && memberExp.member.exp.expType)
                {
                   Type type = memberExp.member.exp.expType;
@@ -1747,9 +1784,9 @@ static void ProcessExpression(Expression exp)
                   Type type = memberExp ? memberExp.member.exp.expType : null;
                   Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null;
                   char className[1024];
-                  bool useInstance = false;
 
-                  if(!exp.call.exp.expType.methodClass && !_class && type && type.classObjectType)
+                  // Added !exp.call.exp.expType.methodClass
+                  if(!expCallExp.expType.methodClass && !_class && type && type.classObjectType)
                      strcpy(className, "class");
                   else
                   {
@@ -1764,35 +1801,38 @@ static void ProcessExpression(Expression exp)
                         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 &&
+                     if(cl.templateClass && !_class && expCallExp.expType._class && !expCallExp.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);
-                     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)
+                  if(type && type.kind == subClassType && !_class && !expCallExp.expType.methodClass && memberExp)
                   {
-                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                     expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
                         MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+
+                     handleNullVMethod = true;
                   }
-                  else if(_class || exp.call.exp.expType.methodClass || !memberExp ||
+                  else if(_class || expCallExp.expType.methodClass || !memberExp ||
                          !regClass || regClass.type != normalClass || !strcmp(regClass.dataTypeString, "char *"))
                   {
                      if(!memberExp)
-                        FreeExpression(exp.call.exp);
-                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                        FreeExpression(expCallExp);
+                     expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
                         MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+
+                     handleNullVMethod = true;
                   }
                   else
                   {
@@ -1800,25 +1840,31 @@ static void ProcessExpression(Expression exp)
                      // as opposed to the File class vTbl one
 
                      // ({ Instance __internal_ClassInst = e; __internal_ClassInst ? __internal_ClassInst._vTbl : __ecereClass_...; })
-                     Expression c;
+                     Expression vTblExp;
                      Context context = PushContext();
                      OldList * specs;
-                     c = MkExpExtensionCompound(MkCompoundStmt(
-                           MkListOne(MkDeclaration(
+                     OldList * declList = MkListOne(MkDeclaration(
                               (specs = MkListOne(MkSpecifierName("Instance"))),
                               MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internal_ClassInst")),
-                                 MkInitializerAssignment(CopyExpression(memberExp.member.exp)))))),
-                           MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
+                                 MkInitializerAssignment(CopyExpression(memberExp.member.exp))))));
+                     OldList * stmtList = MkListOne(MkExpressionStmt(MkListOne(MkExpCondition(
                               MkExpIdentifier(MkIdentifier("__internal_ClassInst")),
                               MkListOne(MkExpPointer(MkExpIdentifier(MkIdentifier("__internal_ClassInst")), MkIdentifier("_vTbl"))),
-                              MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))))));
+                              MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl"))))));
+
+                     vTblExp = MkExpExtensionCompound(MkCompoundStmt(declList, stmtList));
+
                      if(type.specConst)
                         specs->Insert(null, MkSpecifier(CONST));
-                     c.loc = exp.loc;
-                     c.compound.compound.context = context;
+
+                     vTblExp.loc = exp.loc;
+                     vTblExp.compound.compound.context = context;
                      PopContext(context);
-                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                        MkExpIndex(c, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+
+                     expCallExp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                        MkExpIndex(vTblExp, MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+
+                     handleNullVMethod = true;
                   }
                }
             }
@@ -1831,12 +1877,12 @@ static void ProcessExpression(Expression exp)
                strcat(name, method.name);
 
                if(!memberExp)
-                  FreeExpression(exp.call.exp);
-               exp.call.exp = MkExpIdentifier(MkIdentifier(name));
-               DeclareMethod(method, name);
+                  FreeExpression(expCallExp);
+               expCallExp = MkExpIdentifier(MkIdentifier(name));
+               DeclareMethod(curExternal, method, name);
                if(memberExp && memberExp.expType && method.dataType)
                {
-                  exp.call.exp.expType = method.dataType;
+                  expCallExp.expType = method.dataType;
                   method.dataType.refCount++;
                }
             }
@@ -1844,8 +1890,8 @@ static void ProcessExpression(Expression exp)
             {
                if(method.dataType && !method.dataType.staticMethod && !method.dataType.extraParam)
                {
-                  if(!exp.call.arguments)
-                     exp.call.arguments = MkList();
+                  if(!arguments)
+                     arguments = MkList();
 
                   // Testing this (COMMENTED OUT TESTING, CALLING METHODS ON ENUM/UNIT ADDED & IN FRONT OF VARIABLES
                   /*
@@ -1883,35 +1929,37 @@ 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)
                      {
                         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);
+                           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);
+                           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;
@@ -1946,7 +1994,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);
@@ -1956,9 +2010,10 @@ static void ProcessExpression(Expression exp)
                            {
                               parentExp.cast.exp = newExp;
                               // Add a dereference level here
-                              parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
+                              if(newExp.expType && newExp.expType.classObjectType)
+                                 parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
                            }
-                           if(typedObject && !memberExp.member.exp.expType.classObjectType)
+                           if(typedObject && !expType.classObjectType)
                            {
                               Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
                               FreeType((parentExp ? parentExp : newExp).expType);
@@ -1967,17 +2022,17 @@ static void ProcessExpression(Expression exp)
                               (parentExp ? parentExp : newExp).destType = destType;
                               if(checkedExp.expType) checkedExp.expType.refCount++;
                            }
-                           exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
+                           arguments->Insert(null, parentExp ? parentExp : newExp);
                         }
                         else
                         {
-                           exp.call.arguments->Insert(null, memberExp.member.exp);
+                           arguments->Insert(null, memberExp.member.exp);
                            nullMemberExp = true;
                         }
                      }
                      else
                      {
-                        exp.call.arguments->Insert(null, memberExp.member.exp);
+                        arguments->Insert(null, memberExp.member.exp);
                         nullMemberExp = true;
                      }
 
@@ -1995,11 +2050,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])
@@ -2026,12 +2080,12 @@ static void ProcessExpression(Expression exp)
                               if(type.specConst)
                                  specs->Insert(null, MkSpecifier(CONST));
 
-                              exp.call.arguments->Insert(null, c);
+                              arguments->Insert(null, c);
 
                               memberExpMemberExp = null; // We used this
                            }
                            else
-                              exp.call.arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
+                              arguments->Insert(null, MkExpIdentifier(MkIdentifier(className)));
                         }
                      }
 
@@ -2040,7 +2094,7 @@ static void ProcessExpression(Expression exp)
                   }
                   else
                   {
-                     exp.call.arguments->Insert(null, memberExp.member.exp);
+                     arguments->Insert(null, memberExp.member.exp);
                      nullMemberExp = true;
                   }
                }
@@ -2056,9 +2110,9 @@ static void ProcessExpression(Expression exp)
             }
          }
 
-         if(exp.call.arguments)
+         if(arguments)
          {
-            for(e = exp.call.arguments->first; e; e = e.next)
+            for(e = arguments->first; e; e = e.next)
             {
                Type destType = (e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : e.destType;
                //if(e.destType && e.destType.kind == classType && e.destType._class && !strcmp(e.destType._class.string, "class"))
@@ -2117,7 +2171,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)
@@ -2137,8 +2191,8 @@ static void ProcessExpression(Expression exp)
                            {
                               /*
                               Expression newExp = e.op.exp2;
-                              exp.call.arguments->Insert(e.prev, newExp);
-                              exp.call.arguments->Remove(e);
+                              arguments->Insert(e.prev, newExp);
+                              arguments->Remove(e);
                               e.op.exp2 = null;
                               FreeExpContents(e);
                               e = newExp;
@@ -2151,7 +2205,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))))));
@@ -2159,8 +2213,8 @@ static void ProcessExpression(Expression exp)
 
                               if(parentExp.type == callExp)
                               {
-                                 exp.call.arguments->Insert(e.prev, newExp);
-                                 exp.call.arguments->Remove(e);
+                                 arguments->Insert(e.prev, newExp);
+                                 arguments->Remove(e);
                                  e = newExp;
                               }
                               else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
@@ -2226,6 +2280,21 @@ static void ProcessExpression(Expression exp)
                                     PrintTypeNoConst(e.expType, typeString, false, true);
                                     decl = SpecDeclFromString(typeString, specs, null);
                                     newExp.destType = ProcessType(specs, decl);
+                                    if(newExp.destType && e.expType && e.expType.passAsTemplate)
+                                    {
+                                       Expression nbExp = GetNonBracketsExp(newExp);
+                                       if(nbExp.type == castExp)
+                                       {
+                                          // Because we're correcting this after the cast was added from the argument for loop at the beginning of this case block
+                                          // (CheckTemplateTypes() already called), we'll revert the cast to generic uint64 template type
+                                          FreeTypeName(nbExp.cast.typeName);
+                                          nbExp.cast.typeName = MkTypeName(MkListOne(MkSpecifierName("uint64")), null);
+                                       }
+
+                                       newExp.expType = newExp.destType;
+                                       newExp.destType.refCount++;
+                                       modifyPassAsTemplate(&newExp.expType, true);
+                                    }
 
                                     curContext = context;
                                     e.type = extensionCompoundExp;
@@ -2241,6 +2310,7 @@ static void ProcessExpression(Expression exp)
                                        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)))));
+                                       CheckTemplateTypes(newExp);
                                        e.compound = MkCompoundStmt(null, stmts);
                                     }
                                     else
@@ -2262,7 +2332,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,12 +2347,16 @@ 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);
+                                 arguments->Insert(e.prev, newExp);
+                                 arguments->Remove(e);
                                  e = newExp;
                               }
                               else if(parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp)
@@ -2318,12 +2392,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 *"))
@@ -2343,7 +2416,7 @@ static void ProcessExpression(Expression exp)
                               ((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)));
+                              arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
                            }
                            else
                            {
@@ -2363,11 +2436,11 @@ static void ProcessExpression(Expression exp)
                               if(type.specConst)
                                  specs->Insert(null, MkSpecifier(CONST));
 
-                              exp.call.arguments->Insert(e.prev, c);
+                              arguments->Insert(e.prev, c);
                            }
                         }
                         else
-                           exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
+                           arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
                      }
                   }
                }
@@ -2383,13 +2456,68 @@ static void ProcessExpression(Expression exp)
             if(ellipsisDestType)
             {
                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))
+                  (expCallExp.expType && expCallExp.expType.kind == functionType && expCallExp.expType.params.last &&
+                   ((Type)expCallExp.expType.params.last).kind == ellipsisType))
                {
-                  exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
+                  arguments->Insert(arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
                }
             }
          }
+
+         if(handleNullVMethod)
+         {
+            Expression compoundExp;
+            Context context = PushContext();
+            OldList * declList = MkList();
+            OldList * stmtList = MkList();
+            TypeName castTypeName;
+            OldList * specs = MkList();
+            Specifier spec;
+
+            for(spec = typeName.qualifiers ? typeName.qualifiers->first : null; spec; spec = spec.next)
+            {
+               if(spec.type != extendedSpecifier)
+                  specs->Add(CopySpecifier(spec));
+            }
+
+            if(typeName.declarator.type == pointerDeclarator)
+            {
+               Pointer p = typeName.declarator.pointer.pointer.pointer;
+               castTypeName = MkTypeName(specs, CopyDeclarator(typeName.declarator.declarator.declarator.declarator));
+               while(p)
+               {
+                  Pointer pp;
+                  for(pp = castTypeName.declarator.pointer.pointer; pp.pointer; pp = pp.pointer);
+                  pp.pointer = MkPointer(null, null);
+                  pp.qualifiers = CopyList(p.qualifiers, CopySpecifier);
+                  p = p.pointer;
+               }
+            }
+            else
+               castTypeName = MkTypeName(specs, CopyDeclarator(typeName.declarator.declarator.declarator.declarator));
+
+            compoundExp = MkExpExtensionCompound(MkCompoundStmt(declList, stmtList));
+
+            declList->Add(MkDeclaration(CopyList(typeName.qualifiers, CopySpecifier),
+               MkListOne(MkInitDeclarator(PlugDeclarator(CopyDeclarator(typeName.declarator), MkDeclaratorIdentifier(MkIdentifier("__internal_VirtualMethod"))), null))));
+
+            stmtList->Add(MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")), '=', expCallExp))));
+            stmtList->Add(MkExpressionStmt(MkListOne(MkExpCondition(
+               MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")),
+               MkListOne(MkExpCall(MkExpIdentifier(MkIdentifier("__internal_VirtualMethod")), arguments)), MkExpCast(castTypeName, MkExpConstant("1"))))));
+
+            compoundExp.loc = exp.loc;
+            compoundExp.compound.compound.context = context;
+            PopContext(context);
+
+            exp.type = bracketsExp;
+            exp.list = MkListOne(compoundExp);
+         }
+         else
+         {
+            exp.call.exp = expCallExp;
+            exp.call.arguments = arguments;
+         }
          break;
       }
       case memberExp:
@@ -2502,12 +2630,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 +2698,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));
@@ -2650,15 +2778,30 @@ 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);
+                     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(exp.call.arguments, MkExpString(s));
+                        ListAdd(args, MkExpString(s));
                         delete s;
                      }
                      FreeIdentifier(id);
@@ -2695,11 +2838,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"));
@@ -2715,7 +2857,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
                   {
@@ -2726,7 +2868,7 @@ static void ProcessExpression(Expression exp)
                      strcat(name, "_");
                      strcat(name, method.name);
                      exp.identifier = MkIdentifier(name);
-                     DeclareMethod(method, name);
+                     DeclareMethod(curExternal, method, name);
                   }
                }
             }
@@ -2777,7 +2919,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)
@@ -2832,21 +2974,19 @@ static void ProcessExpression(Expression exp)
                   else
                   {
                      Expression bytePtr, e;
-                     Expression classExp;
                      Expression checkedExp;
                      char structName[1024];
                      char className[1024];
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, member._class.fullName, true);
-                     MangleClassName(className);
 
                      // classExp = QMkExpId(className);
 
                      if(!member._class.symbol)
                         member._class.symbol = FindClass(member._class.fullName);
 
-                     DeclareClass(member._class.symbol, className);
-                     DeclareStruct(member._class.fullName, false);
+                     DeclareClass(curExternal, member._class.symbol, className);
+                     DeclareStruct(curExternal, member._class.fullName, false, true);
 
                      structName[0] = 0;
                      FullClassNameCat(structName, member._class.fullName, false);
@@ -2878,14 +3018,27 @@ static void ProcessExpression(Expression exp)
                         compound = MkCompoundStmt(
                            MkListOne(MkDeclaration(MkListOne(MkSpecifier(CHAR)), MkListOne(MkInitDeclarator(
                               MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier(ecereTemp))),
-                                 MkInitializerAssignment(QBrackets(exp.member.exp)))))), null);
+                                 MkInitializerAssignment(MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null, null), null)), QBrackets(exp.member.exp))))))), null);
                         if(member._class.fixed)
                         {
-                           if(member._class.templateClass ? member._class.templateClass.offset : member._class.offset)
+                           Class c = member._class.templateClass ? member._class.templateClass : member._class;
+                           if(c.offset)
                            {
-                              char string[256];
-                              sprintf(string, "%d", member._class.templateClass ? member._class.templateClass.offset : member._class.offset);
-                              e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', MkExpConstant(string)));
+                              Expression se;
+
+                              if(c.offset == c.base.structSize)
+                              {
+                                 se = MkExpClassSize(MkSpecifierName(c.base.fullName));
+                                 ProcessExpressionType(se);
+                                 se.isConstant = false;
+                              }
+                              else
+                              {
+                                 char string[256];
+                                 sprintf(string, "%d", c.offset);
+                                 se = MkExpConstant(string);
+                              }
+                              e = QBrackets(MkExpOp(QMkExpId(ecereTemp), '+', se));
                            }
                            else
                               e = QMkExpId(ecereTemp);
@@ -2919,11 +3072,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;
@@ -2992,20 +3159,7 @@ static void ProcessExpression(Expression exp)
                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);
@@ -3043,9 +3197,12 @@ static void ProcessExpression(Expression exp)
             if(!e.next && exp.usage.usageGet) e.usage.usageGet = true;
             ProcessExpression(e);
          }
-         if(exp.usage.usageGet)
-            exp.cond.elseExp.usage.usageGet = true;
-         ProcessExpression(exp.cond.elseExp);
+         if(exp.cond.elseExp)
+         {
+            if(exp.usage.usageGet)
+               exp.cond.elseExp.usage.usageGet = true;
+            ProcessExpression(exp.cond.elseExp);
+         }
          break;
       }
       case classExp:
@@ -3079,8 +3236,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);
@@ -3104,6 +3261,92 @@ static void ProcessExpression(Expression exp)
       }
    }
    FixRefExp(exp);
+
+   if(exp.needTemplateCast != 2 && (exp.needTemplateCast == 1 || (exp.expType && (exp.expType.kind == templateType || exp.expType.passAsTemplate))))
+   {
+      Expression nbExp = GetNonBracketsExp(exp);
+      Expression inner = GetInnerExp(nbExp);
+
+      if((!exp.expType || exp.expType.kind != templateType || nbExp.type != castExp) && !exp.usage.usageRef &&
+         (!exp.destType || (!exp.destType.truth && (exp.destType.kind != templateType || (exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType))))) &&
+         (exp.usage.usageDelete || exp.usage.usageGet || exp.usage.usageArg) &&
+         (!exp.destType || (!exp.destType.passAsTemplate && exp.expType && (exp.expType.kind != pointerType || (exp.destType.kind == pointerType || exp.destType.kind == intPtrType)) && ((exp.destType.kind != pointerType && exp.destType.kind != intPtrType) || exp.expType.kind == pointerType))) &&
+         !inner.needCast && inner.type != opExp)
+      {
+         Expression e = MoveExpContents(exp);
+         Declarator decl;
+         OldList * specs = MkList();
+         char typeString[1024];
+         bool castingToDest = false;
+         bool pointerCastExp = false;
+
+         typeString[0] = '\0';
+
+         e.needTemplateCast = 2;
+         inner.needTemplateCast = 2;
+         nbExp.needTemplateCast = 2;
+         if(exp.usage.usageDelete)
+            strcpy(typeString, "void *");
+         else
+         {
+            if(exp.expType.kind == templateType && exp.expType.templateParameter && exp.expType.templateParameter.dataTypeString)
+               strcpy(typeString, exp.expType.templateParameter.dataTypeString);
+            else
+               PrintType(exp.expType, typeString, false, false);
+         }
+
+         decl = SpecDeclFromString(typeString, specs, null);
+
+         if(specs && specs->first && ((Specifier)specs->first).type == templateTypeSpecifier &&
+            exp.destType && !exp.destType.passAsTemplate && exp.destType.kind == templateType && exp.destType.templateParameter && (exp.destType.templateParameter.dataTypeString || exp.destType.templateParameter.dataType) && !exp.usage.usageArg)
+         {
+            if(decl) FreeDeclarator(decl);
+            FreeList(specs, FreeSpecifier);
+            if(exp.destType.templateParameter.dataTypeString)
+            {
+               specs = MkList();
+               strcpy(typeString, exp.destType.templateParameter.dataTypeString);
+               decl = SpecDeclFromString(typeString, specs, null);
+            }
+            else
+            {
+               specs = CopyList(exp.destType.templateParameter.dataType.specifiers, CopySpecifier);
+               decl = CopyDeclarator(exp.destType.templateParameter.dataType.decl);
+            }
+
+            castingToDest = true;
+         }
+
+         e.destType = exp.destType;
+         if(exp.destType)
+            exp.destType.refCount++;
+
+         exp.type = bracketsExp;
+
+         {
+            Specifier spec = specs ? specs->first : null;
+            TemplateParameter tp = (spec && spec.type == templateTypeSpecifier) ? spec.templateParameter : null;
+            Type type = castingToDest ? exp.destType : exp.expType;
+            bool specsDeclPointer = (spec.type == nameSpecifier && strcmp(spec.name, "uint64")) ||
+               (decl && decl.type == pointerDeclarator) ||
+               (tp && tp.dataType &&
+                  ( (tp.dataType.decl && tp.dataType.decl.type == pointerDeclarator) ||
+                    (tp.dataType.specifiers && ((Specifier)tp.dataType.specifiers->first).type == nameSpecifier && strcmp(((Specifier)tp.dataType.specifiers->first).name, "uint64")) ) );
+            pointerCastExp = type ? ((type.kind == templateType && specsDeclPointer) || type.isPointerType) : specsDeclPointer;
+         }
+
+         if(pointerCastExp)
+         {
+            e = MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), null), MkExpBrackets(MkListOne(e)));
+            e.needTemplateCast = 2;
+         }
+         exp.list = MkListOne(MkExpCast(MkTypeName(specs, decl), MkExpBrackets(MkListOne(e))));
+         if(exp.destType && pointerCastExp == (exp.destType.passAsTemplate ||
+            (!exp.destType.isPointerType || (exp.destType.kind == templateType && (!exp.destType.templateParameter || (!exp.destType.templateParameter.dataType && !exp.destType.templateParameter.dataTypeString))))))
+            exp.list = MkListOne(MkExpCast(MkTypeName(MkListOne(MkSpecifierName("uintptr")), decl), MkExpBrackets(exp.list)));
+         exp.needTemplateCast = 2;
+      }
+   }
    yylloc = oldyylloc;
 }
 
@@ -3418,14 +3661,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;