wip II
[sdk] / compiler / libec / src / pass2.ec
index 43e6ac6..37b9fd6 100644 (file)
@@ -96,15 +96,12 @@ static Expression FixReference(Expression e, bool wantReference)
          Class _class = type._class ? type._class.registered : null;
          // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
          // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
-         if(_class && (_class.type == structClass || _class.type == noHeadClass || 
+         if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass || 
            (_class.type == systemClass && _class.base && 
            strcmp(_class.fullName, "uintptr") && 
            strcmp(_class.fullName, "intptr") && 
            strcmp(_class.fullName, "uintsize") && 
-           strcmp(_class.fullName, "intsize") && 
-           strcmp(_class.fullName, "ecere::com::Instance") && 
-           strcmp(_class.fullName, "ecere::com::Class") && 
-           strcmp(_class.dataTypeString, "char *"))))
+           strcmp(_class.fullName, "intsize"))))
          {
             // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
             if(wantReference != (e.byReference || isPointer))
@@ -979,10 +976,8 @@ static void ProcessExpression(Expression exp)
             // TOFIX: Same time as when we fix for = 0
 
             if(exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered && 
-               ((exp.expType._class.registered.type == normalClass && 
-                  // TODO: Improve on this, only fixed this issue here... Different String class defined in each module
-                  !eClass_IsDerived(exp.expType._class.registered, eSystem_FindClass(exp.expType._class.registered.module, "char *")) /*strcmp(exp.expType._class.string, "String")*/) ||
-                (exp.expType._class.registered.type == systemClass && !strcmp(exp.expType._class.string, "ecere::com::Instance"))))
+               exp.expType._class.registered.type == normalClass &&
+               strcmp(exp.expType._class.registered.dataTypeString, "char *"))
             {
                Expression decRefExp = MkExpCall(QMkExpId("ecere::com::eInstance_DecRef"), args);
                ProcessExpressionType(decRefExp);
@@ -1672,9 +1667,10 @@ static void ProcessExpression(Expression exp)
 
                   if(type.kind == classType && type._class && type._class.registered)
                   {
-                     ClassType classType = memberExp.member.exp.expType._class.registered.type;
-                     if(classType != normalClass || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
-                        argClass = type._class.registered;
+                     Class regClass = type._class.registered;
+                     ClassType classType = regClass.type;
+                     if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
+                        argClass = regClass;
                   }
                   else if(type.kind == subClassType)
                   {
@@ -1689,7 +1685,7 @@ static void ProcessExpression(Expression exp)
                      argClass = eSystem_FindClass(privateModule, "uintptr");
                      FreeType(memberExp.member.exp.expType);
                      memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
-                     memberExp.member.exp.byReference = false;
+                     memberExp.member.exp.byReference = true;
                   }
                   else
                   {
@@ -1706,60 +1702,62 @@ static void ProcessExpression(Expression exp)
                   */
                }
 
-               // *** Added !_class here
-               if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType)
                {
-                  if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
-                     memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)
+                  Type type = memberExp ? memberExp.member.exp.expType : null;
+                  Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null; 
+                  // *** Added !_class here
+                  if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && type && type.classObjectType)
                   {
-                     // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
-                     // as opposed to the File class vTbl one
-                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                        MkExpIndex(MkExpPointer(MkExpBrackets(MkListOne(CopyExpression(memberExp.member.exp))), MkIdentifier("_vTbl")),
-                        MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                     if(regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))
+                     {
+                        // TOCHECK: Added this if statement here for File::OnSerialize to be calling the instance's own Seek function,
+                        // as opposed to the File class vTbl one
+                        exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                           MkExpIndex(MkExpPointer(MkExpBrackets(MkListOne(CopyExpression(memberExp.member.exp))), MkIdentifier("_vTbl")),
+                           MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                     }
+                     else
+                     {
+                        exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                           MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl")),
+                           MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                     }
                   }
-                  else
+                  else if(memberExp && !_class && exp.call.exp.expType._class &&
+                        (type.kind == subClassType || (regClass && regClass.type == normalClass && strcmp(regClass.dataTypeString, "char *"))))
                   {
                      exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                        MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier("class")), MkIdentifier("_vTbl")),
+                        MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
                         MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
                   }
