compiler/libec: Fixed passing of typed objects in ellipsis functions; Fixed string...
[sdk] / compiler / libec / src / pass15.ec
index 7abf326..1d32137 100644 (file)
@@ -93,6 +93,7 @@ bool NeedCast(Type type1, Type type2)
          case intType:
          case int64Type:
          case intPtrType:
+         case intSizeType:
             if(type1.passAsTemplate && !type2.passAsTemplate)
                return true;
             return type1.isSigned != type2.isSigned;
@@ -317,8 +318,10 @@ public char * PrintDouble(double result)
       Operand op2 = GetOperand(exp);                        \
       if(op2.kind == intType && op2.type.isSigned) *value2 = (t) op2.i; \
       else if(op2.kind == intType) *value2 = (t) op2.ui;                 \
-      if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
+      else if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
       else if(op2.kind == int64Type) *value2 = (t) op2.ui64;                 \
+      else if(op2.kind == intSizeType && op2.type.isSigned) *value2 = (t) op2.i64; \
+      else if(op2.kind == intSizeType) *value2 = (t) op2.ui64; \
       else if(op2.kind == intPtrType && op2.type.isSigned) *value2 = (t) op2.i64; \
       else if(op2.kind == intPtrType) *value2 = (t) op2.ui64;                 \
       else if(op2.kind == shortType && op2.type.isSigned) *value2 = (t) op2.s;   \
@@ -333,18 +336,23 @@ public char * PrintDouble(double result)
       return true;                                                                  \
    }
 
-GETVALUE(Int, int);
-GETVALUE(UInt, unsigned int);
-GETVALUE(Int64, int64);
-GETVALUE(UInt64, uint64);
-GETVALUE(IntPtr, intptr);
-GETVALUE(UIntPtr, uintptr);
-GETVALUE(Short, short);
-GETVALUE(UShort, unsigned short);
-GETVALUE(Char, char);
-GETVALUE(UChar, unsigned char);
-GETVALUE(Float, float);
-GETVALUE(Double, double);
+// To help the deubugger currently not preprocessing...
+#define HELP(x) x
+
+GETVALUE(Int, HELP(int));
+GETVALUE(UInt, HELP(unsigned int));
+GETVALUE(Int64, HELP(int64));
+GETVALUE(UInt64, HELP(uint64));
+GETVALUE(IntPtr, HELP(intptr));
+GETVALUE(UIntPtr, HELP(uintptr));
+GETVALUE(IntSize, HELP(intsize));
+GETVALUE(UIntSize, HELP(uintsize));
+GETVALUE(Short, HELP(short));
+GETVALUE(UShort, HELP(unsigned short));
+GETVALUE(Char, HELP(char));
+GETVALUE(UChar, HELP(unsigned char));
+GETVALUE(Float, HELP(float));
+GETVALUE(Double, HELP(double));
 
 void ComputeExpression(Expression exp);
 
@@ -680,6 +688,7 @@ public int ComputeTypeSize(Type type)
          case intType: type.alignment = size = sizeof(int); break;
          case int64Type: type.alignment = size = sizeof(int64); break;
          case intPtrType: type.alignment = size = targetBits / 8; break;
+         case intSizeType: type.alignment = size = targetBits / 8; break;
          case longType: type.alignment = size = sizeof(long); break;
          case shortType: type.alignment = size = sizeof(short); break;
          case floatType: type.alignment = size = sizeof(float); break;
@@ -3104,17 +3113,19 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          return true;
       else if(dest.kind == shortType && source.kind == charType)
          return true;
-      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType))
+      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType || source.kind == intSizeType /* Exception here for size_t */))
          return true;
-      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == intType))
+      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intPtrType || source.kind == intSizeType))
          return true;
-      else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == intType))
+      else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intSizeType || source.kind == int64Type))
+         return true;
+      else if(dest.kind == intSizeType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == int64Type || source.kind == intPtrType))
          return true;
       else if(source.kind == enumType &&
-         (dest.kind == intType || dest.kind == shortType || dest.kind == charType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType))
+         (dest.kind == intType || dest.kind == shortType || dest.kind == charType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType || dest.kind == intSizeType))
           return true;
       else if(dest.kind == enumType &&
-         (source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType))
+         (source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType || source.kind == intSizeType))
           return true;
       else if((dest.kind == functionType || (dest.kind == pointerType && dest.type.kind == functionType) || dest.kind == methodType) && 
               ((source.kind == functionType || (source.kind == pointerType && source.type.kind == functionType) || source.kind == methodType)))
