compiler/libec: (#316) Added missing edge on opaque structs
[sdk] / compiler / libec / src / pass15.ec
index 4e244c2..6eaa2bb 100644 (file)
@@ -1155,7 +1155,6 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
    External external = null;
    Symbol classSym = FindClass(name);
    OldList * curDeclarations = null;
-   Specifier curSpec = null;
 
    if(!inCompiler || !classSym) return null;
 
@@ -1175,7 +1174,6 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
       for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
          if(spec.type == structSpecifier || spec.type == unionSpecifier)
          {
-            curSpec = spec;
             curDeclarations = spec.definitions;
             break;
          }
@@ -1187,16 +1185,15 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
       OldList * declarations = null;
       char structName[1024];
       bool addedPadding = false;
+      Specifier curSpec = null;
 
       classSym.declaring++;
 
       if(strchr(classSym.string, '<'))
       {
          if(classSym.registered.templateClass)
-         {
             external = _DeclareStruct(neededBy, classSym.registered.templateClass.fullName, skipNoHead, needDereference, fwdDecl);
-            classSym.declaring--;
-         }
+         classSym.declaring--;
          return external;
       }
 
@@ -1222,6 +1219,18 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
             AddMembers(external, declarations, classSym.registered, false, null, classSym.registered, &addedPadding);
          }
 
+         if(external.declaration)
+         {
+            Specifier spec;
+            for(spec = external.declaration.specifiers ? external.declaration.specifiers->first : null; spec; spec = spec.next)
+               if(spec.type == structSpecifier || spec.type == unionSpecifier)
+               {
+                  curSpec = spec;
+                  curDeclarations = spec.definitions;
+                  break;
+               }
+         }
+
          if(declarations && (!declarations->count || (declarations->count == 1 && addedPadding)))
          {
             FreeList(declarations, FreeClassDef);
@@ -1240,10 +1249,6 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
                curSpec.definitions = declarations;
             else
             {
-               char className[1024];
-               strcpy(className, "__ecereClass_");
-               FullClassNameCat(className, classSym.string, true);
-
                specifiers = MkList();
                declarators = MkList();
                ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), declarations));
@@ -1280,6 +1285,18 @@ External _DeclareStruct(External neededBy, const char * name, bool skipNoHead, b
          external.symbol = classSym;
          ast->Add(external);
       }
+      if(reachedPass15 && !external.declaration && classSym.registered && classSym.registered.type == noHeadClass)
+      {
+         // Declare nohead classes without definitions here (e.g. IteratorPointer)
+         char structName[1024];
+         OldList * specifiers, * declarators;
+         structName[0] = 0;
+         FullClassNameCat(structName, name, false);
+         specifiers = MkList();
+         declarators = MkList();
+         ListAdd(specifiers, MkStructOrUnion(structSpecifier, MkIdentifier(structName), null));
+         external.declaration = MkDeclaration(specifiers, declarators);
+      }
       if(fwdDecl)
       {
          External e = external.fwdDecl ? external.fwdDecl : external;
@@ -3920,7 +3937,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          (dest.isSigned ? (value >= -128 && value <= 127) : (value >= 0 && value <= 255)))
       {
          if(source.kind == intType)
+         {
+            FreeType(dest);
+            FreeType(source);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
             return true;
+         }
          else
          {
             specs = MkList();
@@ -3932,7 +3954,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          (source.kind == intType && (dest.isSigned ? (value >= -32768 && value <= 32767) : (value >= 0 && value <= 65535)))))
       {
          if(source.kind == intType)
+         {
+            FreeType(dest);
+            FreeType(source);
+            if(backupSourceExpType) FreeType(backupSourceExpType);
             return true;
+         }
          else
          {
             specs = MkList();
@@ -11146,6 +11173,16 @@ void ProcessExpressionType(Expression exp)
       }
    }
 
+   // Trying to do this here before conversion properties kick in and this becomes a new expression... (Fixing Class c; const char * a = c;)
+   // Mark nohead classes as by reference, unless we're casting them to an integral type
+   if(!notByReference && exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
+      exp.expType._class.registered.type == noHeadClass && (!exp.destType ||
+         (exp.destType.kind != intType && exp.destType.kind != int64Type && exp.destType.kind != intPtrType && exp.destType.kind != intSizeType &&
+          exp.destType.kind != longType && exp.destType.kind != shortType && exp.destType.kind != charType && exp.destType.kind != _BoolType)))
+   {
+      exp.byReference = true;
+   }
+
    yylloc = exp.loc;
    if(exp.destType && (/*exp.destType.kind == voidType || */exp.destType.kind == dummyType) );
    else if(exp.destType && !exp.destType.keepCast)
@@ -11698,7 +11735,7 @@ static void ProcessDeclarator(Declarator decl, bool isFunction)
                                  qualifiers = MkListOne(MkSpecifier(VOID));
                                  declarator = MkDeclaratorPointer(MkPointer(null,null), d);
                               };
-                              if(d.type != pointerDeclarator)
+                              if(!d || d.type != pointerDeclarator)
                                  newParam.qualifiers->Insert(null, MkSpecifier(CONST));
 
                               FreeList(param.qualifiers, FreeSpecifier);
@@ -11719,7 +11756,7 @@ static void ProcessDeclarator(Declarator decl, bool isFunction)
                               FreeList(param.qualifiers, FreeSpecifier);
 
                               param.qualifiers = MkListOne(MkSpecifier(VOID));
-                              if(d.type != pointerDeclarator)
+                              if(!d || d.type != pointerDeclarator)
                                  param.qualifiers->Insert(null, MkSpecifier(CONST));
                               param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
                               break;
@@ -11740,6 +11777,12 @@ static void ProcessDeclarator(Declarator decl, bool isFunction)
                         {
                            ProcessSpecifier(spec, isFunction, true);
                         }
+                        else if((spec.type == structSpecifier || spec.type == unionSpecifier) && !spec.definitions && spec.id && spec.id.string)
+                        {
+                           Declarator d = param.declarator;
+                           if(!d || d.type != pointerDeclarator)
+                              DeclareStruct(curExternal, spec.id.string, false, true);
+                        }
                      }
                   }
 
@@ -13336,6 +13379,8 @@ void DeclareFunctionUtil(External neededBy, const String s)
       FindSymbol(s, globalContext, globalContext, false, false);
 }
 
+bool reachedPass15;
+
 void ComputeDataTypes()
 {
    External external;
@@ -13365,6 +13410,7 @@ void ComputeDataTypes()
    DeclareFunctionUtil(null, "eInstance_StopWatching");
    DeclareFunctionUtil(null, "eInstance_Watch");
    DeclareFunctionUtil(null, "eInstance_FireWatchers");
+   reachedPass15 = true;
 
    for(external = ast->first; external; external = external.next)
    {