wip II
[sdk] / compiler / libec / src / pass2.ec
index a751815..37b9fd6 100644 (file)
@@ -38,7 +38,7 @@ static void _FixRefExp(Expression * expPtr, Expression * memberExpPtr)
          exp.list->Add(newExp);
          FreeExpression(bracketExp);
 
-         *expPtr = newExp; //FixRefExp(newExp);
+         *expPtr = exp; //FixRefExp(newExp);      // TESTING THIS: exp was not used!
       }
    }
    else if(*expPtr && (*expPtr).type == opExp && (*expPtr).op.op == '&' && !(*expPtr).op.exp1 &&
@@ -95,11 +95,13 @@ static Expression FixReference(Expression e, bool wantReference)
       {
          Class _class = type._class ? type._class.registered : null;
          // TOLOOKINTO: What was systemClass used for here? Exclude "typed_object"...
-         if(_class && (_class.type == structClass || _class.type == noHeadClass || 
+         // TOFIX: In which case with systemClass do we actually want this to come here? Can't think of any!
+         if(_class && ((_class.type == structClass && !type.declaredWithStruct) || _class.type == noHeadClass || 
            (_class.type == systemClass && _class.base && 
-           strcmp(_class.fullName, "ecere::com::Instance") && 
-           strcmp(_class.fullName, "ecere::com::Class") && 
-           strcmp(_class.dataTypeString, "char *"))))
+           strcmp(_class.fullName, "uintptr") && 
+           strcmp(_class.fullName, "intptr") && 
+           strcmp(_class.fullName, "uintsize") && 
+           strcmp(_class.fullName, "intsize"))))
          {
             // if(wantReference != ((_class.type == systemClass) ? false : e.byReference))
             if(wantReference != (e.byReference || isPointer))
@@ -707,7 +709,7 @@ static void ProcessExpression(Expression exp)
                               exp.call.arguments = MkList();
                               ListAdd(exp.call.arguments, classExp);
                               ListAdd(exp.call.arguments, MkExpString(QMkString(id.string)));
-                              ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT)), null), value));
+                              ListAdd(exp.call.arguments, MkExpCast(MkTypeName(MkListOne(MkSpecifier(INT64)), null), value));
 
                               FreeIdentifier(id);
 
@@ -974,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);
@@ -1663,83 +1663,101 @@ static void ProcessExpression(Expression exp)
                // Added !exp.call.exp.expType.methodClass
                if(memberExp && memberExp.member.exp.expType)
                {
-                  if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class && memberExp.member.exp.expType._class.registered)
+                  Type type = memberExp.member.exp.expType;
+
+                  if(type.kind == classType && type._class && type._class.registered)
+                  {
+                     Class regClass = type._class.registered;
+                     ClassType classType = regClass.type;
+                     if(classType != normalClass || !strcmp(regClass.dataTypeString, "char *") || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
+                        argClass = regClass;
+                  }
+                  else if(type.kind == subClassType)
+                  {
+                     argClass = FindClass("ecere::com::Class").registered;
+                  }
+                  else if((type.kind == arrayType || type.kind == pointerType) && type.type && type.type.kind == charType)
                   {
-                     ClassType type = memberExp.member.exp.expType._class.registered.type;
-                     if(type != normalClass || (method.dataType.byReference))// TESTING THIS OUT: && !memberExp.member.exp.expType.classObjectType)
-                        argClass = memberExp.member.exp.expType._class.registered;
+                     argClass = FindClass("char *").registered;
+                  }
+                  else if(type.kind == pointerType)
+                  {
+                     argClass = eSystem_FindClass(privateModule, "uintptr");
+                     FreeType(memberExp.member.exp.expType);
+                     memberExp.member.exp.expType = ProcessTypeString("uintptr", false);
+                     memberExp.member.exp.byReference = true;
                   }
                   else
                   {
-                     switch(memberExp.member.exp.expType.kind)
-                     {
-                        case intType:
-                        {
-                           argClass = eSystem_FindClass(privateModule, "int");
-                           break;
-                        }
-                     }
+                     char string[1024] = "";
+                     Symbol classSym;
+                     PrintTypeNoConst(type, string, false, true);
+                     classSym = FindClass(string);
+                     if(classSym) argClass = classSym.registered;
                   }
+
                   /*
                   if(!_class && argClass && strcmp(argClass.fullName, "class"))
                      _class = argClass;
                   */
                }
 