@@ -3427,6 +3438,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 {
    Type source = sourceExp.expType;
    Type realDest = dest;
+   Type backupSourceExpType = null;
 
    if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
       return true;
@@ -3503,9 +3515,9 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                if(tempType._class)
                   MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
 
-               FreeType(sourceExp.expType);
+               // NOTE: To handle bad warnings on int64 vs 32 bit eda::Id incompatibilities
+               backupSourceExpType = sourceExp.expType;
                sourceExp.expType = dest; dest.refCount++;
-
                //sourceExp.expType = MkClassType(_class.fullName);
                flag = true;            
 
@@ -3571,6 +3583,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
             FreeType(source);
             FreeType(dest);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
             return true;
          }
       }
@@ -3707,6 +3720,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                FreeType(source);
                if(inCompiler) FreeType(dest);
 
+               if(backupSourceExpType) FreeType(backupSourceExpType);
                return true;
             }
 
@@ -3762,6 +3776,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          {
             FreeType(source);
             FreeType(dest);
+            if(backupSourceExpType)
+            {
+               // Failed to convert: revert previous exp type
+               if(sourceExp.expType) FreeType(sourceExp.expType);
+               sourceExp.expType = backupSourceExpType;
+            }
             return false;
          }
       }
@@ -3811,6 +3831,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       {
          FreeType(source);
          FreeType(dest);
+         if(backupSourceExpType)
+         {
+            // Failed to convert: revert previous exp type
+            if(sourceExp.expType) FreeType(sourceExp.expType);
+            sourceExp.expType = backupSourceExpType;
+         }
          return false;
       }
 
@@ -3847,6 +3873,8 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
       FreeType(dest);
       FreeType(source);
+      if(backupSourceExpType) FreeType(backupSourceExpType);
+
       return true;
    }
    else
@@ -4203,6 +4231,19 @@ public Operand GetOperand(Expression exp)
                }
                op.kind = intType;
                break;
+            case intSizeType:
+               if(type.isSigned)
+               {
+                  op.i64 = (int64)_strtoi64(exp.constant, null, 0);
+                  op.ops = intOps;
+               }
+               else
+               {
+                  op.ui64 = (uint64)_strtoui64(exp.constant, null, 0);
+                  op.ops = uintOps;
+               }
+               op.kind = intType;
+               break;
             case floatType:
                op.f = (float)strtod(exp.constant, null);
                op.ops = floatOps;
@@ -4330,7 +4371,15 @@ static void PopulateInstanceProcessMember(Instantiation inst, OldList * memberLi
                case intPtrType:
                {
                   FreeExpContents(exp);
-
+                  // TODO: This should probably use proper type
+                  exp.constant = PrintInt64((int64)*(intptr*)ptr);
+                  exp.type = constantExp;
+                  break;
+               }
+               case intSizeType:
+               {
+                  FreeExpContents(exp);
+                  // TODO: This should probably use proper type
                   exp.constant = PrintInt64((int64)*(intptr*)ptr);
                   exp.type = constantExp;
                   break;
@@ -4643,6 +4692,11 @@ void ComputeInstantiation(Expression exp)
                                        GetIntPtr(value, (intptr*)ptr);
                                        break;
                                     }
+                                    case intSizeType:
+                                    {
+                                       GetIntSize(value, (intsize*)ptr);
+                                       break;
+                                    }
                                     case floatType:
                                     {
                                        GetFloat(value, (float*)ptr);
@@ -4711,6 +4765,12 @@ void ComputeInstantiation(Expression exp)
                                        Set(inst.data, (intptr)_strtoi64(value.constant, null, 0));
                                        break;
                                     }
+                                    case intSizeType:
+                                    {
+                                       void (*Set)(void *, intsize) = (void *)prop.Set;
+                                       Set(inst.data, (intsize)_strtoi64(value.constant, null, 0));
+                                       break;
+                                    }
                                  }
                               }
                               else if(value.type == stringExp)