-               }
-               else if(memberExp && !_class && exp.call.exp.expType._class &&
-                     (memberExp.member.exp.expType.kind == subClassType || (memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
-                     memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)))
-               {
-                  exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                     MkExpIndex(MkExpPointer(CopyExpression(memberExp.member.exp), MkIdentifier("_vTbl")),
-                     MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
-               }
-               else 
-               {
-                  char className[1024];
+                  else 
+                  {
+                     char className[1024];
 
-                  // TESTING: Moved this here...
-                  if(!_class && argClass && strcmp(argClass.fullName, "class"))
-                     _class = argClass;
+                     // TESTING: Moved this here...
+                     if(!_class && argClass && strcmp(argClass.fullName, "class"))
+                        _class = argClass;
 
-                  if(!_class)
-                  {
-                     // TODO: Unhandled case here, what should happen?
-                     _class = class(int);
-                  }
+                     if(!_class)
+                     {
+                        // TODO: Unhandled case here, what should happen?
+                        _class = class(int);
+                     }
 
-                  // Need the class itself here...
-                  strcpy(className, "__ecereClass_");
-                  FullClassNameCat(className, _class.fullName, true);
-                  MangleClassName(className);
+                     // Need the class itself here...
+                     strcpy(className, "__ecereClass_");
+                     FullClassNameCat(className, _class.fullName, true);
+                     MangleClassName(className);
 
-                  if(!_class.symbol)
-                     _class.symbol = FindClass(_class.fullName);
+                     if(!_class.symbol)
+                        _class.symbol = FindClass(_class.fullName);
 
-                  DeclareClass(_class.symbol, className);
+                     DeclareClass(_class.symbol, className);
 
-                  exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
-                     MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
-                     MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                     exp.call.exp = MkExpBrackets(MkListOne(MkExpCast(typeName,
+                        MkExpIndex(MkExpPointer(MkExpIdentifier(MkIdentifier(className)), MkIdentifier("_vTbl")),
+                        MkListOne(MkExpIdentifier(MkIdentifier(name)))))));
+                  }
                }
             }
             else
@@ -1824,7 +1822,7 @@ static void ProcessExpression(Expression exp)
 
                      // 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, "ecere::com::Class"))
+                        strcmp(argClass.fullName, "uintptr") && strcmp(argClass.fullName, "intptr"))
                         changeReference = true;
                      if(!memberExp.member.exp.expType.classObjectType && 
                         (((
@@ -1862,7 +1860,7 @@ static void ProcessExpression(Expression exp)
                               else if(checkedExp.type == castExp)
                                  checkedExp = checkedExp.cast.exp;
                            }
-                           newExp = MkExpOp(null, '&', checkedExp);
+                           newExp = (typedObject && !memberExp.member.exp.expType.classObjectType) ? checkedExp : MkExpOp(null, '&', checkedExp);
                            if(parentExp && (parentExp.type == bracketsExp || parentExp.type == extensionExpressionExp))
                            {
                               parentExp.list->Remove(checkedExp);
@@ -1874,6 +1872,13 @@ static void ProcessExpression(Expression exp)
                               // Add a dereference level here
                               parentExp.cast.typeName.declarator = MkDeclaratorPointer(MkPointer(null, null), parentExp.cast.typeName.declarator);
                            }
+                           if(typedObject && !memberExp.member.exp.expType.classObjectType)
+                           {
+                              Type destType { refCount = 1, kind = classType, classObjectType = ClassObjectType::anyObject };
+                              (parentExp ? parentExp : newExp).expType = checkedExp.expType;
+                              (parentExp ? parentExp : newExp).destType = destType;
+                              if(checkedExp.expType) checkedExp.expType.refCount++;
+                           }
                            exp.call.arguments->Insert(null, parentExp ? parentExp : newExp);
                         }
                         else
@@ -1950,6 +1955,8 @@ static void ProcessExpression(Expression exp)
                         _class = eSystem_FindClass(privateModule, "uintptr");
                         FreeType(e.expType);
                         e.expType = ProcessTypeString("uintptr", false);
+                        // Assume null pointers means 'no object' rather than an object holding a null pointer
+                        e.byReference = true;
                      }
                      else
                      {
@@ -1961,8 +1968,8 @@ static void ProcessExpression(Expression exp)
                         // if(!class) _class = eSystem_FindClass(privateModule, "int");
                      }
 
-                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
+                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
+                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
                         destType.byReference)))
                      {
                         //if(!_class || strcmp(_class.fullName, "String"))     // TESTING THIS WITH NEW String class...
@@ -2167,23 +2174,30 @@ static void ProcessExpression(Expression exp)
                            _class = eSystem_FindClass(privateModule, "String");
                         if(!_class) _class = eSystem_FindClass(privateModule, "int");
 
-                        if(!strcmp(_class.name, "class"))
+                        if(_class.type == normalClass && destType.byReference == false && strcmp(_class.dataTypeString, "char *"))
                         {
-                           // Already inside a typed_object function, pass the class through
-                           strcpy(className, "class");
+                           exp.call.arguments->Insert(e.prev, MkExpPointer(CopyExpression(e), MkIdentifier("_class")));
                         }
                         else
                         {
-                           strcpy(className, "__ecereClass_");
-                           FullClassNameCat(className, _class.fullName, true);
-                           MangleClassName(className);
+                           if(!strcmp(_class.name, "class"))
+                           {
+                              // Already inside a typed_object function, pass the class through
+                              strcpy(className, "class");
+                           }
+                           else
+                           {
+                              strcpy(className, "__ecereClass_");
+                              FullClassNameCat(className, _class.fullName, true);
+                              MangleClassName(className);
 
-                           if(!_class.symbol)
-                              _class.symbol = FindClass(_class.fullName);
+                              if(!_class.symbol)
+                                 _class.symbol = FindClass(_class.fullName);
 
-                           DeclareClass(_class.symbol, className);
+                              DeclareClass(_class.symbol, className);
+                           }
+                           exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
                         }
-                        exp.call.arguments->Insert(e.prev, MkExpIdentifier(MkIdentifier(className)));
                      }
                   }
                }