-               // *** Added !_class here
-               if(!exp.call.exp.expType.methodClass && (!memberExp || !_class) && memberExp.member.exp.expType && memberExp.member.exp.expType.classObjectType)
                {
-                  if(memberExp.member.exp.expType.kind == classType && memberExp.member.exp.expType._class &&
-                     memberExp.member.exp.expType._class.registered && memberExp.member.exp.expType._class.registered.type == normalClass)
+                  Type type = memberExp ? memberExp.member.exp.expType : null;
+                  Class regClass = (type && type.kind == classType && type._class) ? type._class.registered : null; 
+                  // *** 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
@@ -1800,16 +1818,30 @@ static void ProcessExpression(Expression exp)
                   
                   if(typedObject && memberExp.member.exp && memberExp.member.exp.expType)
                   {
-                     if(
-                        (argClass && (argClass.type == enumClass || argClass.type == unitClass || argClass.type == bitClass || argClass.type == systemClass) && strcmp(argClass.fullName, "class") && strcmp(argClass.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-                        (!memberExp.member.exp.expType.classObjectType && 
+                     bool changeReference = false;
+
+                     // 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
+                           (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
+                        changeReference = true;
+                     if(typedObject && memberExp.member.exp.expType.classObjectType && memberExp.member.exp.expType.byReference != method.dataType.byReference)
+                        changeReference = true;
+                     if(changeReference)
                      {
-                        if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
+                        if(memberExp.member.exp.type == bracketsExp && memberExp.member.exp.list && memberExp.member.exp.list->count == 1 && 
+                           ((Expression)memberExp.member.exp.list->first).type == opExp && ((Expression)memberExp.member.exp.list->first).op.op == '*' && !((Expression)memberExp.member.exp.list->first).op.exp1)
+                        {
+                           exp.call.arguments->Insert(null, ((Expression)memberExp.member.exp.list->first).op.exp2);
+                           ((Expression)memberExp.member.exp.list->first).op.exp2 = null;
+                        }
+                        else if(memberExp.member.exp.type == opExp && memberExp.member.exp.op.op == '*' && !memberExp.member.exp.op.exp1)
                         {
                            exp.call.arguments->Insert(null, memberExp.member.exp.op.exp2);
                            memberExp.member.exp.op.exp2 = null;
@@ -1828,15 +1860,25 @@ 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);
                               parentExp.list->Add(newExp);
                            }
                            else if(parentExp && parentExp.type == castExp)
+                           {
                               parentExp.cast.exp = newExp;
-
+                              // 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
@@ -1908,19 +1950,26 @@ static void ProcessExpression(Expression exp)
                      {
                         _class = FindClass("char *").registered;
                      }
+                     else if(type.kind == pointerType)
+                     {
+                        _class = eSystem_FindClass(privateModule, "uintptr");
+                        FreeType(e.expType);
+                        e.expType = ProcessTypeString("uintptr", false);
+                        // Assume null pointers means 'no object' rather than an object holding a null pointer
+                        e.byReference = true;
+                     }
                      else
                      {
                         char string[1024] = "";
                         Symbol classSym;
-
-                        PrintType(type, string, false, true);
+                        PrintTypeNoConst(type, string, false, true);
                         classSym = FindClass(string);
                         if(classSym) _class = classSym.registered;
                         // if(!class) _class = eSystem_FindClass(privateModule, "int");
                      }
 
-                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
+                     if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
+                        (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && type.kind != arrayType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
                         destType.byReference)))
                      {
                         //if(!_class || strcmp(_class.fullName, "String"))     // TESTING THIS WITH NEW String class...
@@ -2039,7 +2088,7 @@ static void ProcessExpression(Expression exp)
                                     newExp.next = null;
                                     newExp.expType = null;
 
-                                    PrintType(e.expType, typeString, false, true);
+                                    PrintTypeNoConst(e.expType, typeString, false, true);
                                     decl = SpecDeclFromString(typeString, specs, null);
                                     newExp.destType = ProcessType(specs, decl);
 
@@ -2125,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)));
                      }
                   }
                }
@@ -2151,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)
@@ -2160,7 +2216,7 @@ static void ProcessExpression(Expression exp)
                   (exp.call.exp.expType && exp.call.exp.expType.kind == functionType && exp.call.exp.expType.params.last && 
                    ((Type)exp.call.exp.expType.params.last).kind == ellipsisType))
                {
-                  exp.call.arguments->Insert(exp.call.arguments->last, MkExpConstant("0"));
+                  exp.call.arguments->Insert(exp.call.arguments->last, MkExpCast(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(MkPointer(null, null),null)),MkExpConstant("0")));
                }
             }
          }
@@ -2170,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;
 
@@ -2198,7 +2254,7 @@ static void ProcessExpression(Expression exp)
                // DANGER: Buffer overflow
                char string[2048] = "";
                Symbol classSym;
-               PrintType(type, string, false, true);
+               PrintTypeNoConst(type, string, false, true);
                classSym = FindClass(string);
                _class = classSym ? classSym.registered : null;
             }
@@ -2550,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
@@ -2676,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;
@@ -2690,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);
 
@@ -2801,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);
@@ -3033,6 +3092,9 @@ static void ProcessStatement(Statement stmt)
             for(exp = stmt.expressions->first; exp; exp = exp.next)
             {
                ProcessExpression(exp);
+               // TOCHECK: This was added 2013/02/09 as part of 64 bit port for structs in class properties to automatically be returned by reference
+               if(!exp.next && exp.destType && exp.destType.byReference)
+                  FixReference(exp, true);
             }
          }
          break;
@@ -3071,26 +3133,7 @@ static void ProcessStatement(Statement stmt)
 static void ProcessFunction(FunctionDefinition function)
 {
    if(function.body)
-   {
       ProcessStatement(function.body);
-      if(function.tempCount)
-      {
-         Statement stmt = function.body;
-         int c;
-         // Declare ecereTemp here, we need it!
-         if(!stmt.compound.declarations)
-            stmt.compound.declarations = MkList();
-         curContext = stmt.compound.context;
-         for(c = 1; c<=function.tempCount; c++)
-         {
-            char ecereTemp[100];
-            sprintf(ecereTemp, "__ecereTemp%d", c);
-            stmt.compound.declarations->Insert(null,
-               QMkDeclarationBase(VOID, MkInitDeclarator(QMkPtrDecl(ecereTemp), null)));
-         }
-         curContext = stmt.compound.context.parent;
-      }
-   }
 }
 
 static void ProcessMemberInitData(MemberInit member)