@@ -4824,9 +4884,23 @@ void ComputeInstantiation(Expression exp)
                                     break;
                                  case intPtrType:
                                     if(type.isSigned)
+                                    {
                                        bits |= ((intptr)part << bitMember.pos);
+                                    }
                                     else
+                                    {
                                        bits |= ((uintptr)part << bitMember.pos);
+                                    }
+                                    break;
+                                 case intSizeType:
+                                    if(type.isSigned)
+                                    {
+                                       bits |= ((ssize_t)(intsize)part << bitMember.pos);
+                                    }
+                                    else
+                                    {
+                                       bits |= ((size_t) (uintsize)part << bitMember.pos);
+                                    }
                                     break;
                               }
                            }
@@ -5447,6 +5521,24 @@ void ComputeExpression(Expression exp)
                                  PopulateInstance(exp.instance);
                                  break;
                               }
+                              case intSizeType:
+                              {
+                                 // TOFIX:
+                                 intsize intValue;
+                                 void (*Set)(void *, intsize) = (void *)prop.Set;
+
+                                 exp.instance = Instantiation { };
+                                 exp.instance.data = new0 byte[_class.structSize];
+                                 exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+                                 exp.instance.loc = exp.loc;
+                                 exp.type = instanceExp;
+
+                                 GetIntSize(value, &intValue);
+
+                                 Set(exp.instance.data, intValue);
+                                 PopulateInstance(exp.instance);
+                                 break;
+                              }
                               case doubleType:
                               {
                                  double doubleValue;
@@ -5754,6 +5846,24 @@ void ComputeExpression(Expression exp)
                      exp.type = constantExp;
                   }
                   break;