@@ -2193,7 +2207,7 @@ static void ProcessExpression(Expression exp)
                   //PrintExpression(e, debugString);
 #endif
                   // If expression type is a simple class, make it an address
-                  FixReference(e, true);
+                  FixReference(e, !destType || !destType.declaredWithStruct);
                }
             }
             if(ellipsisDestType)
@@ -2212,7 +2226,7 @@ static void ProcessExpression(Expression exp)
       {
          bool changeToPtr = false;
          bool noHead = false;
-         Type type = exp.member.exp.expType;
+         Type type = exp.member.exp ? exp.member.exp.expType : null;
          Specifier memberClassSpecifier = exp.member.member ? exp.member.member._class : null;
          if(exp.member.member) exp.member.member._class = null;
 
@@ -2592,13 +2606,14 @@ static void ProcessExpression(Expression exp)
                else
                {
                   // If it's a this pointer, replace by precomputed shortcut
-                  if(thisPtr)
+                  if(exp.member.exp.type == identifierExp && thisPtr && (!exp.member.exp.expType || !exp.member.exp.expType.typedByReference))
                   {
                      char pointerName[1024];
 
                      strcpy(pointerName, "__ecerePointer_");
                      FullClassNameCat(pointerName, type._class.registered.fullName, false);
-                     FreeIdentifier(exp.member.exp.identifier);
+                     if(exp.member.exp.identifier)
+                        FreeIdentifier(exp.member.exp.identifier);
                      exp.member.exp.identifier = MkIdentifier(pointerName);
                   }
                   // Otherwise, access the data the hard way
@@ -2718,7 +2733,7 @@ static void ProcessExpression(Expression exp)
          FreeSpecifier(memberClassSpecifier);
 
          // Just moved this at the end... How is it?
-         if(exp.type == memberExp || exp.type == pointerExp)
+         if(exp.member.exp && (exp.type == memberExp || exp.type == pointerExp))
          {
             exp.member.exp.usage.usageGet = true;
             exp.member.exp.usage.usageMember = true;
@@ -2732,8 +2747,9 @@ static void ProcessExpression(Expression exp)
       }
       case extensionCompoundExp:
       {
-         ((Expression)((Statement)exp.compound.compound.statements->last).expressions->last).usage |= exp.usage & 
-            ExpUsage { usageGet = true, usageArg = true, usageMember = true };
+         Expression e = ((Statement)exp.compound.compound.statements->last).expressions->last;
+         if(e)
+            e.usage |= exp.usage & ExpUsage { usageGet = true, usageArg = true, usageMember = true };
 
          ProcessStatement(exp.compound);
 
@@ -2843,11 +2859,12 @@ static void ProcessExpression(Expression exp)
          {
             char className[1024];
             char * string = StringFromSpecDecl(exp._classExp.specifiers, exp._classExp.decl);
+            Symbol classSym = FindClass(string);
             
             strcpy(className, "__ecereClass_");
             FullClassNameCat(className, string, true);      // TODO: Verify this
             MangleClassName(className);
-            DeclareClass(FindClass(string), className);
+            DeclareClass(classSym, className);
             delete string;
 
             FreeList(exp._classExp.specifiers, FreeSpecifier);