+               case intSizeType:
+                  if(type.isSigned)
+                  {
+                     intsize value;
+                     GetIntSize(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintInt64((int64)value);
+                     exp.type = constantExp;
+                  }
+                  else
+                  {
+                     uintsize value;
+                     GetUIntSize(e, &value);
+                     FreeExpContents(exp);
+                     exp.constant = PrintUInt64((uint64)value);
+                     exp.type = constantExp;
+                  }
+                  break;
                case floatType:
                {
                   float value;
@@ -6243,7 +6353,7 @@ static void ProcessDeclaration(Declaration decl);
 
 static void GetTypeSpecs(Type type, OldList * specs)
 {
-   if(!type.isSigned && type.kind != intPtrType) ListAdd(specs, MkSpecifier(UNSIGNED));
+   if(!type.isSigned && type.kind != intPtrType && type.kind != intSizeType) ListAdd(specs, MkSpecifier(UNSIGNED));
    switch(type.kind)
    {
       case classType: 
@@ -6262,6 +6372,7 @@ static void GetTypeSpecs(Type type, OldList * specs)
       case shortType: ListAdd(specs, MkSpecifier(SHORT)); break;
       case int64Type: ListAdd(specs, MkSpecifier(INT64)); break;
       case intPtrType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intptr" : "uintptr")); break;
+      case intSizeType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intsize" : "uintsize")); break;
       case intType: 
       default:
          ListAdd(specs, MkSpecifier(INT)); break;
@@ -6332,6 +6443,7 @@ static void _PrintType(Type type, char * string, bool printName, bool printFunct
          case intType:  strcat(string, type.isSigned ? "int" : "uint"); break;
          case int64Type:  strcat(string, type.isSigned ? "int64" : "uint64"); break;
          case intPtrType:  strcat(string, type.isSigned ? "intptr" : "uintptr"); break;
+         case intSizeType:  strcat(string, type.isSigned ? "intsize" : "uintsize"); break;
          case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
          case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
          case floatType: strcat(string, "float"); break;
@@ -7747,7 +7859,7 @@ void ProcessExpressionType(Expression exp)
 
             if(assign && type1 && type1.kind == pointerType && exp.op.exp2.expType)
             {
-               if(exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
+               if(exp.op.exp2.expType.kind == intSizeType || exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
                {
                   if(exp.op.op != '=' && type1.type.kind == voidType) 
                      Compiler_Error($"void *: unknown size\n");
@@ -7904,14 +8016,14 @@ void ProcessExpressionType(Expression exp)
                      }
                   }
                   
-                  if(!boolResult && ((type1.kind == pointerType || type1.kind == arrayType || (type1.kind == classType && !strcmp(type1._class.string, "String"))) && (type2.kind == intPtrType || type2.kind == int64Type || type2.kind == intType || type2.kind == shortType || type2.kind == charType)))
+                  if(!boolResult && ((type1.kind == pointerType || type1.kind == arrayType || (type1.kind == classType && !strcmp(type1._class.string, "String"))) && (type2.kind == intSizeType || type2.kind == intPtrType || type2.kind == int64Type || type2.kind == intType || type2.kind == shortType || type2.kind == charType)))
                   {
                      if(type1.kind != classType && type1.type.kind == voidType) 
                         Compiler_Error($"void *: unknown size\n");
                      exp.expType = type1;
                      if(type1) type1.refCount++;
                   }
-                  else if(!boolResult && ((type2.kind == pointerType || type2.kind == arrayType || (type2.kind == classType && !strcmp(type2._class.string, "String"))) && (type1.kind == intPtrType || type1.kind == int64Type || type1.kind == intType || type1.kind == shortType || type1.kind == charType)))
+                  else if(!boolResult && ((type2.kind == pointerType || type2.kind == arrayType || (type2.kind == classType && !strcmp(type2._class.string, "String"))) && (type1.kind == intSizeType || type1.kind == intPtrType || type1.kind == int64Type || type1.kind == intType || type1.kind == shortType || type1.kind == charType)))
                   {
                      if(type2.kind != classType && type2.type.kind == voidType) 
                         Compiler_Error($"void *: unknown size\n");
@@ -8691,7 +8803,7 @@ void ProcessExpressionType(Expression exp)
             if(!type) emptyParams = true;
 
             // WORKING ON THIS:
-            if(functionType.extraParam && e)
+            if(functionType.extraParam && e && functionType.thisClass)
             {
                e.destType = MkClassType(functionType.thisClass.string);
                e = e.next;
@@ -8807,8 +8919,16 @@ void ProcessExpressionType(Expression exp)
                }
                else
                {
-                  e.destType = type;
-                  if(type) type.refCount++;
+                  if(type && type.kind == ellipsisType && type.prev && type.prev.kind == classType && type.prev.classObjectType)
+                  {
+                     e.destType = type.prev;
+                     e.destType.refCount++;
+                  }
+                  else
+                  {
+                     e.destType = type;
+                     if(type) type.refCount++;
+                  }
                }
                // Don't reach the end for the ellipsis
                if(type && type.kind != ellipsisType)
@@ -12077,16 +12197,46 @@ void ComputeDataTypes()
 {
    External external;
    External temp { };
+   External after = null;
+
    currentClass = null;
 
    containerClass = eSystem_FindClass(GetPrivateModule(), "Container");
 
-   temp.symbol = Symbol { id = -1000, idCode = -1000 };
-
-   // WHERE SHOULD THIS GO?
-   // curExternal = ast->first;
-   ast->Insert(null, temp);
+   for(external = ast->first; external; external = external.next)
+   {
+      if(external.type == declarationExternal)
+      {
+         Declaration decl = external.declaration;
+         if(decl)
+         {
+            OldList * decls = decl.declarators;
+            if(decls)
+            {
+               InitDeclarator initDecl = decls->first;
+               if(initDecl)
+               {
+                  Declarator declarator = initDecl.declarator;
+                  if(declarator && declarator.type == identifierDeclarator)
+                  {
+                     Identifier id = declarator.identifier;
+                     if(id && id.string)
+                     {
+                        if(!strcmp(id.string, "uintptr_t") || !strcmp(id.string, "intptr_t") || !strcmp(id.string, "size_t") || !strcmp(id.string, "ssize_t"))
+                        {
+                           external.symbol.id = -1001, external.symbol.idCode = -1001;
+                           after = external;
+                        }
+                     }
+                  }
+               }
+            }
+         }
+       }
+   }
 
+   temp.symbol = Symbol { id = -1000, idCode = -1000 };
+   ast->Insert(after, temp);
    curExternal = temp;
 
    DeclareFunctionUtil("eSystem_New");